diff --git a/README.md b/README.md index d3cfd8bb4..9ac8d7fc7 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ sudo ./emba -l ~/log -f ~firmware -p ./scan-profiles/default-scan.emba ## Quick start with system-emulation scan profile: For further details on EMBA's system-emulation engine check the [wiki](https://github.com/e-m-b-a/emba/wiki/System-emulation). ```console -sudo ./emba -l ~/log -f ~/firmware -p ./scan-profiles/default-scan-emulation.emba +sudo ./emba -l ~/log -f ~/firmware -p ./scan-profiles/default-scan-emulation.emba -m s24 ``` --- diff --git a/config/banner/RIP-binwalk-v1.2.3.txt b/config/banner/RIP-binwalk-v1.2.3.txt new file mode 100644 index 000000000..ef6030176 --- /dev/null +++ b/config/banner/RIP-binwalk-v1.2.3.txt @@ -0,0 +1,19 @@ + +EMBA version 1.2.3 - R.I.P. binwalk + + + .:'/*/'`:,·:~·–:., ',:'/¯/`:, ,:´'*:^-:´¯'`:·, ‘ + /::/:/:::/:::;::::::/`':.,' /:/_/::::/';' '/::::/::::::::::;¯'`*:^:-., ‘ + /·*'`·´¯'`^·-~·:–-'::;:::'`; /:' '`:/::;‘/·´'*^-·´¯'`^·,/::::::::::::'`:, + '\ '`;::'i‘ ; ';:';‘'`, ¯'`*^·-:;::::::'\' ‘ + '`; ,– ., 'i:'/ | 'i::i '`·, '`·;:::i'‘ + i i':/:::'; ;/' '; ;'::i '| .,_ \:'/' + i i/:·'´ ,:'' 'i 'i::i' 'i 'i:::'`·, i/' ‘ + '; ' ,:, ~;'´:::'`:, ; 'i::;' 'i 'i::/:,: /' + 'i i:/\ `;::::/:'`;' '; i:/' ; ,'.^*'´ _,.·´‘ + ; ;/ \ '`:/::::/' '; ;/ ° '; ;/ '`*^*'´¯ + '; ,' \ '`;/' '; / ° \ / + `'*´ '`~·-·^'´ `'´ ° '`^'´‘ + ‘ + Binwalk + It was a pleasure diff --git a/config/trickest_blacklist.txt b/config/trickest_blacklist.txt index 344265055..88b1c85b5 100644 --- a/config/trickest_blacklist.txt +++ b/config/trickest_blacklist.txt @@ -64,3 +64,28 @@ Eduardmihai1997/VulnerabilityManagement PotterXma/linux-deployment-standard paramint/AD-Attack-Defense BSG9432/Districts-2023 +YgorAlberto/ygoralberto.github.io +xsudoxx/OSCP +wiz-sec-public/cloud-middleware-dataset +stkcat/awe-base-images +srchen1987/springcloud-distributed-transaction +splunk-soar-connectors/flashpoint +splitlane/FTCLib-Quickstart +sourchib/Framework7_Cordova +skyblueflag/WebSecurityStudy +Skixie/OSCP-Journey +Singhsanjeev617/A-Red-Teamer-diaries +seeu-inspace/easyg +rojasjo/TelnetHoneypot.Net +Rayyan-appsec/ALL-PENTESTING-BIBLE +papicella/cli-snyk-getting-started +NikulinMS/13-01-hw +marklogic/marklogic-kubernetes +karimhabush/cyberowl +heane404/CVE_scan +fernandoreb/dependency-check-springboot +FDlucifer/Proxy-Attackchain +EGI-Federation/SVG-advisories +chorankates/Help +actions-marketplace-validations/ajinkya599_container-scan +0xsyr0/OSCP diff --git a/helpers/helpers_emba_defaults.sh b/helpers/helpers_emba_defaults.sh index 7907d8abb..eb43c3caa 100755 --- a/helpers/helpers_emba_defaults.sh +++ b/helpers/helpers_emba_defaults.sh @@ -26,7 +26,7 @@ set_defaults() { export DEBUG_SCRIPT=0 export UPDATE=0 export ARCH_CHECK=1 - export RTOS=0 # Testing RTOS based OS + export RTOS=1 # Testing RTOS based OS - 1 -> no Linux / 0 -> Linux export CWE_CHECKER=0 export CONTAINER_EXTRACT=0 export DEEP_EXTRACTOR=0 diff --git a/helpers/helpers_emba_dependency_check.sh b/helpers/helpers_emba_dependency_check.sh index 43c78f9d9..e57a03f49 100755 --- a/helpers/helpers_emba_dependency_check.sh +++ b/helpers/helpers_emba_dependency_check.sh @@ -443,6 +443,9 @@ dependency_check() # progpilot for php code checks check_dep_file "progpilot php ini checker" "$EXT_DIR""/progpilot" + # luacheck - lua linter + check_dep_tool "luacheck" + # APKHunt for android apk analysis # hard requirement for v1.2.2 # check_dep_file "APKHunt apk scanner" "$EXT_DIR""/APKHunt/apkhunt.go" diff --git a/helpers/helpers_emba_prepare.sh b/helpers/helpers_emba_prepare.sh index 72195a095..c5125df64 100755 --- a/helpers/helpers_emba_prepare.sh +++ b/helpers/helpers_emba_prepare.sh @@ -381,8 +381,11 @@ prepare_file_arr() # rm_proc_binary "${FILE_ARR[@]}" } -prepare_binary_arr() -{ +prepare_binary_arr() { + local FIRMWARE_PATH="${1:-}" + if ! [[ -d "${FIRMWARE_PATH}" ]]; then + return + fi echo "" print_output "[*] Unique binary auto detection for $ORANGE$FIRMWARE_PATH$NC (could take some time)\\n" diff --git a/modules/L10_system_emulation.sh b/modules/L10_system_emulation.sh index 66ef98c4f..b23ceddd6 100755 --- a/modules/L10_system_emulation.sh +++ b/modules/L10_system_emulation.sh @@ -144,12 +144,14 @@ L10_system_emulation() { IP_ADDRESS_=$(echo "$SYS_EMUL_POS_ENTRY" | grep "TCP ok" | sort -k 7 -t ';' | tail -1 | cut -d\; -f8 | awk '{print $3}') IMAGE_NAME="$(echo "$SYS_EMUL_POS_ENTRY" | grep "TCP ok" | sort -k 7 -t ';' | tail -1 | cut -d\; -f10)" ARCHIVE_PATH="$LOG_PATH_MODULE""/""$IMAGE_NAME" + print_ln print_output "[*] Identified IP address: $ORANGE$IP_ADDRESS_$NC" print_output "[*] Identified IMAGE_NAME: $ORANGE$IMAGE_NAME$NC" print_output "[*] Identified ARCHIVE_PATH: $ORANGE$ARCHIVE_PATH$NC" if [[ -v ARCHIVE_PATH ]] && [[ -f "$ARCHIVE_PATH"/run.sh ]]; then print_output "[+] Identified emulation startup script (run.sh) in ARCHIVE_PATH ... starting emulation process for further analysis" + print_ln restart_emulation "$IP_ADDRESS_" "$IMAGE_NAME" 1 # we should get TCP="ok" and SYS_ONLINE=1 back if [[ "$SYS_ONLINE" -ne 1 ]]; then @@ -2231,6 +2233,7 @@ write_results() { if [[ -f "$LOG_PATH_MODULE"/"$NMAP_LOG" ]]; then TCP_SERV_CNT="$(grep "udp.*open\ \|tcp.*open\ " "$LOG_PATH_MODULE"/"$NMAP_LOG" 2>/dev/null | awk '{print $1}' | sort -u | wc -l || true)" fi + [[ "${TCP_SERV_CNT}" -gt 0 ]] && TCP="ok" ARCHIVE_PATH_="$(echo "$ARCHIVE_PATH_" | rev | cut -d '/' -f1 | rev)" echo "$FIRMWARE_PATH_orig;$RESULT_SOURCE;Booted $BOOTED;ICMP $ICMP;TCP-0 $TCP_0;TCP $TCP;$TCP_SERV_CNT;IP address: $IP_ADDRESS_;Network mode: $NETWORK_MODE ($NETWORK_DEVICE/$ETH_INT/$INIT_FILE);$ARCHIVE_PATH_;$R_PATH_mod" >> "$LOG_DIR"/emulator_online_results.log print_bar "" diff --git a/modules/L22_upnp_checks.sh b/modules/L22_upnp_checks.sh index 998c508a1..9611a0eda 100755 --- a/modules/L22_upnp_checks.sh +++ b/modules/L22_upnp_checks.sh @@ -64,10 +64,10 @@ check_basic_upnp() { if [[ -f "$LOG_PATH_MODULE"/upnp-discovery-check.txt ]]; then print_ln tee -a "$LOG_FILE" < "$LOG_PATH_MODULE"/upnp-discovery-check.txt - fi - print_ln + print_ln - UPNP_UP=$(grep -c "desc\|IGD" "$LOG_PATH_MODULE"/upnp-discovery-check.txt) + UPNP_UP=$(grep -c "desc\|IGD" "$LOG_PATH_MODULE"/upnp-discovery-check.txt || true) + fi fi if [[ "$UPNP_UP" -gt 0 ]]; then diff --git a/modules/P02_firmware_bin_file_check.sh b/modules/P02_firmware_bin_file_check.sh index 133db3060..1b15e18d0 100755 --- a/modules/P02_firmware_bin_file_check.sh +++ b/modules/P02_firmware_bin_file_check.sh @@ -81,6 +81,8 @@ P02_firmware_bin_file_check() { write_link "$LOG_DIR"/pixd.png fi + generate_entropy_graph "$FIRMWARE_PATH" + fw_bin_detector "$FIRMWARE_PATH" backup_p02_vars @@ -115,6 +117,25 @@ set_p02_default_exports() { export QCOW_DETECTED=0 } +generate_entropy_graph() { + local FIRMWARE_PATH_BIN="${1:-}" + # we use the original FIRMWARE_PATH for entropy testing, just if it is a file + if [[ -f $FIRMWARE_PATH_BIN ]] && ! [[ -f "$LOG_DIR"/firmware_entropy.png ]]; then + print_output "[*] Entropy testing with binwalk ... " + # we have to change the working directory for binwalk, because everything except the log directory is read-only in + # Docker container and binwalk fails to save the entropy picture there + if [[ $IN_DOCKER -eq 1 ]] ; then + cd "$LOG_DIR" || return + print_output "$(binwalk -E -F -J "$FIRMWARE_PATH_BIN")" + mv "$(basename "$FIRMWARE_PATH_BIN".png)" "$LOG_DIR"/firmware_entropy.png 2> /dev/null || true + cd /emba || return + else + print_output "$(binwalk -E -F -J "$FIRMWARE_PATH_BIN")" + mv "$(basename "$FIRMWARE_PATH_BIN".png)" "$LOG_DIR"/firmware_entropy.png 2> /dev/null || true + fi + fi +} + fw_bin_detector() { local CHECK_FILE="${1:-}" local FILE_BIN_OUT="" @@ -170,7 +191,7 @@ fw_bin_detector() { write_csv_log "basic compressed (patool)" "yes" "NA" fi fi - if [[ "$FILE_BIN_OUT" == *"QEMU QCOW2 Image"* ]]; then + if [[ "$FILE_BIN_OUT" == *"QEMU QCOW2 Image"* ]] || [[ "$FILE_BIN_OUT" == *"QEMU QCOW Image"* ]]; then print_output "[+] Identified Qemu QCOW image - using QCOW extraction module" export QCOW_DETECTED=1 write_csv_log "Qemu QCOW firmware detected" "yes" "NA" @@ -206,7 +227,7 @@ fw_bin_detector() { write_csv_log "D-Link encrpted_img encrypted" "yes" "NA" fi if [[ "$FILE_BIN_OUT" == *"u-boot legacy uImage"* ]]; then - print_output "[+] Identified u-boot firmware - using u-boot module" + print_output "[+] Identified u-boot firmware image" export UBOOT_IMAGE=1 write_csv_log "Uboot image" "yes" "NA" fi @@ -256,7 +277,7 @@ fw_bin_detector() { write_csv_log "OpenSSL encrypted" "yes" "NA" fi # This check is currently only tested on one firmware - further tests needed: - if [[ "$DLINK_ENC_CHECK" =~ 00000000\ \ 62\ 67\ 6e\ 00\ 00\ 00\ 00\ 00\ \ 00\ 00\ 00\ b9\ 01\ ]]; then + if [[ "$DLINK_ENC_CHECK" =~ 00000000\ \ 62\ 67\ 6e\ 00\ 00\ 00\ 00\ 00\ \ 00\ 00\ 00\ ]]; then print_output "[+] Identified Buffalo encrpyted firmware - using Buffalo extraction module" export BUFFALO_ENC_DETECTED=1 write_csv_log "Buffalo encrypted" "yes" "NA" diff --git a/modules/P05_patools_init.sh b/modules/P05_patools_init.sh index fe28ac7b2..6596962c7 100755 --- a/modules/P05_patools_init.sh +++ b/modules/P05_patools_init.sh @@ -78,9 +78,9 @@ patools_extractor() { else # Fallback if unzip does not work: print_ln - print_output "[*] No valid compressed file detected - extraction process via binwalk started" + print_output "[*] No valid compressed file detected - extraction process via unblob started" - binwalk_deep_extract_helper 0 "$FIRMWARE_PATH_" "$EXTRACTION_DIR_" + unblobber "$FIRMWARE_PATH_" "$EXTRACTION_DIR_" fi print_ln diff --git a/modules/P11_dlink_SHRS_enc_extract.sh b/modules/P11_dlink_SHRS_enc_extract.sh deleted file mode 100755 index 880b4173f..000000000 --- a/modules/P11_dlink_SHRS_enc_extract.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/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 -# Contributor: Benedikt Kuehne - -# Description: Extracts encrypted firmware images from D-Link -# (See https://github.com/0xricksanchez/dlink-decrypt) -# Pre-checker threading mode - if set to 1, these modules will run in threaded mode -export PRE_THREAD_ENA=0 - -P11_dlink_SHRS_enc_extract() { - local NEG_LOG=0 - - if [[ "$DLINK_ENC_DETECTED" -ne 0 ]] && [[ "$MODULE_DISABLED" -ne 1 ]]; then - module_log_init "${FUNCNAME[0]}" - module_title "DLink encrypted firmware extractor" - pre_module_reporter "${FUNCNAME[0]}" - EXTRACTION_FILE="$LOG_DIR"/firmware/firmware_dlink_dec.bin - - if [[ "$DLINK_ENC_DETECTED" -eq 1 ]]; then - dlink_SHRS_enc_extractor "$FIRMWARE_PATH" "$EXTRACTION_FILE" - elif [[ "$DLINK_ENC_DETECTED" -eq 2 ]]; then - dlink_enc_img_extractor "$FIRMWARE_PATH" "$EXTRACTION_FILE" - fi - - NEG_LOG=1 - module_end_log "${FUNCNAME[0]}" "$NEG_LOG" - fi -} - -dlink_SHRS_enc_extractor() { - local DLINK_ENC_PATH_="${1:-}" - local EXTRACTION_FILE_="${2:-}" - if ! [[ -f "$DLINK_ENC_PATH_" ]]; then - print_output "[-] No file for decryption provided" - return - fi - - local MODULE_DISABLED=1 - - if [[ "$MODULE_DISABLED" -eq 1 ]]; then - print_output "[*] Module ${FUNCNAME[0]} is deprecated and will be removed in the future" - return - fi - - sub_module_title "DLink encrypted firmware extractor" - - hexdump -C "$DLINK_ENC_PATH_" | head | tee -a "$LOG_FILE" || true - - print_ln - - dd if="$DLINK_ENC_PATH_" skip=1756 iflag=skip_bytes|openssl aes-128-cbc -d -p -nopad -nosalt -K "c05fbf1936c99429ce2a0781f08d6ad8" -iv "67c6697351ff4aec29cdbaabf2fbe346" --nosalt -in /dev/stdin -out "$EXTRACTION_FILE_" 2>&1 || true | tee -a "$LOG_FILE" - - print_ln - if [[ -f "$EXTRACTION_FILE_" ]]; then - print_output "[+] Decrypted D-Link firmware file to $ORANGE$EXTRACTION_FILE_$NC" - print_ln - print_output "[*] Firmware file details: $ORANGE$(file "$EXTRACTION_FILE_")$NC" - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "DLink SHRS decryptor" "$DLINK_ENC_PATH_" "$EXTRACTION_FILE_" "1" "NA" "NA" - export FIRMWARE_PATH="$EXTRACTION_FILE_" - backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" - if [[ -z "${FW_VENDOR:-}" ]]; then - FW_VENDOR="D-Link" - backup_var "FW_VENDOR" "$FW_VENDOR" - fi - else - print_output "[-] Decryption of D-Link firmware file failed" - fi -} - -dlink_enc_img_extractor(){ - local TMP_DIR="$LOG_DIR""/tmp" - local DLINK_ENC_PATH_="${1:-}" - local EXTRACTION_FILE_="${2:-}" - local TMP_IMAGE_FILE="$TMP_DIR/image.bin" - if ! [[ -f "$DLINK_ENC_PATH_" ]]; then - print_output "[-] No file for decryption provided" - return - fi - local IMAGE_SIZE=0 - local OFFSET=0 - local ITERATION=0 - - local MODULE_DISABLED=1 - - if [[ "$MODULE_DISABLED" -eq 1 ]]; then - print_output "[*] Module ${FUNCNAME[0]} is deprecated and will be removed in the future" - return - fi - - sub_module_title "DLink encrpted_image extractor" - - hexdump -C "$DLINK_ENC_PATH_" | head | tee -a "$LOG_FILE" || true - dd if="$DLINK_ENC_PATH_" skip=16 iflag=skip_bytes of="$TMP_IMAGE_FILE" 2>&1 | tee -a "$LOG_FILE" - - IMAGE_SIZE=$(stat -c%s "$TMP_IMAGE_FILE") - (( ROOF=IMAGE_SIZE/131072 )) - for ((ITERATION=0; ITERATION&1 | tee -a "$LOG_FILE" - done - # Now it should be a .ubi file thats somewhat readable and extractable via ubireader - print_ln - if [[ -f "$EXTRACTION_FILE_" ]]; then - UBI_OUT=$(file "$EXTRACTION_FILE_") - if [[ "$UBI_OUT" == *"UBI image, version"* ]]; then - print_output "[+] Decrypted D-Link firmware file to $ORANGE$EXTRACTION_FILE_$NC" - print_ln - print_output "[*] Firmware file details: $ORANGE$(file "$EXTRACTION_FILE_")$NC" - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "DLink enc_img decryptor" "$DLINK_ENC_PATH_" "$EXTRACTION_FILE_" "1" "NA" "NA" - export FIRMWARE_PATH="$EXTRACTION_FILE_" - backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" - if [[ -z "${FW_VENDOR:-}" ]]; then - FW_VENDOR="D-Link" - backup_var "FW_VENDOR" "$FW_VENDOR" - fi - EXTRACTION_DIR="$LOG_DIR/firmware/dlink_ubi_extracted" - mkdir -p "$EXTRACTION_DIR" || true - ubi_extractor "$FIRMWARE_PATH" "$EXTRACTION_DIR" - else - print_output "[-] Further extraction of D-Link firmware file via deep extraction" - fi - else - print_output "[-] Decryption of D-Link firmware file failed" - fi -} diff --git a/modules/P12_avm_freetz_ng_extract.sh b/modules/P12_avm_freetz_ng_extract.sh deleted file mode 100755 index b602f57b8..000000000 --- a/modules/P12_avm_freetz_ng_extract.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/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: Extracts AVM firmware images with Freetz-NG (see https://github.com/Freetz-NG/freetz-ng.git) -# Pre-checker threading mode - if set to 1, these modules will run in threaded mode -export PRE_THREAD_ENA=0 - -P12_avm_freetz_ng_extract() { - local NEG_LOG=0 - - if [[ "$AVM_DETECTED" -eq 1 ]]; then - module_log_init "${FUNCNAME[0]}" - module_title "AVM freetz-ng firmware extractor" - pre_module_reporter "${FUNCNAME[0]}" - - EXTRACTION_DIR="$LOG_DIR"/firmware/freetz_ng_extractor - - avm_extractor "$FIRMWARE_PATH" "$EXTRACTION_DIR" - - if [[ "$FRITZ_FILES" -gt 0 ]]; then - MD5_DONE_DEEP+=( "$(md5sum "$FIRMWARE_PATH" | awk '{print $1}')" ) - export FIRMWARE_PATH="$LOG_DIR"/firmware/ - backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" - fi - - NEG_LOG=1 - module_end_log "${FUNCNAME[0]}" "$NEG_LOG" - fi -} - -avm_extractor() { - local AVM_FW_PATH_="${1:-}" - local EXTRACTION_DIR_="${2:-}" - if ! [[ -f "$AVM_FW_PATH_" ]]; then - return - fi - local FRITZ_DIRS=0 - local FIT_IMAGES=() - local FIT_IMAGE="" - local RAM_DISKS=() - local RAM_DISK="" - local RAM_DISK_NAME="" - export FRITZ_FILE=0 - export FRITZ_VERSION="" - - local MODULE_DISABLED=1 - - if [[ "$MODULE_DISABLED" -eq 1 ]]; then - print_output "[*] Module ${FUNCNAME[0]} is deprecated and will be removed in the future" - return - fi - - sub_module_title "AVM freetz-ng firmware extractor" - - # read only filesystem bypass: - cp "$EXT_DIR"/freetz-ng/.config "$TMP_DIR"/.config - - "$EXT_DIR"/freetz-ng/fwmod -u -i "$TMP_DIR"/.config -d "$EXTRACTION_DIR_" "$AVM_FW_PATH_" | tee -a "$LOG_FILE" || true - - if [[ -d "$EXTRACTION_DIR_" ]]; then - FRITZ_FILES=$(find "$EXTRACTION_DIR_" -type f | wc -l) - FRITZ_DIRS=$(find "$EXTRACTION_DIR_" -type d | wc -l) - - FRITZ_VERSION=$(grep "detected firmware version:" "$LOG_FILE" | cut -d ":" -f2- || true) - if [[ -z "$FRITZ_VERSION" ]]; then - FRITZ_VERSION="NA" - else - print_output "[+] Detected Fritz version: $ORANGE$FRITZ_VERSION$NC" - fi - - # fitimages are handled here with fitimg - binwalk and unblob are also able to handle these images - # but it is currently more beautiful doing the AVM extraction in one place here - mapfile -t FIT_IMAGES < <(find "$EXTRACTION_DIR_" -type f -name "fit-image") - - if [[ "${#FIT_IMAGES[@]}" -gt 0 ]]; then - if [[ -f "$EXT_DIR"/fitimg-0.8/fitimg ]]; then - for FIT_IMAGE in "${FIT_IMAGES[@]}"; do - print_output "[*] Detected fit-image: $ORANGE$FIT_IMAGE$NC" - print_output "[*] Extracting fit-image with fitimg to $ORANGE$EXTRACTION_DIR/fit-image-extraction$NC" - mkdir -p "$EXTRACTION_DIR/fit-image-extraction" - "$EXT_DIR"/fitimg-0.8/fitimg -x "$FIT_IMAGE" -d "$EXTRACTION_DIR"/fit-image-extraction || true - mapfile -t RAM_DISKS < <(find "$EXTRACTION_DIR_"/fit-image-extraction -type f -name "*ramdisk") - print_ln - done - else - print_output "[-] Fitimg installation not available - check your installation" - fi - fi - if [[ "${#RAM_DISKS[@]}" -gt 0 ]]; then - for RAM_DISK in "${RAM_DISKS[@]}"; do - print_output "[*] Detected AVM ramdisk: $ORANGE$RAM_DISK$NC" - RAM_DISK_NAME="$(basename "$RAM_DISK")" - binwalk_deep_extract_helper 1 "$RAM_DISK" "$EXTRACTION_DIR_"/fit-image-extraction/"$RAM_DISK_NAME"_binwalk - print_ln - done - fi - - if [[ "$FRITZ_FILES" -gt 0 ]]; then - print_ln - print_output "[*] Extracted $ORANGE$FRITZ_FILES$NC files and $ORANGE$FRITZ_DIRS$NC directories from the firmware image." - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "AVM extractor" "$AVM_FW_PATH_" "$EXTRACTION_DIR_" "$FRITZ_FILES" "$FRITZ_DIRS" "$FRITZ_VERSION" - export DEEP_EXTRACTOR=1 - MD5_DONE_DEEP+=( "$(md5sum "$AVM_FW_PATH_" | awk '{print $1}')" ) - - if [[ -z "${FW_VENDOR:-}" ]]; then - FW_VENDOR="AVM" - backup_var "FW_VENDOR" "$FW_VENDOR" - fi - if [[ -z "${FW_VERSION:-}" && "$FRITZ_VERSION" != "NA" ]]; then - FW_VERSION="$FRITZ_VERSION" - fi - fi - fi -} diff --git a/modules/P13_uboot_mkimage.sh b/modules/P13_uboot_mkimage.sh deleted file mode 100755 index c87f619e8..000000000 --- a/modules/P13_uboot_mkimage.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/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: Shows internals of Uboot images -# Pre-checker threading mode - if set to 1, these modules will run in threaded mode -export PRE_THREAD_ENA=0 - -P13_uboot_mkimage() { - local NEG_LOG=0 - if [[ "$UBOOT_IMAGE" -eq 1 ]]; then - module_log_init "${FUNCNAME[0]}" - local IMAGE_NAME="" - local IMAGE_TYPE="" - module_title "Uboot image details" - pre_module_reporter "${FUNCNAME[0]}" - mkimage -l "$FIRMWARE_PATH" | tee -a "$LOG_FILE" - IMAGE_NAME=$(grep "Image Name" "$LOG_FILE" 2>/dev/null | awk '{print $3,$4,$5,$6,$7,$8,$9,$10}' || true) - IMAGE_TYPE=$(grep "Image Type" "$LOG_FILE" 2>/dev/null | awk '{print $3,$4,$5,$6,$7,$8,$9,$10}' || true) - write_csv_log "Identifier" "Value" - write_csv_log "ImageName" "$IMAGE_NAME" - write_csv_log "ImageType" "$IMAGE_TYPE" - NEG_LOG=1 - module_end_log "${FUNCNAME[0]}" "$NEG_LOG" - fi -} diff --git a/modules/P16_EnGenius_decryptor.sh b/modules/P16_EnGenius_decryptor.sh deleted file mode 100755 index 1cccc2652..000000000 --- a/modules/P16_EnGenius_decryptor.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/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: Extracts encrypted firmware images from EnGenius reported by @ryancdotorg -# See https://twitter.com/ryancdotorg/status/1473807312242442240 and -# https://gist.github.com/ryancdotorg/914f3ad05bfe0c359b79716f067eaa99 -# Pre-checker threading mode - if set to 1, these modules will run in threaded mode -export PRE_THREAD_ENA=0 - -P16_EnGenius_decryptor() { - local NEG_LOG=0 - - if [[ "$ENGENIUS_ENC_DETECTED" -ne 0 ]]; then - module_log_init "${FUNCNAME[0]}" - module_title "EnGenius encrypted firmware extractor" - pre_module_reporter "${FUNCNAME[0]}" - - EXTRACTION_FILE="$LOG_DIR"/firmware/firmware_engenius_dec.bin - - engenius_enc_extractor "$FIRMWARE_PATH" "$EXTRACTION_FILE" - - NEG_LOG=1 - module_end_log "${FUNCNAME[0]}" "$NEG_LOG" - fi -} - -engenius_enc_extractor() { - local ENGENIUS_ENC_PATH_="${1:-}" - local EXTRACTION_FILE_="${2:-}" - - if ! [[ -f "$ENGENIUS_ENC_PATH_" ]]; then - print_output "[-] No file for decryption provided" - return - fi - - sub_module_title "EnGenius encrypted firmware extractor" - - hexdump -C "$ENGENIUS_ENC_PATH_" | head | tee -a "$LOG_FILE" || true - - if [[ -f "$EXT_DIR"/engenius-decrypt.py ]]; then - python3 "$EXT_DIR"/engenius-decrypt.py "$ENGENIUS_ENC_PATH_" > "$EXTRACTION_FILE_" - else - print_output "[-] Decryptor not found - check your installation" - fi - - print_ln - if [[ -f "$EXTRACTION_FILE_" ]]; then - print_output "[+] Decrypted EnGenius firmware file to $ORANGE$EXTRACTION_FILE_$NC" - export FIRMWARE_PATH="$EXTRACTION_FILE_" - MD5_DONE_DEEP+=( "$(md5sum "$ENGENIUS_ENC_PATH_" | awk '{print $1}')" ) - print_ln - print_output "[*] Firmware file details: $ORANGE$(file "$EXTRACTION_FILE_")$NC" - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "EnGenius decryptor" "$ENGENIUS_ENC_PATH_" "$EXTRACTION_FILE_" "1" "NA" "NA" - if [[ -z "${FW_VENDOR:-}" ]]; then - FW_VENDOR="EnGenius" - backup_var "FW_VENDOR" "$FW_VENDOR" - fi - else - print_output "[-] Decryption of EnGenius firmware file failed" - fi -} diff --git a/modules/P17_gpg_decompress.sh b/modules/P17_gpg_decompress.sh index 90f8b4c20..a717d5d2a 100755 --- a/modules/P17_gpg_decompress.sh +++ b/modules/P17_gpg_decompress.sh @@ -56,6 +56,7 @@ gpg_decompress_extractor() { backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" print_ln print_output "[*] Firmware file details: $ORANGE$(file "$EXTRACTION_FILE_")$NC" + unblobber "$EXTRACTION_FILE_" "$LOG_DIR"/firmware/firmware_gpg_extracted write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" write_csv_log "GPG decompression" "$GPG_FILE_PATH_" "$EXTRACTION_FILE_" "1" "NA" "NA" else diff --git a/modules/P18_qnap_decryptor.sh b/modules/P18_qnap_decryptor.sh deleted file mode 100755 index 3edcee0b6..000000000 --- a/modules/P18_qnap_decryptor.sh +++ /dev/null @@ -1,405 +0,0 @@ -#!/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: Extracts encrypted firmware images from QNAP as shown here: -# https://github.com/max-boehm/qnap-utils -# Pre-checker threading mode - if set to 1, these modules will run in threaded mode -export PRE_THREAD_ENA=0 - -P18_qnap_decryptor() { - local NEG_LOG=0 - - if [[ "$QNAP_ENC_DETECTED" -ne 0 ]]; then - module_log_init "${FUNCNAME[0]}" - module_title "QNAP encrypted firmware extractor" - pre_module_reporter "${FUNCNAME[0]}" - - EXTRACTION_FILE="$LOG_DIR"/firmware/firmware_qnap_dec.tgz - - qnap_enc_extractor "$FIRMWARE_PATH" "$EXTRACTION_FILE" - - if [[ "$QNAP" -eq 1 ]]; then - qnap_extractor "$FIRMWARE_PATH" - fi - if [[ "$QNAP" -eq 1 ]] && [[ "$FILES_QNAP" -gt 20 ]]; then - MD5_DONE_DEEP+=( "$(md5sum "$FIRMWARE_PATH" | awk '{print $1}')" ) - export FIRMWARE_PATH="$LOG_DIR"/firmware/ - backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" - fi - - NEG_LOG=1 - module_end_log "${FUNCNAME[0]}" "$NEG_LOG" - fi -} - -qnap_enc_extractor() { - local QNAP_ENC_PATH_="${1:-}" - local EXTRACTION_FILE_="${2:-}" - export QNAP=0 - - if ! [[ -f "$QNAP_ENC_PATH_" ]]; then - print_output "[-] No file for decryption provided" - return - fi - - sub_module_title "QNAP encrypted firmware extractor" - - hexdump -C "$QNAP_ENC_PATH_" | head | tee -a "$LOG_FILE" || true - - if [[ -f "$EXT_DIR"/PC1 ]]; then - print_ln - print_output "[*] Decrypting QNAP firmware with leaked key material ..." - print_ln - "$EXT_DIR"/PC1 d QNAPNASVERSION4 "$QNAP_ENC_PATH_" "$EXTRACTION_FILE_" | tee -a "$LOG_FILE" - else - print_output "[-] QNAP decryptor not found - check your installation" - fi - - print_ln - if [[ -f "$EXTRACTION_FILE_" && "$(file "$EXTRACTION_FILE_")" == *"gzip compressed data"* ]]; then - print_output "[+] Decrypted QNAP firmware file to $ORANGE$EXTRACTION_FILE_$NC" - MD5_DONE_DEEP+=( "$(md5sum "$QNAP_ENC_PATH_" | awk '{print $1}')" ) - export FIRMWARE_PATH="$EXTRACTION_FILE_" - backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" - export QNAP=1 - print_ln - print_output "[*] Firmware file details: $ORANGE$(file "$EXTRACTION_FILE_")$NC" - print_ln - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "QNAP decryptor" "$QNAP_ENC_PATH_" "$EXTRACTION_FILE_" "1" "NA" "gzip compressed data" - if [[ -z "${FW_VENDOR:-}" ]]; then - FW_VENDOR="QNAP" - backup_var "FW_VENDOR" "$FW_VENDOR" - fi - - else - print_output "[-] Decryption of QNAP firmware file failed" - fi -} - -qnap_extractor() { - local DECRYPTED_FW_="${1:-}" - if ! [[ -f "$DECRYPTED_FW_" ]]; then - return - fi - - sub_module_title "QNAP firmware extraction" - print_output "[!] WARNING: This module is in an very early alpha state." - print_output "[!] WARNING: Some areas of this module are not tested." - - # This module is a full copy of https://github.com/max-boehm/qnap-utils/blob/master/extract_qnap_fw.sh - # some areas of this code are completely untested. Please report bugs via https://github.com/e-m-b-a/emba/issues - - QNAP_EXTRACTION_ROOT="$LOG_DIR"/firmware/qnap_extraction - QNAP_EXTRACTION_ROOT_DST="$QNAP_EXTRACTION_ROOT"/root_filesystem - mkdir -p "$QNAP_EXTRACTION_ROOT_DST" || true - - if file "$DECRYPTED_FW_" | grep -q ": gzip" ; then - print_output "[*] Extracting $ORANGE$DECRYPTED_FW_$NC into $ORANGE$QNAP_EXTRACTION_ROOT$NC." - mkdir -p "$QNAP_EXTRACTION_ROOT" || true - tar xvf "$DECRYPTED_FW_" -C "$QNAP_EXTRACTION_ROOT" 2>/dev/null || true | tee -a "$LOG_FILE" - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$QNAP_EXTRACTION_ROOT$NC):" - find "$QNAP_EXTRACTION_ROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - else - print_output "[-] No QNAP firmware file found" - return 1 - fi - - UIMAGE="$QNAP_EXTRACTION_ROOT/uImage" # x31,x31+ - UBI="$QNAP_EXTRACTION_ROOT/rootfs2.ubi" # x31,x31+ - IMAGE="$QNAP_EXTRACTION_ROOT_DST/image" - - # initial ramdisk root filesystem - INITRAMFS="$QNAP_EXTRACTION_ROOT_DST/initramfs" # x31,x31+ - INITRD="$QNAP_EXTRACTION_ROOT/initrd.boot" # x10,x12,x19,x20,x21 - if [ ! -e "$INITRD" ]; then - INITRD="$QNAP_EXTRACTION_ROOT/initrd" # x51,x53 - fi - - ROOTFS2="$QNAP_EXTRACTION_ROOT/rootfs2.tgz" - ROOTFS2_BZ="$QNAP_EXTRACTION_ROOT/rootfs2.bz" - ROOTFS2_IMG="$QNAP_EXTRACTION_ROOT/rootfs2.img" - ROOTFS_EXT="$QNAP_EXTRACTION_ROOT/rootfs_ext.tgz" - QPKG="$QNAP_EXTRACTION_ROOT/qpkg.tar" - - if [ -e "$UBI" ]; then - ROOTFS2="$QNAP_EXTRACTION_ROOT_DST/rootfs2.tgz" - ROOTFS_EXT="$QNAP_EXTRACTION_ROOT_DST/rootfs_ext.tgz" - QPKG="$QNAP_EXTRACTION_ROOT_DST/qpkg.tar" - fi - - SYSROOT="$QNAP_EXTRACTION_ROOT_DST/sysroot" - mkdir "$SYSROOT" - - if [ -e "$UIMAGE" ]; then - print_ln - print_output "[*] Scanning $ORANGE$UIMAGE$NC for (gzipped) parts..." - - a=$(od -t x1 -w4 -Ad -v "$UIMAGE" | grep '1f 8b 08 00' | awk '{print $1}') - if [ -n "$a" ]; then - dd if="$UIMAGE" bs="$a" skip=1 of="$IMAGE.gz" status=none - gunzip --quiet "$IMAGE.gz" || [ $? -eq 2 ] - print_output "[+] Extracted and uncompressed $ORANGE$IMAGE$NC at offset $ORANGE$a$NC" - - i=0 - for a in $(od -t x1 -w4 -Ad -v "$IMAGE" | grep '1f 8b 08 00' | awk '{print $1}'); do - i=$((i+1)) - dd if="$IMAGE" bs="$a" skip=1 of="$IMAGE.part$i.gz" status=none - gunzip --quiet "$IMAGE.part$i.gz" || [ $? -eq 2 ] - print_output "[+] Extracted and uncompressed '$IMAGE.part$i' at offset $a" - done - - if [ $i -gt 0 ]; then - mv "$IMAGE.part$i" "$INITRAMFS" || true - print_output "[*] Renamed $ORANGE$IMAGE.part$i$NC to $ORANGE$INITRAMFS$NC" - rm "$IMAGE" || true - fi - fi - print_files_dirs - print_bar "" - fi - - if [ -e "$UBI" ]; then - print_ln - print_output "[*] Unpacking $ORANGE$UBI$NC." - # TODO: we should evaluate moving to the EMBA UBI extractor in the future - - # see http://trac.gateworks.com/wiki/linux/ubi - # - # apt-get install mtd-utils - - # 256MB flash - modprobe -r nandsim || true - if [ -e /dev/mtdblock0 ]; then - print_output "[-] /dev/mtdblock0 does already exist! Exiting to not overwrite it."; exit - fi - modprobe nandsim first_id_byte=0x2c second_id_byte=0xda third_id_byte=0x90 fourth_id_byte=0x95 - - print_output "[*] Copy UBI image into simulated flash device" - # populate NAND with an existing ubi: - modprobe mtdblock - dd if="$UBI" of=/dev/mtdblock0 bs=2048 status=none - - print_output "[*] Attach simulated flash device" - # attach ubi - modprobe ubi - ubiattach /dev/ubi_ctrl -m0 -O2048 - # ubinfo -a - - print_output "[*] Mounting ubifs file system" - # mount the ubifs to host - modprobe ubifs - local TMP_EXT_MOUNT="$TMP_DIR""/ext_mount_$RANDOM" - mkdir -p "$TMP_EXT_MOUNT" || true - mount -t ubifs ubi0 "$TMP_EXT_MOUNT" - if mount | grep -q ext_mount; then - print_output "[*] Copying contents from UBI mount" - cp -a "$TMP_EXT_MOUNT"/boot/* "$QNAP_EXTRACTION_ROOT_DST" || true - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$QNAP_EXTRACTION_ROOT_DST$NC):" - find "$QNAP_EXTRACTION_ROOT_DST" -xdev -ls | tee -a "$LOG_FILE" - - print_output "[*] UBI cleanup" - umount "$TMP_EXT_MOUNT" - else - print_output "[-] Something went wrong!" - fi - rm -r "$TMP_EXT_MOUNT" || true - ubidetach /dev/ubi_ctrl -m0 - modprobe -r nandsim - print_files_dirs - print_bar "" - fi - - if [ -e "$INITRAMFS" ]; then - print_ln - print_output "[*] Extracting $ORANGE$INITRAMFS$NC." - (cd "$SYSROOT" && (cpio -i --make-directories||true) ) < "$INITRAMFS" - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - fi - - if [ -e "$INITRD" ]; then - print_ln - if file "$INITRD" | grep -q LZMA ; then - print_output "[*] Extracting $ORANGE$INITRD$NC (LZMA)." - lzma -d <"$INITRD" | (cd "$SYSROOT" && (cpio -i --make-directories||true) ) - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - fi - - if file "$INITRD" | grep -q gzip ; then - print_ln - print_output "[*] Extracting $ORANGE$INITRD$NC (gzip)." - gzip -d <"$INITRD" >"$QNAP_EXTRACTION_ROOT_DST/initrd.$$" - print_output "[*] Mounting $ORANGE$INITRD$NC." - local TMP_EXT_MOUNT="$TMP_DIR""/ext_mount_$RANDOM" - mkdir -p "$TMP_EXT_MOUNT" || true - mount -t ext2 "$QNAP_EXTRACTION_ROOT_DST/initrd.$$" "$TMP_EXT_MOUNT" -oro,loop - if mount | grep -q ext_mount; then - cp -a "$TMP_EXT_MOUNT"/* "$SYSROOT" || true - umount "$TMP_EXT_MOUNT" - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - rm "$QNAP_EXTRACTION_ROOT_DST/initrd.$$" || true - else - print_output "[-] Something went wrong!" - fi - rm -r "$TMP_EXT_MOUNT" || true - print_files_dirs - print_bar "" - fi - fi - - if [ -e "$ROOTFS2" ]; then - print_ln - print_output "[*] Extracting $ORANGE$ROOTFS2$NC (gzip, tar)." - tar -xvzf "$ROOTFS2" -C "$SYSROOT" - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - fi - - if [ -e "$ROOTFS2_BZ" ]; then - print_ln - if file "$ROOTFS2_BZ" | grep -q "LZMA"; then - print_output "[*] Extracting $ORANGE$ROOTFS2_BZ$NC (LZMA)." - lzma -d <"$ROOTFS2_BZ" | (cd "$SYSROOT" && (cpio -i --make-directories||true) ) - else - print_output "[*] Extracting $ORANGE$ROOTFS2_BZ$NC (bzip2, tar)." - tar -xvjf "$ROOTFS2_BZ" -C "$SYSROOT" - fi - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - fi - - if [ -f "$ROOTFS2_IMG" ]; then - print_ln - print_output "[*] Extracting $ORANGE$ROOTFS2_IMG$NC (ext2)..." - local TMP_EXT_MOUNT="$TMP_DIR""/ext_mount_$RANDOM" - mkdir -p "$TMP_EXT_MOUNT" || true - mount -t ext2 "$ROOTFS2_IMG" "$TMP_EXT_MOUNT" -oro,loop - if mount | grep -q ext_mount; then - tar -xvjf "$TMP_EXT_MOUNT"/rootfs2.bz -C "$SYSROOT" - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - umount "$TMP_EXT_MOUNT" - else - print_output "[-] Something went wrong!" - fi - rm -r "$TMP_EXT_MOUNT" || true - print_files_dirs - print_bar "" - fi - - if [ -e "$ROOTFS_EXT" ]; then - print_ln - print_output "[*] Extracting EXT filesystem $ORANGE$ROOTFS_EXT$NC." - tar xzvf "$ROOTFS_EXT" -C "$QNAP_EXTRACTION_ROOT_DST" - print_output "[*] Mounting EXT filesystem $ORANGE$ROOTFS_EXT$NC." - local TMP_EXT_MOUNT="$TMP_DIR""/ext_mount_$RANDOM" - mkdir -p "$TMP_EXT_MOUNT" || true - mount "$QNAP_EXTRACTION_ROOT_DST"/rootfs_ext.img "$TMP_EXT_MOUNT" -oro,loop - if mount | grep -q ext_mount; then - cp -a "$TMP_EXT_MOUNT"/* "$SYSROOT" || true - umount "$TMP_EXT_MOUNT" - fi - print_output "[*] Removing EXT filesystem ${ORANGE}rootfs_ext.img$NC." - rm "$QNAP_EXTRACTION_ROOT_DST"/rootfs_ext.img || true - rm -r "$TMP_EXT_MOUNT" || true - print_ln - print_output "[*] Extracted firmware structure ($ORANGE$SYSROOT$NC):" - find "$SYSROOT" -xdev -ls | tee -a "$LOG_FILE" - print_files_dirs - print_bar "" - fi - - USR_LOCAL=$(find "$SYSROOT/opt/source" -name "*.tgz" 2>/dev/null) - # if [[ "${#USR_LOCAL[@]}" -gt 0 ]]; then - if [[ -v USR_LOCAL[@] ]]; then - print_ln - for f in "${USR_LOCAL[@]}"; do - print_output "[*] Extracting $ORANGE$f$NC -> ${ORANGE}sysroot/usr/local$NC ..." - mkdir -p "$SYSROOT/usr/local" || true - tar xvzf "$f" -C "$SYSROOT/usr/local" - done - print_files_dirs - print_bar "" - fi - - if [ -e "$QPKG" ]; then - print_ln - print_output "[*] Extracting $ORANGE$QPKG$NC." - mkdir -p "$QNAP_EXTRACTION_ROOT_DST/qpkg" || true - tar xvf "$QPKG" -C "$QNAP_EXTRACTION_ROOT_DST/qpkg" - for f in "$QNAP_EXTRACTION_ROOT_DST"/qpkg/*.tgz; do - if file "$f" | grep -q gzip; then - print_output "[*] Extracting QPKG $ORANGE$f$NC." - tar tvzf "$f" > "$f".txt - fi - done - print_files_dirs - print_bar "" - fi - - for name in apache_php5 mysql5 mariadb5; do - if [ -e "$QNAP_EXTRACTION_ROOT_DST/qpkg/$name.tgz" ]; then - print_output "[*] Extracting ${ORANGE}qpkg/$name.tgz$NC -> ${ORANGE}sysroot/usr/local$NC ..." - tar xvzf "$QNAP_EXTRACTION_ROOT_DST/qpkg/$name.tgz" -C "$SYSROOT/usr/local" - fi - done - - if [ -e "$QNAP_EXTRACTION_ROOT_DST"/qpkg/libboost.tgz ]; then - print_ln - print_output "[*] Extracting ${ORANGE}qpkg/libboost.tgz$NC -> ${ORANGE}sysroot/usr/lib$NC." - mkdir -p "$SYSROOT/usr/lib" || true - tar xvzf "$QNAP_EXTRACTION_ROOT_DST"/qpkg/libboost.tgz -C "$SYSROOT/usr/lib" - elif [ -e "$QNAP_EXTRACTION_ROOT_DST"/qpkg/DSv3.tgz ]; then - print_output "[*] Extracting ${ORANGE}libboost$NC from ${ORANGE}qpkg/DSv3.tgz$NC -> ${ORANGE}sysroot/usr/lib$NC." - tar tzf "$QNAP_EXTRACTION_ROOT_DST"/qpkg/DSv3.tgz |grep libboost | tar xzf "$QNAP_EXTRACTION_ROOT_DST"/qpkg/DSv3.tgz -C "$SYSROOT" -T - - fi - - if [[ -d "$SYSROOT"/usr/lib ]]; then - HOME_DIR="$(pwd)" - (cd "$SYSROOT/usr/lib" || exit; for f in libboost*.so.1.42.0; do ln -s "$f" "${f%.1.42.0}"; done) - cd "$HOME_DIR" || exit - fi - print_files_dirs - print_bar "" -} - -print_files_dirs() { - FILES_QNAP=$(find "$QNAP_EXTRACTION_ROOT" -type f | wc -l) - DIRS_QNAP=$(find "$QNAP_EXTRACTION_ROOT" -type d | wc -l) - print_ln - print_output "[*] Extracted $ORANGE$FILES_QNAP$NC files and $ORANGE$DIRS_QNAP$NC directories from the QNAP firmware image.\n" - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "QNAP extractor" "$DECRYPTED_FW_" "$QNAP_EXTRACTION_ROOT" "$FILES_QNAP" "$DIRS_QNAP" "NA" -} diff --git a/modules/P21_buffalo_decryptor.sh b/modules/P21_buffalo_decryptor.sh index ccb3f7b82..96dad9115 100755 --- a/modules/P21_buffalo_decryptor.sh +++ b/modules/P21_buffalo_decryptor.sh @@ -54,12 +54,28 @@ buffalo_enc_extractor() { BUFFALO_ENC_PATH_STRIPPED="$LOG_DIR/firmware/$(basename "$BUFFALO_ENC_PATH_").stripped" print_output "[*] Removing initial 208 bytes from header to prepare firmware for decryption" - dd bs=208 skip=1 if="$BUFFALO_ENC_PATH_" of="$BUFFALO_ENC_PATH_STRIPPED" - hexdump -C "$BUFFALO_ENC_PATH_STRIPPED" | head | tee -a "$LOG_FILE" || true - print_ln + # on other tests we had 208 -> check again with firmware that failed here: + dd bs=208 skip=1 if="$BUFFALO_ENC_PATH_" of="$BUFFALO_ENC_PATH_STRIPPED""_208" || true + + if [[ -f "$BUFFALO_ENC_PATH_STRIPPED""_208" ]]; then + hexdump -C "$BUFFALO_ENC_PATH_STRIPPED""_208" | head | tee -a "$LOG_FILE" || true + print_ln + fi + + print_output "[*] Removing initial 228 bytes from header to prepare firmware for decryption" + dd bs=228 skip=1 if="$BUFFALO_ENC_PATH_" of="$BUFFALO_ENC_PATH_STRIPPED""_228" || true - print_output "[*] Decrypting firmware ..." - "$EXT_DIR"/buffalo-enc.elf -d -i "$BUFFALO_ENC_PATH_STRIPPED" -o "$EXTRACTION_FILE_" + if [[ -f "$BUFFALO_ENC_PATH_STRIPPED""_228" ]]; then + hexdump -C "$BUFFALO_ENC_PATH_STRIPPED""_228" | head | tee -a "$LOG_FILE" || true + print_ln + fi + + print_output "[*] Decrypting firmware ... offset 208" + "$EXT_DIR"/buffalo-enc.elf -d -i "$BUFFALO_ENC_PATH_STRIPPED""_208" -o "$EXTRACTION_FILE_" || true + if ! [[ -f "$EXTRACTION_FILE_" ]]; then + print_output "[*] Decrypting firmware ... offset 228" + "$EXT_DIR"/buffalo-enc.elf -d -i "$BUFFALO_ENC_PATH_STRIPPED""_228" -o "$EXTRACTION_FILE_" || true + fi hexdump -C "$EXTRACTION_FILE_" | head | tee -a "$LOG_FILE" || true print_ln diff --git a/modules/P22_Zyxel_zip_decrypt.sh b/modules/P22_Zyxel_zip_decrypt.sh index 92992dfe8..28019df6c 100755 --- a/modules/P22_Zyxel_zip_decrypt.sh +++ b/modules/P22_Zyxel_zip_decrypt.sh @@ -58,7 +58,7 @@ zyxel_zip_extractor() { return fi - binwalk_deep_extract_helper 1 "$RI_FILE_" "$EXTRACTION_DIR_" + unblobber "$RI_FILE_" "$EXTRACTION_DIR_" print_ln if command -v jchroot > /dev/null; then @@ -109,6 +109,7 @@ zyxel_zip_extractor() { cp "$RI_FILE_BIN_PATH" "$ZLD_DIR" || ( print_output "[-] Something went wrong" && return) ZLD_BIN=$(basename "$ZLD_BIN") + chmod +x "$ZLD_DIR"/"$ZLD_BIN" timeout --preserve-status --signal SIGINT 2s "$CHROOT" "${OPTS[@]}" "$ZLD_DIR" -- ./"$EMULATOR" -strace ./"$ZLD_BIN" "$RI_FILE_BIN" AABBCCDD >> "$LOG_PATH_MODULE"/zld_strace.log 2>&1 || true rm "$ZLD_DIR"/"$EMULATOR" || true @@ -142,7 +143,7 @@ zyxel_zip_extractor() { COMPRESS_IMG=$(find "$EXTRACTION_DIR_"/firmware_zyxel_extracted -type f -name compress.img | sort -u) if [[ $(file "$COMPRESS_IMG") == *"Squashfs"* ]]; then print_output "[+] Found valid ${ORANGE}compress.img$GREEN and extract it now" - binwalk_deep_extract_helper 1 "$COMPRESS_IMG" "$EXTRACTION_DIR_/firmware_zyxel_extracted/compress_img_extracted" + unblobber "$COMPRESS_IMG" "$EXTRACTION_DIR_/firmware_zyxel_extracted/compress_img_extracted" FILES_ZYXEL=$(find "$EXTRACTION_DIR_"/firmware_zyxel_extracted/compress_img_extracted -type f | wc -l) DIRS_ZYXEL=$(find "$EXTRACTION_DIR_"/firmware_zyxel_extracted/compress_img_extracted -type d | wc -l) print_output "[*] Zyxel 2nd stage - Extracted $ORANGE$FILES_ZYXEL$NC files and $ORANGE$DIRS_ZYXEL$NC directories from the firmware image." diff --git a/modules/P23_qemu_qcow_mounter.sh b/modules/P23_qemu_qcow_mounter.sh index e4304e419..86c35ba9f 100755 --- a/modules/P23_qemu_qcow_mounter.sh +++ b/modules/P23_qemu_qcow_mounter.sh @@ -104,13 +104,13 @@ qcow_extractor() { FILES_QCOW_MOUNT=$(find "$EXTRACTION_DIR_FINAL" -type f | wc -l) DIRS_QCOW_MOUNT=$(find "$EXTRACTION_DIR_FINAL" -type d | wc -l) - fi - print_output "[*] Extracted $ORANGE$FILES_QCOW_MOUNT$NC files and $ORANGE$DIRS_QCOW_MOUNT$NC directories from the firmware image." - write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" - write_csv_log "Qemu QCOW filesystem extractor" "$QCOW_PATH_" "$EXTRACTION_DIR_FINAL" "$FILES_QCOW_MOUNT" "$DIRS_QCOW_MOUNT" "NA" + print_output "[*] Extracted $ORANGE$FILES_QCOW_MOUNT$NC files and $ORANGE$DIRS_QCOW_MOUNT$NC directories from the firmware image." + write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details" + write_csv_log "Qemu QCOW filesystem extractor" "$QCOW_PATH_" "$EXTRACTION_DIR_FINAL" "$FILES_QCOW_MOUNT" "$DIRS_QCOW_MOUNT" "NA" - print_output "[*] Unmounting $ORANGE$TMP_QCOW_MOUNT$NC directory" - umount "$TMP_QCOW_MOUNT" + print_output "[*] Unmounting $ORANGE$TMP_QCOW_MOUNT$NC directory" + umount "$TMP_QCOW_MOUNT" + fi done qemu-nbd --disconnect /dev/nbd0 rm -r "$TMP_QCOW_MOUNT" diff --git a/modules/P70_unblob.sh b/modules/P55_unblob_extractor.sh similarity index 77% rename from modules/P70_unblob.sh rename to modules/P55_unblob_extractor.sh index 33c873122..eb4395b8b 100755 --- a/modules/P70_unblob.sh +++ b/modules/P55_unblob_extractor.sh @@ -20,14 +20,26 @@ # This module extracts the firmware and is blocking modules that needs executed before the following modules can run export PRE_THREAD_ENA=0 -P70_unblob() { +P55_unblob_extractor() { module_log_init "${FUNCNAME[0]}" + # shellcheck disable=SC2153 + if [[ -d "${FIRMWARE_PATH}" ]] && [[ "$RTOS" -eq 1 ]]; then + detect_root_dir_helper "$FIRMWARE_PATH" + fi + + # If we have not found a linux filesystem we try to do an unblob extraction round + if [[ $RTOS -eq 0 ]] ; then + module_end_log "${FUNCNAME[0]}" 0 + return + fi + if [[ -f "$TMP_DIR""/unblob_disable.cfg" ]]; then # if we disable unblob from a background module we need to work with a file to # store the state of this variable (bash rules ;)) UNBLOB="$(cat "$TMP_DIR"/unblob_disable.cfg)" fi + if [[ "$UNBLOB" -eq 0 ]]; then if [[ -f "$TMP_DIR""/unblob_disable.cfg" ]]; then print_output "[-] Unblob module automatically disabled from other module." @@ -38,10 +50,10 @@ P70_unblob() { return fi - local FW_PATH_UNBLOB="$FIRMWARE_PATH_BAK" + local FW_PATH_UNBLOB="$FIRMWARE_PATH" - if ! [[ -f "$FW_PATH_UNBLOB" ]]; then - print_output "[-] Unblob module currently only deals with firmware files - not with directories" + if [[ -d "$FW_PATH_UNBLOB" ]]; then + print_output "[-] Unblob module only deals with firmware files - directories are handled via deep extractor" module_end_log "${FUNCNAME[0]}" 0 return fi @@ -51,14 +63,6 @@ P70_unblob() { return fi - # we need to check if sasquatch is the correct one for unblob: - if ! [[ "$(readlink -q -f "$UNBLOB_PATH"/sasquatch)" == "/usr/local/bin/sasquatch_unblob" ]]; then - if [[ -L "$UNBLOB_PATH"/sasquatch ]]; then - rm "$UNBLOB_PATH"/sasquatch - fi - ln -s /usr/local/bin/sasquatch_unblob "$UNBLOB_PATH"/sasquatch || true - fi - local FILES_EXT_UB=0 local UNIQUE_FILES_UB=0 local DIRS_EXT_UB=0 @@ -68,7 +72,7 @@ P70_unblob() { pre_module_reporter "${FUNCNAME[0]}" export LINUX_PATH_COUNTER_UNBLOB=0 - local OUTPUT_DIR_UNBLOB="$LOG_PATH_MODULE"/unblob_extracted + export OUTPUT_DIR_UNBLOB="$LOG_DIR"/firmware/unblob_extracted if [[ -f "$FW_PATH_UNBLOB" ]]; then unblobber "$FW_PATH_UNBLOB" "$OUTPUT_DIR_UNBLOB" @@ -92,26 +96,11 @@ P70_unblob() { print_output "[*] Found $ORANGE$BINS_UB$NC binaries." print_output "[*] Additionally the Linux path counter is $ORANGE$LINUX_PATH_COUNTER_UNBLOB$NC." print_ln - print_output "[*] ${ORANGE}EMBA/binwalk$NC results:$NC" - if [[ -f "$LOG_DIR/p59_binwalk_extractor.txt" ]]; then - write_link "p59" - fi - print_output "[*] Found $ORANGE$FILES_EXT$NC files ($ORANGE$UNIQUE_FILES$NC unique files) and $ORANGE$DIRS_EXT$NC directories at all." - print_output "[*] Found $ORANGE$BINS$NC binaries." - print_output "[*] Additionally the Linux path counter is $ORANGE$LINUX_PATH_COUNTER$NC." - print_bar - if [[ "$LINUX_PATH_COUNTER" -lt "$LINUX_PATH_COUNTER_UNBLOB" ]]; then - print_output "[+] Unblob extraction is better than binwalk - using Unblob results as additional source for further analysis" - mv "$OUTPUT_DIR_UNBLOB" "$LOG_DIR"/firmware/ || true - detect_root_dir_helper "$LOG_DIR/firmware" - print_ln - tree -sh "$LOG_DIR/firmware/unblob_extracted" | tee -a "$LOG_FILE" - else - print_output "[*] INFO: The Unblob results are not further used as the EMBA/binwalk extraction process looks good." - tree -sh "$OUTPUT_DIR_UNBLOB" | tee -a "$LOG_FILE" - fi + tree -sh "$OUTPUT_DIR_UNBLOB" | tee -a "$LOG_FILE" print_ln + detect_root_dir_helper "$OUTPUT_DIR_UNBLOB" + write_csv_log "FILES Unblob" "UNIQUE FILES Unblob" "directories Unblob" "Binaries Unblob" "LINUX_PATH_COUNTER Unblob" write_csv_log "$FILES_EXT_UB" "$UNIQUE_FILES_UB" "$DIRS_EXT_UB" "$BINS_UB" "$LINUX_PATH_COUNTER_UNBLOB" fi @@ -130,6 +119,14 @@ unblobber() { print_output "[*] Extracting firmware to directory $ORANGE$OUTPUT_DIR_UNBLOB$NC" + # we need to check if sasquatch is the correct one for unblob: + if ! [[ "$(readlink -q -f "$UNBLOB_PATH"/sasquatch)" == "/usr/local/bin/sasquatch_unblob" ]]; then + if [[ -L "$UNBLOB_PATH"/sasquatch ]]; then + rm "$UNBLOB_PATH"/sasquatch + fi + ln -s /usr/local/bin/sasquatch_unblob "$UNBLOB_PATH"/sasquatch || true + fi + if ! [[ -d "$OUTPUT_DIR_UNBLOB" ]]; then mkdir -p "$OUTPUT_DIR_UNBLOB" fi diff --git a/modules/P59_binwalk_extractor.sh b/modules/P59_binwalk_extractor.sh index e43313377..e5bd8e821 100755 --- a/modules/P59_binwalk_extractor.sh +++ b/modules/P59_binwalk_extractor.sh @@ -25,6 +25,22 @@ P59_binwalk_extractor() { export LINUX_PATH_COUNTER=0 + if [[ -d "${FIRMWARE_PATH}" ]] && [[ "$RTOS" -eq 1 ]]; then + detect_root_dir_helper "$FIRMWARE_PATH" + fi + + # we already found a linux root directory + if [[ $RTOS -eq 0 ]] ; then + module_end_log "${FUNCNAME[0]}" 0 + return + fi + + if [[ -d "$FIRMWARE_PATH" ]]; then + print_output "[-] Binwalk module only deals with firmware files - directories are handled via deep extractor" + module_end_log "${FUNCNAME[0]}" 0 + return + fi + # we need to check if sasquatch is the correct one for binwalk: if ! [[ "$(readlink -q -f "$UNBLOB_PATH"/sasquatch)" == "/usr/local/bin/sasquatch_binwalk" ]]; then if [[ -L "$UNBLOB_PATH"/sasquatch ]]; then @@ -37,7 +53,6 @@ P59_binwalk_extractor() { # This means we are using binwalk in Matryoshka mode here # if we have a directory with multiple files in it we automatically pass here and run into the deep extractor if [[ -f "$FIRMWARE_PATH" ]]; then - # we love binwalk ... this is our first chance for extracting everything binwalking "$FIRMWARE_PATH" fi @@ -119,21 +134,6 @@ binwalking() { binwalk "$FIRMWARE_PATH_" | tee -a "$LOG_FILE" print_ln "no_log" - # we use the original FIRMWARE_PATH for entropy testing, just if it is a file - if [[ -f $FIRMWARE_PATH_BAK ]] && ! [[ -f "$LOG_DIR"/firmware_entropy.png ]]; then - print_output "[*] Entropy testing with binwalk ... " - # we have to change the working directory for binwalk, because everything except the log directory is read-only in - # Docker container and binwalk fails to save the entropy picture there - if [[ $IN_DOCKER -eq 1 ]] ; then - cd "$LOG_DIR" || return - print_output "$(binwalk -E -F -J "$FIRMWARE_PATH_BAK")" - mv "$(basename "$FIRMWARE_PATH_".png)" "$LOG_DIR"/firmware_entropy.png 2> /dev/null || true - cd /emba || return - else - print_output "$(binwalk -E -F -J "$FIRMWARE_PATH_BAK")" - mv "$(basename "$FIRMWARE_PATH_".png)" "$LOG_DIR"/firmware_entropy.png 2> /dev/null || true - fi - fi OUTPUT_DIR_BINWALK=$(basename "$FIRMWARE_PATH_") OUTPUT_DIR_BINWALK="$FIRMWARE_PATH_CP""/""$OUTPUT_DIR_BINWALK"_binwalk_emba @@ -160,3 +160,38 @@ linux_basic_identification_helper() { LINUX_PATH_COUNTER="$(find "$FIRMWARE_PATH_CHECK" "${EXCL_FIND[@]}" -xdev -type d -iname bin -o -type f -iname busybox -o -type f -name shadow -o -type f -name passwd -o -type d -iname sbin -o -type d -iname etc 2> /dev/null | wc -l)" backup_var "LINUX_PATH_COUNTER" "$LINUX_PATH_COUNTER" } + +binwalk_deep_extract_helper() { + # Matryoshka mode is first parameter: 1 - enable, 0 - disable + local MATRYOSHKA_="${1:-0}" + local FILE_TO_EXTRACT_="${2:-}" + local DEST_FILE_="${3:-}" + + if ! [[ -f "$FILE_TO_EXTRACT_" ]]; then + print_output "[-] No file for extraction provided" + return + fi + + # we need to check if sasquatch is the correct one for binwalk: + if ! [[ "$(readlink -q -f "$UNBLOB_PATH"/sasquatch)" == "/usr/local/bin/sasquatch_binwalk" ]]; then + if [[ -L "$UNBLOB_PATH"/sasquatch ]]; then + rm "$UNBLOB_PATH"/sasquatch + fi + ln -s /usr/local/bin/sasquatch_binwalk "$UNBLOB_PATH"/sasquatch || true + fi + + if [[ "$BINWALK_VER_CHECK" == 1 ]]; then + if [[ "$MATRYOSHKA_" -eq 1 ]]; then + binwalk --run-as=root --preserve-symlinks --dd='.*' -e -M -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true + else + # no more Matryoshka mode ... we are doing it manually and check the files every round via MD5 + binwalk --run-as=root --preserve-symlinks --dd='.*' -e -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true + fi + else + if [[ "$MATRYOSHKA_" -eq 1 ]]; then + binwalk --dd='.*' -e -M -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true + else + binwalk --dd='.*' -e -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true + fi + fi +} diff --git a/modules/P60_firmware_bin_extractor.sh b/modules/P60_deep_extractor.sh similarity index 74% rename from modules/P60_firmware_bin_extractor.sh rename to modules/P60_deep_extractor.sh index 3f600f0ca..7adab573b 100755 --- a/modules/P60_firmware_bin_extractor.sh +++ b/modules/P60_deep_extractor.sh @@ -18,7 +18,7 @@ # This module extracts the firmware and is blocking modules that needs executed before the following modules can run export PRE_THREAD_ENA=0 -P60_firmware_bin_extractor() { +P60_deep_extractor() { module_log_init "${FUNCNAME[0]}" module_title "Binary firmware deep extractor" pre_module_reporter "${FUNCNAME[0]}" @@ -31,14 +31,6 @@ P60_firmware_bin_extractor() { return fi - # we need to check if sasquatch is the correct one for binwalk: - if ! [[ "$(readlink -q -f "$UNBLOB_PATH"/sasquatch)" == "/usr/local/bin/sasquatch_binwalk" ]]; then - if [[ -L "$UNBLOB_PATH"/sasquatch ]]; then - rm "$UNBLOB_PATH"/sasquatch - fi - ln -s /usr/local/bin/sasquatch_binwalk "$UNBLOB_PATH"/sasquatch || true - fi - check_disk_space if ! [[ "$DISK_SPACE" -gt "$MAX_EXT_SPACE" ]]; then deep_extractor @@ -143,7 +135,7 @@ deep_extractor() { print_output "[*] WARNING: This is the last extraction round that is executed." # if we are already that far we do a final matryoshka extraction mode - deeper_extractor_helper "M" + deeper_extractor_helper detect_root_dir_helper "$FIRMWARE_PATH_CP" fi @@ -153,12 +145,6 @@ deep_extractor() { } deeper_extractor_helper() { - - if [[ -v 1 ]] && [[ "$1" == "M" ]]; then - local MATRYOSHKA=1 - else - local MATRYOSHKA=0 - fi local FILE_TMP="" local FILE_MD5="" @@ -168,18 +154,19 @@ deeper_extractor_helper() { FILE_MD5="$(md5sum "$FILE_TMP" | awk '{print $1}')" # let's check the current md5sum against our array of unique md5sums - if we have a match this is already extracted - # already extracted stuff is now ignored + # already extracted stuff is ignored - if [[ ! " ${MD5_DONE_DEEP[*]} " =~ ${FILE_MD5} ]]; then + [[ "${MD5_DONE_DEEP[*]}" == *"${FILE_MD5}"* ]] && continue - print_output "[*] Details of file: $ORANGE$FILE_TMP$NC" - print_output "$(indent "$(file "$FILE_TMP")")" + print_output "[*] Details of file: $ORANGE$FILE_TMP$NC" + print_output "$(indent "$(orange "$(file "$FILE_TMP")")")" + print_output "$(indent "$(orange "$(md5sum "$FILE_TMP")")")" - # do a quick check if EMBA should handle the file or we give it to binwalk: - # fw_bin_detector is a function from p02 - fw_bin_detector "$FILE_TMP" + # do a quick check if EMBA should handle the file or we give it to unblob: + # fw_bin_detector is a function from p02 + fw_bin_detector "$FILE_TMP" - if [[ "$VMDK_DETECTED" -eq 1 ]]; then + if [[ "$VMDK_DETECTED" -eq 1 ]]; then if [[ "$THREADED" -eq 1 ]]; then vmdk_extractor "$FILE_TMP" "${FILE_TMP}_vmdk_extracted" & BIN_PID="$!" @@ -199,26 +186,28 @@ deeper_extractor_helper() { else ubi_extractor "$FILE_TMP" "${FILE_TMP}_ubi_extracted" fi - elif [[ "$DLINK_ENC_DETECTED" -eq 1 ]]; then - if [[ "$THREADED" -eq 1 ]]; then - dlink_SHRS_enc_extractor "$FILE_TMP" "${FILE_TMP}_shrs_extracted" & - BIN_PID="$!" - store_kill_pids "$BIN_PID" - disown "$BIN_PID" 2> /dev/null || true - WAIT_PIDS_P20+=( "$BIN_PID" ) - else - dlink_SHRS_enc_extractor "$FILE_TMP" "${FILE_TMP}_shrs_extracted" - fi - elif [[ "$DLINK_ENC_DETECTED" -eq 2 ]]; then - if [[ "$THREADED" -eq 1 ]]; then - dlink_enc_img_extractor "$FILE_TMP" "${FILE_TMP}_enc_img_extracted" & - BIN_PID="$!" - store_kill_pids "$BIN_PID" - disown "$BIN_PID" 2> /dev/null || true - WAIT_PIDS_P20+=( "$BIN_PID" ) - else - dlink_enc_img_extractor "$FILE_TMP" "${FILE_TMP}_enc_img_extracted" - fi + # now handled via unblob + # elif [[ "$DLINK_ENC_DETECTED" -eq 1 ]]; then + # if [[ "$THREADED" -eq 1 ]]; then + # dlink_SHRS_enc_extractor "$FILE_TMP" "${FILE_TMP}_shrs_extracted" & + # BIN_PID="$!" + # store_kill_pids "$BIN_PID" + # disown "$BIN_PID" 2> /dev/null || true + # WAIT_PIDS_P20+=( "$BIN_PID" ) + # else + # dlink_SHRS_enc_extractor "$FILE_TMP" "${FILE_TMP}_shrs_extracted" + # fi + # now handled via unblob + # elif [[ "$DLINK_ENC_DETECTED" -eq 2 ]]; then + # if [[ "$THREADED" -eq 1 ]]; then + # dlink_enc_img_extractor "$FILE_TMP" "${FILE_TMP}_enc_img_extracted" & + # BIN_PID="$!" + # store_kill_pids "$BIN_PID" + # disown "$BIN_PID" 2> /dev/null || true + # WAIT_PIDS_P20+=( "$BIN_PID" ) + # else + # dlink_enc_img_extractor "$FILE_TMP" "${FILE_TMP}_enc_img_extracted" + # fi elif [[ "$EXT_IMAGE" -eq 1 ]]; then if [[ "$THREADED" -eq 1 ]]; then ext_extractor "$FILE_TMP" "${FILE_TMP}_ext_extracted" & @@ -229,16 +218,17 @@ deeper_extractor_helper() { else ext_extractor "$FILE_TMP" "${FILE_TMP}_ext_extracted" fi - elif [[ "$ENGENIUS_ENC_DETECTED" -ne 0 ]]; then - if [[ "$THREADED" -eq 1 ]]; then - engenius_enc_extractor "$FILE_TMP" "${FILE_TMP}_engenius_extracted" & - BIN_PID="$!" - store_kill_pids "$BIN_PID" - disown "$BIN_PID" 2> /dev/null || true - WAIT_PIDS_P20+=( "$BIN_PID" ) - else - engenius_enc_extractor "$FILE_TMP" "${FILE_TMP}_engenius_extracted" - fi + # now handled via unblob + # elif [[ "$ENGENIUS_ENC_DETECTED" -ne 0 ]]; then + # if [[ "$THREADED" -eq 1 ]]; then + # engenius_enc_extractor "$FILE_TMP" "${FILE_TMP}_engenius_extracted" & + # BIN_PID="$!" + # store_kill_pids "$BIN_PID" + # disown "$BIN_PID" 2> /dev/null || true + # WAIT_PIDS_P20+=( "$BIN_PID" ) + # else + # engenius_enc_extractor "$FILE_TMP" "${FILE_TMP}_engenius_extracted" + # fi elif [[ "$BSD_UFS" -ne 0 ]]; then if [[ "$THREADED" -eq 1 ]]; then ufs_extractor "$FILE_TMP" "${FILE_TMP}_bsd_ufs_extracted" & @@ -301,27 +291,26 @@ deeper_extractor_helper() { fi else - # default case to binwalk + # default case to Unblob if [[ "$THREADED" -eq 1 ]]; then - binwalk_deep_extract_helper "$MATRYOSHKA" "$FILE_TMP" "${FILE_TMP}_binwalk_extracted" & + unblobber "$FILE_TMP" "${FILE_TMP}_unblob_extracted" & BIN_PID="$!" store_kill_pids "$BIN_PID" disown "$BIN_PID" 2> /dev/null || true WAIT_PIDS_P20+=( "$BIN_PID" ) else - binwalk_deep_extract_helper "$MATRYOSHKA" "$FILE_TMP" "${FILE_TMP}_binwalk_extracted" + unblobber "$FILE_TMP" "${FILE_TMP}_unblob_extracted" fi - fi - - MD5_DONE_DEEP+=( "$FILE_MD5" ) - max_pids_protection "$MAX_MOD_THREADS" "${WAIT_PIDS_P20[@]}" fi + MD5_DONE_DEEP+=( "$FILE_MD5" ) + max_pids_protection "$MAX_MOD_THREADS" "${WAIT_PIDS_P20[@]}" + check_disk_space FREE_SPACE=$(df --output=avail "$LOG_DIR" | awk 'NR==2') if [[ "$FREE_SPACE" -lt 100000 ]]; then - # this stops the complete EMBA test + # this should stop the complete EMBA test in the future - currenlty it is work in progress print_output "[!] $(date) - The system is running out of disk space $ORANGE$FREE_SPACE$NC" "main" print_output "[!] $(date) - Ending EMBA firmware analysis processes" "main" cleaner 1 @@ -338,29 +327,4 @@ deeper_extractor_helper() { [[ "$THREADED" -eq 1 ]] && wait_for_pid "${WAIT_PIDS_P20[@]}" } -binwalk_deep_extract_helper() { - # Matryoshka mode is first parameter: 1 - enable, 0 - disable - local MATRYOSHKA_="${1:-0}" - local FILE_TO_EXTRACT_="${2:-}" - local DEST_FILE_="${3:-}" - if ! [[ -f "$FILE_TO_EXTRACT_" ]]; then - print_output "[-] No file for extraction provided" - return - fi - - if [[ "$BINWALK_VER_CHECK" == 1 ]]; then - if [[ "$MATRYOSHKA_" -eq 1 ]]; then - binwalk --run-as=root --preserve-symlinks --dd='.*' -e -M -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true - else - # no more Matryoshka mode ... we are doing it manually and check the files every round via MD5 - binwalk --run-as=root --preserve-symlinks --dd='.*' -e -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true - fi - else - if [[ "$MATRYOSHKA_" -eq 1 ]]; then - binwalk --dd='.*' -e -M -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true - else - binwalk --dd='.*' -e -C "$DEST_FILE_" "$FILE_TO_EXTRACT_" | tee -a "$LOG_FILE" || true - fi - fi -} diff --git a/modules/P99_prepare_analyzer.sh b/modules/P99_prepare_analyzer.sh index 32a70a81c..dc3c2c8cf 100755 --- a/modules/P99_prepare_analyzer.sh +++ b/modules/P99_prepare_analyzer.sh @@ -32,11 +32,14 @@ P99_prepare_analyzer() { module_title "Analysis preparation" pre_module_reporter "${FUNCNAME[0]}" + LINUX_PATH_COUNTER="$(find "$LOG_DIR"/firmware "${EXCL_FIND[@]}" -xdev -type d -iname bin -o -type f -iname busybox -o -type f -name shadow -o -type f -name passwd -o -type d -iname sbin -o -type d -iname etc 2> /dev/null | wc -l)" + # we have a linux: if [[ $LINUX_PATH_COUNTER -gt 0 || ${#ROOT_PATH[@]} -gt 1 ]] ; then export FIRMWARE=1 export FIRMWARE_PATH - FIRMWARE_PATH="$(abs_path "$OUTPUT_DIR")" + # FIRMWARE_PATH="$(abs_path "$OUTPUT_DIR")" + FIRMWARE_PATH="$LOG_DIR"/firmware backup_var "FIRMWARE_PATH" "$FIRMWARE_PATH" fi @@ -44,13 +47,13 @@ P99_prepare_analyzer() { check_firmware print_ln - prepare_file_arr + prepare_file_arr "$FIRMWARE_PATH" print_ln - prepare_binary_arr + prepare_binary_arr "$FIRMWARE_PATH" print_ln if [[ $KERNEL -eq 0 ]] ; then - architecture_check + architecture_check "${FIRMWARE_PATH}" architecture_dep_check fi @@ -69,6 +72,10 @@ P99_prepare_analyzer() { if [[ "${#ROOT_PATH[@]}" -gt 0 ]] && ! [[ -f "$CSV_DIR"/p99_prepare_analyzer.csv ]]; then write_csv_log "FILES" "UNIQUE_FILES" "DIRS" "Binaries" "LINUX_PATH_COUNTER" "Root PATH detected" "architecture" "endianess" for R_PATH in "${ROOT_PATH[@]}"; do + FILES_EXT=$(find "$ROOT_PATH" -xdev -type f | wc -l ) + UNIQUE_FILES=$(find "$ROOT_PATH" "${EXCL_FIND[@]}" -xdev -type f -exec md5sum {} \; 2>/dev/null | sort -u -k1,1 | cut -d\ -f3 | wc -l ) + DIRS_EXT=$(find "$ROOT_PATH" -xdev -type d | wc -l ) + BINS=$(find "$ROOT_PATH" "${EXCL_FIND[@]}" -xdev -type f -exec file {} \; | grep -c "ELF" || true) write_csv_log "$FILES_EXT" "$UNIQUE_FILES" "$DIRS_EXT" "$BINS" "$LINUX_PATH_COUNTER" "$R_PATH" "$ARCH" "$D_END" done fi diff --git a/modules/S23_lua_check.sh b/modules/S23_lua_check.sh index 53c847670..3d68b7340 100755 --- a/modules/S23_lua_check.sh +++ b/modules/S23_lua_check.sh @@ -23,6 +23,7 @@ S23_lua_check() local S23_LUA_VULNS=0 local LUA_SCRIPT="" local S23_LUA_SCRIPTS=() + export ISSUE_FOUND=0 write_csv_log "Script path" "LUA issues detected" "LUA vulnarabilities detected" "common linux file" mapfile -t S23_LUA_SCRIPTS < <(find "$FIRMWARE_PATH" -xdev -type f -iname "*.lua" -exec md5sum {} \; 2>/dev/null | sort -u -k1,1 | cut -d\ -f3 ) @@ -56,7 +57,7 @@ S23_lua_check() write_log "" write_log "[*] Statistics:$S23_LUA_VULNS:${#LUA_CGI_FILES[@]}" - module_end_log "${FUNCNAME[0]}" "$S23_LUA_VULNS" + module_end_log "${FUNCNAME[0]}" "$ISSUE_FOUND" } # this is a very basic checker for LUA issues @@ -84,21 +85,25 @@ s23_luaseccheck() { S23_LUA_VULNS=$((S23_LUA_VULNS+1)) ISSUES_FILE=$((ISSUES_FILE+1)) print_output "[+] Found lua QUERY (GET/POST) entry: ${ORANGE}${ENTRY}${GREEN} in file ${ORANGE}${QUERY_FILE}${GREEN} with file access capabilities." + ISSUE_FOUND=1 fi if grep "$ENTRY" "${QUERY_FILE}" | grep -q "os.execute"; then # command exec - critical S23_LUA_VULNS=$((S23_LUA_VULNS+1)) ISSUES_FILE=$((ISSUES_FILE+1)) print_output "[+] Found lua QUERY (GET/POST) entry: ${ORANGE}${ENTRY}${GREEN} in file ${ORANGE}${QUERY_FILE}${GREEN} with command execution capabilities." + ISSUE_FOUND=1 fi done if [[ "${ISSUES_FILE}" -eq 0 ]] && grep -q "os.execute" "${QUERY_FILE}"; then # command exec - not our parameter but we check it print_output "[*] Found lua file ${ORANGE}${QUERY_FILE}${NC} with possible command execution for review." + ISSUE_FOUND=1 fi if [[ "${ISSUES_FILE}" -eq 0 ]] && grep -E -q "io\.(p)?open" "${QUERY_FILE}"; then # command exec - not our parameter but we check it print_output "[*] Found lua file ${ORANGE}${QUERY_FILE}${NC} with possible file access for review." + ISSUE_FOUND=1 fi if [[ "${ISSUES_FILE}" -gt 0 ]]; then @@ -118,6 +123,7 @@ s23_luacheck() { ISSUES=$(strip_color_codes "$(grep Total "$LUA_LOG" | awk '{print $2}' 2> /dev/null || true)") if [[ "$ISSUES" -gt 0 ]] ; then + ISSUE_FOUND=1 # check if this is common linux file: local COMMON_FILES_FOUND local CFF