我正在尝试在堆栈缓冲区溢出区域进行练习。我正在做经典的例子,其中的vuln允许你覆盖EIP。我的问题是我只能使用以00开头的地址,这意味着我不能覆盖大于ESP指向的地址。因此,在我覆盖EIP的地址之后放置shellcode的经典方法将无效。相反,我需要将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],......(也有较大的偏移),然后是子ESP,EBX + jmp ESP,xor ESP,EBX + jmp ESP等等。我应该在这里添加,看起来我也可以覆盖EBX。因此,如果存在子ESP,EBX + jmp ESP或类似的那样,那么我可以通过从ESP首先减去ESP的偏移来向EBX填充负偏移跳转到shellcode。但无论我尝试什么,我都找不到模块中的说明。我认为我的主要问题是我不太了解x86汇编语言。我在代码中看过像jmp DWORD PTR DS:[ESP + 8]这样的指令,并且谷歌搜索了一下,我的有限理解告诉我,这是数据段的相对跳跃。所以我需要在堆栈段中执行类似的操作,理想情况下从EBX寄存器获取偏移量......这样的存在吗?
答案 0 :(得分:3)
间接跳转到寄存器中的值不能获取偏移量。在运行jmp
指令之前,您必须执行所有地址数学运算。无法编码jmp esp - 200
或类似的任何内容。
jmp [ESP-8]
将从[ESP-8]
加载,然后跳转到该地址。您可以告诉它正在进行加载,因为它有方括号。
所以你应该尝试寻找像
这样的序列lea eax, [esp-200]
jmp eax # or call eax
或者
sub esp, 200
jmp esp
寄存器间接跳转的AT&amp; T语法是jmp *eax
,BTW。
这些指示不必相邻;您可能会发现ret2reg攻击所需的内容被一些指令分隔,但这很难搜索,因为您需要将搜索范围限制为以sub
开始解码的情况,{{1或者其他什么,并且在经过一些有效指令后得到lea
,这些指令不会因你jmp
攻击时预期的寄存器值而出错。您可以尝试在可能的ret
或jmp reg
指令之前从每个偏移量开始反汇编,最多20个字节,并查看是否有任何偏移量产生了有效的指令。
您不一定要找到以call reg
开头的序列;如果指向缓冲区中其他位置的指针存在于另一个寄存器中,则可以查找该寄存器的esp
或jmp
。
执行call
/ sub esp, 200
会使堆栈指向代码的最低地址,因此 jmp esp
数据不会覆盖堆栈的结尾您的代码在执行之前到达,这可能是接近或超过原始push
的长代码的问题。
堆栈增长,但执行会增加地址,所以如果你从EIP = ESP开始,只有esp
或以其他方式增加ESP才会遇到麻烦。