diff --git a/.github/workflows/default_install.yml b/.github/workflows/default_install.yml index ffd83bcf3..e9535834e 100644 --- a/.github/workflows/default_install.yml +++ b/.github/workflows/default_install.yml @@ -41,7 +41,7 @@ jobs: wget https://ftp.dlink.de/dir/dir-300/archive/driver_software/DIR-300_fw_revb_214b01_ALL_de_20130206.zip - name: EMBA default analysis run: | - sudo ./emba -f ./DIR-300_fw_revb_214b01_ALL_de_20130206.zip -l ./logs_emba -S -p ./scan-profiles/default-scan-emulation.emba -y -j + sudo ./emba -f ./DIR-300_fw_revb_214b01_ALL_de_20130206.zip -l ./logs_emba -S -p ./scan-profiles/default-scan.emba -y -j - name: Check result files exist id: check_files uses: andstor/file-existence-action@v2 diff --git a/config/linux_common_files.txt b/config/linux_common_files.txt index 4c3a0375c..2b93a1b94 100644 --- a/config/linux_common_files.txt +++ b/config/linux_common_files.txt @@ -177046,7 +177046,6 @@ sof-hda-generic.tplg sof-hsw.ldc sof-hsw.ri sof-hsw-rt5640.tplg -Sofia sof-icl-dmic-4ch.tplg sof-icl.ldc sof-icl-nocodec.tplg diff --git a/emba b/emba index b7a094b69..958f2fad9 100755 --- a/emba +++ b/emba @@ -480,6 +480,13 @@ main() { echo "GID: $(id -g "${SUDO_USER:-${USER}}")" >> "${LOG_DIR}"/orig_user.log fi + if [[ "${IN_DOCKER}" -eq 0 ]]; then + print_running_modules & + RUN_MOD_PID="$!" + store_kill_pids "${RUN_MOD_PID}" + disown "${RUN_MOD_PID}" 2> /dev/null || true + fi + # Print additional information about the firmware (-Y, -X, -Z, -N) print_firmware_info "${FW_VENDOR}" "${FW_VERSION}" "${FW_DEVICE}" "${FW_NOTES}" if [[ "${KERNEL}" -ne 1 ]] && [[ "${CONTAINER_EXTRACT}" -ne 1 ]] && [[ "${ONLY_DEP}" -eq 0 ]]; then @@ -749,9 +756,9 @@ main() { print_ln "no_log" if [[ -d "${LOG_DIR}" ]]; then - print_output "[!] Pre-checking phase ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "main" + print_output "[!] Pre-checking phase ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "main" else - print_output "[!] Pre-checking phase ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "no_log" + print_output "[!] Pre-checking phase ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "no_log" fi write_notification "Pre-checking phase finished" @@ -785,9 +792,9 @@ main() { print_ln "no_log" if [[ -d "${LOG_DIR}" ]]; then - print_output "[!] Testing phase ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "main" + print_output "[!] Testing phase ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "main" else - print_output "[!] Testing phase ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "no_log" + print_output "[!] Testing phase ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "no_log" fi write_notification "Testing phase ended" @@ -812,9 +819,9 @@ main() { print_ln "no_log" if [[ -d "${LOG_DIR}" ]]; then - print_output "[!] System emulation phase ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "main" + print_output "[!] System emulation phase ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "main" else - print_output "[!] System emulation ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "no_log" + print_output "[!] System emulation ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "no_log" fi write_notification "System emulation phase ended" fi @@ -846,14 +853,14 @@ main() { fi print_ln "no_log" if [[ -d "${LOG_DIR}" ]]; then - print_output "[!] Test ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "main" + print_output "[!] Test ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "main" write_notification "EMBA finished analysis" rm -r "${TMP_DIR}" 2>/dev/null || true else - print_output "[!] Test ended on ""$(date)"" and took about ""$(date -d@"${SECONDS}" -u +%H:%M:%S)"" \\n" "no_log" + print_output "[!] Test ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "no_log" fi write_grep_log "$(date)" "TIMESTAMP" - write_grep_log "$(date -d@"${SECONDS}" -u +%H:%M:%S)" "DURATION" + write_grep_log "$(date -d@"${SECONDS}" -u +%d:%H:%M:%S)" "DURATION" else print_output "[!] No extracted firmware found" "no_log" print_output "$(indent "Try using binwalk or something else to extract the firmware")" diff --git a/helpers/helpers_emba_helpers.sh b/helpers/helpers_emba_helpers.sh index 743ab879b..2c7664875 100755 --- a/helpers/helpers_emba_helpers.sh +++ b/helpers/helpers_emba_helpers.sh @@ -174,7 +174,7 @@ cleaner() { fi export CLEANED=1 if [[ "$INTERRUPT_CLEAN" -eq 1 ]]; then - print_output "[!] Test ended on ""$(date)"" and took about ""$(date -d@"$SECONDS" -u +%H:%M:%S)"" \\n" "no_log" + print_output "[!] Test ended on ""$(date)"" and took about ""$(show_runtime)"" \\n" "no_log" exit 1 fi } diff --git a/helpers/helpers_emba_html_generator.sh b/helpers/helpers_emba_html_generator.sh index c36cd3734..81aa4ce7e 100755 --- a/helpers/helpers_emba_html_generator.sh +++ b/helpers/helpers_emba_html_generator.sh @@ -92,6 +92,7 @@ add_link_tags() { readarray -t REF_LINKS_L_NUMBER < <(grep -a -n -E '\[REF\].*' "$LINK_FILE" | cut -d':' -f1 ) for REF_LINK_NUMBER in "${REF_LINKS_L_NUMBER[@]}" ; do REF_LINK="$(sed "$REF_LINK_NUMBER""q;d" "$LINK_FILE" | cut -c12- | cut -d'<' -f1 || true)" + URL_REGEX='(www.|https?|ftp|file):\/\/' if [[ -f "$(echo "$REF_LINK" | cut -d"#" -f1)" ]] ; then if [[ ( ("${REF_LINK: -4}" == ".txt") || ("${REF_LINK: -4}" == ".log") ) || ( ("$REF_LINK" == *".txt#"*) || ("$REF_LINK" == *".log#"*) ) ]] ; then REF_ANCHOR="" @@ -150,7 +151,6 @@ add_link_tags() { done LINK_COMMAND_ARR+=( "$LINE_NUMBER_INFO_PREV"'s@^@'"$HTML_LINK"'@' "$LINE_NUMBER_INFO_PREV"'s@$@'"$LINK_END"'@') fi - URL_REGEX='(www.|https?|ftp|file):\/\/' elif [[ "$REF_LINK" =~ $URL_REGEX ]] ; then LINE_NUMBER_INFO_PREV="$(( REF_LINK_NUMBER - 1 ))" while [[ ("$(sed "$LINE_NUMBER_INFO_PREV""q;d" "$LINK_FILE")" == "$P_START$SPAN_END$P_END") || ("$(sed "$LINE_NUMBER_INFO_PREV""q;d" "$LINK_FILE")" == "$BR" ) ]] ; do @@ -269,7 +269,7 @@ add_link_tags() { for SNYK_KEY in "${SNYK_KEY_F[@]}" ; do SNYK_ID_LINE="$(echo "$SNYK_KEY" | cut -d ":" -f 1)" SNYK_ID_STRING="$(echo "$SNYK_KEY" | cut -d ":" -f 2-)" - readarray -t SNYK_KEY_STRING_ARR < <(echo "$SNYK_ID_STRING" | tr " " "\n" | grep "SNYK-" | uniq) + readarray -t SNYK_KEY_STRING_ARR < <(echo "$SNYK_ID_STRING" | tr " " "\n" | grep "SNYK-" | uniq || true) for SNYK_KEY_ELEM in "${SNYK_KEY_STRING_ARR[@]}" ; do HTML_LINK="$(echo "$SNYK_LINK" | sed -e "s@LINKNAME@$SNYK_KEY_ELEM@g" | sed -e "s@LINK@$SNYK_KEY_ELEM@g")""$SNYK_KEY_ELEM""$LINK_END" LINK_COMMAND_ARR+=( "$SNYK_ID_LINE"'s@'"$SNYK_KEY_ELEM"'@'"$HTML_LINK"'@' ) @@ -282,7 +282,7 @@ add_link_tags() { for PSS_KEY in "${PSS_KEY_F[@]}" ; do PSS_ID_LINE="$(echo "$PSS_KEY" | cut -d ":" -f 1)" PSS_ID_STRING="$(echo "$PSS_KEY" | cut -d ":" -f 2-)" - readarray -t PSS_KEY_STRING_ARR < <(echo "$PSS_ID_STRING" | tr " " "\n" | grep -E "[0-9]+/.*\.html" | uniq) + readarray -t PSS_KEY_STRING_ARR < <(echo "$PSS_ID_STRING" | tr " " "\n" | grep -E "[0-9]+/.*\.html" | uniq || true) for PSS_KEY_NAME in "${PSS_KEY_STRING_ARR[@]}" ; do # PSS_KEY_NAME="$(echo "$PSS_KEY_ELEM" | tr "/" "_")" HTML_LINK="$(echo "$PSS_LINK" | sed -e "s@LINKNAME@$PSS_KEY_NAME@g" | sed -e "s@LINK@$PSS_KEY_NAME@g")""$PSS_KEY_NAME""$LINK_END" diff --git a/helpers/helpers_emba_print.sh b/helpers/helpers_emba_print.sh index 4b522d54d..1c505d5d0 100755 --- a/helpers/helpers_emba_print.sh +++ b/helpers/helpers_emba_print.sh @@ -832,3 +832,23 @@ print_notification() { fi done } + +print_running_modules() { + sleep 1h + while true; do + local STARTED_EMBA_PROCESSES=() + local EMBA_STARTED_PROC="" + mapfile -t STARTED_EMBA_PROCESSES < <(grep starting "${LOG_DIR}""/""${MAIN_LOG_FILE}" | awk '{print $9}'|| true) + + for EMBA_STARTED_PROC in "${STARTED_EMBA_PROCESSES[@]}"; do + if ! grep -i -q "${EMBA_STARTED_PROC}"" finished" "${LOG_DIR}""/""${MAIN_LOG_FILE}"; then + print_output "[*] EMBA module ${ORANGE}${EMBA_STARTED_PROC}${NC} currently running" "no_log" + fi + done + sleep 1h + done +} + +show_runtime() { + date -ud "@$SECONDS" +"$(( SECONDS/3600/24 )) days and %H:%M:%S" +} diff --git a/helpers/helpers_emba_system_emulation.sh b/helpers/helpers_emba_system_emulation.sh index f6760cae7..1cf4d2055 100755 --- a/helpers/helpers_emba_system_emulation.sh +++ b/helpers/helpers_emba_system_emulation.sh @@ -19,6 +19,7 @@ restart_emulation() { local IMAGE_NAME_="${2:-}" # restart_scan is used to indicate a restarted scan. For this we do not need to restart the network local RESTART_SCAN="${3:-0}" + local STATE_CHECK="${4:-"PING"}" if ping -c 1 "$IP_ADDRESS_" &> /dev/null; then print_output "[+] System with $ORANGE$IP_ADDRESS_$GREEN responding again - probably it recovered automatically.$NC" @@ -43,7 +44,46 @@ restart_emulation() { ./run.sh & cd "$HOME_PATH" || (print_output "[-] EMBA path not available?") - COUNTER=0 + if [[ "$STATE_CHECK" == "PING" ]]; then + ping_check "${IP_ADDRESS_}" + elif [[ "$STATE_CHECK" == "HPING" ]]; then + hping_check "${IP_ADDRESS_}" + elif [[ "$STATE_CHECK" == "TCP" ]]; then + # local PORT=80 + print_output "[-] Check currently not implemented!" + # tcp_check "${IP_ADDRESS_}" "${PORT}" + fi +} + +ping_check() { + local IP_ADDRESS_="${1:-}" + local COUNTER=0 + + while ! [[ "$(hping3 -n -c 1 "$IP_ADDRESS_" 2> /dev/null | grep -c "^len=")" -gt 0 ]]; do + print_output "[*] Waiting for restarted system ..." + ((COUNTER+=1)) + if [[ "$COUNTER" -gt 50 ]]; then + print_output "[-] System not recovered" + break + fi + sleep 6 + done + + if [[ "$(hping3 -n -c 1 "$IP_ADDRESS_" 2>/dev/null | grep -c "^len=")" -gt 0 ]]; then + print_output "[*] System automatically maintained and should be available again in a few moments ... check ip address $ORANGE$IP_ADDRESS_$NC" + sleep 60 + export SYS_ONLINE=1 + export TCP="ok" + else + export SYS_ONLINE=0 + export TCP="not ok" + fi +} + +hping_check() { + local IP_ADDRESS_="${1:-}" + local COUNTER=0 + while ! ping -c 1 "$IP_ADDRESS_" &> /dev/null; do print_output "[*] Waiting for restarted system ..." ((COUNTER+=1)) diff --git a/installer/ID1_ubuntu_os.sh b/installer/ID1_ubuntu_os.sh index 71ca5dbf5..911287518 100755 --- a/installer/ID1_ubuntu_os.sh +++ b/installer/ID1_ubuntu_os.sh @@ -42,18 +42,6 @@ ID1_ubuntu_os() { echo "Exec=/usr/lib/notification-daemon/notification-daemon" >> /usr/share/dbus-1/services/org.freedesktop.Notifications.service fi - if ! dpkg -l libssl1.1 &>/dev/null; then - # libssl1.1 missing - echo -e "\\n""$BOLD""Installing libssl1.1 for mongodb!""$NC" - # echo "deb http://security.ubuntu.com/ubuntu impish-security main" | tee /etc/apt/sources.list.d/impish-security.list - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1-1ubuntu2.1~18.04.22_amd64.deb -O external/libssl-dev_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1-1ubuntu2.1~18.04.22_amd64.deb -O external/libssl1.1_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - dpkg -i external/libssl1.1_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - dpkg -i external/libssl-dev_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - rm external/libssl1.1_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - rm external/libssl-dev_1.1.1-1ubuntu2.1~18.04.22_amd64.deb - fi - if [[ "$WSL" -eq 1 ]]; then # docker installation on Ubuntu jammy in WSL environment is somehow broken echo -e "\\n""$MAGENTA""$BOLD""Docker installation for Ubuntu:jammy in WSL environment!""$NC" diff --git a/installer/IF20_cve_search.sh b/installer/IF20_cve_search.sh index 2b58fb792..015eaa544 100755 --- a/installer/IF20_cve_search.sh +++ b/installer/IF20_cve_search.sh @@ -114,7 +114,35 @@ IF20_cve_search() { else echo -e "\\n""$MAGENTA""cve-search database not ready.""$NC" fi + + cd "$HOME_PATH" || ( echo "Could not install EMBA component cve-search" && exit 1 ) if [[ "$CVE_INST" -eq 1 ]]; then + if ! dpkg -s libssl1.1 &>/dev/null; then + # libssl1.1 missing + echo -e "\\n""$BOLD""Installing libssl1.1 for mongodb!""$NC" + # echo "deb http://security.ubuntu.com/ubuntu impish-security main" | tee /etc/apt/sources.list.d/impish-security.list + for i in {21..29}; do + echo "Testing download of libssl package version libssl1.1_1.1.1-1ubuntu2.1~18.04.${i}_amd64.deb" + wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1-1ubuntu2.1~18.04."${i}"_amd64.deb -O external/libssl-dev.deb || true + # http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1-1ubuntu2.1~18.04.22_amd64.deb + wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1-1ubuntu2.1~18.04."${i}"_amd64.deb -O external/libssl.deb || true + # http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1-1ubuntu2.1~18.04.22_amd64.deb + if [[ "$(file external/libssl.deb)" == *"Debian binary package (format 2.0), with control.tar.xz, data compression xz"* ]]; then + break + else + [[ -f external/libssl.deb ]] && rm external/libssl.deb + [[ -f external/libssl-dev.deb ]] && rm external/libssl-dev.deb + fi + done + + ! [[ -f external/libssl.deb ]] && ( "Could not install libssl" && exit 1) + ! [[ -f external/libssl-dev.deb ]] && ( "Could not install libssl-dev" && exit 1) + dpkg -i external/libssl.deb + dpkg -i external/libssl-dev.deb + [[ -f external/libssl.deb ]] && rm external/libssl.deb + [[ -f external/libssl-dev.deb ]] && rm external/libssl-dev.deb + fi + wget --no-check-certificate -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongodb.gpg > /dev/null echo "deb [ signed-by=/etc/apt/trusted.gpg.d/mongodb.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list apt-get update -y @@ -135,6 +163,7 @@ IF20_cve_search() { mongod --config /etc/mongod.conf & fi + cd ./external/cve-search/ || ( echo "Could not install EMBA component cve-search" && exit 1 ) echo -e "\\n""$MAGENTA""$BOLD""The cve-search database will be downloaded and updated!""$NC" CVE_INST=1 echo -e "\\n""$MAGENTA""Check if the cve-search database is already installed and populated.""$NC" diff --git a/modules/L10_system_emulation.sh b/modules/L10_system_emulation.sh index 400a4b010..671b2d352 100755 --- a/modules/L10_system_emulation.sh +++ b/modules/L10_system_emulation.sh @@ -138,7 +138,7 @@ L10_system_emulation() { print_ln print_output "[+] Identified the following system emulation results (with running network services):" local SYS_EMUL_POS_ENTRY="" - SYS_EMUL_POS_ENTRY="$(grep "TCP ok" "$LOG_DIR"/emulator_online_results.log | sort -t ';' -k6 -n -r | head -1 || true)" + SYS_EMUL_POS_ENTRY="$(grep "TCP ok" "$LOG_DIR"/emulator_online_results.log | sort -t ';' -k7 -n -r | head -1 || true)" print_output "$(indent "$(orange "$SYS_EMUL_POS_ENTRY")")" IP_ADDRESS_=$(echo "$SYS_EMUL_POS_ENTRY" | grep "TCP ok" | sort -k 7 -t ';' | tail -1 | cut -d\; -f8 | awk '{print $3}') @@ -152,7 +152,12 @@ L10_system_emulation() { 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 + if grep -q "ICMP not ok" "$LOG_DIR"/emulator_online_results.log; then + restart_emulation "$IP_ADDRESS_" "$IMAGE_NAME" 1 "HPING" + else + restart_emulation "$IP_ADDRESS_" "$IMAGE_NAME" 1 "PING" + fi + # we should get TCP="ok" and SYS_ONLINE=1 back if [[ "$SYS_ONLINE" -ne 1 ]]; then print_output "[-] System recovery went wrong. No further analysis possible" @@ -225,7 +230,7 @@ create_emulation_filesystem() { print_output "[*] Create Qemu filesystem for emulation - $ROOT_PATH.\\n" IMAGE_SIZE="$(du -b --max-depth=0 "$ROOT_PATH" | awk '{print $1}')" - IMAGE_SIZE=$((IMAGE_SIZE + 200 * 1024 * 1024)) + IMAGE_SIZE=$((IMAGE_SIZE + 400 * 1024 * 1024)) print_output "[*] Size of filesystem for emulation - $ORANGE$IMAGE_SIZE$NC.\\n" print_output "[*] Name of filesystem for emulation - $ORANGE$IMAGE_NAME$NC.\\n" @@ -258,7 +263,7 @@ create_emulation_filesystem() { if mount | grep -q "$MNT_POINT"; then print_output "[*] Copy extracted root filesystem to new QEMU image" - cp -prf "$ROOT_PATH"/* "$MNT_POINT"/ || true + cp -prf "$ROOT_PATH"/* "$MNT_POINT"/ || (print_output "[-] Warning: Root filesystem not copied!" && return) if [[ -f "$HELP_DIR"/fix_bins_lnk_emulation.sh ]] && [[ $(find "$MNT_POINT" -type l | wc -l) -lt 10 ]]; then print_output "[*] No symlinks found in firmware ... Starting link fixing helper ..." @@ -310,15 +315,22 @@ create_emulation_filesystem() { if [[ -f "$MODULE_SUB_PATH/injection_check.sh" ]]; then # injection checker - future extension - cp "$MODULE_SUB_PATH/injection_check.sh" "${MNT_POINT}"/bin/a || true - cp "$MODULE_SUB_PATH/injection_check.sh" "${MNT_POINT}"/sbin/a || true - chmod a+x "${MNT_POINT}/bin/a" || true - chmod a+x "${MNT_POINT}/sbin/a" || true INJECTION_MARKER="$RANDOM" - sed -i 's/asdfqwertz/'"d34d_${INJECTION_MARKER}"'/' "${MNT_POINT}"/bin/a || true - sed -i 's/asdfqwertz/'"d34d_${INJECTION_MARKER}"'/' "${MNT_POINT}"/sbin/a || true - print_output "[*] Generated injection scripts with marker ${ORANGE}${INJECTION_MARKER}${NC}." - cat "${MNT_POINT}"/bin/a + if [[ -d "${MNT_POINT}"/bin ]]; then + cp "$MODULE_SUB_PATH/injection_check.sh" "${MNT_POINT}"/bin/a || true + chmod a+x "${MNT_POINT}/bin/a" || true + sed -i 's/asdfqwertz/'"d34d_${INJECTION_MARKER}"'/' "${MNT_POINT}"/bin/a || true + fi + if [[ -d "${MNT_POINT}"/sbin ]]; then + cp "$MODULE_SUB_PATH/injection_check.sh" "${MNT_POINT}"/sbin/a || true + chmod a+x "${MNT_POINT}/sbin/a" || true + sed -i 's/asdfqwertz/'"d34d_${INJECTION_MARKER}"'/' "${MNT_POINT}"/sbin/a || true + fi + if [[ -f "${MNT_POINT}/sbin/a" ]] || [[ -f "${MNT_POINT}/bin/a" ]]; then + print_output "[*] Generated injection scripts with marker ${ORANGE}${INJECTION_MARKER}${NC}." + cat "${MNT_POINT}"/bin/a + fi + # setup a marker for traversal tests echo "EMBA_${INJECTION_MARKER}_EMBA" > "${MNT_POINT}"/dir_trav_check echo "$INJECTION_MARKER" > "$LOG_PATH_MODULE"/injection_marker.log @@ -477,7 +489,7 @@ main_emulation() { sed -i -r 's/(.*exit\ [0-9])$/\#\ \1/' "$INIT_OUT" fi - handle_fs_mounts + handle_fs_mounts "${FS_MOUNTS[@]}" print_output "[*] Add network.sh entry to $ORANGE$INIT_OUT$NC" @@ -841,6 +853,7 @@ handle_fs_mounts() { # Next we are trying to find them in the extracted data. If we identify something # with jffs2 in the name we copy it to the original root filesystem # This is very dirty but if it works ... it works ;) + local FS_MOUNTS=("$@") for FS_MOUNT in "${FS_MOUNTS[@]}"; do local MOUNT_PT="" @@ -854,7 +867,7 @@ handle_fs_mounts() { MOUNT_PT=$(echo "$FS_MOUNT" | awk '{print $NF}') MOUNT_FS=$(echo "$FS_MOUNT" | grep " \-t " | sed 's/.*-t //g' | awk '{print $1}') # we test for paths including the MOUNT_FS part like "jffs2" in the path - FS_FIND=$(find "$LOG_DIR"/firmware -path "*/$MOUNT_FS*" | head -1 || true) + FS_FIND=$(find "$LOG_DIR"/firmware -path "*/*$MOUNT_FS*_extract" | head -1 || true) print_output "[*] Identified mount point: $ORANGE$MOUNT_PT$NC" print_output "[*] Identified mounted fs: $ORANGE$MOUNT_FS$NC" @@ -902,13 +915,22 @@ handle_fs_mounts() { print_output "[*] Creating target directory $MNT_POINT$MOUNT_PT" mkdir -p "$MNT_POINT""$MOUNT_PT" fi - print_output "[*] Let's copy the identified area to the root filesystem" + print_output "[*] Let's copy the identified area to the root filesystem - $ORANGE$N_PATH$NC to $ORANGE$MNT_POINT$MOUNT_PT$NC" cp -pr "$N_PATH"* "$MNT_POINT""$MOUNT_PT" - print_output "[*] Target directory: $MNT_POINT$MOUNT_PT" find "$MNT_POINT""$MOUNT_PT" -xdev -ls || true done done + # Todo: move this to somewhere, where we only need to do this once + print_output "[*] Fix script and ELF permissions - again" + readarray -t BINARIES_L10 < <( find "$MNT_POINT" -xdev -type f -exec file {} \; 2>/dev/null | grep "ELF\|executable" | cut -d: -f1) + for BINARY_L10 in "${BINARIES_L10[@]}"; do + [[ -x "${BINARY_L10}" ]] && continue + if [[ -f "$BINARY_L10" ]]; then + chmod +x "$BINARY_L10" + fi + done + # now we need to startup the inferFile/inferService script again cp "$(command -v bash-static)" "$MNT_POINT" || true cp "$(command -v busybox)" "$MNT_POINT" || true @@ -1535,7 +1557,7 @@ setup_network_emulation() { HOSTNETDEV_0="$TAPDEV_0" print_output "[*] Creating TAP device $ORANGE$TAPDEV_0$NC..." write_script_exec "echo -e \"Creating TAP device $TAPDEV_0\n\"" "$ARCHIVE_PATH"/run.sh 0 - write_script_exec "command -v tunctl > /dev/null || (echo \"Missing tunctl ... check your installation\" && exit 1)" "$ARCHIVE_PATH"/run.sh 0 + write_script_exec "command -v tunctl > /dev/null || (echo \"Missing tunctl ... check your installation - install uml-utilities package\" && exit 1)" "$ARCHIVE_PATH"/run.sh 0 write_script_exec "tunctl -t $TAPDEV_0" "$ARCHIVE_PATH"/run.sh 1 if [[ "$VLAN_ID" != "NONE" ]]; then @@ -1594,19 +1616,21 @@ write_network_config_to_filesystem() { [[ "${FILE_PATH_MISSING}" == *"firmadyne"* ]] && continue [[ "${FILE_PATH_MISSING}" == *"/proc/"* ]] && continue [[ "${FILE_PATH_MISSING}" == *"/sys/"* ]] && continue + [[ "${FILE_PATH_MISSING}" == *"/dev/"* ]] && continue print_output "[!] MISSING_FILE: ${FILE_PATH_MISSING}" FILENAME_MISSING=$(basename "${FILE_PATH_MISSING}") + [[ "${FILENAME_MISSING}" == '*' ]] && continue print_output "[*] Found missing area ${ORANGE}${FILENAME_MISSING}${NC} in filesystem ... trying to fix this now" DIR_NAME_MISSING=$(dirname "${FILE_PATH_MISSING}") if ! [[ -d "${MNT_POINT}""${DIR_NAME_MISSING}" ]]; then print_output "[*] Create missing directory ${ORANGE}${DIR_NAME_MISSING}${NC} in filesystem ... trying to fix this now" mkdir -p "${MNT_POINT}""${DIR_NAME_MISSING}" fi - FOUND_MISSING=$(find "${MNT_POINT}" -name "${FILENAME_MISSING}" | head -1) - if [[ -f ${FOUND_MISSING} ]]; then + FOUND_MISSING=$(find "${MNT_POINT}" -name "${FILENAME_MISSING}" | head -1 || true) + if [[ -f ${FOUND_MISSING} ]] && ! [[ -f "${MNT_POINT}""${DIR_NAME_MISSING}"/"${FOUND_MISSING}" ]]; then print_output "[*] Recover missing file ${ORANGE}${FILENAME_MISSING}${NC} in filesystem ... trying to fix this now" - cp "${FOUND_MISSING}" "${MNT_POINT}""${DIR_NAME_MISSING}"/ + cp "${FOUND_MISSING}" "${MNT_POINT}""${DIR_NAME_MISSING}"/ || true fi done fi @@ -2236,6 +2260,9 @@ write_results() { fi [[ "${TCP_SERV_CNT}" -gt 0 ]] && TCP="ok" ARCHIVE_PATH_="$(echo "$ARCHIVE_PATH_" | rev | cut -d '/' -f1 | rev)" + if ! [[ -f "$LOG_DIR"/emulator_online_results.log ]]; then + echo "FIRMWARE_PATH;RESULT_SOURCE;Booted state;ICMP state;TCP-0 state;TCP state;online services;IP address;Network mode (NETWORK_DEVICE/ETH_INT/INIT_FILE);ARCHIVE_PATH_;R_PATH" > "$LOG_DIR"/emulator_online_results.log + fi 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/L10_system_emulation/inferService.sh b/modules/L10_system_emulation/inferService.sh index dd4a49dd2..276494033 100755 --- a/modules/L10_system_emulation/inferService.sh +++ b/modules/L10_system_emulation/inferService.sh @@ -16,6 +16,17 @@ NC="\033[0m" "${BUSYBOX}" echo "[*] Service detection running ..." +# The manual starter can be used to write startup scripts manually and help +# EMBA getting into the right direction +# This script must be placed directly into the filesystem as /etc/manual.starter +if [ -e /etc/manual.starter ]; then + if ! "${BUSYBOX}" grep -q "/etc/manual.starter" /firmadyne/service 2>/dev/null; then + "${BUSYBOX}" echo -e "[*] Writing EMBA service for ${ORANGE}manual starter service${NC}" + "${BUSYBOX}" echo -e -n "/etc/manual.starter\n" >> /firmadyne/service + fi +fi + + if [ -e /etc/init.d/miniupnpd ]; then if ! "${BUSYBOX}" grep -q "/etc/init.d/miniupnpd" /firmadyne/service 2>/dev/null; then "${BUSYBOX}" echo -e "[*] Writing EMBA service for ${ORANGE}miniupnpd service${NC}" diff --git a/modules/L10_system_emulation/injection_check.sh b/modules/L10_system_emulation/injection_check.sh new file mode 100644 index 000000000..89026162b --- /dev/null +++ b/modules/L10_system_emulation/injection_check.sh @@ -0,0 +1,6 @@ +#!/firmadyne/sh + +# Injection checker script for detecting command injection vulnerabilities + +/firmadyne/busybox asdfqwertz & +asdfqwertz & diff --git a/modules/L22_upnp_hnap_checks.sh b/modules/L22_upnp_hnap_checks.sh index 13fcd1f9a..9634bd7ac 100755 --- a/modules/L22_upnp_hnap_checks.sh +++ b/modules/L22_upnp_hnap_checks.sh @@ -115,8 +115,10 @@ check_basic_hnap() { fi if [[ "$SSL" -eq 0 ]]; then + curl -v -L --max-redir 0 -f -m 5 -s -X GET http://"${IP_ADDRESS_}":"${PORT}"/HNAP/ >> "$LOG_PATH_MODULE"/hnap-discovery-check.txt || true curl -v -L --max-redir 0 -f -m 5 -s -X GET http://"${IP_ADDRESS_}":"${PORT}"/HNAP1/ >> "$LOG_PATH_MODULE"/hnap-discovery-check.txt || true else + curl -v -L --max-redir 0 -f -m 5 -s -X GET https://"${IP_ADDRESS_}":"${PORT}"/HNAP/ >> "$LOG_PATH_MODULE"/hnap-discovery-check.txt || true curl -v -L --max-redir 0 -f -m 5 -s -X GET https://"${IP_ADDRESS_}":"${PORT}"/HNAP1/ >> "$LOG_PATH_MODULE"/hnap-discovery-check.txt || true fi diff --git a/modules/S14_weak_func_radare_check.sh b/modules/S14_weak_func_radare_check.sh index aae852cfb..ba3908d89 100755 --- a/modules/S14_weak_func_radare_check.sh +++ b/modules/S14_weak_func_radare_check.sh @@ -29,6 +29,7 @@ S14_weak_func_radare_check() pre_module_reporter "${FUNCNAME[0]}" local STRCPY_CNT=0 + local FCT_CNT=0 if [[ -n "$ARCH" ]] ; then # as this module is slow we only run it in case the objdump method from s13 was not working as expected @@ -139,15 +140,20 @@ S14_weak_func_radare_check() if [[ -f "$TMP_DIR"/S14_STRCPY_CNT.tmp ]]; then STRCPY_CNT=$(awk '{sum += $1 } END { print sum }' "$TMP_DIR"/S14_STRCPY_CNT.tmp) + FCT_CNT="${STRCPY_CNT}" + fi + if [[ "$FCT_CNT" -eq 0 ]] && [[ -f "$TMP_DIR"/S14_FCT_CNT.tmp ]]; then + # FCT_CNT respects also other functions + FCT_CNT=$(awk '{sum += $1 } END { print sum }' "$TMP_DIR"/S14_FCT_CNT.tmp) fi write_log "" - write_log "[*] Statistics:$STRCPY_CNT" + write_log "[*] Statistics:${STRCPY_CNT}" write_log "" write_log "[*] Statistics1:$ARCH" fi - module_end_log "${FUNCNAME[0]}" "$STRCPY_CNT" + module_end_log "${FUNCNAME[0]}" "$FCT_CNT" } radare_function_check_PPC32(){ @@ -480,6 +486,7 @@ radare_print_top10_statistics() { fi done print_ln + echo "${#RESULTS[@]}" >> "$TMP_DIR"/S14_FCT_CNT.tmp fi done else diff --git a/modules/S15_radare_decompile_checks.sh b/modules/S15_radare_decompile_checks.sh index adc37994f..a5e7ff39c 100755 --- a/modules/S15_radare_decompile_checks.sh +++ b/modules/S15_radare_decompile_checks.sh @@ -100,7 +100,7 @@ radare_decompilation(){ # with axt we are looking for function usages and store this in $FUNCTION_usage # pdd is for decompilation - with @@ we are working through all the identified functions # We analyse only 200 functions per binary - r2 -e io.cache=true -e scr.color=false -q -A -c \ + timeout --preserve-status --signal SIGINT 3600 r2 -e io.cache=true -e scr.color=false -q -A -c \ 'axt `is~'"${FUNCTION}"'[2]`~[0] | tail -n +2 | grep -v "nofunc" | sort -u | tail -n 200 > '"${LOG_PATH_MODULE}""/""${FUNCTION}""_""${NAME}""_usage"'; pdd --assembly @@ `cat '"${LOG_PATH_MODULE}""/""${FUNCTION}""_""${NAME}"'_usage`' "$BINARY" 2> /dev/null >> "$FUNC_LOG" || true if [[ -f "$FUNC_LOG" ]] && [[ $(wc -l "$FUNC_LOG" | awk '{print $1}') -gt 3 ]] ; then diff --git a/modules/S21_python_check.sh b/modules/S21_python_check.sh index ef43b398c..f2fbc4192 100755 --- a/modules/S21_python_check.sh +++ b/modules/S21_python_check.sh @@ -50,7 +50,7 @@ S21_python_check() [[ "$THREADED" -eq 1 ]] && wait_for_pid "${WAIT_PIDS_S21[@]}" if [[ -f "$TMP_DIR"/S21_VULNS.tmp ]]; then - S21_PY_VULNS=$(awk '{sum += $1 } END { print sum }'"$TMP_DIR"/S21_VULNS.tmp) + S21_PY_VULNS=$(awk '{sum += $1 } END { print sum }' "$TMP_DIR"/S21_VULNS.tmp) fi if [[ "$S21_PY_VULNS" -gt 0 ]]; then diff --git a/scan-profiles/sbom-default.emba b/scan-profiles/sbom-default.emba new file mode 100644 index 000000000..d21034b00 --- /dev/null +++ b/scan-profiles/sbom-default.emba @@ -0,0 +1,40 @@ +# 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 is a default SBOM profile. You can Use it as a template for your own profiles +# or start emba with "-p sbom-default.emba" to use it + +export FORMAT_LOG=1 +export THREADED=1 +export SHORT_PATH=1 +export HTML=1 +export QEMULATION=1 +export SELECT_MODULES=( "S08" "S09" "S24" "S25" "S115" "S116") + +# we output the profile only at the beginning - outside the docker environment +if [[ $IN_DOCKER -ne 1 ]] ; then + print_output "$(indent "$(orange "Adds ANSI color codes to log")")" "no_log" + print_output "$(indent "$(orange "Activate multi threading (destroys regular console output)")")" "no_log" + print_output "$(indent "$(orange "Prints only relative paths")")" "no_log" + print_output "$(indent "$(orange "Activates web report creation in log path")")" "no_log" + if [[ "$USE_DOCKER" -ne 1 ]]; then + print_output "$(indent "$(orange "Enables automated qemu emulation tests (WARNING this module could harm your host!)")")" "no_log" + else + print_output "$(indent "$(orange "Enables automated qemu emulation tests")")" "no_log" + fi + print_output "$(indent "$(orange "Runs EMBA in docker container")")" "no_log" + print_output "$(indent "$(orange "Enabled EMBA module via profile")")" "no_log" + for MODULE_ in "${SELECT_MODULES[@]}"; do + print_output "$(indent "$(orange "Enabled module: $MODULE_")")" "no_log" + done + export USE_DOCKER=1 +fi