AMD64 溢出和空字节

信息安全 缓冲区溢出 建筑学
2021-09-04 23:32:18

过去,我曾设法溢出我自己和其他人的易受攻击的程序,但仅限于 32 位环境。每次我在 64 位机器上尝试简单的堆栈粉碎时,都会遇到问题。我试图写入的地址总是包含空字节。

昨天一个问题的一个简单例子;我试图覆盖 GOT 以使以后的调用printf()成为调用system()我需要的所有地址(ASLR 关闭,DEP 开启)。

当我试图用 heapland(低内存地址)值覆盖 stackland 指针(高内存地址)时,我陷入了困境。

0x7fffffff_ff480a90 -> 0x00000000_0068a9a0

我的溢出以 结束\xa0\xa9\x68,它带有空终止符,使指针看起来像;

0x7fffffff_0068a9a0

这不好,我看了好几个小时,想不出办法。就像我说的我已经多次遇到这个空字节问题。我一直认为这只是其中之一,但它似乎完全不可能破解 64 位系统,因为地址经常包含空字节。

我只是不走运吗?我错过了一些明显的东西吗?我还没有听到有人用 32 对 64 来谈论这个问题。

2个回答

您可能想阅读此http://www.x86-64.org/documentation/abi.pdf

从本质上讲,x86 和 x64 的工作方式不同。新的 ABI 描述了它处理叶子和非叶子调用、异常处理和展开的新方法。

由于目的本质上是溢出 - 您需要了解新的 ABI 它是如何工作的,以及现在在稍微不同的地方的东西在哪里,以便能够“插入”和“改变”。

首先,您的示例有些奇怪。当前实现amd64 模式的处理器(又名 x86_64 又名 x64 又名一堆其他名称)不使用完整的 64 位地址寄存器。它们使用 48 位地址,并强制要求 48 到 63 位相同(就好像它是“符号扩展”一样)。因此,7fffffff_ff480a90任何当前生产的 CPU 都不会接受类似的地址。更有可能的是,您有00007fff_ff480a90. 这将您的问题减少到两个字节而不是四个字节。

一种通用方法是执行几个连续的溢出;根据您可以溢出数据的确切条件,这可能会也可能不会。00000054_54545454有几个溢出,你用, 然后00000000_54545454, 然后 finally替换你的目标槽00000000_0068a9a0每次溢出都允许您写入一个终止空字节,您要写入三个空字节,因此会出现三个溢出。