Skip to content

Commit

Permalink
Merge pull request fkie-cad#12 from m-1-k-3/pre-checker
Browse files Browse the repository at this point in the history
Binary blob testing
  • Loading branch information
p4cx authored Dec 9, 2020
2 parents 2e55490 + 988da5f commit 105eb34
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 26 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Dependency check
-d Only check dependencies
-F Check dependencies but ignore errors
Test kernel config
Special tests
-k [./config] Kernel config path
Modify output
Expand Down Expand Up @@ -126,6 +126,7 @@ For using _emba_ with all features, you will need following tools on your __Kali
- `Option: docker`
- `Option: yara`
- `Option: qemu static user mode emulators`
- `Option: binwalk`

To check these dependencies, only run `sudo ./emba.sh -d`

Expand Down
67 changes: 62 additions & 5 deletions emba.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ main()
export ONLY_DEP=0 # test only dependency
export FORCE=0
export QEMULATION=0
export PRE_CHECK=0 # test and extract binary files with binwalk
# afterwards do a default emba scan

export LOG_DIR="./logs"
export CONFIG_DIR="./config"
Expand All @@ -86,7 +88,7 @@ main()
exit 1
fi

while getopts a:A:cde:Ef:Fhk:l:m:psvz OPT ; do
while getopts a:A:cde:Ef:Fhk:l:m:sz OPT ; do
case $OPT in
a)
export ARCH="$OPTARG"
Expand Down Expand Up @@ -151,15 +153,26 @@ main()

FIRMWARE_PATH="$(abs_path "$FIRMWARE_PATH")"

echo
if [[ -d "$FIRMWARE_PATH" ]]; then
PRE_CHECK=0
print_output "[*] Firmware directory detected." "no_log"
print_output "[*] Emba starts with testing the environment." "no_log"
elif [[ -f "$FIRMWARE_PATH" ]]; then
PRE_CHECK=1
print_output "[*] Firmware binary detected." "no_log"
print_output "[*] Emba starts with some basic tests on it." "no_log"
else
print_output "[-] Invalid firmware file" "no_log"
print_help
exit 1
fi

if [[ $ONLY_DEP -eq 0 ]] ; then
# check if LOG_DIR exists and prompt to terminal to delete its content (y/n)
log_folder

set_exclude

if [[ $KERNEL -eq 0 ]] ; then
architecture_check
fi
fi

dependency_check
Expand All @@ -176,9 +189,53 @@ main()
fi
fi

if [[ $PRE_CHECK -eq 1 ]] ; then
if [[ -f "$FIRMWARE_PATH" ]]; then

echo
print_output "[!] Extraction started on ""$(date)""\\n""$(indent "$NC""Firmware binary path: ""$FIRMWARE_PATH")" "no_log"

# 'main' functions of imported modules
# in the pre-check phase we execute all modules with P[Number]_Name.sh

if [[ ${#SELECT_MODULES[@]} -eq 0 ]] ; then
local MODULES
MODULES=$(find "$MOD_DIR" -name "P*_*.sh" | sort -V 2> /dev/null)
for MODULE_FILE in $MODULES ; do
if ( file "$MODULE_FILE" | grep -q "shell script" ) ; then
MODULE_BN=$(basename "$MODULE_FILE")
MODULE_MAIN=${MODULE_BN%.*}
$MODULE_MAIN
fi
done
else
for SELECT_NUM in "${SELECT_MODULES[@]}" ; do
local MODULE
MODULE=$(find "$MOD_DIR" -name "P""$SELECT_NUM""_*.sh" | sort -V 2> /dev/null)
if ( file "$MODULE" | grep -q "shell script" ) ; then
MODULE_BN=$(basename "$MODULE")
MODULE_MAIN=${MODULE_BN%.*}
$MODULE_MAIN
fi
done
fi

echo
print_output "[!] Extraction ended on ""$(date)"" and took about ""$(date -d@$SECONDS -u +%H:%M:%S)"" \\n" "no_log"

fi
fi

if [[ $FIRMWARE -eq 1 ]] ; then
if [[ -d "$FIRMWARE_PATH" ]]; then

echo
print_output "=================================================================\n" "no_log"

if [[ $KERNEL -eq 0 ]] ; then
architecture_check
fi

check_firmware

prepare_binary_arr
Expand Down
2 changes: 1 addition & 1 deletion helpers/dependency_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ dependency_check()
echo -e "$RED"" This script is only tested on KALI linux""$NC" 1>&2
fi

if [[ $ONLY_DEP -eq 1 ]] && [[ -z "$ARCH" ]] ; then
if [[ $ONLY_DEP -eq 1 ]] && [[ -z "$ARCH" ]] || [[ "$PRE_CHECK" -eq 1 ]]; then
print_output " architecture - ""$ORANGE""not checked""$NC" "no_log"
elif [[ $FIRMWARE -eq 1 ]] || { [[ $ONLY_DEP -eq 1 ]] && [[ -n "$ARCH" ]] ; } ; then
print_output " architecture - \\c" "no_log"
Expand Down
4 changes: 2 additions & 2 deletions helpers/print.sh
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,15 @@ print_help()
echo -e "$CYAN""-a [MIPS]""$NC"" Architecture of the linux firmware [MIPS, ARM, x86, x64, PPC]"
echo -e "$CYAN""-A [MIPS]""$NC"" Force Architecture of the linux firmware [MIPS, ARM, x86, x64, PPC] (disable architecture check)"
echo -e "$CYAN""-l [./path]""$NC"" Log path"
echo -e "$CYAN""-f [./path]""$NC"" Firmware path"
echo -e "$CYAN""-f [./path]""$NC"" Extracted firmware root directory path"
echo -e "$CYAN""-e [./path]""$NC"" Exclude paths from testing (multiple usage possible)"
echo -e "$CYAN""-m [MODULE_NO.]""$NC"" Test only with set modules [e.g. -m 05 -m 10 ... ]] (multiple usage possible)"
echo -e "$CYAN""-c""$NC"" Enable cwe-checker"
echo -e "$CYAN""-E""$NC"" Enable automated qemu emulation tests (WARNING this module could harm your host!)"
echo -e "\\nDependency check"
echo -e "$CYAN""-d""$NC"" Only check dependencies"
echo -e "$CYAN""-F""$NC"" Check dependencies but ignore errors"
echo -e "\\nTest kernel config"
echo -e "\\nSpecial tests"
echo -e "$CYAN""-k [./config]""$NC"" Kernel config path"
echo -e "\\nModify output"
echo -e "$CYAN""-s""$NC"" Print only relative paths"
Expand Down
44 changes: 27 additions & 17 deletions installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ apt-get install shellcheck -y
apt-get install device-tree-compiler -y
apt-get install docker.io -y
apt-get install unzip -y
apt-get install qemu-user-static -y
if ! command -v qemu-mips-static > /dev/null ; then
echo -e "\\n""$ORANGE""$BOLD""Install qemu package""$NC"
apt-get install qemu-user-static -y
fi
if ! command -v binwalk > /dev/null ; then
echo -e "\\n""$ORANGE""$BOLD""Install binwalk package""$NC"
apt-get install binwalk -y
fi


if ! [[ -d "external" ]] ; then
Expand Down Expand Up @@ -144,26 +151,29 @@ if ! [[ -f "external/objdump" ]] ; then
if [[ -f "external/binutils-2.34/binutils/objdump" ]] ; then
mv "external/binutils-2.34/binutils/objdump" "external/objdump"
rm -R external/binutils-2.34
if [[ -f "external/objdump" ]] ; then
echo -e "$GREEN""objdump installed successfully""$NC"
fi
else
echo -e "$ORANGE""objdump installation failed - check it manually""$NC"
fi
else
echo -e "$ORANGE""objdump is already downloaded and compiled""$NC"
fi

# aha for html generation
echo -e "\\n""$ORANGE""$BOLD""Downloading aha""$NC"
if ! [[ -f "external/aha" ]] ; then
apt-get install make
wget https://github.com/theZiz/aha/archive/master.zip -O external/aha-master.zip
unzip ./external/aha-master.zip -d ./external
rm external/aha-master.zip
cd ./external/aha-master || exit 1
echo -e "$ORANGE""$BOLD""Compile aha""$NC"
make
cd ../.. || exit 1
mv "external/aha-master/aha" "external/aha"
rm -R external/aha-master
else
echo -e "$ORANGE""aha is already downloaded and compiled""$NC"
fi
# aha for html generation - future extension of emba
#echo -e "\\n""$ORANGE""$BOLD""Downloading aha""$NC"
#if ! [[ -f "external/aha" ]] ; then
# apt-get install make
# wget https://github.com/theZiz/aha/archive/master.zip -O external/aha-master.zip
# unzip ./external/aha-master.zip -d ./external
# rm external/aha-master.zip
# cd ./external/aha-master || exit 1
# echo -e "$ORANGE""$BOLD""Compile aha""$NC"
# make
# cd ../.. || exit 1
# mv "external/aha-master/aha" "external/aha"
# rm -R external/aha-master
#else
# echo -e "$ORANGE""aha is already downloaded and compiled""$NC"
#fi
29 changes: 29 additions & 0 deletions modules/P02_firmware_bin_file_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# emba - EMBEDDED LINUX ANALYZER
#
# Copyright 2020 Siemens Energy AG
#
# emba comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
# emba is licensed under GPLv3
#
# Author(s): Michael Messner, Pascal Eckmann

P02_firmware_bin_file_check() {
module_log_init "firmware_bin_file_log"
module_title "Binary firmware file analyzer"

local FILE_BIN_OUT
FILE_BIN_OUT=$(file "$FIRMWARE_PATH")
local FILE_LS_OUT
FILE_LS_OUT=$(ls -lh "$FIRMWARE_PATH")

print_output "[*] Details of the binary file:"
print_output "$(indent "$FILE_LS_OUT")"
print_output "$(indent "$FILE_BIN_OUT")"

# probably we can do a lot more stuff in the future ...
}
47 changes: 47 additions & 0 deletions modules/P05_firmware_bin_extractor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

# emba - EMBEDDED LINUX ANALYZER
#
# Copyright 2020 Siemens Energy AG
#
# emba comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
# emba is licensed under GPLv3
#
# Author(s): Michael Messner, Pascal Eckmann

P05_firmware_bin_extractor() {
module_log_init "firmware_bin_extractor_log"
module_title "Binary firmware extractor"

binwalking
# probably we can do something more in the future
}

binwalking() {
sub_module_title "Analyze binary firmware blob with binwalk"

local MAIN_BINWALK
print_output "[*] basic analysis with binwalk"
MAIN_BINWALK=$(binwalk "$FIRMWARE_PATH")
echo "$MAIN_BINWALK"

echo
print_output "[*] Entropy testing with binwalk ... "
print_output "$(binwalk -E -F -J "$FIRMWARE_PATH")"
mv "$(basename "$FIRMWARE_PATH".png)" "$LOG_DIR"/"$(basename "$FIRMWARE_PATH"_entropy.png)" 2> /dev/null

# This test takes a long time and so I have removed it
# we come back to this topic later on - leave it here for the future
#print_output "\n[*] Architecture testing with binwalk ... could take a while"
#binwalk -Y "$FIRMWARE_BIN_PATH"

OUTPUT_DIR=$(basename "$FIRMWARE_PATH")
OUTPUT_DIR="$LOG_DIR"/"$OUTPUT_DIR"_binwalk_emba

echo
print_output "[*] Extracting firmware to directory $OUTPUT_DIR"
print_output "$(binwalk -e -M -C "$OUTPUT_DIR" "$FIRMWARE_PATH")"
}
59 changes: 59 additions & 0 deletions modules/P07_firmware_bin_base_analyzer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

# emba - EMBEDDED LINUX ANALYZER
#
# Copyright 2020 Siemens Energy AG
#
# emba comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
# emba is licensed under GPLv3
#
# Author(s): Michael Messner, Pascal Eckmann

P07_firmware_bin_base_analyser() {
module_log_init "firmware_bin_base_analyser_log"
module_title "Binary firmware OS detection"

os_identification
}

os_identification() {

# We can improve this search stuff a lot in the future:
COUNTER_Linux="$(find "$OUTPUT_DIR" -type f -exec strings {} \; | grep -c Linux 2> /dev/null)"
COUNTER_Linux_FW="$(strings "$FIRMWARE_PATH" | grep -c Linux 2> /dev/null)"
COUNTER_Linux=$((COUNTER_Linux+COUNTER_Linux_FW))

COUNTER_VxWorks="$(find "$OUTPUT_DIR" -type f -exec strings {} \; | grep -c VxWorks 2> /dev/null)"
COUNTER_VxWorks_FW="$(strings "$FIRMWARE_PATH" | grep -c VxWorks 2> /dev/null)"
COUNTER_VxWorks=$((COUNTER_VxWorks+COUNTER_VxWorks_FW))

COUNTER_FreeRTOS="$(find "$OUTPUT_DIR" -type f -exec strings {} \; | grep -c FreeRTOS 2> /dev/null)"
COUNTER_FreeRTOS_FW="$(strings "$FIRMWARE_PATH" | grep -c FreeRTOS 2> /dev/null)"
COUNTER_FreeRTOS=$((COUNTER_FreeRTOS+COUNTER_FreeRTOS_FW))

COUNTER_eCos="$(find "$OUTPUT_DIR" -type f -exec strings {} \; | grep -c eCos 2> /dev/null)"
COUNTER_eCos_FW="$(strings "$FIRMWARE_PATH" | grep -c eCos 2> /dev/null)"
COUNTER_eCos=$((COUNTER_eCos+COUNTER_eCos_FW))

if [[ $((COUNTER_VxWorks+COUNTER_FreeRTOS+COUNTER_eCos)) -gt 0 ]] ; then
print_output "$(indent "$(orange "Operating system detection:")")" "no_log"
if [[ $COUNTER_VxWorks -gt 0 ]] ; then print_output "$(indent "$(orange "VxWorks ""$COUNTER_VxWorks")")" "no_log" ; fi
if [[ $COUNTER_FreeRTOS -gt 0 ]] ; then print_output "$(indent "$(orange "FreeRTOS ""$COUNTER_FreeRTOS")")" "no_log" ; fi
if [[ $COUNTER_eCos -gt 0 ]] ; then print_output "$(indent "$(orange "eCos ""$COUNTER_eCos")")" "no_log" ; fi
if [[ $COUNTER_Linux -gt 0 ]] ; then print_output "$(indent "$(orange "Linux ""$COUNTER_Linux")")" "no_log"; fi
fi

echo
print_output "[*] Trying to identify a Linux root path in $OUTPUT_DIR"
# just to check if there is somewhere a linux filesystem in the extracted stuff
# emba is able to handle the rest
LINUX_PATH_COUNTER="$(find "$OUTPUT_DIR" "${EXCL_FIND[@]}" -type d -iname bin -o -type d -iname busybox -o -type d -iname sbin -o -type d -iname etc 2> /dev/null | wc -l)"
if [[ $LINUX_PATH_COUNTER -gt 0 ]] ; then
print_output "[+] Found possible Linux system in $OUTPUT_DIR"
export FIRMWARE=1
export FIRMWARE_PATH="$OUTPUT_DIR"
fi
}

0 comments on commit 105eb34

Please sign in to comment.