设为首页 - 加入收藏
广告 1000x90
您的当前位置:144177黄大仙有求必应 > 静态分析 > 正文

细说CVE-2010-2883从原理分析到样本构造

来源:未知 编辑:admin 时间:2019-07-21

  可能是各位大佬都比较忙的缘故,在学习了网上各种前辈们的漏洞报告之后,总感觉叙述的不够详细,小白理解起来较为困难。因此秉承着前人栽树后人浇水的原则,我也想尝试写一篇个人认为较为详细的漏洞分析,但由于水平有限不足之处请谅解。并借此记录下近日的学习成果。望各位不吝赐教!

  strcat 会将参数 src字符串复制到参数 dest 所指的字符串尾部,dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。

  往上追溯会发现这里的 strcat 函数的两个参数一个值是 ebp+108h+var_108 另一个值是 ebp+108h+var_12C,仔细观察会发现这里并没有去验证 src的长度是否可能会超出 dest 数组定义的长度,因此如果我们有可能将超出 dest 数组定义长度的数据放入 src中有可能可以在后方调用 strcat 函数时覆盖栈区从而实现代码执行。

  这里我们先借助 Metasploit 帮助我们生成一个样本用于动态调试 (之后会分析这个样本是如何构造出来的)。

  为了便于等下动态调试识别一些关键数据块,我们考虑修改一下这个 exploit 的一处地方。

  这里的 rand_text 主要作用是取随机字符,目的是为了增强样本的随机性从而躲避一些检测。这里我们只做研究之用,所以不必随机。修改之后保存

  我们将刚才的样本拖入到 Adobe Reader 中。程序就会停在刚才下的断点上面。

  执行这句指令之后我们来看看 ecx 到底存了什么。此时的 ecx = 0x0012E4B4,首先猜测这是一个指针地址,定位到数据区域之后,取出前 32 位的十六进制。

  由于在 X86 架构下是小端字节序,因此我们将数据排列成 0x046D41F4。这应该就是 ecx 指针所指向的地址,定位到数据区域。可以看到如下数据

  在分析这段数据之前我们先来看看 TrueType 字体格式标准文档里是怎么说的。

  在 TrueType 字体文件中,从 0 字节偏移的位置开始处有一个表目录。且这个表目录的第一个字段是名为 sfnt version 是用来表明所用 ttf 格式版本的字段。在文档中清楚的标注了,对于 1.0 版本的 TTF 字体文件开头要用 0×00010000 来表示版本。回到我们刚才 0x046D41F4 位置处的数据,会发现开头正好是 0×00010000,这就证明了 ecx 保存的是一个指向 ttf 对象的指针地址并且在这里应该是作为 this 指针。

  分析到这里,继续我们的动态调试。接下来遇到了一个 call 指令,意味着即将调用一个函数。在调用函数前我们不妨先看看这个函数传入了哪些参数。

  很明显它将 SING 字符串当作参数了。这里我们单步 F8 不进入 call 函数内部。

  这里大量的 A 原本都是随机字符,由于刚才我们修改了 exploit 的代码因此使得这里的数据块更容易辨认。实际上这些数据都是样本中 SING 表里构造好的恶意数据。

  因此总结一下,以上的指令主要就是将 SING 表的 tag 名传入到 08021B06 函数中通过表目录来获取到 SING 表的入口地址,而目前 eax 的值 0x046BE598 即是 SING 表的入口地址。分析 SING 表的这些数据,我们就能知道样本到底做了些什么。

  第一个 pusheax 将刚刚获取到的 SING 表入口地址压入栈区。第二个 pusheax 获取了当前栈区的 ebp 地址即要连接字符串的目的地址。我们单步过 strcat 之后,查看一下 ebp 开始的栈区数据。

  此时栈溢出已经发生,栈区数据已经被修改成了 SING 表中构造的恶意数据 (实际上是从 uniqueName 字段开始的数据)。

  执行到 0x0808B308 时,我们发现了一个很有意思的地方。即调用了 [eax] 地址指向的函数。此时的 eax = 0012E6D0,这正好处于我们刚才覆盖的栈区数据范围内。

  这里又到了一个关键的地方。看到 0x0C0C0C0C 我们很自然的会想到 HeapSpary 技术。在这个样本中确实利用到了堆喷射的技术,借助 PDF 本身支持执行 JS 的特性,将 shellcode 借助 JS 写入内存中。实际上这里也可以不借助堆喷射来实现任意代码执行,但是这样的话就会增大 ROP 链的构造难度,因此选择利用堆喷射的方法来写入 shellcode 是一种非常巧妙的做法。

  仔细观察可以发现接下来的 ROP 链调用的都是 icucnv36.dll 这个库中的地址,原因在于这个库是没有开启 ASLR 保护的。还有需要说明的一点是,之所以要借助堆喷射技术来执行代码的原因是为了绕过 windows 环境下的 DEP 保护。

  继续动态分析。此时即将执行 retn,而 esp 指向的地址是 0x0c0c0c0c,即

  dwDesiredAccess 用于指定访问权限一般都是读、写之类的。这里的 GENERIC_ALL 指的是采用所有可能的访问权限。

  dwShareMode 用于指定请求的文件或设备的共享模式,这里指定的 0 代表了阻止其他进程在请求删除,读取或写入访问权限时打开文件或设备。

  lpSecurityAttributes 用于设置安全描述符和子进程是否可继承,这个属性可为 NULL,这里用的就是 NULL。

  dwCreationDisposition 设置对文件执行的操作。这里的 CREATE_ALWAYS 代表总是会创建文件,即使目标文件已存在也会覆盖它。

  hTemplateFile 设置具有 GENERIC_READ 访问权限的模板文件的有效句柄。这个属性这里也没用到直接指定 NULL。

  总之这里创建了一个临时文件,文件名是 iso88591。可以在当前样本 pdf 同目录下找到。

  这里利用同样的方法调转到 [eax] 所在的函数 CreateFileMappingA 处,该函数用于创建一个文件映射内核对象。

  这里用到的 memcpy 函数将要执行的 shellcode 写入到 MapViewOfFile 返回的地址。因为这段内存是可读可写的,所以就绕过了 DEP 的保护。

  call ebp 之后执行 calc.exe 命令。总结一下这部分由堆喷射覆盖在栈上的数据都做了一些什么。主要做了新建临时文件,将文件映射到内存,将真正的 shellcode 拷贝到内存的某一块区域并且解码这些 shellcode 然后执行。

  前面提到过,这个漏洞样本的编写中,借助了 PDF 本身支持 JS 的特性实现了堆喷射。这里我们借助 PDFStreamDumper 工具提取样本中的这段实现堆喷射的 JS 代码段。

  这样的指令执行的效果对 al 寄存器不会产生任何影响很适合当作滑板指令是堆喷射的常用技巧。

  接下来的 var_b 保存了前面的所有滑板指令以及 shellcode。最关键的实现堆喷射的语句是 new Array

  利用数组来开辟内存区域,然后通过填充数组数据的方式来喷射 shellcode。

  先回顾一下漏洞的触发点,漏洞的触发点是在解析 TTF 字体的 SING 表时出现的问题。那很显然我们首先要了解一下 TTF 的格式定义以及 SING 表的具体字段。同时我们还需要了解 PDF 格式规范当中是如何来引用 TTF 字体文件的,以及 PDF 是怎么支持 Java 脚本执行的。

  首先看到的是 Header 部分。这是 PDF 文件的开始部分。主要用来指明当前 PDF 文件所遵循的 PDF 格式标准版本。例如%PDF-1.5

  Body 部分包含了 PDF 文档的主要内容,所有向用户展现的内容都在此存放。

  Cross-reference table 即交叉引用表,包含了当前 PDF 文档中所有对象的引用、偏移量以及字节长度。借助这个引用表可以在全文档范围内随机访问任何一个对象,非常的方便。

  Trailer 主要包含了指向交叉引用表的指针以及一些关键对象的指针并且以%%EOF 标记文件结束,帮助符合标准的阅读器能够快速定位到需要的对象。所有的 PDF 阅读器都是要从这里开始解析。

  了解完 PDF 基本格式。秉承着用到什么再提什么的原则,我们这里通过分析 MSF 提供的 exp 来帮助理解 PDF 文档的构造过程。

  这个脚本是用 ruby 语言编写的,对于 ruby 语法的相关细节本文不再赘述。

  这里描述的是 Header 部分的内容,首先定义了版本号,这个样本遵循的是 PDF1.5 版本。

  该函数用于随机出不再 ASCII 范围内的字符。换句线 个字符。关于这四个字符的作用。Adobe 给出的 PDF 文档里是这样描述的

  这四个 code 大于 128 的字符用于确保当前 PDF 文档被当作二进制文件来对待而不是文本文件。

  看完了 Header 部分的实现,再看 Body 部分的实现之前,先来了解一下 Body 部分大致的组织结构。

  用于表示对象编号和生成数,在 PDF 中间接对象都是由两个关键词obj和endobj表示的,endobj 关键字必须自成一行,obj 对象所在行需要有两个由空格隔开的数字来分别表示对象编号和对象生成数。对象编号用来唯一区分和标识各个对象,对象生成数会随着对象每次被释放之后递增 (具体详情可以参考官方文档)。下面是一个间接对象的例子:

  很显然 io_def 函数的主要作用就是用来表示对象的对象编号和生成数以及 obj 关键字。这里的生成数默认是 0。

  该函数随机编码字母字符 (以 #%x 的形式)。主要作用应该是混淆和免杀。

  在 catalog 中包含了非常多的可选和必选的字段条目。首先在 catalog 中,/Type 条目是必须要存在的,它的值被固定为/Catalog。/Page 条目也是必选的,它指向了一个间接对象 Page。io_ref 函数的定义如下:

  在 PDF 中引用 (或指向) 一个间接对象需要用一个对象编号,生成数以及一个关键字R来表示。这里的 io_ref(2) 表示引用了一个对象编号为 2 的对象。

  其中/OpenAction 是 PDF 执行 JS 的关键也是该样本实现堆喷射的地方。/OpenAction 中指向了一个数组或者字典对象,该对象可能描述了某种行为,这个行为会在 PDF 文档被加载时执行。剩下的/AcroForm 则指向了一个交互式表单字典 (之后会解释为什么在样本中使用了一个交互式表单)。

  我们从/Pages 指向的页面对象开始分析。/Page 条目指向了一个对象编号为 2 的页面对象。

  同样的/Type 条目是必选的并且值固定为/Pages,/Count 条目用来记录 Page 树中的叶子结点个数。这里其实还有一个/Parent 必选条目用来指定父结点,但是由于这里是根结点所以可以忽略该条目。/Kid 条目用来引用一个数组,数组的元素是当前结点的直接子结点。/MediaBox 是个可选条目,定义了要显示或打印页面的物理媒介的区域。/Resources 记录了当前 Page 用到的所有资源,可空。在当前样本中就是在 Resources 条目中指定了字体,从而引入有恶意数据的 TTF 字体文件。这里我们重点分析一下/Resources 条目。

  这里的/F1 代表了使用 Type 1 字体技术定义字形形状的字体 (关于 Type1 详情请看文档)

  FontFile2 指向了一个流对象,这个流对象即是 TTF 字体数据,我们构造的 SING 表数据也包含在内。在 PDF 中流对象由 Stream 和 Endstream 关键字标识。

  接下来分析一下如何构造 ttf。分析 MSF 提供的 exp 发现它在构造的时候并没有从头根据 TrueType 字体的标准文档从零开始构造,而是选择了采用一个现有的字体文件并把 SING 表格插入进去。这确实是很省力的一种做法。

  这里首先填充了 uniqueName 字段之前的字段数据。并且注意到这里使用了 pack(『v』) 函数来实现小端字节序。如果你仔细阅读 TrueType 的文档描述,会了解到 TrueType 实际上遵循的是大端字节序来描述数据,这里之所以采用小端是因为此时的 uniqueName 字段数据已然不是原先的作用了,它此时包含的是要在 x86 架构环境下执行的指令地址,而 x86 架构下需要遵循的是小端字节序。

  继续往下看,这里使用了 rand_text 函数填充了随机字符,主要作用是混淆。在前面为了方便识别数据块,我们将随机字符固定成了「A」。

  之后就是将前面我们动态调试时分析过的几个关键地址写入 SING 表中。并把 TTF 字体中的 name 表替换成 SING 表。

  到此为止,我们已经知道了如何构造 SING 表和 TTF 以及在 PDF 中如何引用这个 TTF 字体文件。接下来再来分析一下 PDF 中是如何执行 Java 的。

  这个函数将 ASCII 转换成十六进制并且中间随机间隔 1 到 3 个空格。

  在前面的介绍中已经把核心的 JS 代码介绍了。接下来看下 EXP 中是怎么构造 JS 的。

  首先定义了一个 stack_data 变量,该变量中存储了构造的 ROP 链。由于代码太长,省略了中间的 shellcode。同样这里也用了 pack(『V*』) 按照小端字节序来处理。

  再将刚才的变量代入到进 js 变量中形成完整的 Java 堆喷射代码。至此 js 部分就分析完成了。

  以上代码是 PDF 构造的结尾部分。用于生成交叉引用表和 trailer 表。交叉引用表每一行包含了一个对象的文件偏移,生成数以及空间占用标识符。并以%%EOF 标识结束。

  至此样本构造部分的分析就结束了,虽然有很多地方还是没有讲的很清楚,有兴趣的朋友可以阅读 PDF 的官方文档深入了解 PDF 的详细情况。

  该函数获取了字段的长度,判断是否超出限制。如果超出限制就用 strncat 限制了拷贝的字节数从而修复了该漏洞。

本文链接:http://that-a-way.com/jingtaifenxi/429.html

相关推荐:

网友评论:

栏目分类

现金彩票 联系QQ:24498872301 邮箱:24498872301@qq.com

Copyright © 2002-2011 DEDECMS. 现金彩票 版权所有 Power by DedeCms

Top