CVE-2010-2883 漏洞研究

CVE-2010-2883 是 Adobe Reader 和 Acrobat 中的 CoolType.dll 库在解析字体文件 SING 表中的 uniqueName 项时存在的栈溢出漏洞,用户受骗打开了特制的 PDF 文件就有可能导致任意代码执行。这种”打开 PDF 即刻中招”的效果堪称”简单暴力”的典范,也使其作为漏洞而言非常经典
影响范围:
Adobe Reader 8.2.4 - 9.3.4
TTF 结构与 SING 表结构
一个 PDF(Portable Document Format)文件在文件结构上主要由四个部分组成
- Header 文件头,用于注明 PDF 文件的版本号,其值为 %PDF-版本号
- Body 文件体,主要有组成文件的对象组成,如图片,文字等
- Cross-reference table 交叉引用表,用于存放所有对象的位置偏移,可以方便地访问 PDF 中的任意对象
- Trailer 文件尾,给出了交叉引用表的位置和一些关键对象的信息,以 %%EOF 结尾
PDF Body 可以被视作一个树状的层次结构,其中的每一个结点都是一个对象,由其根节点 Document Catalog 开始,其节点包括了文档的内容(Page Tree),纲要(Outline)等等属性。在 PDF 中会包含字体对象,它的内容是一个 TTF 字体文件
一个 TTF 文件(The TrueType Font File)由一个表目录与一系列的表组成,表目录 Font Directory 记录了整个文件以及各个表的信息,其记录的每张表目录项的结构如下
1 | typedef struct |
每一张表都有一个四字节大小的标签,SING(Smart INdependent Glyphlets,智能独立字形包)则是这些标签之一。SING 技术是Adobe公司推出的针对“外字”(Gaiji)的解决方案,外字是日语中的意思,中文中就是生僻字的意思。的意思。SING 允许用户创建新字形,每个新字形作为一个独立的字体打包。这样打包出来的字形称为字形包(glyphlet)。这一规范允许字形包随同文件一起传送,这样包含SING字符的文件也是可携带的,而又不会字符乱码、异常显示。SING 表目录项的结构体值往往为
1 | TableEntry |
TrueType字体中的所有数据都使用big-endian编码,最高位字节在最前面(因为TrueType字体最初是由apple公司定义的,而apple公司的os运行在motorola的cpu上)。
而一个 SING 表的内容的数据结构则如下所示
1 |
|
其中 uniqueName 字段需要记住,因为这与该漏洞的利用密切相关
漏洞分析
使用 IDA 打开 CoolType.dll 库,从漏洞描述可知漏洞代码引用了 SING 字符串,这意味着攻击者可以直接采用基于字符串定位的分析方法,即搜索 “SING” 字符串并查看交叉引用,便能够定位到这段代码
1 | .rdata:0819DB4C aSing db 'SING',0 ; DATA XREF: sub_8015AD9+D2↑o |
反编译后得到
1 | sub_80217D7(v20,a1,"name"); |
它首先会读取 SING 表,之后将 SING 表中 0x10 偏移处(即 UniqueName 字段)通过调用 strcat 函数直接拼接到 Destination 中,而 strcat 函数会将参数 src 字符串复制到参数 dest 所指的字符串尾部,src 字符串的拷贝从第一个字符开始,直到遇到 “\x00” 时结束。这一函数调用过程没有检验拼接的字符串的长度,即未考虑拼接后的字符串超度是否会超出 dest 字符串长度,故存在栈溢出漏洞,攻击者可通过在 TTF 文件的 SING 表的 uniqueName 字段处(0x10 偏移位置)填入任意长度的字符串实施栈溢出攻击
漏洞利用
使用 MSF 搜索该漏洞的 exp
1 | msfconsole |
搜索结果
1 | Matching Modules |
调用该模块并查看模块详情
1 | msf6 > use exploit/windows/fileformat/adobe_cooltype_sing |
模块详情信息
1 | Name: Adobe CoolType SING Table "uniqueName" Stack Buffer Overflow |
使用该模块生成木马 PDF 文件
1 | msf6 exploit(adobe_cooltype_sing) > set FILENAME Crash.pdf |
Exploit 分析
Exploit 代码概览
该模块的 exp 位于
1 | /usr/share/metasploit-framework/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb |
让我们来看看这个 exp 是如何进行漏洞利用的
1 | require 'msf/core' |
通过审计 exploit 函数,我们能够很快地理解这个 exp 工作的大体流程是生成恶意的 ttf 与 js 文件,把它们封装到木马 pdf 文件中并导出 pdf 到本地。忽略制作 pdf 文件与增加 payload 随机性进行混淆的相关函数,exp 进行漏洞利用的核心代码显然位于 make_ttf 与 make_js 两个函数中。由于栈溢出是由 ttf 文件中的中的 payload 触发的,因此我们先从 make_ttf 函数开始审计
make_ttf 函数
1 | def make_ttf |
查看基础文件的 0xec 与 0x11c 处,发现这两处其实是基础文件的 name 表。make_ttf 函数的实际工作流程就是把基础文件的 NAME 表 tag 改为了 SING,并用包含了 Payload 的 sing 字符串的内容替换了基础文件的 NAME 表内容。查看导出的 TTF 文件能够发现该文件中不存在 NAME 表,与上述结论相符合。接下来让我们仔细审计 uniqueName 字段中填入的 payload
1 | # 0xffffffff gets written here @ 0x7001400 (in BIB.dll) |
以上代码设置了一条 ROP 链,用于劫持执行流到 Heap Spray 的用于绕过 DEP 的 payload 处,如下图所示(图来自 Sp4n9x 的博客)
其中的 ROP Gadget 选择了 icucnv36.dll 中的指令,选择这两处地址中的指令的原因在于,如果打开 icucnv36.dll,会发现其 IMAGE_OPTIONAL_HEADER 中的IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 的值为 0,也就是说这个 dll 库没有开启 ASLR。事实上,在 Adobe Reader 的各个版本上,这个库应该都基于 Adobe 的某种需要而始终没有开启 ASLR。这使得该 exp 对受影响的各版本 Adobe Reader 都能够稳定且兼容地进行漏洞利用
make_js 函数
既然 ttf 文件中的 payload 是用来跳转到真正的执行 shellcode 的 payload 上的,后者存在的位置也就只能是在 make_js 函数里了。事实上,在审计 exploit ruby 代码时就能够非常容易发现 make_js 函数里存放的大量 payload。接下来审计 make_js 函数
1 | def make_js(encoded_payload) |
make_js 需要接受一段加密后的 shellcode 作为参数,这段 shellcode 将会经过 make_js 函数的处理后被执行。可以发现 exp 在讲 shellcode 存入 payload_buf 前,先向 payload_buf 中存入了 stack_data 内的 payload,对其进行审计
1 | 0x41414141, # unused 用于补齐堆块内容长度占用的 4B |
这段 payload 同样包含了一条 ROP 链,且其中的 ROP Gadget 均位于未开启 ASLR 的 icucnv36.dll 库中,其执行内容为调用四个函数,分别是
- CreateFileA 创建一个文件或设备,payload 创建了一个名为iso88591的文件,且该文件可读可写可执行
- CreateFileMappingA 创建文件映射内核对象,文件与物理页映射,payload 将创建的文件映射到了物理内存地址
- MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间。payload 将创建的文件映射到了程序所处的虚拟内存地址空间
- memcpy 将源地址的内容复制到目的地址,payload 将 0x1000 字节
即通过前三个函数创建一个可读可写的内存段,并将 shellcode 复制到该内存段中,进而绕过 DEP 执行 shellcode。
在这之后,exp 创建了一段 JavaScrip 代码,并将上述 payload 及 shellcode 封装到了 JS 代码中,其中
1 | payload_buf = '' |
用于封装 payload 的格式化 JS 代码为
1 | // 重命名函数 |
填充后的 JS 代码和 TTF 文件一同被封装到木马 PDF 文件中,并被传播给攻击目标
漏洞修复
Adobe Reader v9.4.0 修复了这个漏洞,其中 CoolType.dll 从 v5.5.72.1 更新到了 v5.5.73.1,区别在于 strcat 函数加入了长度检查,令人感慨
Reference
NVD - CVE-2010-2883
CVE - CVE-2010-2883
漏洞战争
Adobe Official Document
没有比我更详细的CVE-2010-2883分析了
TTF Document
SING Table Definition
sp4n9x’s Blog
2010.09.09 - VUPEN - Criminals Are Getting Smarter: Analysis of the Adobe Acrobat/Reader 0-Day Exploit
- Title: CVE-2010-2883 漏洞研究
- Author: 7erry
- Created at : 2024-08-11 19:28:31
- Updated at : 2024-08-11 19:28:31
- Link: http://7erry.com/2024/08/11/CVE-2010-2883-漏洞研究/
- License: This work is licensed under CC BY-NC 4.0.