Friday, February 23, 2018

ELF Black Magic Collections - Evading from static analysis



HITCON CTF 2017 Qual 

 void: https://github.com/david942j/ctf-writeups/tree/master/hitcon-quals-2017/void

".rela.dyn" section is patched to rewrite (and append) an address (0x935) into ".fini_array" at load time. ".fini_array" is a function pointer array ended with NULL pointer. These function handlers are called in the reverse order in the exit after main function returns.



textile: https://github.com/edwardchoijc/ctf-writeups/blob/master/2017-Hitcon/rev-textile/textile


There are 2 program_header_table (PHDR) in this ELF binary - first one is at offset 0x204270, the second one is at offset 0x40.




Disassemblers take 0x40 as the PHDR offset.

radare2 - rabin2 -S
readelf -e

But the Linux kernel (wrongly?) calculate the offset with 0x400000 (base address) + 0x204270, which corresponds to offset 0x4270 in the raw binary - PT_LOAD has a 0x600000 base. So, this is the actual PHDR at runtime, and PT_DYNAMIC is changed to 0x6677CD:


So this time, the dynamic loader didn't check the p_offset and take p_vaddr directly. In PT_DYNAMIC, DT_SYMTAB is changed to 0x6E125B (0x4002C0 on the other hand). So that's where we can see the "memcmp" symbol is modified to "strcmp". The second "strcmp" symbol is set to be STB_LOCAL to avoid name conflict.

Code from glibc/elf/rtld.c



Google CTF 2018 Qual
 APT42: https://github.com/p4-team/ctf/tree/master/2018-06-23-google-ctf/apt42-part1

This binary is built with PIE/PIC disabled, and its text section starts from a fixed base address of 0x400000. The binary is all normal except that several bytes were changed in the .got.plt section --- the resolving address of sleep is changed to an arbitrary one. This tricked my IDA Pro 6.8 without seeing the dl-resolve hijacking.

IDA Pro 6.8 Disassembly
.got.plt from raw binary
Debugging & BP on _dl_start




References:

                                 http://www.skyfree.org/linux/references/ELF_Format.pdf