其他
殊途同归的CVE-2012-0774 TrueType字体整数溢出漏洞分析
本文为看雪论坛精华文章
看雪论坛作者ID:LarryS
1
介绍
Integer overflow in Adobe Reader and Acrobat 9.x before 9.5.1 and 10.x before 10.1.3 allows attackers to execute arbitrary code via a crafted TrueType font.
2
文件格式分析理解
2.1 利用010editor初步分析TTF文件结构
Executing template 'C:\Users\test\Documents\SweetScape\010 Templates\Repository\TTF.bt' on 'D:\Myfiles\vul_study\ldzz\2012-0774\poc.ttf'...
*WARNING Line 158: Variable 'glyphIdArray' not generated since array size is zero.
typedef struct tcmap_format4 {
cmap_subtable = FTell();
USHORT format; // Format number is set to 4.
USHORT length; // This is the length in bytes of the subtable.
USHORT language; // Please see "Note on the language field in 'cmap' subtables" in this document.
USHORT segCountX2; // 2 x segCount.
USHORT searchRange; // 2 x (2**floor(log2(segCount)))
USHORT entrySelector; // log2(searchRange/2)
USHORT rangeShift; // 2 x segCount - searchRange
USHORT endCount[segCountX2 / 2]; // End characterCode for each segment, last=0xFFFF.
USHORT reservedPad; // Set to 0.
USHORT startCount[segCountX2 / 2]; // Start character code for each segment.
SHORT idDelta[segCountX2 / 2]; // Delta for all character codes in segment.
USHORT idRangeOffset[segCountX2 / 2]; // Offsets into glyphIdArray or 0
USHORT glyphIdArray[(length-(FTell()-cmap_subtable))/2 ]; // Glyph index array (arbitrary length) !!!就是这里出现了问题!!!
};
2.2 通过文档详细了解TTF文件格式
2.2.1 name表
2.2.2 cmap表
2.2.3 maxp表
2.2.4 loca表
2.2.5 glyf表
3
漏洞调试
3.1 确定异常成因
(158.f9c): Access violation - code c0000005 (!!! second chance !!!)
eax=632c622c ebx=00000214 ecx=632d0000 edx=3fffd88a esi=632d0004 edi=00004141
eip=630979ce esp=0030cdf0 ebp=0030ce84 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Adobe\Reader 9.0\Reader\CoolType.dll -
CoolType+0x79ce:
630979ce 8919 mov dword ptr [ecx],ebx ds:0023:632d0000=00001000
0:000> !address 632d0000
Failed to map Heaps (error 80004005)
Usage: Image
Allocation Base: 63090000
Base Address: 632d0000
End Address: 632ef000
Region Size: 0001f000
Type: 01000000 MEM_IMAGE
State: 00001000 MEM_COMMIT
Protect: 00000002 PAGE_READONLY
More info: lmv m CoolType
More info: !lmi CoolType
More info: ln 0x632d0000
int __cdecl vulFunc(int a1) {
if ( (a - 4) < *b
|| (high = *(b + 0x154), a - 4 >= high)
|| (end = (a - 4), len = *(a - 4), start = (a - 4 - 4 * len), start < *b)
|| start >= high ) {
result = dword_232438;
dword_232434 = 0x1110;
} else {
v5 = *start;
if ( len > 0 ) {
do {
--len;
*start = start[1]; // 异常发生位置
++start;
}
while ( len );
--end;
}
*end = v5;
a = (end + 1);
result = a1;
}
return result;
}
0:000> p
eax=6426622c ebx=00000000 ecx=03ec2e04 edx=6426622c esi=64266220 edi=64266344
eip=640379af esp=0031cd90 ebp=0031ce24 iopl=0 nv up ei pl nz na po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000203
CoolType+0x79af:
640379af 8b10 mov edx,dword ptr [eax] ds:0023:6426622c=40000001 // 长度是40000001
0:000> p
eax=6426622c ebx=00000000 ecx=03ec2e04 edx=40000001 esi=64266220 edi=64266344
eip=640379b1 esp=0031cd90 ebp=0031ce24 iopl=0 nv up ei pl nz na po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000203
CoolType+0x79b1:
640379b1 8bda mov ebx,edx
0:000> p
eax=6426622c ebx=40000001 ecx=03ec2e04 edx=40000001 esi=64266220 edi=64266344
eip=640379b3 esp=0031cd90 ebp=0031ce24 iopl=0 nv up ei pl nz na po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000203
CoolType+0x79b3:
640379b3 c1e302 shl ebx,2 // 长度*4
0:000> p
eax=6426622c ebx=00000004 ecx=03ec2e04 edx=40000001 esi=64266220 edi=64266344
eip=640379b6 esp=0031cd90 ebp=0031ce24 iopl=0 ov up ei pl nz na po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000a03
CoolType+0x79b6:
640379b6 8bc8 mov ecx,eax
3.2 确定数据来源
3.2.1 TrueType指令系统分析
0:000> dd 64266200 lc
64266200 00000000 00000000 00000000 00000000
64266210 00000000 00000000 00000000 00000000
64266220 00004141 00004141 00004141 40000001
// NPUSHW操作,入栈6个WORD,同时扩展为DWORD
41, 06, 41 41, 41 41, 41 41, 00 03, 00 00, 00 40
// Write Store操作,弹出两个DWORD
42
// NPUSHW操作,入栈2个WORD,同时扩展为DWORD
41, 02, 7F FF, 7F FF
// MULtiply操作,弹出两个DWORD,入栈乘法结果
63
// ADD操作,弹出两个DWORD,入栈加法结果
60
// NPUSHW操作,入栈4个WORD,同时扩展为DWORD
41, 04, FF E8, 00 00, 00 00, 00 00
// Read Store操作,弹出一个读取位置DWORD,入栈一个读取结果DWORD
43
// PUSHB操作,入栈1个BYTE,同时扩展为DWORD
B0, 01
// SUBtract操作,弹出2两个DWORD,入栈减法结果
61
// Write Store操作,弹出两个DWORD
42
// Read Store操作,弹出一个读取位置DWORD,入栈一个读取结果DWORD
43
// Jump Relative On True操作,弹出两个DWORD,并根据第一个DWORD决定指令要不要跳转
78
// NPUSHW操作,入栈2个WORD,同时扩展为DWORD
41, 02, 7F FF, 7F FF
// ADD操作,弹出两个DWORD,入栈加法结果
60
// ADD操作,弹出两个DWORD,入栈加法结果
60
//Move the INDEXed element to the top of the stack 从栈顶弹出一个元素k,循环移动栈中接下来的k个元素
26
// 注意这里就是vulFunc在执行的操作,所以不再向下分析
3.2.2 代码分析及动态调试
.text:00006955
.text:00006955 loc_6955:
.text:00006955 51 push ecx
.text:00006956 50 push eax
.text:00006957 FF 14 8D D0 BE 21 00 call funcs_6409C64D[ecx*4]
.text:0000695E 59 pop ecx
.text:0000695F 59 pop ecx
.data:0021BED0 6A 6C 00 00 C5 6C 00 00 20 6D+funcs_6409C64D dd offset sub_6C6A, offset sub_6CC5, offset sub_6D20, offset sub_6D6D
.data:0021BED0 00 00 6D 6D 00 00 BA 6D 00 00+ ; DATA XREF: sub_690E+49↑r
.data:0021BED0 F3 6D 00 00 2C 6E 00 00 2C 6E+ ; sub_6C605+48↑r
.data:0021BED0 00 00 6B 70 00 00 6B 70 00 00+ dd offset sub_6DBA, offset sub_6DF3, offset sub_6E2C, offset sub_6E2C
.data:0021BED0 52 71 00 00 5F C6 06 00 CA 71+ dd offset sub_706B, offset sub_706B, offset sub_7152, offset sub_6C65F
.data:0021BED0 00 00 1F 72 00 00 74 72 00 00+ dd offset sub_71CA, offset sub_721F, offset sub_7274, offset sub_729E
.data:0021BED0 9E 72 00 00 95 75 00 00 D5 75+ dd offset sub_7595, offset sub_75D5, offset sub_7615, offset sub_76CC
.data:0021BED0 00 00 15 76 00 00 CC 76 00 00+ dd offset sub_76CC, offset sub_76CC, offset sub_76CC, offset sub_7655
.data:0021BED0 CC 76 00 00 CC 76 00 00 CC 76+ dd offset sub_7756, offset sub_7767, offset sub_751B, offset sub_995C
.data:0021BED0 00 00 55 76 00 00 56 77 00 00+ dd offset sub_999F, offset sub_7558, offset sub_6C6C8
.data:0021BED0 67 77 00 00 1B 75 00 00 5C 99+ dd offset sub_6C70D, offset sub_78A2, offset sub_7696
.data:0021BED0 00 00 9F 99 00 00 58 75 00 00+ dd offset sub_6C815, offset sub_78FB, offset sub_6C826
.data:0021BED0 C8 C6 06 00 0D C7 06 00 A2 78+ dd offset sub_7939, offset vulFunc, offset sub_6CBDA, offset sub_6C7A0
...
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=03ec2e04 edi=03ec2c54
eip=6403690e esp=0031cf08 ebp=0031cf80 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
CoolType+0x690e:
6403690e 8b442404 mov eax,dword ptr [esp+4] ss:0023:0031cf0c=03ec2f6c
0:000> bc *
0:000> bp CoolType+0x6957 "r ecx;g"
ecx=00000078
ecx=00000041
ecx=00000063
ecx=00000060
ecx=00000041
ecx=00000043
ecx=000000b0
ecx=00000061
ecx=00000042
ecx=00000043
4
总结
参考资料:
1、TrueType Reference Manual(关于各个表以及指令的介绍都在这里)(https://developer.apple.com/fonts/TrueType-Reference-Manual/)
2、《漏洞战争》
看雪ID:LarryS
https://bbs.pediy.com/user-home-600394.htm
# 往期推荐
2.DAP-LINK研究笔记-用STM32单片机替换J-LINK
球分享
球点赞
球在看
点击“阅读原文”,了解更多!