mirror of
https://github.com/e-m-b-a/emba.git
synced 2026-10-11 22:09:54 +00:00
503 lines
20 KiB
Bash
Executable File
503 lines
20 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
|
|
|
|
# Description: Determines kernel version and description and checks for kernel configuration.
|
|
# It uses linux-exploit-suggester to check for possible kernel exploits and analyzes kernel modules to find which
|
|
# license they have and if they are stripped.
|
|
# It also looks for the modprobe.d directory and lists its content.
|
|
|
|
S25_kernel_check() {
|
|
module_log_init "${FUNCNAME[0]}"
|
|
module_title "Identify and analyze kernel version"
|
|
pre_module_reporter "${FUNCNAME[0]}"
|
|
|
|
export KERNEL_VERSION=()
|
|
export KERNEL_DESC=()
|
|
export KERNEL_MODULES=()
|
|
export VERIFIED_KERNEL_MODULES=0
|
|
local lFOUND=0
|
|
export KMOD_BAD=0
|
|
|
|
# This module waits for S24_kernel_bin_identifier
|
|
# check emba.log for S24_kernel_bin_identifier starting
|
|
module_wait "S24_kernel_bin_identifier"
|
|
|
|
# This check is based on source code from lynis: https://github.com/CISOfy/lynis/blob/master/include/tests_kernel
|
|
|
|
populate_karrays
|
|
|
|
if [[ ${#KERNEL_VERSION[@]} -ne 0 ]]; then
|
|
write_csv_log "BINARY" "VERSION" "CVE identifier" "CVSS rating" "exploit db exploit available" "metasploit module" "trickest PoC" "Routersploit" "local exploit" "remote exploit" "DoS exploit" "known exploited vuln"
|
|
print_output "Kernel version:"
|
|
local lENTRY=""
|
|
for lENTRY in "${KERNEL_VERSION[@]}"; do
|
|
print_output "$(indent "${ORANGE}${lENTRY}${NC}")"
|
|
lFOUND=1
|
|
done
|
|
if [[ ${#KERNEL_DESC[@]} -ne 0 ]]; then
|
|
print_ln
|
|
print_output "Kernel details:"
|
|
for lENTRY in "${KERNEL_DESC[@]}"; do
|
|
print_output "$(indent "${lENTRY}")"
|
|
lFOUND=1
|
|
done
|
|
fi
|
|
if [[ "${SBOM_MINIMAL:-0}" -ne 1 ]]; then
|
|
get_kernel_vulns
|
|
check_modprobe
|
|
fi
|
|
else
|
|
print_output "[-] No kernel version identified"
|
|
fi
|
|
|
|
if [[ "${KERNEL}" -eq 1 ]] && [[ -f "${KERNEL_CONFIG}" ]] && [[ "${SBOM_MINIMAL:-0}" -eq 0 ]]; then
|
|
# we use check_kconfig from s24 module
|
|
check_kconfig "${KERNEL_CONFIG}"
|
|
lFOUND=1
|
|
else
|
|
print_output "[-] No check for kernel configuration"
|
|
fi
|
|
|
|
if [[ ${#KERNEL_MODULES[@]} -ne 0 ]]; then
|
|
analyze_kernel_module
|
|
lFOUND=1
|
|
fi
|
|
|
|
if [[ ${#KERNEL_VERSION[@]} -ne 0 ]]; then
|
|
local lK_VERS=""
|
|
for lK_VERS in "${KERNEL_VERSION[@]}"; do
|
|
write_log "[*] Statistics:${lK_VERS}"
|
|
done
|
|
fi
|
|
write_log "[*] Statistics1:${VERIFIED_KERNEL_MODULES}:${KMOD_BAD}"
|
|
|
|
module_end_log "${FUNCNAME[0]}" "${lFOUND}"
|
|
}
|
|
|
|
populate_karrays() {
|
|
local lKERNEL_VERSION_ARR=()
|
|
local lK_MODULE=""
|
|
local lVER=""
|
|
local lK_VER=""
|
|
local lV=""
|
|
local lK_MOD_FILE=""
|
|
|
|
mapfile -t KERNEL_MODULES < <(find "${FIRMWARE_PATH}" "${EXCL_FIND[@]}" -xdev \( -iname "*.ko" -o -iname "*.o" \) -type f -print0 | xargs -r -0 -P 16 -I % sh -c 'md5sum "%"' 2>/dev/null | sort -u -k1,1 | cut -d\ -f3)
|
|
|
|
for lK_MODULE in "${KERNEL_MODULES[@]}"; do
|
|
lK_MOD_FILE=$(file -b "${lK_MODULE}")
|
|
|
|
# What is the old .o kernel modules showing in the file output?
|
|
# Linux v2.4.x and before is using .o kernel modules
|
|
if [[ "${lK_MODULE}" =~ .*\.o ]]; then
|
|
KERNEL_VERSION+=("$(strings "${lK_MODULE}" 2>/dev/null | grep "kernel_version=" | cut -d= -f2 || true)")
|
|
continue
|
|
fi
|
|
|
|
if [[ ! "${lK_MOD_FILE}" == *"ELF"* ]]; then
|
|
continue
|
|
fi
|
|
KERNEL_VERSION+=("$(modinfo "${lK_MODULE}" 2>/dev/null | grep -E "vermagic" | cut -d: -f2 | sed 's/^ *//g' || true)")
|
|
KERNEL_DESC+=("$(modinfo "${lK_MODULE}" 2>/dev/null | grep -E "description" | cut -d: -f2 | sed 's/^ *//g' | tr -c '[:alnum:]\n\r' '_' | sort -u || true)")
|
|
done
|
|
|
|
# we also extract the kernel version from the /lib/modules/<Kernel version>/ path
|
|
local lKERNEL_MODULES_PATHS_ARR=()
|
|
local lPATH_TO_CHECK=""
|
|
|
|
mapfile -t lKERNEL_MODULES_PATHS_ARR < <(grep -E "/lib/modules/*[0-9]+\.[0-9]+" "${P99_CSV_LOG}" | cut -d ';' -f2 || true)
|
|
for lPATH_TO_CHECK in "${lKERNEL_MODULES_PATHS_ARR[@]}"; do
|
|
# we remove the complete path in front of the possible kernel version:
|
|
# asdf/bla/root-dir/lib/modules/ -> gets removed
|
|
lPATH_TO_CHECK="${lPATH_TO_CHECK/*\/lib\/modules\//}"
|
|
if [[ "${lK_VERSION_ARR[*]}" != *"${lPATH_TO_CHECK}"* ]]; then
|
|
# we currently do not care about additional parts of a path
|
|
# This is later handled during cleanup
|
|
KERNEL_VERSION+=("${lPATH_TO_CHECK}")
|
|
fi
|
|
done
|
|
|
|
for lVER in "${KERNEL_VERSION[@]}"; do
|
|
demess_kv_version "${lVER}"
|
|
|
|
# nosemgrep
|
|
local IFS=" "
|
|
IFS=" " read -r -a KV_C_ARR <<<"$(echo "${KV_ARR[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
|
|
for lV in "${KV_C_ARR[@]}"; do
|
|
if [[ -z "${lV:-}" ]]; then
|
|
# remove empty entries:
|
|
continue
|
|
fi
|
|
if ! [[ "${lV}" =~ .*[0-9]\.[0-9].* ]]; then
|
|
continue
|
|
fi
|
|
lKERNEL_VERSION_ARR+=("${lV}")
|
|
done
|
|
done
|
|
|
|
# if we have found a kernel version in binary kernel:
|
|
if [[ -f "${S24_CSV_LOG}" ]]; then
|
|
while IFS=";" read -r lK_VER; do
|
|
shopt -s extglob
|
|
lK_VER="${lK_VER//Linux\ version\ /}"
|
|
lK_VER="${lK_VER//+([\(\)\#])/}"
|
|
shopt -u extglob
|
|
|
|
demess_kv_version "${lK_VER}"
|
|
|
|
IFS=" " read -r -a KV_C_ARR <<<"$(echo "${KV_ARR[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
|
|
|
|
for lV in "${KV_C_ARR[@]}"; do
|
|
lKERNEL_VERSION_ARR+=("${lV}")
|
|
done
|
|
done < <(cut -d ";" -f2 "${S24_CSV_LOG}")
|
|
fi
|
|
|
|
# unique our results
|
|
eval "lKERNEL_VERSION_ARR=($(for i in "${lKERNEL_VERSION_ARR[@]}"; do
|
|
if [[ -z "${i}" ]]; then
|
|
# remove empty entries:
|
|
continue
|
|
fi
|
|
if ! [[ "${i}" =~ .*[0-9]\.[0-9].* ]]; then
|
|
# remove lines without a possible version identifier like *1.2*
|
|
continue
|
|
fi
|
|
echo "\"${i}\""
|
|
done | sort -u))"
|
|
|
|
# eval "KERNEL_DESC=($(for i in "${KERNEL_DESC[@]}" ; do echo "\"${i}}\"" ; done | sort -u))"
|
|
mapfile -t KERNEL_DESC < <(printf "%s\n" "${KERNEL_DESC[@]}" | sort -u)
|
|
|
|
# if we have no kernel version identified -> we try to identify a possible identifier in the path:
|
|
if [[ "${#lKERNEL_VERSION_ARR[@]}" -eq 0 && "${#KERNEL_MODULES[@]}" -ne 0 ]]; then
|
|
# remove the first part of the path:
|
|
local lKERNEL_VERSION1=""
|
|
lKERNEL_VERSION1=$(echo "${KERNEL_MODULES[0]}" | sed 's/.*\/lib\/modules\///')
|
|
lKERNEL_VERSION_ARR+=("${lKERNEL_VERSION1}")
|
|
# demess_kv_version removes the unneeded stuff after the version:
|
|
demess_kv_version "${lKERNEL_VERSION_ARR[@]}"
|
|
# now rewrite the temp lKERNEL_VERSION_ARR array
|
|
IFS=" " read -r -a lKERNEL_VERSION_ARR <<<"$(echo "${KV_ARR[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
|
|
fi
|
|
|
|
KERNEL_VERSION=("${lKERNEL_VERSION_ARR[@]}")
|
|
}
|
|
|
|
demess_kv_version() {
|
|
local lK_VERSION_ARR=("$@")
|
|
local lKV=""
|
|
local lVER=""
|
|
export KV_ARR=()
|
|
|
|
# sometimes our kernel version is wasted with some "-" -> so we exchange them with spaces for the exploit suggester
|
|
for lVER in "${lK_VERSION_ARR[@]}"; do
|
|
if ! [[ "${lVER}" == *[0-9]* ]]; then
|
|
continue
|
|
fi
|
|
|
|
# split dirty things on space
|
|
shopt -s extglob
|
|
lKV="${lVER//+([-+_\/\ ])/\ }"
|
|
shopt -u extglob
|
|
|
|
# the first field is usually the real kernel version:
|
|
lKV="${lKV/\ */}"
|
|
|
|
while [[ "${lKV}" =~ [a-zA-Z] ]]; do
|
|
lKV="${lKV::-1}"
|
|
done
|
|
|
|
KV_ARR+=("${lKV}")
|
|
done
|
|
}
|
|
|
|
get_kernel_vulns() {
|
|
sub_module_title "Kernel vulnerabilities"
|
|
|
|
local lVER=""
|
|
local lLES_ENTRY=""
|
|
local lLES_CVE=""
|
|
local lLES_CVE_ENTRIES_ARR=()
|
|
|
|
if [[ "${#KERNEL_VERSION[@]}" -gt 0 ]]; then
|
|
print_output "[+] Found linux kernel version/s:"
|
|
for lVER in "${KERNEL_VERSION[@]}"; do
|
|
print_output "$(indent "${ORANGE}${lVER}${NC}")"
|
|
done
|
|
print_ln
|
|
|
|
if [[ -f "${EXT_DIR}""/linux-exploit-suggester.sh" ]]; then
|
|
# sometimes our kernel version is wasted with some "-" -> so we exchange them with spaces for the exploit suggester
|
|
demess_kv_version "${KERNEL_VERSION[@]}"
|
|
IFS=" " read -r -a KV_C_ARR <<<"$(echo "${KV_ARR[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
|
|
for lVER in "${KV_C_ARR[@]}"; do
|
|
sub_module_title "Possible exploits via linux-exploit-suggester.sh for kernel version ${ORANGE}${lVER}${NC}"
|
|
print_output "[*] Search possible exploits via linux-exploit-suggester.sh for kernel version ${ORANGE}${lVER}${NC}"
|
|
print_output "$(indent "https://github.com/mzet-/linux-exploit-suggester")"
|
|
"${EXT_DIR}""/linux-exploit-suggester.sh" --skip-more-checks -f -d -k "${lVER}" >>"${LOG_PATH_MODULE}""/linux_exploit_suggester_kernel_${lVER}.txt"
|
|
tee -a "${LOG_FILE}" <"${LOG_PATH_MODULE}""/linux_exploit_suggester_kernel_${lVER}.txt"
|
|
if [[ -f "${LOG_PATH_MODULE}""/linux_exploit_suggester_kernel_${lVER}.txt" ]]; then
|
|
mapfile -t lLES_CVE_ENTRIES_ARR < <(grep "[+]" "${LOG_PATH_MODULE}""/linux_exploit_suggester_kernel_${lVER}.txt" | grep -E "CVE-[0-9]+")
|
|
for lLES_ENTRY in "${lLES_CVE_ENTRIES_ARR[@]}"; do
|
|
lLES_ENTRY=$(strip_color_codes "${lLES_ENTRY}")
|
|
lLES_CVE=$(echo "${lLES_ENTRY}" | awk '{print $2}' | tr -d '[' | tr -d ']')
|
|
local lKNOWN_EXPLOITED=0
|
|
if [[ -f "${KNOWN_EXP_CSV}" ]]; then
|
|
if grep -q \""${lLES_CVE}"\", "${KNOWN_EXP_CSV}"; then
|
|
print_output "[+] ${ORANGE}WARNING: ${GREEN}Vulnerability ${ORANGE}${lLES_CVE}${GREEN} is a known exploited vulnerability.${NC}"
|
|
lKNOWN_EXPLOITED=1
|
|
fi
|
|
fi
|
|
|
|
if ! grep -q ":linux:linux_kernel;${lVER};${lLES_CVE}" "${S25_CSV_LOG}"; then
|
|
write_csv_log ":linux:linux_kernel" "${lVER}" "${lLES_CVE}" "NA" "NA" "NA" "NA" "NA" "NA" "NA" "NA" "${lKNOWN_EXPLOITED}"
|
|
fi
|
|
done
|
|
fi
|
|
done
|
|
else
|
|
print_output "[-] linux-exploit-suggester.sh is not installed"
|
|
print_output "$(indent "https://github.com/mzet-/linux-exploit-suggester")"
|
|
fi
|
|
else
|
|
print_output "[-] No linux kernel version information found."
|
|
fi
|
|
}
|
|
|
|
analyze_kernel_module() {
|
|
sub_module_title "Analyze kernel modules"
|
|
write_anchor "kernel_modules"
|
|
|
|
local lKMODULE=""
|
|
local lWAIT_PIDS_S25_ARR=()
|
|
local lFILE_KMOD=""
|
|
|
|
KMOD_BAD=0
|
|
|
|
print_output "[*] Found ${ORANGE}${#KERNEL_MODULES[@]}${NC} potential kernel modules."
|
|
|
|
local lOS_IDENTIFIED=""
|
|
lOS_IDENTIFIED=$(distri_check)
|
|
|
|
for lKMODULE in "${KERNEL_MODULES[@]}"; do
|
|
lFILE_KMOD=$(file "${lKMODULE}")
|
|
if [[ "${lFILE_KMOD}" != *"ELF"* ]]; then
|
|
continue
|
|
fi
|
|
VERIFIED_KERNEL_MODULES=$((VERIFIED_KERNEL_MODULES + 1))
|
|
module_analyzer "${lKMODULE}" "${lOS_IDENTIFIED}" &
|
|
local lTMP_PID="$!"
|
|
lWAIT_PIDS_S25_ARR+=("${lTMP_PID}")
|
|
done
|
|
|
|
[[ "${THREADED}" -eq 1 ]] && wait_for_pid "${lWAIT_PIDS_S25_ARR[@]}"
|
|
|
|
if [[ "${VERIFIED_KERNEL_MODULES}" -eq 0 ]]; then
|
|
print_output "[-] No verified kernel module identified."
|
|
fi
|
|
# in threading we need to go via a temp file with the need to count it now:
|
|
if [[ -f "${TMP_DIR}"/KMOD_BAD.tmp ]]; then
|
|
KMOD_BAD=$(awk '{sum += $1 } END { print sum }' "${TMP_DIR}"/KMOD_BAD.tmp)
|
|
fi
|
|
}
|
|
|
|
module_analyzer() {
|
|
local lKMODULE="${1:-}"
|
|
local lOS_IDENTIFIED="${2:-}"
|
|
|
|
if [[ "${lKMODULE}" == *".ko" ]]; then
|
|
local lLICENSE=""
|
|
local lK_VERSION=""
|
|
local lMD5_CHECKSUM="NA"
|
|
local lSHA256_CHECKSUM="NA"
|
|
local lSHA512_CHECKSUM="NA"
|
|
local lK_ARCH="NA"
|
|
local lK_AUTHOR="NA"
|
|
local lK_INTREE="NA"
|
|
local lK_DESC="NA"
|
|
local lCPE_IDENTIFIER=""
|
|
local lPURL_IDENTIFIER=""
|
|
local lMOD_VERSION=""
|
|
local lAPP_NAME=""
|
|
local lK_FILE_OUT=""
|
|
local lAPP_TYPE="operating-system"
|
|
|
|
lLICENSE=$(modinfo "${lKMODULE}" | grep "^license:" || true)
|
|
lLICENSE=${lLICENSE/license:\ /}
|
|
lLICENSE=${lLICENSE//[[:space:]]/}
|
|
[[ "${lLICENSE}" == "GPL" ]] && lLICENSE="GPL-2.0-only"
|
|
# intree - if the module is maintained in the kernel Git repository
|
|
lK_INTREE=$(modinfo "${lKMODULE}" | grep "^intree:" || true)
|
|
lK_INTREE=${lK_INTREE/vermagic:\ /}
|
|
lK_INTREE=$(clean_package_details "${lK_INTREE}")
|
|
[[ "${lK_INTREE}" == "Y" ]] && lLICENSE="GPL-2.0-only"
|
|
|
|
lK_VERSION=$(modinfo "${lKMODULE}" | grep "^vermagic:" || true)
|
|
lK_VERSION=${lK_VERSION/vermagic:\ /}
|
|
lK_VERSION=$(clean_package_details "${lK_VERSION}")
|
|
demess_kv_version "${lK_VERSION}"
|
|
# => we make a nice KV_ARR with the one version only
|
|
# this means we can further proceed with ${KV_ARR[*]} to access
|
|
# the complete version
|
|
|
|
# Just in case we have no kernel version extracted from the module
|
|
# we can use the original array of kernel versions:
|
|
if [[ "${#KV_ARR[@]}" -eq 0 && "${#KERNEL_VERSION[@]}" -gt 0 ]]; then
|
|
KV_ARR+=("${KERNEL_VERSION[0]}")
|
|
fi
|
|
|
|
lMOD_VERSION=$(modinfo "${lKMODULE}" | grep "^version:" || true)
|
|
lMOD_VERSION=${lMOD_VERSION/version:\ /}
|
|
lMOD_VERSION=${lMOD_VERSION//[[:space:]]/}
|
|
|
|
lAPP_NAME="$(basename "${lKMODULE}")"
|
|
lAPP_NAME=${lAPP_NAME,,}
|
|
|
|
lK_AUTHOR=$(modinfo "${lKMODULE}" | grep "^author:" || true)
|
|
lK_AUTHOR="${lK_AUTHOR//author:\ /}"
|
|
lK_AUTHOR="${lK_AUTHOR//Maintainer:\ /}"
|
|
lK_AUTHOR="${lK_AUTHOR//$'\n'/-}"
|
|
lK_AUTHOR=$(clean_package_details "${lK_AUTHOR}")
|
|
|
|
lK_DESC=$(modinfo "${lKMODULE}" | grep "^description:" || true)
|
|
lK_DESC=${lK_DESC/description:\ /}
|
|
lK_DESC=$(clean_package_details "${lK_DESC}")
|
|
|
|
lMD5_CHECKSUM="$(md5sum "${lKMODULE}" | awk '{print $1}')"
|
|
lSHA256_CHECKSUM="$(sha256sum "${lKMODULE}" | awk '{print $1}')"
|
|
lSHA512_CHECKSUM="$(sha512sum "${lKMODULE}" | awk '{print $1}')"
|
|
|
|
lK_FILE_OUT=$(file -b "${lKMODULE}" 2>/dev/null)
|
|
lK_ARCH=$(cut -d ',' -f2 <<<"${lK_FILE_OUT}") # field 2
|
|
lK_ARCH=${lK_ARCH#\ }
|
|
|
|
if [[ "${lK_FILE_OUT}" == *"not stripped"* ]]; then
|
|
if [[ "${lLICENSE}" == *"GPL"* || "${lLICENSE}" == *"BSD"* ]]; then
|
|
# kernel module is GPL/BSD license then not stripped is fine
|
|
print_output "[*] Found kernel module ""${NC}""$(orange "$(print_path "${lKMODULE}")")"" - ${ORANGE}""License ${lLICENSE}""${NC}"" - ""${GREEN}""NOT STRIPPED""${NC}"
|
|
elif ! [[ ${lLICENSE} =~ "License:" ]]; then
|
|
print_output "[-] Found kernel module ""${NC}""$(orange "$(print_path "${lKMODULE}")")"" - ${ORANGE}""License not found""${NC}"" - ""${RED}""NOT STRIPPED""${NC}"
|
|
else
|
|
# kernel module is NOT GPL license then not stripped is bad!
|
|
print_output "[-] Found kernel module ""${NC}""$(orange "$(print_path "${lKMODULE}")")"" - ${ORANGE}""License ${lLICENSE}""${NC}"" - ""${RED}""NOT STRIPPED""${NC}"
|
|
echo "1" >>"${TMP_DIR}"/KMOD_BAD.tmp
|
|
fi
|
|
else
|
|
print_output "[*] Found kernel module ""${NC}""$(orange "$(print_path "${lKMODULE}")")"" - ${ORANGE}""License ${lLICENSE}""${NC}"" - ""${GREEN}""STRIPPED""${NC}"
|
|
fi
|
|
|
|
# we log to our sbom log with the kernel module details only if we have some module version detected
|
|
if [[ -n "${lMOD_VERSION}" ]]; then
|
|
# we store the kernel version (lVERSION:-NA) and the kernel module version (lMOD_VERSION:-NA)
|
|
check_for_s08_csv_log "${S08_CSV_LOG}"
|
|
|
|
local lPACKAGING_SYSTEM="kernel_module"
|
|
# add source file path information to our properties array:
|
|
local lPROP_ARRAY_INIT_ARR=()
|
|
lPROP_ARRAY_INIT_ARR+=("source_path:${lKMODULE}")
|
|
lPROP_ARRAY_INIT_ARR+=("source_arch:${lK_ARCH}")
|
|
lPROP_ARRAY_INIT_ARR+=("source_details:${lK_FILE_OUT}")
|
|
lPROP_ARRAY_INIT_ARR+=("minimal_identifier::${lK_AUTHOR}:${lAPP_NAME}:${lMOD_VERSION}:")
|
|
lPROP_ARRAY_INIT_ARR+=("confidence:high")
|
|
lPROP_ARRAY_INIT_ARR+=("dependency:linux_kernel")
|
|
|
|
build_sbom_json_properties_arr "${lPROP_ARRAY_INIT_ARR[@]}"
|
|
|
|
# build_json_hashes_arr sets lHASHES_ARR globally and we unset it afterwards
|
|
# final array with all hash values
|
|
if ! build_sbom_json_hashes_arr "${lKMODULE}" "${lAPP_NAME:-NA}" "${lMOD_VERSION:-NA}" "${lPACKAGING_SYSTEM:-NA}"; then
|
|
print_output "[*] Already found results for ${lAPP_NAME} / ${lMOD_VERSION}" "no_log"
|
|
else
|
|
# create component entry - this allows adding entries very flexible:
|
|
build_sbom_json_component_arr "${lPACKAGING_SYSTEM}" "${lAPP_TYPE:-library}" "${lAPP_NAME:-NA}" "${lMOD_VERSION:-NA}" "${lK_AUTHOR:-NA}" "${lLICENSE:-NA}" "${lCPE_IDENTIFIER:-NA}" "${lPURL_IDENTIFIER:-NA}" "${lK_DESC:-NA}"
|
|
fi
|
|
|
|
write_log "${lPACKAGING_SYSTEM};${lKMODULE:-NA};${lMD5_CHECKSUM:-NA}/${lSHA256_CHECKSUM:-NA}/${lSHA512_CHECKSUM:-NA};${lAPP_NAME};${lMOD_VERSION:-NA};NA;${lLICENSE};${lK_AUTHOR};${lK_ARCH};CPE not available;PURL not available;${SBOM_COMP_BOM_REF:-NA};Linux kernel module - ${lAPP_NAME} - description: ${lK_DESC:-NA}" "${S08_CSV_LOG}"
|
|
fi
|
|
|
|
if [[ "${#KV_ARR[@]}" -gt 0 ]]; then
|
|
# ensure we do not log the kernel multiple times
|
|
local lK_AUTHOR="linux"
|
|
local lLICENSE="GPL-2.0-only"
|
|
# we can rewrite the APP_NAME as we also log the source_path from where we know the exact source of this kernel entry
|
|
local lAPP_NAME="linux_kernel"
|
|
local lPACKAGING_SYSTEM="${lAPP_NAME}+module"
|
|
|
|
# lCPE_IDENTIFIER="cpe:${CPE_VERSION}:a:${lK_AUTHOR}:${lAPP_NAME}:${KV_ARR[*]}:*:*:*:*:*:*"
|
|
lCPE_IDENTIFIER=$(build_cpe_identifier ":${lK_AUTHOR}:${lAPP_NAME}:${KV_ARR[*]}" "o")
|
|
|
|
lPURL_IDENTIFIER=$(build_generic_purl ":${lK_AUTHOR}:${lAPP_NAME}:${KV_ARR[*]}" "${lOS_IDENTIFIED}" "${lK_ARCH:-NA}")
|
|
|
|
# add source file path information to our properties array:
|
|
local lPROP_ARRAY_INIT_ARR=()
|
|
lPROP_ARRAY_INIT_ARR+=("source_path:${lKMODULE}")
|
|
lPROP_ARRAY_INIT_ARR+=("source_arch:${lK_ARCH}")
|
|
lPROP_ARRAY_INIT_ARR+=("source_details:${lK_FILE_OUT}")
|
|
lPROP_ARRAY_INIT_ARR+=("minimal_identifier::${lK_AUTHOR}:${lAPP_NAME}:${KV_ARR[*]}:")
|
|
lPROP_ARRAY_INIT_ARR+=("module_version_details:${lK_VERSION,,}")
|
|
lPROP_ARRAY_INIT_ARR+=("confidence:high")
|
|
|
|
build_sbom_json_properties_arr "${lPROP_ARRAY_INIT_ARR[@]}"
|
|
|
|
# build_json_hashes_arr sets lHASHES_ARR globally and we unset it afterwards
|
|
# final array with all hash values
|
|
if ! build_sbom_json_hashes_arr "${lKMODULE}" "${lAPP_NAME:-NA}" "${KV_ARR[*]}" "${lPACKAGING_SYSTEM:-NA}"; then
|
|
print_output "[*] Already found results for ${lAPP_NAME} / ${KV_ARR[*]}" "no_log"
|
|
else
|
|
# create component entry - this allows adding entries very flexible:
|
|
build_sbom_json_component_arr "${lPACKAGING_SYSTEM}" "${lAPP_TYPE:-library}" "${lAPP_NAME:-NA}" "${KV_ARR[*]}" "${lK_AUTHOR:-NA}" "${lLICENSE:-NA}" "${lCPE_IDENTIFIER:-NA}" "${lPURL_IDENTIFIER:-NA}" "${lK_DESC:-NA}"
|
|
write_log "${lPACKAGING_SYSTEM};${lKMODULE:-NA};${lMD5_CHECKSUM:-NA}/${lSHA256_CHECKSUM:-NA}/${lSHA512_CHECKSUM:-NA};linux_kernel:${lAPP_NAME};${lK_VERSION,,};:linux:linux_kernel:${KV_ARR[*]};${lLICENSE};kernel.org;${lK_ARCH};${lCPE_IDENTIFIER};${lPURL_IDENTIFIER};${SBOM_COMP_BOM_REF:-NA};Detected via Linux kernel module - ${lAPP_NAME}" "${S08_CSV_LOG}"
|
|
fi
|
|
fi
|
|
elif [[ "${lKMODULE}" == *".o" ]] && [[ "${SBOM_MINIMAL:-0}" -ne 1 ]]; then
|
|
print_output "[-] No support for .o kernel modules - ${ORANGE}${lKMODULE}${NC}" "no_log"
|
|
fi
|
|
}
|
|
|
|
# This check is based on source code from lynis: https://github.com/CISOfy/lynis/blob/master/include/tests_usb
|
|
|
|
check_modprobe() {
|
|
sub_module_title "Check modprobe.d directory and content"
|
|
|
|
local lMODPROBE_D_DIRS_ARR=()
|
|
local lMPROBE_DIR=""
|
|
local lMP_CHECK=0
|
|
local lMP_F_CHECK=0
|
|
local lMP_CONF=""
|
|
|
|
readarray -t lMODPROBE_D_DIRS_ARR < <(find "${FIRMWARE_PATH}" -xdev "${EXCL_FIND[@]}" -iname '*modprobe.d*' -print0 | xargs -r -0 -P 16 -I % sh -c 'md5sum "%" 2>/dev/null || true' | sort -u -k1,1 | cut -d\ -f3)
|
|
for lMPROBE_DIR in "${lMODPROBE_D_DIRS_ARR[@]}"; do
|
|
if [[ -d "${lMPROBE_DIR}" ]]; then
|
|
lMP_CHECK=1
|
|
print_output "[+] Found ""$(print_path "${lMPROBE_DIR}")"
|
|
readarray -t MODPROBE_D_DIR_CONTENT <<<"$(find "${lMPROBE_DIR}" -xdev -iname '*.conf' -print0 | xargs -r -0 -P 16 -I % sh -c 'md5sum "%" 2>/dev/null || true' | sort -u -k1,1 | cut -d\ -f3)"
|
|
for lMP_CONF in "${MODPROBE_D_DIR_CONTENT[@]}"; do
|
|
if [[ -e "${lMP_CONF}" ]]; then
|
|
lMP_F_CHECK=1
|
|
print_output "$(indent "$(orange "$(print_path "${lMP_CONF}")")")"
|
|
fi
|
|
done
|
|
if [[ ${lMP_F_CHECK} -eq 0 ]]; then
|
|
print_output "[-] No config files in modprobe.d directory found"
|
|
fi
|
|
fi
|
|
done
|
|
if [[ ${lMP_CHECK} -eq 0 ]]; then
|
|
print_output "[-] No modprobe.d directory found"
|
|
fi
|
|
}
|