Recovering Section Meta-data
- ELF header field e_shentsize - showing the size of the section headers
- ELF header field e_shnum - showing the start of the section header table
- ELF header field e_shoff - showing the offset in the ELF file where the section headers begin.
- Section Header Table - list of data fields for sections (offset, size, type, flags all that schpeel)
- Section String Table .shstrtab - list of strings for labeling the sections in the Section Header Table.
That's freakishly close to the section we guessed above. Another huge clue that this is probably our section string table is obviously the prevalence of section names! Now, if you've found this, you know something else, you know how many sections there are---probably, well a really good guess!
- The section header table entries have two very similar in value fields right after one another, namely: the sh_addr and sh_offset, these fields specify the virtual address of the section (where it will appear in a memory) and the offset of the section in the file, respectively. The reason this has such low entropy during manual inspection is because one number will usually be a predictable offset from the other or likely be the same number repeated! There's a common pattern of sh_offset being at some 0xYYY and the sh_addr then at 0xDYYY where 0xD is some some number between 0x1 and 0xF. This is actually pretty easy to spot in a hex dump.
- For Linux based ELF files, there is a noticeable pattern to the type fields, you would only see numbers from a small range. Typically you'll also see some SHT_NOTE sections. Also if the binary is compiled with GNU GCC it may slap in a familiar byte pattern into the sh_type field for its own meta-data, namely the .gnu.version section and its cousins.
|example of the "familiar pattern" left in GCC compiled binaries, this is the GNU_HASH section. try to remember this pattern of bytes for later on 0xf6ffff6f|
- A good place to start the search is after the .shstrtab, in my experience, at least for Ubuntu/GNU GCC ELFs the section header table is usually placed there (this of course may vary by compiler and operating system). In fact the offset usually configured as the start of the e_shoff is actually just the first byte after the .shstrtab ends, which is usually a field of nulls and then the actual section header table.
The screenshots above are for grep, please note the extract from readelf as before showing that the section string table begins at 0x3013c. In the dump we can see the end of the section string table and the beginning of the section header table, as confirmed by this screenshot:
hex(197216) = 0x30260, which is right were the .shtrtab ends for us! You're gonna hafta believe me that this is a common enough pattern., mostly because I'm not going to bloat my blog post with lots repetitive examples.
So lets try using these tricks on a real binary, and work it from being a undebuggable defiled corpse to a living breathing totally under our control.
ELF Necromancy in Practice
"/home/kh3m/Research/CTF/elf_necromancy/misc/./dead.elf": not in executable format: file truncated