- 献词
- 致谢
- 前言
- 第一部分 IDA 简介
- 第 1 章 反汇编简介
- 第 2 章 逆向与反汇编工具
- 第 3 章 IDA Pro 背景知识
- 第二部分 IDA 基本用法
- 第 4 章 IDA 入门
- 第 5 章 IDA 数据显示窗口
- 第 6 章 反汇编导航
- 第 7 章 反汇编操作
- 第 8 章 数据类型与数据结构
- 第 9 章 交叉引用与绘图功能
- 第 10 章 IDA 的多种面孔
- 第三部分 IDA 高级应用
- 第 11 章 定制 IDA
- 第 12 章 使用 FLIRT 签名来识别库
- 第 13 章 扩展 IDA 的知识
- 第 14 章 修补二进制文件及其他 IDA 限制
- 第四部分 扩展 IDA 的功能
- 第 15 章 编写 IDA 脚本
- 第 16 章 IDA 软件开发工具包
- 第 17 章 IDA 插件体系结构
- 第 18 章 二进制文件与 IDA 加载器模块
- 第 19 章 IDA 处理器模块
- 第五部分 实际应用
- 第 20 章 编译器变体
- 第 21 章 模糊代码分析
- 第 22 章 漏洞分析
- 第 23 章 实用 IDA 插件
- 第六部分 IDA 调试器
- 第 24 章 IDA 调试器
- 第 25 章 反汇编器/ 调试器集成
- 第 26 章 其他调试功能
- 附录 A 使用 IDA 免费版本 5.0
- 附录 B IDC/SDK 交叉引用
22.2 使用 IDA 在事后发现漏洞
对于发现软件漏洞的具体过程,一直以来都存在激烈的讨论。对于在软件中发现的任何漏洞,我们都可以指定(漏洞)发现者和(软件)维护者的角色。此外,我们还可以指定在发现漏洞的过程中可能或不可能发生的许多事件。下面我们简要描述其中一些事件。请记住,发现漏洞的整个过程是人们激烈争论的主题,下面的这些术语绝非标准,也未被广泛接受。
发现 。最初发现一个漏洞的时刻。为了方便讨论,我们还把这个时刻看成是初步开发一个针对该漏洞的破解程序的时刻。
通知 。软件维护者最初知道其产品中存在漏洞的时刻。如果是供应商自己发现的漏洞,则这个时刻与“发现”时刻一样。
公布 。向公众公布漏洞的时刻。根据所发布的有关漏洞的细节信息,这个事件可能会令人困惑。公布可能伴随着发布或识别有效的破解程序。有时候,公布也会作为通知提供给供应商。
缓解 。公布防范措施的时刻,如果遵循这些措施,用户可以免于成为现有破解程序的受害者。缓解措施是等待发布补丁的用户的折中解决方案。
补丁可用性 。维护者(或第三方)为易受攻击的软件提供更正版本的时刻。
补丁应用 。用户安装已更新、已更正的软件,使自己免受(希望如此)所有依赖于给定漏洞的已知攻击侵害的时刻。
有大量论文介绍所有有关漏洞的信息,如漏洞发现者和维护者的责任,他们应公开多少信息,应何时公开这些信息等。通常,供应商会在公开漏洞的同时发布补丁。
许多时候,供应商在发布补丁的同时,还会发布一个漏洞公告。这个漏洞公告提供了一些技术信息,描述已被补丁修复的问题的本质和严重程度,但这些信息的详细程度一般不足以开发一个针对该问题的有效破解程序。那么,为什么有人想要开发一个有效的破解程序呢?很明显,一些人想要利用那些还没有安装补丁的计算机。开发破解程序的速度越快,他们利用更多计算机的几率就越大。另外,供应商可能希望开发一些工具,用于扫描网络中未安装补丁的系统,或者找到一些技巧,以实时检测入侵尝试。多数情况下,开发这样的工具需要开发者深入了解新修复的漏洞的本质。
漏洞公告中可能缺乏一些基本的信息,如包含漏洞的具体文件、任何易受攻击的函数的名称或位置,以及这些函数中的什么内容被变更。但是,被修复的文件本身包含了大量信息,破解程序开发者可以借助这些信息开发一个利用新修复的漏洞的有效破解程序。一开始,这些信息并不十分明显,看起来似乎不能被破解程序开发者使用。我们为消除基本的漏洞所做的变更正是这些信息的表示形式。要突出这些变更,一个最简单的方法是将已打补丁的二进制文件与对应的未打补丁的文件比较。如果只需要在已打补丁的源文件中寻找不同,那么,使用 diff
之类面向文本、较为实用的标准工具,就可以迅速指出发生变更的位置。然而,跟踪一个二进制文件的两个修订版本之间的行为变更,远比简单的文本文件比较复杂得多。
使用差异计算隔离两个二进制文件中发生的变更的困难在于,二进制文件可能会因为各种原因而发生变更。有许多操作都有可能触发变更,如编译器优化、编译器本身的变化、源代码重组、添加与漏洞无关的代码,当然还有添加修复漏洞的代码。我们面临的挑战在于如何将行为变更(如那些修改漏洞所需的变更)与表面变更(如使用不同的寄存器完成相同的任务)区分开来。
有很多工具专门用于二进制文件差异比较,包括 Zynamics1 开发的商业版 BinDiff、eEye Digital Security2 开发的免费 BDS (二进制差异比较套件)可以 Core Labs(属于 Core Impact3 的开发者 Core Security)下载的免费工具 Turbodiff4 以及 Nicolas Pouvesle 的 PatchDiff2 5 。这些工具的每一种都以某种方式依赖于提供的 IDA 。BinDiff 和 BDS 利用 IDA 脚本和插件对所分析的二进制文件的已打补丁版本和未打补丁版本进行初步的分析。由插件提取出的信息存储在一个后端数据库中。每个工具均提供一个基于图形的显示窗口,并可以导航在分析阶段检测到的差异。Turbodiff 和 PatchDiff2 以 IDA 插件的方式实现,并在 IDA 中显示它们的结果。使用这些工具的最终目的是迅速指出修复一个漏洞需要做出的变更,以快速了解代码易于受到攻击的原因。有关这两款产品的其他信息,请访问它们各自公司的网站。
1. 参见 http://www.zynamics.com/bindiff.html 。
2. 参见 http://research.eeye.com/html/tools/RT20060801-1.html 。
3. 参见 http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=tool&name=turbodiff 。
4. 参见 http://www.coresecurity.com/content/core-impact-overview/ 。
5. 参见 http://code.google.com/p/patchdiff2 。还请注意,Alexander Pick 将 latch Diff2 用于 OS X 的 IDA6.0。更多信息参见 https://github.com/Alexander-pick/patchdiff-ida6 。
PatchDiff2 是一款典型的免费差异比较工具,它是一个开源项目,提供该插件的 32 位和 64 位已编译 Windows 版本以及用于访问该插件源代码的子版本。要安装该插件,只需将插件二进制文件复制到<IDADIR>/plugins 目录中即可。
使用 PatchDiff2(参见表 22-2 )的第一步是创建两个独立的 IDA 数据库,分别用于要比较的两个二进制文件。通常,一个数据库用于二进制文件的原始版本,而另一个数据库则用于该二进制文件的已打补丁版本。
表 22-2 PatchDiff2
名称 | PatchDiff2 |
---|---|
作者 | Nicolas Pouvesle |
发布 | 用于 IDA 5.7 的源代码和二进制文件 |
价格 | 免费 |
描述 | 生成并显示二进制文件差异 |
信息 | http://code.google.com/p/patchdiff2/ |
通常,如果调用该插件,将打开用于原始二进制文件的数据库,然后通过 Edit ▶Plugins (编辑▶插件)菜单或其关联的热键(默认为 CTRL-8)激活 PatchDiff2。PatchDiff2 将你从中调用该插件的数据库称为 IDB1 或“第一个 idb”。激活后,PatchDiff2 将打开将与当前打开的数据库进行比较的另一个数据库,此数据库称为 IDB2 或“第二个 idb”。选择第二个数据库后,PatchDiff2 将计算每个数据库中每一个函数的许多辨别性特性,包括各种类型的签名、散列值和 CRC 值。利用这些特性,PatchDiff2 将创建 3 个函数列表,分别称为“相同的函数”、“不匹配的函数”和“匹配的函数”。这些列表分别在 PatchDiff2 打开的新选项卡式窗口中显示。
“相同的函数”列表包含 PatchDiff2 认为在两个数据库中均相同的函数的列表。从解析角度看,你可能不会对这些函数感兴趣,因为它们对于生成的二进制文件的已打补丁版本并未作出任何更改。
“不匹配的函数”列表显示两个数据库中根据 PatchDiff2 应用的标准彼此不同的函数。实际上,这些函数或者已添加到已打补丁的版本并从未打补丁的版本中删除,或者与同一二进制文件中的其他函数过于相似,以至于无法与另一个二进制文件中的对应函数区别开来。通过仔细的手动分析,通常可以匹配“不匹配的函数”列表中的函数对。经验证明,手动比较签名数量相同的函数的结构是一个不错的主意。为此,最好是对基于 sig 列的列表进行排序,以便把具有相同数量的签名的函数放在一起列出。按 sig 列排序的“不匹配的函数”列表的前几行如下所示。
File Function name Function address Sig Hash CRC ---- ------------- ---------------- --- ---- --- 1 sub_7CB25FE9 7CB25FE9 000000F0 F4E7267B 411C3DCC 1 sub_7CB6814C 7CB6814C 000000F0 F4E7267B 411C3DCC 2 sub_7CB6819A 7CB6819A 000000F0 F4E7267B 411C3DCC 2 sub_7CB2706A 7CB2706A 000000F0 F4E7267B 411C3DCC
很明显,文件 1 中的两个函数与文件 2 中的两个函数相关,但 PatchDiff2 无法确定如何对它们进行配对。在使用 C++ 标准模板库(STL )的二进制文件中,我们常常可以看到多个结构相同的函数。如果你能够手动将一个文件中的函数与其在另一个文件中的对应函数相匹配,就可以使用 PatchDiff2 的 Set Match(设置匹配)功能(位于上下文菜单中)在列表中选择一个函数,然后将其与列表中的另一个函数相匹配。Set Match 对话框如图 22-1 所示。
图 22-1 使用 PatchDiff2 手动匹配函数
要进行手动匹配,首先你需要使用 Set Match 菜单项选择一个函数。在生成的对话框中,你必须输入匹配的函数在你未查看的文件中的地址。Propagate (传播)选项会要求 PatchDiff2 尽可能多地匹配其他函数(只要你告知它出现的新匹配)。
“匹配的函数”列表包含 PatchDiff2 根据在匹配过程中应用的标准认为足够相似但并非完全相同的函数。右击此列表中的任何条目并选择 Display Graphs(显示图形),PatchDiff2 将显示两个匹配的函数的流图形。图 22-2 显示了一个这样的图形对。PatchDiff2 利用颜色编码突出显示已添加到二进制文件的已打补丁版本中的代码块,以便于你重点关注代码中已更改的部分。
图 22-2 PatchDiff2 的图形化函数比较
在这些图形中,两个函数中均包含代码块➊到➍,而代码块➎则添加到函数的已打补丁版本中。在差异化分析过程中,最初你会对匹配的函数最感兴趣,因为它们可能包含已合并到已打补丁的二进制文件中的更改(这些更改修复了原始二进制文件中发现的漏洞)。仔细研究这些更改,可以发现为解决错误行为或可利用条件而进行的更正或添加的安全检查。如果在“匹配的函数”列表中找不到任何感兴趣的突出显示的更改,则“不匹配的函数”列表将成为我们查找已打补丁的代码的唯一其他选项。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论