Files
emba/installer.sh
2026-06-25 16:14:12 +02:00

534 lines
19 KiB
Bash
Executable File

#!/bin/bash -p
# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2023 Siemens AG
# Copyright 2020-2026 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
# SPDX-License-Identifier: GPL-3.0-only
#
# Author(s): Michael Messner, Pascal Eckmann
# Contributor(s): Stefan Haboeck, Nikolas Papaioannou
# Description: Installs needed stuff for EMBA
# if the installer fails you can try to change it to 0
STRICT_MODE=1
ORIG_USER="${SUDO_USER:-${USER}}"
ORIG_GROUP=$(groups "${ORIG_USER}" | cut -d: -f2 | awk '{print $1}')
export DEBIAN_FRONTEND=noninteractive
export INSTALL_APP_LIST=()
export DOWNLOAD_FILE_LIST=()
export INSTALLER_DIR="./installer"
if [[ "${STRICT_MODE}" -eq 1 ]]; then
export DEBUG_SCRIPT=0
if [[ -f "./helpers/helpers_emba_load_strict_settings.sh" ]]; then
# shellcheck source=/dev/null
source ./helpers/helpers_emba_load_strict_settings.sh
elif [[ -f "/installer/helpers_emba_load_strict_settings.sh" ]]; then
# in docker this is in /emba/...
# shellcheck source=/dev/null
source /installer/helpers_emba_load_strict_settings.sh
else
echo "Warning - strict mode module not found"
fi
load_strict_mode_settings
trap 'wickStrictModeFail $? | tee -a /tmp/emba_installer.log' ERR # The ERR trap is triggered when a script catches an error
fi
# install docker EMBA
export IN_DOCKER=0
export DOCKER_SETUP=0
# list dependencies
export LIST_DEP=0
export FULL=0
export REMOVE=0
export FORCE=0
# other os stuff
export OTHER_OS=0
export UBUNTU_OS=0
export RHEL_OS=0
export WSL=0
export GH_ACTION=0
export SSL_REPOS=0
if [[ -f /installer/gh_action ]]; then
export GH_ACTION=1
fi
## Color definition
export RED="\033[0;31m"
export GREEN="\033[0;32m"
export ORANGE="\033[0;33m"
export MAGENTA="\033[0;35m"
export CYAN="\033[0;36m"
export BLUE="\033[0;34m"
export NC="\033[0m" # no color
## Attribute definition
export BOLD="\033[1m"
echo -e "\\n""${ORANGE}""${BOLD}""EMBA - Embedded Linux Analyzer Installer""${NC}"
echo -e "${BOLD}""=================================================================""${NC}"
# import all the installation modules
mapfile -t INSTALLERS < <(find "${INSTALLER_DIR}" -iname "*.sh" 2>/dev/null)
INSTALLER_COUNT=0
for INSTALLER_FILE in "${INSTALLERS[@]}"; do
# https://github.com/koalaman/shellcheck/wiki/SC1090
# shellcheck source=/dev/null
source "${INSTALLER_FILE}"
((INSTALLER_COUNT += 1))
done
echo ""
echo -e "==> ""${GREEN}""Imported ""${INSTALLER_COUNT}"" installer module files""${NC}"
echo ""
# expect the user to provide at least one argument
if [[ "$#" -lt 1 ]]; then
echo -e "${RED}""${BOLD}""Invalid number of arguments""${NC}"
echo -e "\n\n------------------------------------------------------------------"
echo -e "If you are going to install EMBA in default mode you can use:"
echo -e "${CYAN}"" sudo ./installer.sh -d""${NC}"
echo -e "------------------------------------------------------------------\n\n"
print_help
exit 1
fi
while getopts CdDfFghlrsc: OPT; do
case ${OPT} in
d)
export DOCKER_SETUP=1
export CVE_SEARCH=0
echo -e "${GREEN}${BOLD}Install all dependencies for EMBA in default/docker mode${NC}"
;;
D)
export IN_DOCKER=1
export DOCKER_SETUP=0
export CVE_SEARCH=0
echo -e "${GREEN}${BOLD}Install EMBA in docker image - used for building a docker image${NC}"
;;
f)
export FORCE=1
echo -e "${GREEN}${BOLD}Forcing install - bypassing multiple checks${NC}"
;;
F)
export FULL=1
export DOCKER_SETUP=0
export CVE_SEARCH=1
echo -e "${GREEN}${BOLD}Install all dependencies for developer mode (deprecated and not supported anymore)${NC}"
;;
g)
export DOCKER_SETUP=1
export GH_ACTION=1
export CVE_SEARCH=0
echo -e "${GREEN}${BOLD}Install all dependecies for EMBA test via Github actions${NC}"
echo -e "${GREEN}${BOLD}This mode is a default installation without populating the CVE-search database${NC}"
;;
h)
print_help
exit 0
;;
l)
export LIST_DEP=1
export CVE_SEARCH=0
export DOCKER_SETUP=0
echo -e "${GREEN}${BOLD}List all dependecies (Warning: deprecated feature)${NC}"
;;
r)
export REMOVE=1
echo -e "${GREEN}${BOLD}Remove EMBA from the system${NC}"
;;
s)
export SSL_REPOS=1
echo -e "${GREEN}${BOLD}HTTPS repos are used for installation${NC}"
;;
c)
export CONTAINER="${OPTARG}"
;;
*)
echo -e "${RED}${BOLD}Invalid option: ${OPT}${NC}"
print_help
exit 1
;;
esac
done
# Hard workaround to disable the usage of ssl repos for github actions:
if [[ "${GH_ACTION}" -eq 1 ]]; then
export SSL_REPOS=0
fi
# make sure the argument combination passed results in a valid install operation
if [[ ! ("${LIST_DEP}" -eq 1 || "${DOCKER_SETUP}" -eq 1 || "${FULL}" -eq 1 || "${REMOVE}" -eq 1 || "${IN_DOCKER}" -eq 1) ]]; then
echo -e "${RED}""${BOLD}""Missing operation""${NC}"
echo -e "\n\n------------------------------------------------------------------"
echo -e "If you are going to install EMBA in default mode you can use:"
echo -e "${CYAN}"" sudo ./installer.sh -d""${NC}"
echo -e "------------------------------------------------------------------\n\n"
print_help
exit 1
fi
if ! [[ -v CONTAINER ]]; then
if [[ -f docker-compose.yml ]]; then
CONTAINER="$(grep image docker-compose.yml | awk '{print $2}' | sort -u)"
else
CONTAINER="embeddedanalyzer/emba"
fi
fi
if [[ "${LIST_DEP}" -eq 1 ]]; then
echo -e "\n${ORANGE}WARNING: This feature is deprecated and not maintained anymore.${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
# WSL support - currently experimental!
if grep -q -i wsl /proc/version; then
echo -e "\n${ORANGE}INFO: System running in WSL environment!${NC}"
echo -e "\n${ORANGE}INFO: WSL is currently experimental!${NC}"
echo -e "\n${ORANGE}Please check the documentation https://github.com/e-m-b-a/emba/wiki/Installation#prerequisites${NC}"
echo -e "\n${ORANGE}WARNING: If you are using WSL2, disable docker integration from the docker-desktop daemon!${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
WSL=1
fi
# distribution check
if grep -Eq "ID(_LIKE)?=.*(rhel|fedora|rocky|centos)" /etc/os-release 2>/dev/null; then
RHEL_OS=1
elif ! grep -Eq "ID(_LIKE)?=(\")?(ubuntu)?( )?(debian)?" /etc/os-release 2>/dev/null; then
echo -e "\\n""${RED}""EMBA only supports debian based distributions!""${NC}\\n"
print_help
exit 1
elif ! grep -q "kali" /etc/debian_version 2>/dev/null; then
if grep -q "VERSION_ID=\"22.04\"\|VERSION_ID=\"24.04\"" /etc/os-release 2>/dev/null; then
# How to handle sub-versioning ? if grep -q -E "PRETTY_NAME=\"Ubuntu\ 22\.04(\.[0-9]+)?\ LTS\"" /etc/os-release 2>/dev/null ; then
OTHER_OS=1
UBUNTU_OS=1
elif grep -q "PRETTY_NAME=\"Ubuntu 20.04 LTS\"" /etc/os-release 2>/dev/null; then
echo -e "\\n""${RED}""EMBA is not fully supported on Ubuntu 20.04 LTS.""${NC}"
echo -e "${RED}""For EMBA installation you need to update docker-compose manually. See also https://github.com/e-m-b-a/emba/issues/247""${NC}"
echo -e "\\n""${ORANGE}""Please check the documentation https://github.com/e-m-b-a/emba/wiki/Installation#prerequisites""${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you have updated docker-compose you can press any key to continue ..." -n1 -s -r
fi
OTHER_OS=0 # installation procedure identical to kali install
UBUNTU_OS=0 # installation procedure identical to kali install
else
echo -e "\n${ORANGE}WARNING: compatibility of distribution/version unknown!${NC}"
OTHER_OS=1
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
else
OTHER_OS=0
UBUNTU_OS=0
fi
if ! uname -m | grep -q "x86_64" 2>/dev/null; then
echo -e "\n${ORANGE}WARNING: Architecture probably unsupported!${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
if ! grep -q "ssse3" /proc/cpuinfo 2>/dev/null; then
echo -e "\n${ORANGE}WARNING: CPU type and feature set probably unsupported - Missing SSSE3 support detected!${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
if ! [[ ${EUID} -eq 0 ]] && [[ ${LIST_DEP} -eq 0 ]]; then
echo -e "\\n""${RED}""Run EMBA installation script with root permissions!""${NC}\\n"
print_help
exit 1
fi
# standard stuff before installation run
HOME_PATH=$(pwd)
if [[ "${REMOVE}" -eq 1 ]]; then
R00_emba_remove
exit 0
fi
# quick check if we have enough disk space for the docker image
if [[ "${IN_DOCKER}" -eq 0 ]]; then
if [[ -d "/var/lib/docker/" ]]; then
# docker is already installed
DDISK="/var/lib/docker"
else
# default
DDISK="/var/lib/"
fi
FREE_SPACE=$(df --output=avail "${DDISK}" | awk 'NR==2')
if [[ "${FREE_SPACE}" -lt 19000000 ]]; then
echo -e "\\n""${ORANGE}""EMBA installation in default mode needs a minimum of 18Gig for the docker image""${NC}"
echo -e "\\n""${ORANGE}""Please free enough space on /var/lib/docker""${NC}"
echo -e "\\n""${ORANGE}""Please check the documentation https://github.com/e-m-b-a/emba/wiki/Installation#prerequisites""${NC}"
echo ""
df -h || true
echo ""
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
TOTAL_MEMORY="$(grep MemTotal /proc/meminfo | awk '{print $2}' || true)"
if [[ "${TOTAL_MEMORY}" -lt 4000000 ]]; then
echo -e "\\n""${ORANGE}""EMBA installation in default mode needs a minimum of 4Gig of RAM""${NC}"
echo -e "\\n""${ORANGE}""Please check the documentation https://github.com/e-m-b-a/emba/wiki/Installation#prerequisites""${NC}"
echo ""
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
fi
if [[ ${LIST_DEP} -eq 0 ]]; then
if ! [[ -d "external" ]]; then
echo -e "\\n""${ORANGE}""Created external directory: ./external""${NC}"
mkdir external
# currently this is needed for full install on Ubuntu
# the freetz installation is running as freetzuser and needs write access:
chown "${ORIG_USER}":"${ORIG_GROUP}" ./external
chmod 777 ./external
else
echo -e "\\n""${ORANGE}""WARNING: external directory available: ./external""${NC}"
echo -e "${ORANGE}""Please remove it before proceeding ...""${NC}"
echo ""
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
echo -e "\\n""${ORANGE}""Update package lists.""${NC}"
if [[ "${SSL_REPOS}" -eq 1 ]]; then
apt-get -y update
apt-get -y install apt-transport-https ca-certificates
if [[ -f /etc/apt/sources.list ]]; then
sed -i 's/deb http:\/\//deb https:\/\//g' /etc/apt/sources.list
sed -i 's/deb-src http:\/\//deb-src https:\/\//g' /etc/apt/sources.list
fi
if [[ -f /etc/apt/sources.list.d/kali.sources ]]; then
sed -i 's/http:\/\//https:\/\//g' /etc/apt/sources.list.d/kali.sources
fi
fi
if [[ "${RHEL_OS}" -eq 1 ]]; then
dnf install epel-release -y
dnf update -y
else
apt-get -y update
fi
fi
# setup the python virtual environment in external directory
# external is also setup in the docker image
if [[ "${RHEL_OS}" -eq 1 ]]; then
dnf install -y python3-virtualenv
else
apt-get -y install python3-venv
fi
create_pipenv "./external/emba_venv"
activate_pipenv "./external/emba_venv"
if ! command -v docker >/dev/null || ! command -v docker compose >/dev/null; then
if [[ "${RHEL_OS}" -eq 1 ]]; then
echo "RHEL/Rocky system detected. Installing Docker using dnf..."
# Install dnf-utils which provides the 'dnf config-manager' command
dnf install -y 'dnf-command(config-manager)'
# Add the official Docker repository
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Install Docker Engine and plugins. Allow erasing because we want to use docker instead of podman
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin --allowerasing
systemctl start docker
systemctl enable docker
# The original logic for Debian-family systems (Debian, Ubuntu, Kali, etc.)
else
echo "Debian/Ubuntu system detected. Installing Docker using apt..."
# OS debian is for Kali Linux
OS="debian"
[[ "${UBUNTU_OS}" -eq 1 ]] && OS="ubuntu"
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/"${OS}"/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
if [[ "${UBUNTU_OS}" -eq 1 ]]; then
# shellcheck source=/dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${OS} \
$(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
else
# probably a kali linux
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${OS} \
bookworm stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
fi
apt-get update -y
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
fi
export DOCKER_COMPOSE=("docker" "compose")
elif command -v docker-compose >/dev/null; then
echo -e "\n${ORANGE}""${BOLD}""WARNING: Old docker-compose installation found""${NC}"
echo -e "${ORANGE}""${BOLD}""It is recommend to remove the current docker installation and restart the EMBA installation afterwards!""${NC}"
echo -e "${ORANGE}Please check the installed docker packages the following way: dpkg -l | grep docker.${NC}"
echo -e "${ORANGE}Afterwards it can be cleaned up via apt-get the following way:${NC}"
echo -e "${ORANGE}$ sudo apt-get remove docker docker-compose docker.io python3-docker${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
export DOCKER_COMPOSE=("docker-compose")
# if we do not have the docker command it probably is a more modern system and we need to install the docker-cli package
if ! command -v docker >/dev/null; then
echo -e "\n${ORANGE}WARNING: No docker command available -> we check for docker-cli package${NC}"
if [[ "$(apt-cache search docker-cli | wc -l)" -gt 0 ]]; then
echo -e "\n${ORANGE}Info: No docker command available -> we install the docker-cli package now${NC}"
apt-get install docker-cli -y
fi
fi
fi
# docker moved around v7 to a new API (API v2)
# we need to check if our installed docker version has support for the compose sub-command:
if command -v docker >/dev/null; then
if docker --help | grep -q compose; then
# new docker API version v2 -> docker v7
export DOCKER_COMPOSE=("docker" "compose")
elif command -v docker-compose >/dev/null; then
# we only need to check the docker-compose version if we are running on the old API with docker-compose
DOCKER_COMP_VER=$("${DOCKER_COMPOSE[@]}" -v | grep version | tr '-' ' ' | awk '{print $4}' | tr -d ',' | sed 's/^v//')
if [[ $(version "${DOCKER_COMP_VER}") -lt $(version "1.28.5") ]]; then
echo -e "\n${ORANGE}WARNING: compatibility of the used docker-compose version is unknown!${NC}"
echo -e "\n${ORANGE}Please consider updating your docker-compose installation to version 1.28.5 or later.${NC}"
echo -e "\n${ORANGE}Please check the EMBA wiki for further details: https://github.com/e-m-b-a/emba/wiki/Installation#prerequisites${NC}"
if [[ "${FORCE}" -ne 1 ]]; then
read -p "If you know what you are doing you can press any key to continue ..." -n1 -s -r
fi
fi
fi
fi
# if DOCKER_COMPOSE is not set we are in trouble
if ! [[ -v DOCKER_COMPOSE[@] ]]; then
echo -e "\n${ORANGE}${BOLD}WARNING: No docker installation performed${NC}"
echo -e "${ORANGE}If you are running into installation issues please check your docker installation${NC}"
echo -e "${ORANGE}and ensure the docker and docker compose command are available in your system path.${NC}"
echo ""
echo -e "\n${ORANGE}${BOLD}IMPORTANT: IF you do not perform a working docker (including docker compose) installation${NC}"
echo -e "${ORANGE}${BOLD} EMBA can't run on your machine!${NC}"
echo -e "\n${ORANGE}${BOLD}WARNING: EMBA installation process will be stopped -> fix the environment and try again.${NC}"
exit 1
fi
# initial installation of the host environment:
I01_default_apps_host
if [[ "${OTHER_OS}" -eq 1 ]]; then
# UBUNTU
if [[ "${UBUNTU_OS}" -eq 1 ]]; then
ID1_ubuntu_os
fi
fi
INSTALL_APP_LIST=()
if [[ "${WSL}" -eq 1 ]]; then
echo "[*] Starting dockerd manually in wsl environments:"
dockerd --iptables=false &
sleep 3
reset
fi
if [[ "${CVE_SEARCH}" -ne 1 ]] || [[ "${DOCKER_SETUP}" -ne 1 ]] || [[ "${IN_DOCKER}" -eq 1 ]]; then
I01_default_apps
I13_disasm
I05_emba_docker_image_dl
IP00_extractors
IP35_uefi_extraction
IP61_unblob
IP99_binwalk_default
I02_UEFI_fwhunt
I17_apk_check
I20_sourcecode_check
I24_25_kernel_tools
I108_stacs_password_search
I110_yara_check
I199_default_tools_github
I120_cwe_checker
IL10_system_emulator
IL15_emulated_checks_init
IL16_legacy_ssl_curl
IF17_cve_bin_tool
IF50_aggregator_common
if [[ -f "${INSTALLER_DIR}/EMBA_python_imports.sh" ]]; then
# testing and fixing python imports
python_imports_check 1 "./external/emba_venv"
else
echo -e "\\n${MAGENTA}${BOLD}INFO: Python imports checker not available!${NC}"
fi
fi
if [[ "${IN_DOCKER}" -ne 1 ]]; then
# NVD CVE data feed is always installed on the host:
IF20_nvd_feed
fi
deactivate destructive
cd "${HOME_PATH}" || exit 1
# we reset the permissions of external from 777 back to 755:
chmod 755 ./external
if [[ "${LIST_DEP}" -eq 0 ]] || [[ ${IN_DOCKER} -eq 0 ]] || [[ ${DOCKER_SETUP} -eq 1 ]] || [[ ${FULL} -eq 1 ]]; then
echo -e "\\n""${MAGENTA}""${BOLD}""Installation notes:""${NC}"
echo -e "\\n""${MAGENTA}""WARNING: If you plan using the emulator (-E switch) your host and your internal network needs to be protected.""${NC}"
echo -e "\\n""${MAGENTA}""INFO: Do not forget to checkout current development of EMBA at https://github.com/e-m-b-a.""${NC}"
fi
if [[ "${WSL}" -eq 1 ]]; then
echo -e "\\n""${MAGENTA}""INFO: In the current WSL installation the docker and mongod services started manually!""${NC}"
fi
if [[ "${LIST_DEP}" -eq 0 ]]; then
echo -e "${GREEN}""EMBA installation finished ""${NC}"
fi