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

X86 缓冲区溢出:如何从ESP进行相对跳转?,x86,buffer-overflow,exploit,X86,Buffer Overflow,Exploit,我正在尝试在堆栈缓冲区溢出区域进行一个练习。我正在做一个经典的例子,vuln允许你覆盖EIP。我的问题是,我只能使用以00开头的地址,这意味着我不能覆盖比ESP指向的地址大的地址。因此,将外壳代码放在覆盖EIP的地址之后的经典方法是行不通的。相反,我需要将外壳代码放在地址之前放入缓冲区。请参见下面的简单图 <larger stack addresses> ........... <smaller stack addresses> ESP

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

<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... ........... 我得想办法跳到这里来 | | V V XXXX | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA |。。。。 A. | | 我的缓冲区无法到达任何地址 比ESP大,因为其中有0。。。
现在的问题是:我需要搜索的汇编指令是什么,它将跳转到比ESP小200字节的地址?我对x86汇编程序了解不够。我已经尝试过像jmp[ESP-8]、jmp[ESP-16]、。。。(也有较大的偏移量),然后是子ESP、EBX+jmp ESP、xor ESP、EBX+jmp ESP等。我应该在这里补充一点,看起来我也可以覆盖EBX。因此,如果有子ESP,EBX+jmp ESP或类似的东西,那么我可以通过从ESP中减去偏移量,用负偏移量跳转到外壳代码来填充EBX。但是无论我尝试什么,我都找不到模块中的指令。我认为我的主要问题是我对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

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

这些指令不必相邻;您可能会找到由几个指令分隔的攻击所需的内容,但这更难搜索,因为您需要将搜索限制在解码从
lea
或其他位置开始的情况,并在一些有效指令之后到达
jmp
,这些指令不会与您要攻击的
ret
处预期的寄存器值发生故障。在可能的
jmp-reg
call-reg
指令之前,您可以尝试从每个偏移量(最多20个字节)开始反汇编,并查看是否有任何偏移量生成有效的指令来执行有趣的操作

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


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


堆栈向下增长,但执行朝着增加地址的方向上升,因此,如果从EIP=ESP开始,只有当您
pop
或以其他方式增加ESP时,您才会遇到麻烦。

间接跳转到寄存器中的某个值时,无法获得偏移量。在运行
jmp
指令之前,您必须进行所有的地址计算。没有办法对jmp esp-200或类似的东西进行编码

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

所以你应该试着寻找像这样的序列

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

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

这些指令不必相邻;您可能会找到由几个指令分隔的攻击所需的内容,但这更难搜索,因为您需要将搜索限制在解码从
lea
或其他位置开始的情况,并在一些有效指令之后到达
jmp
,这些指令不会与您要攻击的
ret
处预期的寄存器值发生故障。在可能的
jmp-reg
call-reg
指令之前,您可以尝试从每个偏移量(最多20个字节)开始反汇编,并查看是否有任何偏移量生成有效的指令来执行有趣的操作

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


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


堆栈变小,但执行朝着增加地址的方向发展,因此如果你从EIP=ESP开始,只有当你
pop
或以其他方式增加ESP时,你才会遇到麻烦。

我日夜在谷歌上搜索这件事。。。找到了一些