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

时间:2015-12-23 11:07:57

标签: x86 buffer-overflow exploit

我正在尝试在堆栈缓冲区溢出区域进行练习。我正在做经典的例子,其中的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寄存器获取偏移量......这样的存在吗?

1 个答案:

答案 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攻击时预期的寄存器值而出错。您可以尝试在可能的retjmp reg指令之前从每个偏移量开始反汇编,最多20个字节,并查看是否有任何偏移量产生了有效的指令。

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

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

堆栈增长,但执行会增加地址,所以如果你从EIP = ESP开始,只有esp或以其他方式增加ESP才会遇到麻烦。