3.1 KiB
Raw Blame History

Ret2esp / Ret2reg

{{#include ../../../banners/hacktricks-training.md}}

Ret2esp

因为 ESP栈指针始终指向栈的顶部,该技术涉及用 jmp espcall esp 指令的地址替换 EIP指令指针。通过这样做shellcode 被放置在被覆盖的 EIP 之后。当 ret 指令执行时ESP 指向下一个地址,正好是存储 shellcode 的地方。

如果 地址空间布局随机化ASLR 在 Windows 或 Linux 中未启用,可以使用在共享库中找到的 jmp espcall esp 指令。然而,当 ASLR 激活时,可能需要在易受攻击的程序内部查找这些指令(并且可能需要击败 PIE)。

此外,能够将 shellcode 放置在 EIP 损坏之后,而不是在栈的中间,确保在函数操作期间执行的任何 pushpop 指令不会干扰 shellcode。如果 shellcode 被放置在函数栈的中间,可能会发生这种干扰。

缺乏空间

如果在覆盖 RIP 后缺乏写入空间(可能只有几个字节),可以写一个初始的 jmp shellcode

sub rsp, 0x30
jmp rsp

在栈的早期写入 shellcode。

示例

您可以在 https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp 中找到此技术的示例,最终利用如下:

from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

jmp_rsp = next(elf.search(asm('jmp rsp')))

payload = b'A' * 120
payload += p64(jmp_rsp)
payload += asm('''
sub rsp, 10;
jmp rsp;
''')

pause()
p.sendlineafter('RSP!\n', payload)
p.interactive()

Ret2reg

类似地,如果我们知道一个函数返回存储 shellcode 的地址,我们可以利用 call eaxjmp eax 指令(称为 ret2eax 技术),提供另一种执行我们的 shellcode 的方法。就像 eax 一样,任何其他寄存器 中包含有趣地址的寄存器都可以被使用(ret2reg)。

示例

您可以在这里找到一个示例: https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg

保护措施

  • NX: 如果栈不可执行,这将无济于事,因为我们需要将 shellcode 放在栈中并跳转以执行它。
  • ASLRPIE: 这些可能会使找到跳转到 esp 或任何其他寄存器的指令变得更加困难。

参考

{{#include ../../../banners/hacktricks-training.md}}