TTF 字体是 Apple 和 Microsoft 两家公司共同推出的字体格式,现在已经广泛的运用于 Windows 操作系统,其中 PDF 文档也可以嵌入 TTF 字体,该漏洞的成因是由于在运行 TTF - glyf 表中的图元指令时没有对传入的数据做严格的过滤,导致整数溢出,经过利用之后可以执行任意代码
这个就是 POC 文件当中嵌入的 TTF 字体文件,经过 PdfStreamDumper 提取过后,可用工具查看
分析环境:Windows 7 + Adode Reader 9 Pro(提取码:yc76)
分析工具:Windbg、IDA、OD、PdfStreamDumper、C32Asm
漏洞样本:poc.pdf(提取码:x84d)
VeryARM TTF 介绍:https://www.veryarm.com/42913.html
苹果 TTF 文档官网:https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
Windbg 附加进程拖入 POC 后断在了这个地方,读写了不可访问的地址所以触发异常,出问题的模块是 CoolType.dll 动态链接库
由于缺少符号文件所以堆栈中看不出什么信息来,而且 ecx 的地址既不属于进程堆,也不属于进程栈,可能是 DLL 中划分的地址空间
IDA 反编译以后的漏洞触发点,该漏洞触发点在 sub_800798b 中,在调试中 82323E0 存放的是栈顶的地址,而 82323EC 存放的栈底的地址
经过交叉引用,发现是在这个地方调用了 sub_800798b 函数,参考一些资料后发现这个调用并不是简单的函数调用,而是根据 TTF - glyf 表中的图元指令间接的调用的
由于清楚了调用关系,所以在这个地方下内存记录断点,看看图元指令是怎么调用的,ecx 中保存着图元指令
由于是堆栈计算器,进行简单计算只需要压入或弹出两个操作数即可,所以记录栈顶向下的两个操作数即可,一个位于栈顶减去 4 个字节,一个位于栈顶减去 8 个字节
在堆栈上计算比较特殊,比如:压入指令把一个值压入堆栈,弹出指令从堆栈中弹出上面的值,二元加法指令弹出上面的两个值 ,然后把它们的和压入堆栈,这个上面说过
图元指令操作完成之后,再记录一下,以便做对比,便于看出图元指令是怎么计算的
设置分隔符,便于看清
运行之后断在了触发漏洞的地方,这时查看 log 窗口,截取了一部分
与 TTF 样本中的数据进行对比,是基本一致的。从 41 号图元指令开始,构造用于溢出的数据,最后的 26 号图元指令就是最后触发漏洞的图元指令
结合苹果文档,可以看出堆栈是怎么计算的,下面列出了堆栈的详细计算过程
图元指令
操作数
功能
41
06 4141 4141 4141 0030 0000 0040
将 \x4141 \x4141 \x4141 \x0030 \x0000 \x0040 压入虚拟堆栈
42
无
将数据储存到临时空间并弹出两个栈顶数据
41
02 7FFF 7FFF
将 \x7FFF \x7FFF 压入虚拟堆栈
63
位于栈顶的两个值
将 \x7FFF 乘以 \x7FFFF,结果存放在堆栈中
60
位于栈顶的两个值
将 \x3EFF0404 + \xFFFC00,结果存放在栈顶
41
04 FFE8 0000 0000 0000
将 \xFFE8 \x0000 \x0000 \x0000 压入栈中
43
位于栈顶的值
读取数据,将 1 压入栈中
B0
01
将 \x01 压入栈中
61
位于栈顶的两个值
将 1 - 1,结果存入栈顶
42
无
将数据储存到临时空间并弹出两个栈顶数据
43
无
读取数据,虚拟栈不变
78
无
跳转指令用于循环操作
41
02 7FFF 7FFF
将 \x7FFF \x7FFF 压入虚拟堆栈当中
60
位于的栈顶两个值
将 \x7FFF + \x7FFF,结果存放在栈顶
60
位于的栈顶两个值
将 \x7FFF + \x3FFF0003 = \x40000001,结果存放在栈顶
当执行完上面的指令操作之后,就会执行 26 号图元指令,也就是触发漏洞的函数,下面来调试看看
重新运行之后,断在了指令函数里面,此时 ecx 保存的指令值为正是 26
首先会将虚拟栈顶和栈底的地址分别储存再 eax 和 ecx 寄存器中,之后会进行栈边界是否超出的判断
之后会取出位于栈顶的操作数 \x40000001 存入 edx 中,这个操作数就是之前经过一系列图元指令计算后得到的结果,之后将 \x40000001 * 4,溢出后结果为 \x4,从而绕过了之后堆栈边界检查,这也是漏洞的根源所在
最后会将 \x40000001 作为循环计数,利用一种算法循环把整个栈空间的数据向栈顶移动 4 个字节
这个就是移动栈空间的糟糕算法,因为循环计数太大,导致超出栈底大量的数据都会朝栈顶移动 4 个字节,鉴于这个特殊原因,所以这个漏洞利用起来难度也是蛮大的
参考资料:0day安全 + 漏洞战争
以上就是对 CVE-2012-0774 漏洞分析的全部内容,如有错误,欢迎指正
手机扫一扫
移动阅读更方便
你可能感兴趣的文章