抗 ROP 无小工具二进制文件

信息安全 开发
2021-08-17 03:53:56

G-Free:通过无小工具的二进制文件击败面向回报的编程

如果源可用,本文描述了一种看起来非常酷的技术来防止 ROP 攻击。他们使用 gcc 之间的汇编预处理器和汇编器来删除或保护所有可能的自由分支(返回和间接跳转)。他们声称对速度/性能的影响小于 3%(平均 1%)。

他们修改指令或添加无操作以更改对齐方式,从而消除意外/未对齐的分支指令。为了保护合法的返回和跳转,他们在函数序言中使用随机运行时密钥加密返回地址,并在返回之前通过 XOR 对其进行解密。这应该防止返回语句成功执行,除非入口点位于函数本身的开头。

我的问题是返回地址加密将如何防止使用 ROP 小工具?密钥/cookie 存储在返回地址正上方的堆栈中,那么如何防止攻击者修改堆栈上的小工具链,使其在每个返回地址之后也包含一个密钥 0x00000000?

这篇论文似乎被引用了 73 次,据我所知,没有人提到过这样的事情,所以我一定遗漏了一些东西。有人可以解释一下合法跳转和返回的保护代码是如何工作的吗?

(我知道这是一个很长的问题,需要阅读一篇长篇论文,但我希望至少阅读这篇文章的人会发现这篇论文和我一样酷)


更新

这显然与 StackGuard 和 ProPolice 中使用的技术相同(或非常相似)。谁能告诉我他们如何应对内存泄露漏洞?我似乎无法确定。我所发现的要么是顺便提及他们,要么只是夸大他们的美德。

1个回答

返回地址加密会阻止使用 ROP gadget,因为攻击者无法预测密钥的值,因此攻击者将不知道在堆栈上写什么以导致在一个 gadget 末尾的返回指令将控制权转移到下一个小工具。

记住 ROP 攻击的工作原理。攻击涉及执行一系列 ROP 小工具。攻击者必须安排内存,以便这些小工具以所需的顺序执行。在 ROP 攻击中,攻击者通过覆盖堆栈以包含一堆假堆栈帧来实现此目的,其中每个堆栈帧包含单个小工具所需/预期的任何堆栈数据。每个 ROP gadget 都以 RET(返回)指令结束,因此相应的假堆栈帧包含一个保存的返回地址,将由 RET 指令使用:当您执行 gadget 时,当它到达 RET 指令时,RET 指令将弹出堆栈上的“返回地址”并跳转到它。因此,攻击者安排堆栈的内容,使每个小工具都有一个假的“返回地址”,而假的“

在标准的 ROP 攻击中,这是可行的,因为攻击者知道每个小工具的地址,并且可以将这些地址写入堆栈。

使用 G-Free 的返回地址加密,这种攻击不再有效。攻击者无法将gadget的地址存储到堆栈中;相反,攻击者需要存储一个加密的返回地址(即下一个gadget地址的加密)。如果不知道加密密钥,攻击者将不知道要写什么。

因此,在不知道加密密钥的情况下,ROP 攻击不起作用,因为攻击者无法将这些小工具链接在一起。

PS我同意你的看法。G-Free 确实很棒。我希望我有一个编译器标志,可以让我用 G-Free 编译程序;这是一个非常酷的防御,对性能的影响不大。