首页
社区
课程
招聘
Fuzzing101 Exercise 4 - LibTIFF CVE-2016-9297&CVE-2016-9448分析
发表于: 2023-7-30 18:21 14852

Fuzzing101 Exercise 4 - LibTIFF CVE-2016-9297&CVE-2016-9448分析

2023-7-30 18:21
14852

最近在进行Fuzzing的学习,发现对Crash分析的内容较少,故而写此篇分析记录一下,望与各位同行共同进步。
由于笔者也属于刚入门,若有误望大家指正。

• 漏洞名称:Libtiff 越界读取漏洞

• 漏洞编号:CVE-2016-9297

• 漏洞类型:越界读取

• 漏洞影响:拒绝服务

• CVSS评分:(CVSS 3.0 )7.5

• 利用难度:低

• 基础权限:不需要

LibTIFF是一个开源的用于处理TIFF(Tagged Image File Format)图像文件的C/C++库。TIFF是一种常见的图像文件格式,广泛应用于图像处理和存储。LibTIFF提供了一组功能丰富的API,允许开发者读取、写入、编辑和处理TIFF格式的图像。

使用tiffinfo解析Fuzzing出的样本。

image-20230730163505886

Libtiff <= 4.0.6

更新至Libtiff4.0.7以上版本

详细搭建可以参考Fuzzing101

目录创建

下载tiff-4.0.4

使用ASAN模糊测试。

image-20230726191551638

漏洞产生在tif_dirread.c函数中,在Field的TIFFSetGetFieldType属性为TIFF_SETGET_C32_ASCII或TIFF_SETGET_C16_ASCII时,输出Tag Value未在字符串末尾置0,从而可能导致越界读取。

此次的分析基于Fuzzing101的Exercise4所以选择4.0.4版本进行分析,CVE对该漏洞的描述为:

The TIFFFetchNormalTag function in LibTiff 4.0.6 allows remote attackers to cause a denial of service (out-of-bounds read) via crafted TIFF_SETGET_C16ASCII or TIFF_SETGET_C32_ASCII tag values.

在LibTiff 4.0.6中,TIFFFetchNormalTag函数存在漏洞,该漏洞可以被远程攻击者利用,通过精心构造的TIFF_SETGET_C16ASCII或TIFF_SETGET_C32_ASCII标签值来造成拒绝服务(越界读取)攻击。

查看一下crash文件。

image-20230729202713032

00h~01h:0x4949,使用小端序

02h~03h:0x002a,十进制42,为tif文件标识符。

04h~07h:第一个IFD(Image File Dirctory)的偏移。

image-20230729204018058

随后是10h开始的第一个IFD结构。

10h~11h:Directory Entries的数目。此处为11。

后续每12字节代表1个IFD Entry。

最后一个IFD Entry的后四个字节表示下一个IFD结构的偏移,如果没有为0。

IFD Entry结构(一个Entry也可以叫做一个field)。

00h~01h:该field的标识。

02h~03h :该field的数据类型。

04h~07h:数量,Count of the indicated Type,根据数量和类型确定其字节数。

08h~0Bh:值的文件偏移,如果该tag value占用字节数小于四字节,那么value存放于此。

划分一下数据

image-20230729211335813

红框处是下面出现crash寄存器出现的Tag 63253。此处可以注意一下。

tag:0xf715 63253

type:0x0002 ASCII类型

数量:0x00000001 1

Offset or 数据:0x00000003 3

AFL+ASAN对Libtiff4.0.4进行Fuzzing,执行Fuzzing出的Crash,得到提示,部分DirectoryEntry(简称DE结构)解析错误,错误为堆溢出。

image-20230729200522596

根据官方提示在__asan::ReportGenericError下断点,这里中断在asan报告错误之前,发生错误之后的地方,bt查看调用栈,产生错误的代码在tif_print.c:127

image-20230729191941723

由于ASAN会对程序进行插桩,阻碍汇编代码的阅读,所以笔者重新编译了一下源程序方便后续的调试。

gdb --args ./install/bin/tiffinfo -D -j -c -r -s -w ./out/default/crashes/crash对程序进行调试,从上述信息得出断点位置b tif_print.c:126,执行的时候上下文信息如图。

image-20230729212409579

这里将raw_data字符串打印了出来,raw_data对应的field为Tag 63253对应的field也就是我们crash文件红框标识的0xf715那一个DE结构。可以猜想一下逻辑,该DE结构被读入内存,输出的时候分配了一段内存空间用来存储其Value,随后根据其DE结构的类型(ASCII)输出Tag和对应的Value。回想一下,当时我们的数据长度为0x1,每一个ASCII类型占8位,所以我们该Tag的Value应该是0x3,但是这里显然,如果将raw_data输出,会输出03 3b e4 e4 f7 ff 7f。这里显然访问了不应该访问的内存。但是这并不会产生crash,因为该内存地址是可读写的。

image-20230729213248332

随后raw_data的内存下一个写入断点,重新执行程序,看看它是什么时候写入的。

第一次,该内存存放了一个_TIFFField结构指针

image-20230729214055057

从信息可以看出,该结构是一些的Tag信息,由于Tag 63253是一个在标准的Tag列表中没有,所以会进行一次Merge。

第三次,0x00007ffff7e43be0和最后输出的值很接近了。

image-20230730133820704

image-20230730133717401

image-20230730133705291

bt查看一下调用栈。笔者决定从tif_dirread.c:5351开始跟一遍。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 4
支持
分享
最新回复 (5)
雪    币: 15170
活跃值: (16832)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
2
感谢师傅分享,这个角度真的很少有人过多关注
2023-8-3 09:35
0
雪    币: 2948
活跃值: (30846)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2023-8-3 09:49
1
雪    币: 1511
活跃值: (398)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4

感谢师傅分享,我这里是SetByteArray把无关数据写进raw_data所在的地址



读中断

#0  0x0000ffff8b2ed7c4 in tcache_get (tc_idx=<optimized out>) at ./malloc/malloc.c:3197
#1  __GI___libc_malloc (bytes=bytes@entry=1) at ./malloc/malloc.c:3313
#2  0x0000aaaaadf185ec in _TIFFmalloc (s=s@entry=1) at tif_unix.c:283
#3  0x0000aaaaadf0663c in setByteArray (vpp=0xaaaadfa59c68, vp=0xaaaadfa59be0, nmemb=1, elem_size=<optimized out>) at tif_dir.c:51
#4  0x0000aaaaadf0864c in _TIFFVSetField (tif=0xaaaadfa592a0, tag=57347, ap=...) at tif_dir.c:539
#5  0x0000aaaaadf09604 in TIFFVSetField (tif=0xaaaadfa592a0, tag=57347, ap=...) at tif_dir.c:820
#6  0x0000aaaaadf09710 in TIFFSetField (tif=<optimized out>, tag=<optimized out>) at tif_dir.c:764
...



写中断

#0  __memcpy_generic () at ../sysdeps/aarch64/multiarch/../memcpy.S:123
#1  0x0000aaaaadf0864c in _TIFFVSetField (tif=0xaaaadfa592a0, tag=57347, ap=...) at tif_dir.c:539
#2  0x0000aaaaadf09604 in TIFFVSetField (tif=0xaaaadfa592a0, tag=57347, ap=...) at tif_dir.c:820
#3  0x0000aaaaadf09710 in TIFFSetField (tif=<optimized out>, tag=<optimized out>) at tif_dir.c:764
...
最后于 2023-8-15 23:01 被KitTraumen编辑 ,原因:
2023-8-15 23:00
0
雪    币: 1036
活跃值: (641)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
KitTraumen 感谢师傅分享,我这里是SetByteArray把无关数据写进raw_data所在的地址读中断#0&nbsp;&nbsp;0x0000ffff8b2ed7c4&nbsp;in&a ...
师傅的tag是57347是不同的样本吗?按理说最后print的raw_data就是#3  0x0000aaaaadf0663c in setByteArray (vpp=0xaaaadfa59c68, vp=0xaaaadfa59be0, nmemb=1, elem_size=<optimized out>) at tif_dir.c:51 这里malloc的内存地址。 而setByteArray应该对应此时的tag(57347)的value,师傅能提供样本让我看看吗?
2023-9-22 10:46
0
雪    币: 1036
活跃值: (641)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6

最近突然看到一篇对main_arena利用的文章,文中未写入tag对应value之前,内存中存放的是main_arena+96的地址,这样越界读取可能会造成glic的基址泄露。但是我仍未明白为何CVE-2016-9297这个洞会标明拒绝服务。 main_arena相关:https://cloud.tencent.com/developer/article/1740444

最后于 2023-9-22 10:50 被hu1y40编辑 ,原因:
2023-9-22 10:49
0
游客
登录 | 注册 方可回帖
返回
//