-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Open
Labels
Description
Currently, Ret2dlresolve chooses a data_addr within the .bss arbitrarily, and errors if the corresponding VERSYM ndx is not mapped.
However, the value at VERSYM[ ELF32_R_SYM (reloc->r_info) ] also must be legal for dl_runtime_resolve() to not segfault. This can cause some nasty hard-to-debug segfaults.
To fix this, Ret2dlresolvePayload._get_recommended_address should search for addresses where the corresponding VERSYM index is set to 0 (or other legal values, although these seem to vary depending on the libc/ld version) in the ELF data.
As an example, here is something I wrote for a CTF chal once (32-bit):
def suitable_r_info(elf: pwn.ELF, base: int | None = None) -> int:
dynsym = elf.get_section_by_name(".dynsym").address + (elf.address - elf.load_addr)
gnu_version = elf.get_section_by_name(".gnu.version").address + (elf.address - elf.load_addr)
bss = elf.get_section_by_name(".bss").address + (elf.address - elf.load_addr)
if base is None:
base = bss + 0x100
dynsym_offset = pwn.align(0x10, base - dynsym)
while True:
versym_ptr = gnu_version + (dynsym_offset // 0x10) * 2
if self.binary.u16(versym_ptr) == 0:
return ((dynsym_offset // 0x10) << 8) | 7
dynsym_offset += 0x10
Happy to open a PR and try to implement unless there are any issues with doing this.
Reactions are currently unavailable