Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firmware diffing modules #838

Merged
merged 4 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 2 additions & 13 deletions emba
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ main() {
fi

#######################################################################################
# Diff mode (D-modules - currently not public)
# Diff mode (D-modules)
#######################################################################################
if [[ "${DIFF_MODE}" -eq 1 ]] ; then

Expand All @@ -896,18 +896,7 @@ main() {
fi
write_notification "Diff mode started"

if [[ "$(find "${MOD_DIR_LOCAL}" -name "D[0-9][0-9]_*.sh" | wc -l)" -gt 0 ]] || [[ "$(find "${MOD_DIR}" -name "D[0-9][0-9]_*.sh" | wc -l)" -gt 0 ]]; then
run_modules "D" "${THREADED}" "0"
else
if [[ -d "${LOG_DIR}" ]]; then
print_output "[!] Diff mode currently not supported in this EMBA installation." "main"
print_output "[!] EMBA exits now." "main"
else
print_output "[!] Diff mode currently not supported in this EMBA installation." "no_log"
print_output "[!] EMBA exits now." "no_log"
fi
exit 1
fi
run_modules "D" "${THREADED}" "0"

if [[ -d "${LOG_DIR}" ]]; then
print_output "[!] Diff mode ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "main"
Expand Down
73 changes: 73 additions & 0 deletions modules/D02_firmware_diffing_bin_details.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/bash -p

# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2023 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
#
# Description: This module is for the firmware diffing mode. To use the diffing mode
# a second firmware to compare with the first one needs to be configured
# via the -o EMBA parameter.
# This module is doing some basic checks on the firmware. It uses mainly
# the functionality from the p02 module but on both firmware images.

D02_firmware_diffing_bin_details() {

module_log_init "${FUNCNAME[0]}"
module_title "Firmware differ - binary details"
local NEG_LOG=0

if ! [[ -f "$FIRMWARE_PATH" ]]; then
print_output "[-] No 1st file for diffing provided"
return
fi
if ! [[ -f "$FIRMWARE_PATH1" ]]; then
print_output "[-] No 2nd file for diffing provided"
return
fi

local MD5_FW_BIN1=""
local MD5_FW_BIN2=""

# shellcheck disable=SC2153
MD5_FW_BIN1=$(md5sum "${FIRMWARE_PATH}")
m-1-k-3 marked this conversation as resolved.
Show resolved Hide resolved
# shellcheck disable=SC2153
MD5_FW_BIN2=$(md5sum "${FIRMWARE_PATH1}")
if [[ "${MD5_FW_BIN1}" == "${MD5_FW_BIN2}" ]]; then
print_output "[-] Same firmware binary files - no further analysis"
module_end_log "${FUNCNAME[0]}" 0
return
fi

NEG_LOG=1
sub_module_title "Firmware binary details - firmware image 1"
get_fw_file_details "${FIRMWARE_PATH}"
generate_entropy_graph "${FIRMWARE_PATH}"
print_fw_file_details "${FIRMWARE_PATH}"
# generate_pixde "${FIRMWARE_PATH}"
fw_bin_detector "${FIRMWARE_PATH}"
if [[ -f "$LOG_DIR"/firmware_entropy.png ]]; then
mv "$LOG_DIR"/firmware_entropy.png "${LOG_PATH_MODULE}"/firmware1_entropy.png
write_link "${LOG_PATH_MODULE}"/firmware1_entropy.png
fi

sub_module_title "Firmware binary details - firmware image 2"
get_fw_file_details "${FIRMWARE_PATH1}"
generate_entropy_graph "${FIRMWARE_PATH1}"
print_fw_file_details "${FIRMWARE_PATH1}"
# generate_pixde "${FIRMWARE_PATH1}"
fw_bin_detector "${FIRMWARE_PATH1}"
if [[ -f "$LOG_DIR"/firmware_entropy.png ]]; then
mv "$LOG_DIR"/firmware_entropy.png "${LOG_PATH_MODULE}"/firmware2_entropy.png
write_link "${LOG_PATH_MODULE}"/firmware2_entropy.png
fi

module_end_log "${FUNCNAME[0]}" "$NEG_LOG"
}
101 changes: 101 additions & 0 deletions modules/D05_firmware_diffing_extractor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash -p

# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2023 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
#
# Description: This module is for the firmware diffing mode. To use the diffing mode
# a second firmware to compare with the first one needs to be configured
# via the -o EMBA parameter.
# This module is for the extraction of both firmware images. It uses the
# unblob extraction from module p55. There is currently no deep extraction
# mode supported.


D05_firmware_diffing_extractor() {
module_log_init "${FUNCNAME[0]}"
module_title "Firmware diffing - extractor module"
local NEG_LOG=0

m-1-k-3 marked this conversation as resolved.
Show resolved Hide resolved
local MD5_FW_BIN1=""
local MD5_FW_BIN2=""
export OUTPUT_DIR_UNBLOB1=""
export OUTPUT_DIR_UNBLOB2=""

# shellcheck disable=SC2153
MD5_FW_BIN1=$(md5sum "${FIRMWARE_PATH}")
# shellcheck disable=SC2153
MD5_FW_BIN2=$(md5sum "${FIRMWARE_PATH1}")
if [[ "${MD5_FW_BIN1}" == "${MD5_FW_BIN2}" ]]; then
print_output "[-] Same firmware binary files - no further analysis"
module_end_log "${FUNCNAME[0]}" 0
return
fi

sub_module_title "Firmware extraction - firmware image 1"
OUTPUT_DIR_UNBLOB1="${LOG_PATH_MODULE}"/extractor_"$(basename "${FIRMWARE_PATH}")"
unblobber "${FIRMWARE_PATH}" "${OUTPUT_DIR_UNBLOB1}" 0

if [[ -d "$OUTPUT_DIR_UNBLOB1" ]]; then
NEG_LOG=1
linux_basic_identification_unblobber "${OUTPUT_DIR_UNBLOB1}"
FILES_EXT_UB=$(find "$OUTPUT_DIR_UNBLOB1" -xdev -type f | wc -l )
UNIQUE_FILES_UB=$(find "$OUTPUT_DIR_UNBLOB1" -xdev -type f -exec md5sum {} \; 2>/dev/null | sort -u -k1,1 | cut -d\ -f3 | wc -l )
DIRS_EXT_UB=$(find "$OUTPUT_DIR_UNBLOB1" -xdev -type d | wc -l )
tree -Csh "$OUTPUT_DIR_UNBLOB1" > "${LOG_PATH_MODULE}"/firmware_image1.txt

print_ln
print_output "[*] ${ORANGE}Unblob$NC results:"
print_output "[*] Found $ORANGE$FILES_EXT_UB$NC files ($ORANGE$UNIQUE_FILES_UB$NC unique files) and $ORANGE$DIRS_EXT_UB$NC directories at all."
if [[ -f "${LOG_PATH_MODULE}"/firmware_image1.txt ]]; then
write_link "${LOG_PATH_MODULE}"/firmware_image1.txt
fi
print_output "[*] Additionally the Linux path counter is $ORANGE$LINUX_PATH_COUNTER_UNBLOB$NC."
prepare_binary_arr "${OUTPUT_DIR_UNBLOB1}"
architecture_check
detect_root_dir_helper "$OUTPUT_DIR_UNBLOB1"
print_ln
fi

sub_module_title "Firmware extraction - firmware image 2"
OUTPUT_DIR_UNBLOB2="${LOG_PATH_MODULE}"/extractor_"$(basename "${FIRMWARE_PATH1}")"
unblobber "${FIRMWARE_PATH1}" "${OUTPUT_DIR_UNBLOB2}" 0

if [[ -d "$OUTPUT_DIR_UNBLOB2" ]]; then
NEG_LOG=1
linux_basic_identification_unblobber "${OUTPUT_DIR_UNBLOB2}"
FILES_EXT_UB=$(find "$OUTPUT_DIR_UNBLOB2" -xdev -type f | wc -l )
UNIQUE_FILES_UB=$(find "$OUTPUT_DIR_UNBLOB2" -xdev -type f -exec md5sum {} \; 2>/dev/null | sort -u -k1,1 | cut -d\ -f3 | wc -l )
DIRS_EXT_UB=$(find "$OUTPUT_DIR_UNBLOB2" -xdev -type d | wc -l )
tree -Csh "$OUTPUT_DIR_UNBLOB2" > "${LOG_PATH_MODULE}"/firmware_image2.txt

print_ln
print_output "[*] ${ORANGE}Unblob$NC results:"
print_output "[*] Found $ORANGE$FILES_EXT_UB$NC files ($ORANGE$UNIQUE_FILES_UB$NC unique files) and $ORANGE$DIRS_EXT_UB$NC directories at all."
if [[ -f "${LOG_PATH_MODULE}"/firmware_image2.txt ]]; then
write_link "${LOG_PATH_MODULE}"/firmware_image2.txt
fi
print_output "[*] Additionally the Linux path counter is $ORANGE$LINUX_PATH_COUNTER_UNBLOB$NC."
prepare_binary_arr "${OUTPUT_DIR_UNBLOB2}"
architecture_check
detect_root_dir_helper "$OUTPUT_DIR_UNBLOB2"

# detect_root_dir_helper includes a link to a module that is usually not executed in diff mode
# let's remove this link now:
if ! [[ -f "${LOG_DIR}"/S05_firmware_details.txt ]]; then
sed -i "/\[REF\]\ s05/d" "${LOG_FILE}"
fi
print_ln
fi

module_end_log "${FUNCNAME[0]}" "$NEG_LOG"
}