Ret2dlresolve

Resolving an arbitrary libc functions

The attacker tricks the binary into resolving an arbitrary function ( such as system) into the PLT.

The attacks can then use this PLT function as an original binary's function, bypassing ASLR and requiring no libc leaks.

How it works ?

Dynamically-linked ELF objects import libc functions when they are first called using the PLT and GOT. During the relocation of a runtime symbol, RIP will jump to the PLT and attempt to resolve the symbol. During this process a "resolver" is called.

  1. From the .text section, instead of calling read directly, there is a call to the corresponding function in the .plt section (0x401090).

0x00000000004015c9 <+129>: call 0x401090 <printf@plt>

2. From here, there is an indirect jump in the corresponding .got.plt section (0x404048)

0x401090 <printf@plt>: jmp QWORD PTR [rip+0x2fb2] # 0x404048 <[email protected]>

3. Since the symbol has not been resolved yet, this address contains the address of the next instruction in the function stub (0x401096).

gdb-peda$ x/gx 0x404048
0x404048 <[email protected]>: 0x0000000000401096

4. At this point, the execution flow is redirected to the next instruction in the function stub. Here, reloc_arg is pushed on the stack.

0x401096 <printf@plt+6>: push 0x6 # reloc_offset

5. The last instruction in the function stub is an indirect jump to the default stub (0x401020). Here the link_map address is pushed on the stack and finally the control is given to _dl_runtime_resolve().

0x40109b <printf@plt+11>: jmp 0x401020
0x401020: push QWORD PTR [rip+0x2fe2] # 0x404008 # link_map
0x401026: jmp  QWORD PTR [rip+0x2fe4] # 0x404010 # _dl_runtime_resolve

If the **GOT ** entry is unpopulated, the reloc_offset value is pushed and the binary jump to the beginning of the .plt section. A few instructions later, the dl-resolve() function is called, with reloc_offset being one of the arguments. It then uses this reloc_offset to calculate the relocation and symtab entries.

In order to resolve the functions, there are 3 structures that need to exist within the binary.

There are the 3 structures :

  • JMPREL segment (.rel.plt) that stores the Relocation Table, which maps each entry to a symbol

The column name coresponds to the symbol name. The offset is the GOT entry for the symbol. info stores additional metadata.

These entry are of type Elf32_Rel for 0x86 instruction set and Elf64_Rel for 0x64 instruction set.

  • STRTAB, a strings table for the names.

  • SYMTAB, store symbol informations in structure.

The most important value here is st_name as this gives the offset in STRTAB of the symbol name. The other fields are not relevant to the exploit itself.

Exploit

Faking these 3 structures could enable to trick the linker into resolving an arbitrary function, parameters can also be pass in (such as /bin/sh) once resolved.

This function will fake and write the structures at the correct address in order to call an arbitrary function system with /bin/sh as argument.

Resources

Last updated