Skip to content

Commit

Permalink
Merge pull request #374 from BenediktMKuehne/aa64-efi-test
Browse files Browse the repository at this point in the history
Better UEFI extractor
  • Loading branch information
m-1-k-3 committed Nov 20, 2022
2 parents b1c05bd + aeba4b1 commit 43f652d
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 18 deletions.
5 changes: 4 additions & 1 deletion helpers/helpers_emba_dependency_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,10 @@ dependency_check()

check_dep_tool "ubireader image extractor" "ubireader_extract_images"
check_dep_tool "ubireader file extractor" "ubireader_extract_files"


# UEFI
check_dep_tool "UEFI image extractor" "$EXT_DIR""/UEFITool/UEFIExtract"

if function_exists F20_vul_aggregator; then
# CVE-search
# TODO change to portcheck and write one for external hosts
Expand Down
2 changes: 1 addition & 1 deletion installer.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ if [[ "$CVE_SEARCH" -ne 1 ]] || [[ "$DOCKER_SETUP" -ne 1 ]] || [[ "$IN_DOCKER" -

IP18_qnap_decryptor

# IP35_uefi_extraction
IP35_uefi_extraction

IP61_unblob

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

# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2022 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): Benedikt Kuehne

# Description: Installs UEFIExtract from https://github.com/LongSoft/UEFITool/releases
# into external/UEFITool/UEFIExtract

IP35_uefi_extraction() {
module_title "${FUNCNAME[0]}"


INSTALL_APP_LIST=()

print_file_info "UEFIExtract_NE_A62_linux_x86_64.zip" "Release-version A62" "https://github.com/LongSoft/UEFITool/releases/download/A62/UEFIExtract_NE_A62_linux_x86_64.zip" "external/UEFITool/UEFIExtract_NE_A62_linux_x86_64.zip"
print_tool_info "unzip" 1

if [[ "$LIST_DEP" -eq 1 ]] || [[ $DOCKER_SETUP -eq 1 ]]; then
ANSWER=("n")
else
echo -e "\\n""$MAGENTA""$BOLD""UEFI Extraction Tool"" will be downloaded (if not already on the system) installed!""$NC"
ANSWER=("y")
fi

case ${ANSWER:0:1} in
y|Y )
apt-get install "${INSTALL_APP_LIST[@]}" -y --no-install-recommends
if ! [[ -d external/UEFITool ]]; then
mkdir external/UEFITool
fi
download_file "UEFIExtract_NE_A62_linux_x86_64.zip" "https://github.com/LongSoft/UEFITool/releases/download/A62/UEFIExtract_NE_A62_linux_x86_64.zip" "external/UEFITool/UEFIExtract_NE_A62_linux_x86_64.zip"
if [[ -f "external/UEFITool/UEFIExtract_NE_A62_linux_x86_64.zip" ]]; then
if ! [[ -f external/UEFITool/UEFIExtract ]]; then
unzip external/UEFITool/UEFIExtract_NE_A62_linux_x86_64.zip -d external/UEFITool
fi
else
echo -e "$ORANGE""UEFITool installation failed - check it manually""$NC"
fi
;;
esac
}
12 changes: 10 additions & 2 deletions installer/helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,20 @@ print_pip_info() {

print_file_info()
{
local CONTENT_LENGTH=""
local FILE_SIZE=0
echo -e "\\n""$ORANGE""$BOLD""${1:-}""$NC"
if [[ -n "${2:-}" ]] ; then
echo -e "Description: ""${2:-}"
fi
# echo "$(wget "${3}" --spider --server-response -O -)"
FILE_SIZE=$(("$(wget "${3:-}" --no-check-certificate --spider --server-response 2>&1 | sed -ne '/.ontent-.ength/{s/.*: //;p}' | sed '$!d' || true)"))
CONTENT_LENGTH=$(wget "${3:-}" --no-check-certificate --spider --server-response --output-file=./.wget.log 2>&1 | sed -ne '/.ontent-.ength/{s/.*: //;p}' | sed '$!d')
if [[ -n "$CONTENT_LENGTH" ]]; then
FILE_SIZE=$(("$CONTENT_LENGTH"))
else
# try grep from .wget.log
FILE_SIZE=$(("$(sed -ne '/.ontent-.ength/{s/.*: //;p}' ./.wget.log | sed '$!d')"))
fi

if (( FILE_SIZE > 1048576 )) ; then
echo -e "Download-Size: ""$(( FILE_SIZE / 1048576 ))"" MB"
Expand Down Expand Up @@ -213,7 +221,7 @@ download_file()
if [[ "$D_FILE" == "${1:-}" ]] ; then
echo -e "\\n""$ORANGE""$BOLD""Downloading ""${1:-}""$NC"
if ! [[ -f "${3:-}" ]] ; then
wget --no-check-certificate "${2:-}" -O "${3:-}"
wget --no-check-certificate --output-file=./.wget.log "${2:-}" -O "${3:-}"
else
echo -e "$GREEN""${1}"" is already downloaded - no further action performed.""$NC"
fi
Expand Down
12 changes: 12 additions & 0 deletions modules/F50_base_aggregator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ F50_base_aggregator() {
CVE_AGGREGATOR_LOG="f20_vul_aggregator.txt"
F20_EXPLOITS_LOG="$LOG_DIR"/f20_vul_aggregator/exploits-overview.txt
P02_LOG="p02_firmware_bin_file_check.csv"
P35_LOG="p35_uefi_extractor.txt"
S03_LOG="s03_firmware_bin_base_analyzer.txt"
S05_LOG="s05_firmware_details.txt"
S06_LOG="s06_distribution_identification.txt"
Expand Down Expand Up @@ -119,6 +120,11 @@ output_overview() {
write_csv_log "architecture_verified" "unknown" "NA"
write_csv_log "architecture_unverified" "$PRE_ARCH" "NA"
fi
if [[ -n "$EFI_ARCH" ]]; then
print_output "[+] Detected architecture:""$ORANGE"" ""$EFI_ARCH""$NC"
write_link "p99"
write_csv_log "architecture_verified" "$EFI_ARCH" "NA"
fi
else
write_csv_log "architecture_verified" "unknown" "NA"
fi
Expand Down Expand Up @@ -684,6 +690,7 @@ get_data() {
export KNOWN_EXPLOITED_COUNTER=0
export ENTROPY=""
export PRE_ARCH=""
export EFI_ARCH=""
export FILE_ARR_COUNT=0
export DETECTED_DIR=0
export LINUX_DISTRIS=()
Expand Down Expand Up @@ -731,6 +738,11 @@ get_data() {
if [[ -f "$LOG_DIR"/"$P02_LOG" ]]; then
ENTROPY=$(grep -a "Entropy" "$LOG_DIR"/"$P02_LOG" | cut -d\; -f2 | cut -d= -f2 | sed 's/^\ //' || true)
fi
if [[ -f "$LOG_DIR"/"$P35_LOG" ]]; then
EFI_ARCH=$(grep -a "Possible architecture details found" "$LOG_DIR"/"$P35_LOG" | cut -d: -f2 | sed 's/\ //g' | tr '\n' '/' || true)
EFI_ARCH="${EFI_ARCH%\/}"
EFI_ARCH=$(strip_color_codes "$EFI_ARCH")
fi
if [[ -f "$LOG_DIR"/"$S02_LOG" ]]; then
FWHUNTER_CNT=$(grep -a "\[\*\]\ Statistics:" "$LOG_DIR"/"$S02_LOG" | cut -d: -f2 || true)
fi
Expand Down
95 changes: 81 additions & 14 deletions modules/P35_UEFI_extractor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ P35_UEFI_extractor() {

EXTRACTION_DIR="$LOG_DIR"/firmware/uefi_extraction/

if [[ "$UEFI_AMI_CAPSULE" -gt 0 ]]; then
ami_extractor "$FIRMWARE_PATH" "$EXTRACTION_DIR"
fi
# if [[ "$UEFI_AMI_CAPSULE" -gt 0 ]]; then
# ami_extractor "$FIRMWARE_PATH" "$EXTRACTION_DIR"
# else
uefi_extractor "$FIRMWARE_PATH" "$EXTRACTION_DIR"
# fi

if [[ "$FILES_UEFI" -gt 0 ]]; then
MD5_DONE_DEEP+=( "$(md5sum "$FIRMWARE_PATH" | awk '{print $1}')" )
Expand All @@ -42,36 +44,101 @@ P35_UEFI_extractor() {
fi
}

ami_extractor() {
sub_module_title "AMI capsule extractor"
# TODO marked for deletion
# ami_extractor() {
# sub_module_title "AMI capsule extractor"
#
# local FIRMWARE_PATH_="${1:-}"
# local EXTRACTION_DIR_="${2:-}"
# local DIRS_UEFI=0
# local FIRMWARE_NAME_=""
#
# if ! [[ -f "$FIRMWARE_PATH_" ]]; then
# print_output "[-] No file for extraction provided"
# return
# fi
#
# FIRMWARE_NAME_="$(basename "$FIRMWARE_PATH_")"
#
# echo -ne '\n' | python3 "$EXT_DIR"/BIOSUtilities/AMI_PFAT_Extract.py -o "$EXTRACTION_DIR_" "$FIRMWARE_PATH_" &> "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log
#
# if [[ -f "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log ]]; then
# tee -a "$LOG_FILE" < "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log
# fi
#
# print_ln
# print_output "[*] Using the following firmware directory ($ORANGE$EXTRACTION_DIR_$NC) as base directory:"
# find "$EXTRACTION_DIR_" -xdev -maxdepth 1 -ls | tee -a "$LOG_FILE"
# print_ln
#
# FILES_UEFI=$(find "$EXTRACTION_DIR_" -type f | wc -l)
# DIRS_UEFI=$(find "$EXTRACTION_DIR_" -type d | wc -l)
# print_output "[*] Extracted $ORANGE$FILES_UEFI$NC files and $ORANGE$DIRS_UEFI$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 "UEFI AMI extractor" "$FIRMWARE_PATH_" "$EXTRACTION_DIR_" "$FILES_UEFI" "$DIRS_UEFI" "NA"
# print_ln
# }

uefi_extractor(){
sub_module_title "UEFI Extractor"

local FIRMWARE_PATH_="${1:-}"
local EXTRACTION_DIR_="${2:-}"
local DIRS_UEFI=0

local FIRMWARE_NAME_=""
local UEFI_EXTRACT_REPORT_FILE=""

local UEFI_EXTRACT_BIN="$EXT_DIR""/UEFITool/UEFIExtract"
local FILES_UEFI=0
local DIRS_UEFI=0
local NVARS=0
local PE32_IMAGE=0
local EFI_ARCH=""

if ! [[ -f "$FIRMWARE_PATH_" ]]; then
print_output "[-] No file for extraction provided"
return
fi

FIRMWARE_NAME_="$(basename "$FIRMWARE_PATH_")"
if ! [[ -d "$EXTRACTION_DIR_" ]]; then
mkdir -p "$EXTRACTION_DIR_"
fi
cp "$FIRMWARE_PATH_" "$EXTRACTION_DIR_"
$UEFI_EXTRACT_BIN "$EXTRACTION_DIR_"firmware all &> "$LOG_PATH_MODULE"/uefi_extractor_"$FIRMWARE_NAME_".log
UEFI_EXTRACT_REPORT_FILE="$EXTRACTION_DIR_"firmware.report.txt
mv "$UEFI_EXTRACT_REPORT_FILE" "$LOG_PATH_MODULE"
UEFI_EXTRACT_REPORT_FILE="$LOG_PATH_MODULE"/firmware.report.txt
if [[ -f "$EXTRACTION_DIR_"/firmware ]]; then
rm "$EXTRACTION_DIR_"/firmware
fi

echo -ne '\n' | python3 "$EXT_DIR"/BIOSUtilities/AMI_PFAT_Extract.py -o "$EXTRACTION_DIR_" "$FIRMWARE_PATH_" &> "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log

if [[ -f "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log ]]; then
tee -a "$LOG_FILE" < "$LOG_PATH_MODULE"/uefi_ami_"$FIRMWARE_NAME_".log
if [[ -f "$LOG_PATH_MODULE"/uefi_extractor_"$FIRMWARE_NAME_".log ]]; then
tee -a "$LOG_FILE" < "$LOG_PATH_MODULE"/uefi_extractor_"$FIRMWARE_NAME_".log
fi

print_ln
print_output "[*] Using the following firmware directory ($ORANGE$EXTRACTION_DIR_$NC) as base directory:"
find "$EXTRACTION_DIR_" -xdev -maxdepth 1 -ls | tee -a "$LOG_FILE"
print_output "[*] Using the following firmware directory ($ORANGE${EXTRACTION_DIR_}firmware.dump$NC) as base directory:"
find "$EXTRACTION_DIR_"firmware.dump -xdev -maxdepth 1 -ls | tee -a "$LOG_FILE"
print_ln

FILES_UEFI=$(find "$EXTRACTION_DIR_" -type f | wc -l)
NVARS=$(grep -c "NVAR entry" "$UEFI_EXTRACT_REPORT_FILE")
PE32_IMAGE=$(grep -c "PE32 image" "$UEFI_EXTRACT_REPORT_FILE")
DRIVER_COUNT=$(grep -c "DXE driver" "$UEFI_EXTRACT_REPORT_FILE")
EFI_ARCH=$(find "$EXTRACTION_DIR_" -name 'info.txt' -exec grep 'Machine type:' {} \; | sed -E 's/Machine\ type\:\ //g' | uniq | head -n 1)

if [[ -n "$EFI_ARCH" ]]; then
print_output "[*] Found $ORANGE$PE32_IMAGE$NC PE32 images for architecture $ORANGE$EFI_ARCH$NC drivers."
print_output "[+] Possible architecture details found ($ORANGE UEFI Extractor $NC): $ORANGE$EFI_ARCH$NC"
export EFI_ARCH
backup_var "EFI_ARCH" "$EFI_ARCH"
fi

FILES_UEFI=$(grep -c "File" "$UEFI_EXTRACT_REPORT_FILE")
DIRS_UEFI=$(find "$EXTRACTION_DIR_" -type d | wc -l)
print_output "[*] Extracted $ORANGE$FILES_UEFI$NC files and $ORANGE$DIRS_UEFI$NC directories from the firmware image."
print_output "[*] Found $ORANGE$NVARS$NC NVARS and $ORANGE$DRIVER_COUNT$NC drivers."
write_csv_log "Extractor module" "Original file" "extracted file/dir" "file counter" "directory counter" "further details"
write_csv_log "UEFI AMI extractor" "$FIRMWARE_PATH_" "$EXTRACTION_DIR_" "$FILES_UEFI" "$DIRS_UEFI" "NA"
write_csv_log "UEFI extractor" "$FIRMWARE_PATH_" "$EXTRACTION_DIR_" "$FILES_UEFI" "$DIRS_UEFI" "NA"
print_ln
}

0 comments on commit 43f652d

Please sign in to comment.