0x01 前言

  • CVE-2010-2883 漏洞的成因是由于 CoolType.dll 这个动态链接库在解析 SING 表中的 uniqueName 这个项时没有对长度进行限制,导致使用 strcat 函数拼接字符串时造成了溢出
  • 分析工具:ODImmunity Debutter(基于 OD 的漏洞调试工具)、PdfStreamDumper(PDF文档分析工具)
  • 环境:Windows 7 家庭版(虚拟机)、开启了 ASLR 和 DEP 保护
  • 样本:触发漏洞的 PDF 文件(提取码:95h4,请在虚拟机中测试),Adobe Reader 9.3.4(提取码:yc76)

0x02 基于样本的调试分析

  • 使用 PdfStreamDumper 载入 PDF 样本

  • 根据官方文档,入口地址 0x11c 为 SING 表的真实数据

  • 之后在偏移 0x10 即是 uniqueName 的数据,uniqueName 为 28 位,对齐后为 4 个字节

  • 先断一下 CoolType.dll 中的断点

  • 右击->中文搜索引擎->智能搜索->搜索SING字符串,搜索结果有好多,需要一个一个筛选

  • 找到漏洞触发的地方,按 F2 键下断

  • PDF 阅读器载入 OD

  • 运行程序,打开有漏洞的样本,期间可能会弹出程序崩溃对话框,关闭即可

  • 在漏洞出断下,可以看到标志性的 strcat 函数

  • 执行到如下位置

  • 将堆栈在数据窗口中跟随

  • 对紫色覆盖的区域,也就是样本中的数据下内存访问断点(经过多次测试的结果),什么是内存访问断点,就是读取有内存访问断点的内存的时候就对断下来,有助于看出什么时候程序在读取样本

  • F9 执行,经过多次执行,发现断在了 retn 这个地方(因为 retn 太特殊了)

  • 观察此时堆栈窗口,发现返回值为 4A82a714

  • 单步 F8,此时已经到达 icucnv36.dll 的动态链接库中,这个 pop esp 是跳到 shellcode 的关键一步

  • 此时的堆栈窗口

  • 单步 F8

  • 此时 ESP 为 0x0c0c0c0c,点睛之笔

  • 堆栈成功变为 shellcode(是不是很神奇,以后制作 ROP 链的时候又多了一种方法)

0x03 逻辑图

0x04 样本是如何绕过系统对缓冲区的防御

  • 堆栈 cookie 我没有研究过,所以不清楚样本文件是如何绕过的
  • 针对 ASLR 样本绕过的方式是使用未被 ASLR 的动态链接库 icucnv36.dll 这个动态链接库,使用 Immunity Debugger 载入这个动态链接库

  • F9 运行两次,之后在命令行输入 !mona modules 查询一下,发现这个动态链接库果然没有受到 ASLR 的保护(Immunity Debutter 运行 !mona modules 命令时需要用到 mona.py 脚本,提取码:6ehp,将脚本复制到 Immunity Debutter 目录下的 PyCommands 文件夹即可)

  • 那么样本文件是如何绕过 DEP 防护的呢,原来是使用了 PDF 中可以执行 JavaScript 的特性,利用堆喷射(Heap Spray)来绕过 DEP 的防护(这时 shellcode 执行的区域并不在 DEP 的保护之下),这个 JavaScript 代码变量都经过了模糊处理,增强了伪装性,以下就是利用 JavaScript 代码的堆喷射

0x05 总结

  • 一般缓冲区的栈溢出会溢出到函数的返回点,通过返回点来构造绕过防御机制的代码,最后跳到 shellcode 上执行来完成攻击;但是这个漏洞是非常特殊的,在溢出之后一直填充并覆盖了函数的返回值,程序并没有按照规定流程一直执行到函数的返回点(之前就会中断并退出),目前并不知道是什么原因,只能使用内存访问断点的方法来追踪函数到底在堆栈变为什么状态之后才会返回,跟踪之后终于发现了在堆栈变为样本数据中的 0x4a82a714 的时候函数才会返回,这样就了解了样本的执行步骤

0x06 参考资料

  • 漏洞战争:软件漏洞分析精要
  • 0day安全:软件漏洞分析技术

最新文章

  1. Android数据加密之异或加密算法
  2. LeetCode 263 Ugly Number
  3. 使用opencv设置图像的格式以及帧率
  4. [linux]执行pip安装的程序:command not found
  5. [充电][ios]ios充电接口
  6. 哪些字符需要urlencode编码?具体怎么处理?
  7. SQL Join PK ChinaJoy
  8. mysql 表操作
  9. 【动态规划】XMU 1588 01序列计数
  10. Linux下根据进程的名字杀死进程
  11. uva-699 Not so Mobile (杠杆,巧妙递归)
  12. Android Gradle Plugin指南(六)——高级构建定制
  13. pageoffice 开发笔记
  14. 存储与索引------《Designing Data-Intensive Applications》读书笔记3
  15. Kafka,Mq,Redis作为消息队列使用时的差异?
  16. Python 2.7的字典实现简化版(C语言)
  17. php里进程创建和分析
  18. 关于reduce输出write方法
  19. XTU1254 Blance 如何实现称出1∼n 克的物品,请问最少需要几颗砝码?
  20. AI-终极算法-神经网络(连结学派)

热门文章

  1. MySql数据库列表数据分页查询、全文检索API零代码实现
  2. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
  3. Graylog日志管理单机部署、日志节点的Sidecar配置以及简单的警告事件邮件发送
  4. JavaScript初级学习
  5. SQL字符串传参
  6. WPF 基础 - 图片之界面截图
  7. Java内存区域略解
  8. Django之cookie 与session组件
  9. 在linux系统中登录mysql时出现Enter password: ERROR 1045 (28000): Access denied for user 'debian-sys-maint'@'localhost' (using password: YES)的解决办法
  10. 【JVM进阶之路】一:Java虚拟机概览