@SmashStack
2017-09-19T19:55:00.000000Z
字数 2683
阅读 1735
Binary
这篇论文发表于 USENIX 2015,文章通过构造由基于变量地址和相关地址写入时间的二维图像表示的数据流图,实现了自动化生成有效的数据流攻击的工具 FLOWSTITCH
,并通过实践运用证明了相关方法的可行性。
作者
- Hong Hu @ National University of Singapore
- Zheng Leong Chua @ National University of Singapore
- Sendroiu Adrian @ National University of Singapore
- Prateek Saxena @ National University of Singapore
- Zhenkai Liang @ National University of Singapore
作者提出,在过去,攻击者们常常通过程序内存处理错误实现程序控制流的劫持,并以此获得任意代码执行。但是随着相关防御手段的提出与应用,特别是 CFI、DEP 以及 ASLR 的出现,使得对控制流的劫持越来越难以实现。
但是另一方面,内存操纵错误同样可以导致针对非控制流数据的攻击,这类攻击可以是泄漏敏感数据,也可以是非法提权。作者称这类攻击为 data-oriented attacks
。因为 data-oriented attacks 并不改变程序的基本控制流,所以现有的安全措施并不能防御这类攻击,加之 data-oriented attacks 并未被人熟知,也少有对应的防御方案。
因此,提出一个系统化的针对数据流的攻击方案,并自动化其 Exploit 过程是必要且重要的。
上图是一个存在栈溢出的程序,在 15 行的 strcat
可能导致 fullPath 的溢出,考虑到栈 cookie 等安全措施,传统的控制流劫持在这里显得无能为力。但是另一方面,我们可以通过溢出 fullPath 来修改 reqFile 指针的值,使其指向 privKey 所在内存,就可以通过 16 和 17 行的代码,对 privKey 进行泄漏了。
上述攻击就是 data-oriented attacks 的一个简单的例子。
data-oriented attacks 的攻击目标一般有如下分类:
信息泄漏
非法提权
攻击者不能修改程序的基本控制流,以获得/修改所有事先未知的系统自动生成的值为攻击目标
作者指出,通过构造一个 2D-DFG
图,实现对 data-oriented attacks 的数学抽象。
作者构建了一个二维的图,横纵坐标分别为地址与执行时间,如果程序在 x 时刻对 y 地址进行了写操纵,着图中会有一个位于 (x,y) 的顶点。而 2D-DFG
的边则类似于正常数据流中的 def-use 链,如果这次写操作以 (p,q) 节点为操纵数,则有一个由 (p,q) 指向 (x,y) 的边。下图是前文中样例程序的 2D-DFG。
需要指出,作者提出的 Exploit 生成方法是基于 binary 动态分析的,所以 2D-DFG 不同于静态分析中的数据流图,其中所有的数据流情况都是基于一次运行情况来的。当然,作者也提到了,符号执行或许能极大程度上提高 Exploit 的生成效率。
所以,问题可以抽象为:
基本的思路就是枚举内存错误操纵的影响顶点,去尝试各种情况。但是其中存在一些问题:
实际上,很多有效的数据流攻击都是通过添加单边造成的,因此现在最大的问题是去实现搜索的剪枝,而作者提供了一个有效的剪枝方案,基于如下三个条件:
因此,作者给出了如下的剪枝伪代码:
单边链接的攻击方法虽然简单,但是多边的攻击方式同样可行,这里我们需要定义 Pointer Stitches
, 通过指针的方式实现添加多边的方法。
如果一个顶点,指向了另一个图中的顶点,我们称之为 Pointer, 通过改变 Pointer 的值,实现多边攻击。另一方面,我们需要注意区分信源链和目标链中 Pointer 的改变方向想法。具体的思路可见下图中的伪代码
对于 ASLR 带来的问题,作者提出了两种方案去解决,事实上,这些方法也大量被使用在控制流劫持的技术中,具体包括:
下图展示了根据已有 CVE 生成的试验情况
而下图则给出了生成的 Exploit 的执行情况
当然,程序的 overhead 也在可接受的范围内
这篇论文可以说是我这个月来读到的最耳目一新的文章,个人认为 Data-Oriented Exploits 和 2D-DFG 的提出是整个文章中最为精彩的部分。问题抽象过程也很有亮点,能发表作者在作者水平毋庸置疑。虽然暂未查证相关思路是否原创,但是不论如何这篇文章确实在相关领域做出了巨大贡献(至少我受益匪浅哈哈哈哈哈哈哈)。