hu1y40's blog

hu1y40'blog
天堂的穹空遍布地狱之火的颜色,但也是天堂。
  1. 首页
  2. FUZZ
  3. 正文

CVE-2016-9297 & CVE-2016-9448 Libtiff 越界读取漏洞挖掘,分析与调试

2023年10月7日 2074点热度 0人点赞 0条评论

0x01 漏洞信息

1.漏洞简述

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

• 漏洞编号:CVE-2016-9297

• 漏洞类型:越界读取

• 漏洞影响:拒绝服务

• CVSS评分:(CVSS 3.0 )7.5

• 利用难度:低

• 基础权限:不需要

2.组件概述

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

3.漏洞利用

使用tiffinfo解析Fuzzing出的样本。

fig:

4.漏洞影响

Libtiff <= 4.0.6

5.解决方案

更新至Libtiff4.0.7以上版本

0x02 漏洞复现

1. 环境准备

目录创建

cd $HOME
mkdir fuzzing_tiff && cd fuzzing_tiff/

下载tiff-4.0.4

wget https://download.osgeo.org/libtiff/tiff-4.0.4.tar.gz
tar -xzvf tiff-4.0.4.tar.gz

使用ASAN模糊测试。

rm -r $HOME/fuzzing_tiff/install
cd $HOME/fuzzing_tiff/tiff-4.0.4/
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared
AFL_USE_ASAN=1 make -j4
AFL_USE_ASAN=1 make install
afl-fuzz -m none -i $HOME/fuzzing_tiff/tiff-4.0.4/test/images/ -o $HOME/fuzzing_tiff/out/ -s 123 -- $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w @@

2.FUZZING

fig:

0x03 漏洞分析

1. 基本信息

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

2. 详细分析

2.1基础分析

此次的分析基于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标签值来造成拒绝服务(越界读取)攻击。

2.2静态分析

查看一下crash文件。

fig:

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

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

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

fig:

随后是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存放于此。

划分一下数据

fig:

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

tag:0xf715 63253

type:0x0002 ASCII类型

数量:0x00000001 1

Offset or 数据:0x00000003 3

2.3动态分析

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

fig:

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

fig:

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

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

fig:

这里将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,因为该内存地址是可读写的。

fig:

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

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

struct _TIFFField {
uint32 field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
uint32 reserved; /* reserved for future extension */
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */
TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */
unsigned short field_bit; /* bit in fieldsset bit vector */
unsigned char field_oktochange; /* if true, can change while writing */
unsigned char field_passcount; /* if true, pass dir count on set */
char* field_name; /* ASCII name */
TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */
};

fig:

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

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

fig:

fig:

fig:

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

fig:

TIFFSetField函数传入了一个DE结构,一个data,这个data存放的值Tag 的Value。

fig:

随后进入内部,发现该函数做了如下操作,执行_TIFFVSetField函数找到Tag对应的TIFField malloc一个TIFFValue给它,最后分配了一个空间存储Value,该空间的起始地址也就是后续print的raw_data,尽管只分配了1字节的空间,但是由于是64位的Linux,内存分配的大小最小也是0x20字节,所以如下图,0x20为chunkSize,03为存储的Value。

fig:

fig:

后续打印会打印0x7ffff7e43b03,属于是越界读取。但是由于该地方的内存只是单纯的一个地址信息,且由内存管理机制决定,所以似乎无法造成信息泄露。尝试修改Tag的Value数目使得读取其他内存,其计算的偏移会和文件的Size进行一个比较,无法利用。

fig:

2.4 补丁分析

在输出字符串的结尾提前放置了\x00防止越界读取。

但是显然这里产生了新的漏洞,如果dp->tdir_count=0,那么data就是NULL,这时候对空指针进行了Read操作。

fig:

CVE-2016-9448 的描述看起来起来就是这个原因。

fig:

fig:

按照第一次的补丁修改一下源码,随后修改Tag的Count为0,果然出现了Segmentation fault。

fig:

fig:

 

标签: 漏洞
最后更新:2023年10月7日

hu1y40

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • 0x01 漏洞信息
    • 1.漏洞简述
    • 2.组件概述
    • 3.漏洞利用
    • 4.漏洞影响
    • 5.解决方案
  • 0x02 漏洞复现
    • 1. 环境准备
    • 2.FUZZING
  • 0x03 漏洞分析
    • 1. 基本信息
    • 2. 详细分析
      • 2.1基础分析
      • 2.2静态分析
      • 2.3动态分析
      • 2.4 补丁分析

分类目录

  • 0day安全
  • Bypass
  • C++Prime
  • CTF
  • DoS
  • DoS
  • FUZZ
  • iot
  • JSONP
  • MISC
  • MISC
  • PHP伪协议
  • Python
  • REVERSE
  • sqli-labs
  • SQL注入
  • Trick
  • UAF
  • WEB
  • WEB
  • XXE
  • 书籍阅读
  • 二进制
  • 代码阅读
  • 信息搜集
  • 信息泄露
  • 加密与解密
  • 双重释放漏洞
  • 反序列化
  • 命令执行
  • 命令执行
  • 堆溢出
  • 密码学
  • 弱加密
  • 提权漏洞
  • 整数溢出
  • 文件上传
  • 未分类
  • 栈溢出
  • 格式化字符串漏洞
  • 模型
  • 汇编语言
  • 渗透测试
  • 漏洞分析
  • 漏洞利用
  • 漏洞战争
  • 漏洞挖掘
  • 病毒分析
  • 越界读取
  • 路径遍历
  • 逻辑漏洞
  • 配置不当
  • 钓鱼
  • 靶场
最新 热点 随机
最新 热点 随机
加密算法 2023年度总结 RTSPServer StackOverflow Vulnerability FUZZ 总览篇 MP4Box 无限循环漏洞 CVE-2023-40477 Winrar RCE漏洞分析
bugku 多种方法解决 加密与解密 第2章实验 bignum库遭受S3 Bucket劫持攻击 CVE-2010-3974 fxscover双重释放漏洞 文件上传靶场pass-11-20 sqli-labs 21-30

COPYRIGHT © 2023 hu1y40's blog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鄂ICP备2021009673号-1