以上文章由作者【hackedbylh】的连载有赏投稿,共有五篇,本文为第四篇;也欢迎广大朋友继续投稿,详情可点击 OSRC重金征集文稿!!! 了解~~ 温馨提示:建议投稿的朋友尽量用markdown格式,特别是包含大量代码的文章
概述
本节以FoxitReader和IrfanView为例介绍内存 Fuzz的实现以及 WINAFL 的常规使用技巧。FoxitReader
软件分析 目前Fuzz大型软件的常用方式是对大型软件分析,找到软件中的负责数据处理的模块,然后编写一个Loader把模块加载起来后进行测试。本节以FoxitReader为例介绍如何分析软件并进行内存Fuzz以及用WinAFL来Fuzz程序。 FoxitReader是一款PDF工具,可以查看、创建和修改PDF文件,它还可以通过图片来创建PDF文件,使用图片创建PDF时,FoxitReader会对图片进行解析然后再去创建PDF文件,由于图片文件的格式复杂多样,软件在解析图片时就有可能会产生漏洞,下面就去看看如何Fuzz FoxitReader中负责图片解析的模块。 首先我们需要定位当通过图片创建PDF时,处理图片的逻辑在哪个模块,后面才能针对性地去Fuzz。Process Monitor可以监控程序执行过程的注册表、文件和网络操作,对于一些关键的API还会记录调用栈。为了定位图片处理所在的模块,首先打开Process Monitor监控事件,然后用图片来创建一个PDF文件,PDF创建好后让Process Monitor停止监控事件,下面就可以去分析日志了。使用过滤功能Process Monitor只显示对图片文件的操作 查看监控API的调用栈可以发现读取文件的模块是 ConvertToPDF_x86.dll,看文件名也感觉是进行PDF转换任务的。 下面分析一下程序是如何使用这个库的,首先用IDA分析这个DLL,先看看DLL的导出函数,因为其他模块使用DLL的功能,肯定会使用DLL的导出函数 。 可以看到ConvertToPDF_x86.dll只有两个导出函数,下面用windbg给导出函数下个断点,看看这两个函数的调用顺序。首先打开程序,然后用 windbg 附加进程,用sxe命令设置模块加载断点,当ConvertToPDF_x86模块加载起来时调试器会断下来sxe ld:ConvertToPDF_x86
断下来后我们给模块的所有导出函数下断点
bm /a ConvertToPDF_x86!*
继续运行后,程序首先会断在CreateFXPDFConvertor函数
0:000> bm /a ConvertToPDF_x86!*
1: 00000000`6d798e30 @!"ConvertToPDF_x86!DestorFXPDFConvertor"
2: 00000000`6d79aaf0 @!"ConvertToPDF_x86!CreateFXPDFConvertor"
0:000> g
Breakpoint 2 hit
ConvertToPDF_x86!CreateFXPDFConvertor:
6d79aaf0 a10cd1c36d mov eax,dword ptr [ConvertToPDF_x86!CreateFXPDFConvertor+0x4a261c (6dc3d10c)] ds:002b:6dc3d10c=00000000
拿IDA分析一下这个函数
_DWORD *CreateFXPDFConvertor()
{
_DWORD *result; // eax
void *obj; // eax
result = dword_104AD10C;
if ( dword_104AD10C )
return result; // 调用malloc分配内存
obj = alloc(0x1BDCu);
if ( obj )
{
result = init_obj(obj); // 初始化对象
dword_104AD10C = result;
}
else
{
result = 0;
dword_104AD10C = 0;
}
return result;
}
这个函数比较简单首先会用 malloc 分配0x1BDC的内存,然后会调用init_obj初始化分配的内存块,init_obj函数会先设置虚表,然后设置对象里的其他一些字段。
_DWORD *__thiscall init_obj(int this)
{
int v1; // esi
v1 = this;
*this = &CFX_PDFConvertor::`vftable'; // 给对象设置虚表
sub_1000A720((this + 4));
*(v1 + 7104) = 0;
*(v1 + 7108) = 0;
*(v1 + 7112) = 0;
*(v1 + 7120) = 0;
*(v1 + 7116) = 1;
dword_104AD104 = 0;
*(v1 + 7124) = 0;
*(v1 + 7128) = 0;
return v1;
}
虚表的结构如下
.rdata:10336F1C ; const CFX_PDFConvertor::`vftable'
.rdata:10336F1C ??_7CFX_PDFConvertor@@6B@ dd offset sub_1000B060
.rdata:10336F1C ; DATA XREF: init_obj+6↑o
.rdata:10336F1C ; sub_1000A8F0+BA↑o
.rdata:10336F20 dd offset sub_10009B40
.rdata:10336F24 dd offset sub_1000A2D0
.rdata:10336F28 dd offset sub_1000A8F0
虚表里面有4个函数,按照正常的程序逻辑,程序在创建模块对象后,肯定会调用对象的函数来使用模块提供的功能,接下来给这4个函数下断点,看看这些函数的调用关系以及参数信息。windbg的打印信息如下
0:000:x86> lm m Conver*start end module name6d790000 6dcb5000 ConvertToPDF_x86 (export symbols) C:\Program Files (x86)\Foxit Software\Foxit Reader\Plugins\Creator\x86\ConvertToPDF_x86.dll0:000:x86> dd 0x6dac6f1c l4 // 查看虚表的函数的实际地址6dac6f1c 6d79b060 6d799b40 6d79a2d0 6d79a8f00:000:x86> bp 6d79b060 0:000:x86> bp 6d799b40 0:000:x86> bp 6d79a2d0 0:000:x86> bp 6d79a8f00:000:x86> bl0 e x86 6d79b060 0001 (0001) 0:**** ConvertToPDF_x86!CreateFXPDFConvertor+0x5701 e x86 6d798e30 0001 (0001) 0:**** ConvertToPDF_x86!DestorFXPDFConvertor2 e x86 6d79aaf0 0001 (0001) 0:**** ConvertToPDF_x86!CreateFXPDFConvertor3 e x86 6d799b40 0001 (0001) 0:**** ConvertToPDF_x86!DestorFXPDFConvertor+0xd104 e x86 6d79a2d0 0001 (0001) 0:**** ConvertToPDF_x86!DestorFXPDFConvertor+0x14a05 e x86 6d79a8f0 0001 (0001) 0:**** ConvertToPDF_x86!DestorFXPDFConvertor+0x1ac00:000:x86> gBreakpoint 3 hitConvertToPDF_x86!DestorFXPDFConvertor+0xd10:6d799b40 55 push ebp 0:000:x86> r // 首先调用6d799b40函数eax=6d799b40 ebx=0ad6a1a8 ecx=0ad6a1a8 edx=6dac6f1c esi=0088fb68 edi=00000002eip=6d799b40 esp=002cce0c ebp=002cece8 iopl=0 nv up ei pl zr na pe nccs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246ConvertToPDF_x86!DestorFXPDFConvertor+0xd10:6d799b40 55 push ebp0:000:x86> dps esp l4 # 参数为 2002cce0c 02398a54 FoxitReader!CryptUIWizExport+0x885514002cce10 00000002002cce14 711d4f33002cce18 02c2f814 FoxitReader!CryptUIWizExport+0x111c2d40:000:x86> gBreakpoint 4 hitConvertToPDF_x86!DestorFXPDFConvertor+0x14a0:6d79a2d0 55 push ebp0:000:x86> r // 然后调用6d79a2d0eax=002cec10 ebx=0ad6a10b ecx=0ad6a1a8 edx=6d79a2d0 esi=0ad6a1a8 edi=0000