缓冲区溢出:如何从 ESP 进行相对跳转?
Buffer overflow: How to do a relative jump from ESP?
我正在尝试在堆栈缓冲区溢出方面做一个练习。我正在做一个经典的例子,漏洞允许你覆盖 EIP。我的问题是我只能使用以 00 开头的地址,这意味着我不能覆盖大于 ESP 指向的地址。因此,将 shellcode 放在我用来覆盖 EIP 的地址之后的经典方法是行不通的。相反,我需要将地址之前的 shellcode 放入缓冲区。请看下面的简单图。
<larger stack addresses> ........... <smaller stack addresses>
ESP Need to jump here somehow
| |
V V
XXXX|AAAA|AAAA|AAAA|AAAA|AAAA|....|AAAA|AAAA|AAAA|....
A
|
|
My buffer won't reach any addresses
larger than ESP because of the 0 in it...
现在的问题是:我需要搜索的汇编指令是什么,它会跳转到比 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 寄存器中获取偏移量......这样的事情是否存在?
间接跳转到寄存器中的值不能采用偏移量。您必须在 运行 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 攻击所需的内容由几条指令分隔,但这更难搜索,因为您需要将搜索限制在解码从 sub
、[=18 开始的情况=] 或其他任何东西,并在一定数量的有效指令后到达 jmp
,这些指令不会与您正在攻击的 ret
处预期的寄存器值发生故障。您可以尝试从每个可能的 jmp reg
或 call reg
指令之前最多 20 个字节的每个偏移量开始反汇编,并查看是否有任何偏移量产生有效的指令来做一些有趣的事情。
您不一定要找到以 esp
开头的序列;如果指向缓冲区中其他地方的指针存在于另一个寄存器中,您可以查找该寄存器的 jmp
或 call
。
执行 sub esp, 200
/ jmp esp
会使堆栈指向代码的最低地址,因此 push
将数据写入堆栈不会覆盖在执行到达之前结束代码,这可能是接近或超过原始 esp
.
的长代码的问题
堆栈向下增长,但执行会随着地址的增加而上升,因此如果您从 EIP=ESP 开始,只有在 pop
或以其他方式增加 ESP 时才会遇到麻烦。
我正在尝试在堆栈缓冲区溢出方面做一个练习。我正在做一个经典的例子,漏洞允许你覆盖 EIP。我的问题是我只能使用以 00 开头的地址,这意味着我不能覆盖大于 ESP 指向的地址。因此,将 shellcode 放在我用来覆盖 EIP 的地址之后的经典方法是行不通的。相反,我需要将地址之前的 shellcode 放入缓冲区。请看下面的简单图。
<larger stack addresses> ........... <smaller stack addresses> ESP Need to jump here somehow | | V V XXXX|AAAA|AAAA|AAAA|AAAA|AAAA|....|AAAA|AAAA|AAAA|.... A | | My buffer won't reach any addresses larger than ESP because of the 0 in it...
现在的问题是:我需要搜索的汇编指令是什么,它会跳转到比 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 寄存器中获取偏移量......这样的事情是否存在?
间接跳转到寄存器中的值不能采用偏移量。您必须在 运行 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 攻击所需的内容由几条指令分隔,但这更难搜索,因为您需要将搜索限制在解码从 sub
、[=18 开始的情况=] 或其他任何东西,并在一定数量的有效指令后到达 jmp
,这些指令不会与您正在攻击的 ret
处预期的寄存器值发生故障。您可以尝试从每个可能的 jmp reg
或 call reg
指令之前最多 20 个字节的每个偏移量开始反汇编,并查看是否有任何偏移量产生有效的指令来做一些有趣的事情。
您不一定要找到以 esp
开头的序列;如果指向缓冲区中其他地方的指针存在于另一个寄存器中,您可以查找该寄存器的 jmp
或 call
。
执行 sub esp, 200
/ jmp esp
会使堆栈指向代码的最低地址,因此 push
将数据写入堆栈不会覆盖在执行到达之前结束代码,这可能是接近或超过原始 esp
.
堆栈向下增长,但执行会随着地址的增加而上升,因此如果您从 EIP=ESP 开始,只有在 pop
或以其他方式增加 ESP 时才会遇到麻烦。