0x00 前言
drops中看到一篇XSS另类上传涉及到EXIF,于是对EXIF存储进行学习记录下。美国人制定这些标准很直观的意思,非要命名一个玄乎的。。所以自己记东西更多的还是转换成自己理解的角度,因此口头语也较多,可能这也会导致存在一定的不严谨或者错误,如果发现请帮忙指出,谢谢!
0x01 简介
Exif(Exchangeable image file format 可交换图像文件格式),是一种图像文件格式,其数据存储与JPEG格式是完全相同的。Exif可以附加于JPEG、TIFF、RIFF 等文件之中,也就是在这些文件的头部插入了数码照片的信息,包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及GPS全球定位系统数据、缩略图等。
0x02 原理
JPEG文件都是以十六进制 '0xFFD8'
开始,以'0xFFD9'
结束。在JPEG数据中有一系列0xFF??
格式的字符串,这些被称为“标志”,用来标记JPEG文件的信息段。其中0xFFD8
表示SOI(Start of image 图像开始),0xFFD9
表示EOI(End of image 图像结束)。这两个特殊的标志没有附加的数据,而其他的标志在标志后都会带有附加的数据。
0xFFE0 — 0xFFEF
之间的标识符称为“应用标志”,在解码JPEG 图像的时候不是必需使用的。其中Exif信息即存在应用标志中,以0xFFE1
作为开头标记,后两个字节表示Exif信息的长度,内部采用TIFF格式存储。如通过下图直观发现jpeg的开头和结尾标志内均没有附加数据,Exif信息存在在引用标志App1中。
首先开头十六进制FF D8
是SOI标志(表示图片开头);
紧跟着FF E1 2F FE
是APP1标志以及其长度(后面两个字节表示EXIF数据长度,这里的长度是包含自身的。);
接下来紧跟着就是APP1的数据内容,内容这块分为两部分,第一个部分用来定义我这张图片是否要使用Exif,如果要就如上图紧跟着45 78 69 66 00 00
(转换后就是ASCII字符串”Exif”加上两个字节的0x00);
接下来就是正常的Exif数据内容(用TIFF格式存储数据),紧跟着的是4D 4D
表示采用大端字节顺序(定义TIFF数据采用什么字节顺序,如果是0x4949 = "II"
就表示采用”Intel”的小端字节顺序,如果为0x4d4d = ''MM"
,表示采用”Motorola”的大端字节顺序,这个字节只要知道下即可。);
接下来几个字节分别是'00 2A'
(标识)'00 00 00 08'
(APP1偏移地址) '00 0B'
(IFD 的个数),这几个只要大概了解下即可。
接下来的的字节就是各种IFD信息,IFD就相当于文件夹,然后在文件夹下面存放着各种资料,比如资料可以是GPS,设备信息,厂家等,我们正常使用电脑会创建很多文件夹,所以同理IFD也有多个文件夹(IFD编号),比如IFD0(主图的元数据),IFD1(缩略图的元数据),这里说的元数据乍一听很抽象,不过仔细一听还是很抽象QAQ。。,这个可以理解成用来描述IFD内信息的一种数据叫法,比如相机型号:索尼 这就是一条元数据。
我们正常操作电脑肯定不会一个个磁盘下一个个文件夹打开然后再依次找到你想要的那个文件夹对吧,直接找比如C盘下xx文件夹更方便嘛,所以同理这里我主要找的是GPS IFD,一方面用于修改GPS,一方面用于注入恶意代码。因此接下来任务就是定位GPS IFD 入口。
在定位之前需要了解下IFD格式这样对于后面分析有很大帮助,IFD格式是一个 IFD 由四部分组成,每一个 IFD都是固定的12个字节,分别是
Bytes 0-1 Tag(用于标记这个IFD类别) Bytes 2-3 Type(用于指定数据类型) Bytes 4-7 Count(用于指数据的数量,比如纬度就用度、分、秒三个数来描述) Bytes 8-11 Value Offset(真实数据所在的偏移地址(相对于 File header),而且需要注意的是,这里记录的值小于 4 个字节,则数据左对齐。)
Exif规范在定义时并没有规定必须包含哪些 IFD 及其顺序。但是,第一个 IFD 的位置是可以确定的,从第一个每隔十二字节又可以确定一个 IFD,再从 tag 确定 IFD 类别,然后依次类推找到对应IFD。还有一种比较简便的,十六进制0x8825
是GPS IFD入口,直接搜这个然后根据tag定位也可以。
比如寻找GPS IFD Pointer(这个东西可以理解成我们电脑的磁盘,比如C盘下存在11个文件夹,其中有个文件夹就是用来存放GPS,在GPS IFD下面又存在子文件夹也就是子tag,比如说经纬度,高度,视觉方向等等。)
根据IFD格式分割得:
88 25 00 04 数据类型为Long 00 00 00 01 00 00 06 48
可以看出GPS信息位于地址68 48
处。但是这个值是相对于 File Header (也就是地址 000C
)产生的,因此真实的地址为16进制的6848 + 000C = 6854
修改GPS的话主要关心的是经纬度,与之相关的Tag如下:
#GPSLatitudeRef Tag = 1 Type = ASCII Count = 2 Default = None 'N' = North latitude 'S' = South latitude Other = reserved
#GPSLatitude Tag = 2 Type = RATIONAL Count = 3 Default = None
#GPSLongtitudeRef Tag = 3 Type = ASCII Count = 2 Default = None 'E' = East longtitude 'W' = West longtitude Other = reserved
#GPSLongtitude Tag = 4 Type = RATIONAL Count = 3 Default = None
接下来分别进行定位
第一个横线处4E00
是ASCII中的N,这个不需要修改。
第二个横线处指出真实纬度的偏移位置 0702 + 000C = 070E
第三个横线处4500
是ASCII中的E,这个也不需要修改。
第四个横线处指出真实经度的偏移位置 071A + 000C = 0726
然后根据真实地址070E
再进行跟进,这里采用WinHex分析,方便修改保存数据。
其中前4字节为分子,后4字节为分母,十六进制先转为十进制,之所以这样是因为之前说到的FID数据类型决定的;
从而得到纬度数据为: 20.H/01.H = 32;01.H/0.H = 0;0FE2.H/64.H = 40.66
,对比得完全一致
同理跟进出精度位置。
接下来就是修改数据,比如这里修改成114.146288,22.440669(114°8'46.6368",22°26'26.4084")
转换成16进制纬度为72.H 8.H 2e.H
,经度(16.H 1a.H 1a.H
)接下来写入
测试GPS经纬已经变化,原图检验也过了。
0x03 辨别
由于Exif信息是可以被任意编辑的,因此可以利用JPEGsnoop或者MagicEXIF工具判断Exif是原始的还是被修改过的(工具修改大多会留下痕迹),不过这种辨别方式也只能作为参考,(比如上面修改的GPS信息后他检测还是原图)如果对方修改的很细致(上面修改虽然检测还是原图但是不是非常细致,我的分母为了方面是一直设置为1的,更细致点分母应该多合理变化下。),一般MagicExif这类工具就很难辨别;对于更为细致的辨别可以参考这篇论文:Exif信息在数码照片真实性鉴定中的应用。
0x04 利用
定位
利用火狐插件查看其exif信息,
然后复制其GPS坐标到在线经纬转换,得到结果为 39.90884722222222,116.39958333333334
接下来放入Google Earth、百度拾取坐标系统或者openstreet等这类地图定位网站。
反社工
既然EXIF信息能修改,比如可以在别人社工之前提前修改好图片定位可以迷惑下对方,也可以在图片中注入xss,如果对方通过浏览器一些插件查看则会被触发,因此存在一定限制条件,可以做为一个手法结合其他姿势搞搞。
0x05 工具
0x06 引用
*作者:coco413,原创投稿MottoIN。未经允许禁止转载!
原创文章,作者:M0tto1n,如若转载,请注明出处:http://www.mottoin.com/article/web/97860.html