Skip to content

Commit

Permalink
Merge pull request e-m-b-a#207 from m-1-k-3/master
Browse files Browse the repository at this point in the history
STACS hash detection and Matrix mode
  • Loading branch information
p4cx committed Jan 7, 2022
2 parents fa2c0ba + 3799315 commit 32aa707
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 9 deletions.
2 changes: 1 addition & 1 deletion config/bin_version_strings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ mongodb;;unknown;"^MongoDB\ shell\ version\ v[0-9](\.[0-9]+)+?$";"sed -r 's/Mong
mongodb;;unknown;"^db\ version\ v[0-9](\.[0-9]+)+?$";"sed -r 's/db\ version\ v([0-9](\.[0-9]+)+?)$/mongodb:mongodb:\1/'";
mpicalc;;unknown;"mpicalc\ [0-9]\.[0-9]+";"sed -r 's/mpicalc\ ([0-9](\.[0-9]+)+?)/mpicalc:\1/'";
mtd-utils;;gplv2;"mtdinfo\ [0-9]\.[0-9]\.[0-9]+$";"sed -r 's/mtdinfo\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
mtd-utils;;gplv2;"\(mtd-utils\)\ [0-9]\.[0-9]\.[0-9]+$";"sed -r 's/mtdinfo\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
mtd-utils;;gplv2;"\(mtd-utils\)\ [0-9]\.[0-9]\.[0-9]+$";"sed -r 's/\(mtd-utils\)\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
mtd-utils;;gplv2;"nanddump\ [0-9](\.[0-9]+)+?$";"sed -r 's/nanddump\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
mtd-utils;;gplv2;"nanddump\ \$Revision:\ [0-9](\.[0-9]+)+?\ \$$";"sed -r 's/nanddump\ \$Revision:\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
mtd-utils;;gplv2;"nandwrite\ [0-9]\.[0-9]\.[0-9]+$";"sed -r 's/nandwrite\ ([0-9](\.[0-9]+)+?)$/mtd-utils:\1/'";
Expand Down
14 changes: 11 additions & 3 deletions emba.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ check_cve_search_job() {
EMBA_PID="$1"
while true; do
if [[ -f "$LOG_DIR"/emba.log ]]; then
if grep -q "Test ended\|Emba failed" "$LOG_DIR"/emba.log 2>/dev/null; then
if grep -q "Test ended\|EMBA failed" "$LOG_DIR"/emba.log 2>/dev/null; then
break
fi
fi
Expand Down Expand Up @@ -202,6 +202,7 @@ main()
INVOCATION_PATH="$(dirname "$0")"

export EMBA_PID="$$"
export MATRIX_MODE=0
export FULL_EMULATION=0
export ARCH_CHECK=1
export RTOS=0 # Testing RTOS based OS
Expand Down Expand Up @@ -267,7 +268,7 @@ main()
export EMBA_COMMAND
EMBA_COMMAND="$(dirname "$0")""/emba.sh ""$*"

while getopts a:A:cdDe:Ef:Fghik:l:m:N:op:QrstxX:Y:WzZ: OPT ; do
while getopts a:A:cdDe:Ef:Fghik:l:m:MN:op:QrstxX:Y:WzZ: OPT ; do
case $OPT in
a)
export ARCH="$OPTARG"
Expand Down Expand Up @@ -324,6 +325,9 @@ main()
m)
SELECT_MODULES=("${SELECT_MODULES[@]}" "$OPTARG")
;;
M)
export MATRIX_MODE=1
;;
N)
export FW_NOTES="$OPTARG"
;;
Expand Down Expand Up @@ -519,6 +523,10 @@ main()
check_cve_search_job "$EMBA_PID" &
fi

if [[ "$MATRIX_MODE" -eq 1 && $IN_DOCKER -eq 0 ]]; then
matrix_mode &
fi

#######################################################################################
# Docker
#######################################################################################
Expand All @@ -536,7 +544,7 @@ main()

OPTIND=1
ARGUMENTS=()
while getopts a:A:cdDe:Ef:Fghik:l:m:N:op:QrstX:Y:WxzZ: OPT ; do
while getopts a:A:cdDe:Ef:Fghik:l:m:MN:op:QrstX:Y:WxzZ: OPT ; do
case $OPT in
D|f|i|l)
;;
Expand Down
3 changes: 3 additions & 0 deletions helpers/helpers_emba_dependency_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ dependency_check()

# yara
check_dep_tool "yara"

# stacs - https://github.com/stacscan/stacs
check_dep_tool "STACS hash detection" "stacs"
fi

if [[ $DEP_ERROR -gt 0 ]] || [[ $DEP_EXIT -gt 0 ]]; then
Expand Down
52 changes: 52 additions & 0 deletions helpers/helpers_emba_print.sh
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ print_help()
echo -e "\\nModify output"
echo -e "$CYAN""-s""$NC"" Prints only relative paths"
echo -e "$CYAN""-z""$NC"" Adds ANSI color codes to log"
echo -e "$CYAN""-M""$NC"" MATRIX mode (Warning: CPU intense)"
echo -e "\\nFirmware details"
echo -e "$CYAN""-X [version]""$NC"" Firmware version (double quote your input)"
echo -e "$CYAN""-Y [vendor]""$NC"" Firmware vendor (double quote your input)"
Expand Down Expand Up @@ -560,3 +561,54 @@ module_end_log() {
strip_color_codes() {
echo "$1" | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g"
}

matrix_mode() {
# based on source: https://bruxy.regnet.cz/web/linux/EN/matrix-sh/
export MATRIX_PIDs=()

echo -e "\033[2J\033[?25l"

R=$(tput lines)
C=$(tput cols);: $((R--))

while true; do
(
j=$((RANDOM%C))
d=$((RANDOM%R))

for i in $(eval echo -e "{1..$R}"); do
# shellcheck disable=SC2006
c=`printf '\\\\0%o' $((RANDOM%57+33))` ### http://bruxy.regnet.cz/web/linux ###
echo -e "\033[$((i-1));${j}H\033[32m$c\033[$i;${j}H\033[37m""$c"
sleep 0.1

if [ "$i" -ge "$d" ]; then
echo -e "\033[$((i-d));${j}H "
fi
done

for i in $(eval echo -e "{$((i-d))..$R}"); do #[mat!rix]
echo -e "\033[$i;${j}f "
sleep 0.1
done)&

MATRIX_PIDs+=( "$!" )

if [[ "${#MATRIX_PIDs[@]}" -gt 200 ]]; then
for PID in "${MATRIX_PIDs[@]}"; do
kill "$PID" 2>/dev/null
done
MATRIX_PIDs=()
fi

if [[ -f "$LOG_DIR"/emba.log ]]; then
if grep -q "Test ended\|EMBA failed" "$LOG_DIR"/emba.log 2>/dev/null; then
break
fi
fi

sleep 0.1

done #(c) 2011 -- [ BruXy ]
reset
}
44 changes: 42 additions & 2 deletions installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -765,9 +765,9 @@ if [[ "$CVE_SEARCH" -ne 1 ]]; then
;;
esac
fi

# binwalk

INSTALL_APP_LIST=()
if [[ "$LIST_DEP" -eq 1 ]] || [[ $IN_DOCKER -eq 1 ]] || [[ $DOCKER_SETUP -eq 0 ]] || [[ $FULL -eq 1 ]]; then
cd "$HOME_PATH" || exit 1
Expand Down Expand Up @@ -1195,6 +1195,46 @@ if [[ "$CVE_SEARCH" -ne 1 ]]; then
;;
esac
fi

# STACS - https://github.com/stacscan/stacs

if [[ "$LIST_DEP" -eq 1 ]] || [[ $IN_DOCKER -eq 1 ]] || [[ $DOCKER_SETUP -eq 0 ]] || [[ $FULL -eq 1 ]]; then

cd "$HOME_PATH" || exit 1

echo -e "\\nTo find password hashes in firmware files we install STACS and the default rules."

print_tool_info "libarchive-dev" 1
print_pip_info "stacs"
print_git_info "stacs-rules" "stacscan/stacs-rules" "STACS is a fast, easy to use tool for searching of password hashes in firmware files."

if [[ "$FORCE" -eq 0 ]] && [[ "$LIST_DEP" -eq 0 ]] ; then
echo -e "\\n""$MAGENTA""$BOLD""Do you want to download STACS and the default rules (if not already on the system)?""$NC"
read -p "(y/N)" -r ANSWER
elif [[ "$LIST_DEP" -eq 1 ]] || [[ $DOCKER_SETUP -eq 1 ]] ; then
ANSWER=("n")
else
echo -e "\\n""$MAGENTA""$BOLD""STACS and the default rules (if not already on the system) will be downloaded!""$NC"
ANSWER=("y")
fi
case ${ANSWER:0:1} in
y|Y )
apt-get install "${INSTALL_APP_LIST[@]}" -y
git clone https://github.com/stacscan/stacs-rules.git external/stacs-rules
cd ./external/stacs-rules || exit 1
find rules -name "*.yar" | sed 's/rules\///' | xargs -I{} sh -c "\
mkdir -p ./tests/fixtures/{}/{positive,negative} ; \
touch ./tests/fixtures/{}/{negative,positive}/.gitignore"
pip3 install stacs 2>/dev/null
cd "$HOME_PATH" || exit 1
if command -v stacs > /dev/null ; then
echo -e "$GREEN""STACS installed successfully""$NC"
else
echo -e "$ORANGE""STACS installation failed - check it manually""$NC"
fi
;;
esac
fi
fi

# cve-search database for host
Expand Down
8 changes: 5 additions & 3 deletions modules/S107_deep_password_search.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/bin/bash

# emba - EMBEDDED LINUX ANALYZER
# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2021 Siemens Energy AG
# Copyright 2020-2021 Siemens AG
#
# emba comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# 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
# EMBA is licensed under GPLv3
#
# Author(s): Michael Messner, Pascal Eckmann

Expand All @@ -27,10 +27,12 @@ S107_deep_password_search()

if [[ $(wc -l "$TMP"/pw_hashes.txt | awk '{print $1}') -gt 0 ]]; then
print_output "[+] Found the following password hash values:"
write_csv_log "PW_PATH" "PW_HASH"
while read -r PW_HASH; do
PW_PATH=$(echo "$PW_HASH" | cut -d: -f1)
PW_HASH=$(echo "$PW_HASH" | cut -d: -f2- | sed -r "s/[[:blank:]]+/\ /g")
print_output "[+] PATH: $ORANGE$(print_path "$PW_PATH")$GREEN\t-\tHash: $ORANGE$PW_HASH$GREEN."
write_csv_log "$PW_PATH" "$PW_HASH"
((PW_COUNTER++))
done < "$TMP"/pw_hashes.txt

Expand Down
62 changes: 62 additions & 0 deletions modules/S108_stacs_password_search.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash

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

# Description: Searches for password patterns within the firmware.
# This module uses the stacs engine - https://github.com/stacscan/stacs
# including the community ruleset - https://github.com/stacscan/stacs-rules

S108_stacs_password_search()
{
module_log_init "${FUNCNAME[0]}"
module_title "Stacs analysis of firmware for password hashes"

local STACS_RULES_DIR="$EXT_DIR"/stacs-rules
local STACS_LOG_FILE="$LOG_DIR"/etc/stacs_pw_hashes.json
local ELEMENTS=0
local ELEMENTS_=0
local PW_PATH
local PW_HASH

if command -v stacs > /dev/null ; then
stacs --rule-pack "$STACS_RULES_DIR"/credential.json "$FIRMWARE_PATH" > "$STACS_LOG_FILE"

if [[ -f "$STACS_LOG_FILE" && $(jq ".runs[0] .results[] | .message[]" "$STACS_LOG_FILE" | wc -l) -gt 0 ]]; then
ELEMENTS_="$(jq ".runs[0] .results[] .message.text" "$STACS_LOG_FILE" | wc -l)"
print_output "[+] Found $ORANGE$ELEMENTS_$GREEN password hash values:"
write_csv_log "Message" "PW_PATH" "PW_HASH" "PW_HASH_real"
ELEMENTS=$((ELEMENTS_-1))

for ELEMENT in $(seq 0 "$ELEMENTS"); do
MESSAGE=$(jq ".runs[0] .results[$ELEMENT] .message.text" "$STACS_LOG_FILE" | grep -v null)
PW_PATH=$(jq ".runs[0] .results[$ELEMENT] .locations[] .physicalLocation[].uri" "$STACS_LOG_FILE" \
| grep -v null | sed 's/^"//' | sed 's/"$//')
PW_HASH=$(jq ".runs[0] .results[$ELEMENT] .locations[] .physicalLocation[].snippet" "$STACS_LOG_FILE" \
| grep -v null | grep "text\|binary" | head -1 | cut -d: -f2- | sed 's/\\n//g' | tr -d '[:blank:]')
PW_HASH_REAL=$(jq ".runs[0] .results[$ELEMENT] .locations[] .physicalLocation[].snippet.text" "$STACS_LOG_FILE" \
| grep -v null | head -2 | tail -1 | sed 's/\\n//g' | tr -d '[:blank:]')

print_output "[+] PATH: $ORANGE/$PW_PATH$GREEN\t-\tHash: $ORANGE$PW_HASH_REAL$GREEN."
write_csv_log "$MESSAGE" "/$PW_PATH" "$PW_HASH" "$PW_HASH_REAL"
done

print_output ""
print_output "[*] Found $ORANGE$ELEMENTS_$NC password hashes."
fi
write_log ""
write_log "[*] Statistics:$ELEMENTS_"
fi

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

0 comments on commit 32aa707

Please sign in to comment.