缓冲区溢出:如何从 ESP 进行相对跳转?

Posted

技术标签:

【中文标题】缓冲区溢出:如何从 ESP 进行相对跳转?【英文标题】:Buffer overflow: How to do a relative jump from ESP? 【发布时间】:2015-12-23 11:07:57 【问题描述】:

我正在尝试在堆栈缓冲区溢出方面进行练习。我正在做一个经典的例子,其中 vuln 允许您覆盖 EIP。我的问题是我只能使用以 00 开头的地址,这意味着我不能覆盖大于 ESP 指向的地址。因此,将 shellcode 放在我覆盖 EIP 的地址之后的经典方法将不起作用。相反,我需要将地址之前的 shellcode 放入缓冲区。请看下面的简单图。

......... ESP 需要以某种方式跳到这里 | | 五五 XXXX|AAAA|AAAA|AAAA|AAAA|AAAA|....|AAAA|AAAA|AAAA|.... 一种 | | 我的缓冲区不会到达任何地址 比 ESP 大,因为它里面有 0...

现在的问题是:我需要搜索的汇编指令是什么,它将跳转到比 ESP 小 200 字节的地址?我不太了解 x86 汇编程序。我已经尝试过 jmp [ESP-8]、jmp [ESP-16]、...(也有更大的偏移量),然后是 sub ESP、EBX + jmp ESP、xor ESP、EBX + jmp ESP 等。我应该在这里补充一点,看起来我也可以覆盖 EBX。因此,如果有 sub ESP、EBX + jmp ESP 或类似的东西,那么我可以通过首先从 ESP 中减去偏移量来填充 EBX 与跳转到 shellcode 的负偏移量。但是无论我尝试什么,我都找不到模块中的说明。我认为我的主要问题是我不太了解 x86 汇编语言。我在代码中看到了 jmp DWORD PTR DS:[ESP+8] 之类的指令,并且一直在谷歌搜索,我有限的理解告诉我这是数据段中的相对跳转。所以我需要在堆栈段中做这样的事情,理想情况下从 EBX 寄存器中获取偏移量......这样的事情存在吗?

【问题讨论】:

我日夜在谷歌上搜索这个东西......并找到了一些可能有帮助的东西。有 2 个有趣的 mona.py 搜索命令:findwild 和 jmp。 您很可能可以使用 ROP 解决此问题 【参考方案1】:

间接跳转到寄存器中的值不能使用偏移量。在运行jmp 指令之前,您必须完成所有地址数学运算。没有办法编码jmp esp - 200 或类似的东西。

jmp [ESP-8] 将从[ESP-8] 加载,并跳转到该地址。你可以看出它正在加载,因为它有方括号。

所以你应该尝试寻找类似的序列

lea   eax, [esp-200]
jmp   eax               # or call eax

或者

sub  esp, 200
jmp  esp

寄存器间接跳转的 AT&T 语法是 jmp *eax,顺便说一句。

这些指令不必相邻;您可能会找到ret2reg 攻击所需的内容,由几条指令分隔,但这更难搜索,因为您需要将搜索限制在解码从sublea 或其他开始的情况下,并且在经过一定数量的有效指令后到达jmp,这些指令不会与您正在攻击的ret 预期的寄存器值发生故障。您可以尝试在可能的 jmp regcall reg 指令之前从每个偏移量开始反汇编,最多 20 个字节,看看是否有任何偏移量产生有效的指令来做一些有趣的事情。

您不一定要找到以esp 开头的序列;如果另一个寄存器中存在指向缓冲区中其他位置的指针,您可以在该寄存器中查找jmpcall


执行sub esp, 200 / jmp esp 会使堆栈指向代码的最低地址,因此push将数据放入堆栈不会在执行到达之前覆盖代码的末尾,这可能是接近或超过原始 esp 的长代码的问题。

堆栈会向下增长,但执行会随着地址的增加而增加,因此如果您以 EIP=ESP 开头,则只有在 pop 或以其他方式增加 ESP 时才会遇到麻烦。

【讨论】:

以上是关于缓冲区溢出:如何从 ESP 进行相对跳转?的主要内容,如果未能解决你的问题,请参考以下文章

软件安全实验——lab6(缓冲区溢出2:使用jmp esp或者call esp方法和修改函数指针)

缓冲区下溢异常

python 中的out of memory是怎么回事,内存不够吗?

利用IAT导入表进行代码的注入

利用IAT导入表进行代码的注入

windows缓冲区溢出