elfmaster / libelfmaster

Secure ELF parsing/loading library for forensics reconstruction of malware, and robust reverse engineering tools
http://www.bitlackeys.org
411 stars 64 forks source link

malformed e_phnum value leads to OOB read #36

Open echel0nn opened 1 year ago

echel0nn commented 1 year ago

Describe the Bug

A bad ELF File which can lead elf_segment_iterator_next() to access out of bound memory or memory leak due to malformed e_phnum value.

To Reproduce

1) Simply run examples/elfparse with 1.bin, 2.bin, 3.bin

To Reproduce afl-fuzz:

Note: Most of them are just my laziness, usually I just copy/paste the environment values.

1) CC=afl-cc CXX=afl-c++ CFLAGS="-g -flto=auto" CXXFLAGS=-g CPPFLAGS=-g PKG_CONFIG_PATH=./build ./configure --prefix=$PWD deleted dl from required packages 2) CC=afl-cc CXX=afl-c++ CFLAGS="-g -flto=auto" CXXFLAGS=-g CPPFLAGS=-g AR=llvm-ar make -j24 all 3) INSTRUMENTATIONS

export AFL_LLVM_CMPLOG=1 
export AFL_LLVM_LAF_ALL=1
export AFL_USE_CFISAN=1 

Expected Behaviour

Parse and Detect the e_phnum anomaly, refuse to allocate memory for non-existent segments and exit gracefully.

Environment

Additional Comments

Found more bugs with the dead_bytes.bin binary that is produced by libgolf.h as one and only unique seed but they need more time to triage. screenshot-2023-04-11-04-25-50

echel0nn commented 1 year ago

The reason why sanity check do not working for these binaries and their phdr values can be explained by these; 1.bin example has these values

pwndbg> print obj->ehdr64->e_phoff 
   $5 = 0
// obj->ehdr64->e_phnum greater than 0
// obj->type is ET_EXEC

if (obj->ehdr64->e_phnum > 0 && obj->ehdr64->e_phoff > 0) It means that ELF_PHDRS_F flag is never set, and unsafe phdr values are never checked here if (elf_flags(obj, ELF_PHDRS_F) == true && elf_type(obj) != ET_REL) For 2.bin and 3.bin the ELF_PHDRS_F flag is set, binaries are type of ET_REL, so unsafe phdr values are never checked. Problems can be solved by removing comparing e_phoff against zero and object's type against ET_REL. However, i couldn't check yet whether there will be side effects other than redundancy in some cases.