Skip to content

Ret2dlresolve should check that VERSYM[ ELF32_R_SYM (reloc->r_info) ] is valid #2670

@J-0-3

Description

@J-0-3

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions