mirror of
https://github.com/e-m-b-a/emba.git
synced 2026-10-12 02:13:21 +00:00
cleanup, rip of Q02, fixes
This commit is contained in:
@@ -175,8 +175,7 @@ set_defaults() {
|
||||
export SVG_BUILD_TIMEOUT="12h"
|
||||
export SVG_FILE="${LOG_PATH_MODULE}/EMBA-dependency-map.svg"
|
||||
|
||||
DEPENDENCY_TRACK_ENABLED=0
|
||||
OPENAI_API_KEY=""
|
||||
export DEPENDENCY_TRACK_ENABLED=0
|
||||
|
||||
# we can enable/disable the s08 submodules with the following array configuration
|
||||
# -> just comment the submodule that should not be used
|
||||
|
||||
@@ -300,7 +300,7 @@ dependency_check() {
|
||||
echo -e "${RED}not ok${NC}"
|
||||
print_output "[!] Warning: EMBA has NO internet connection!" "no_log"
|
||||
print_output "[!] Warning: Update checks and multiple EMBA modules are disabled!" "no_log"
|
||||
print_output "[!] Warning: GPT (Q02), kernel verification (S26) and further online modules are disabled!" "no_log"
|
||||
print_output "[!] Warning: Kernel verification (S26) and further online modules are disabled!" "no_log"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -335,74 +335,6 @@ dependency_check() {
|
||||
# in our containers we have mounted our current EMBA dir to /emba, this includes the host ./external with the onlinechecker
|
||||
local lONLINE_CHECK_FILE="/emba/external/onlinechecker/EMBA_VERSION.txt"
|
||||
fi
|
||||
|
||||
# as we first check the onlinechecker/EMBA_VERSION.txt file we know if we are online or not:
|
||||
if ! [[ -f "${lONLINE_CHECK_FILE}" ]] && [[ -n "${OPENAI_API_KEY}" ]]; then
|
||||
# if we have no EMBA_VERSION identified, we do not need to check our GPT key now -> there is no internet
|
||||
print_output "$(indent "${ORANGE}As there is no Internet connection available, no GPT checks performed.${NC}")" "no_log"
|
||||
elif [[ -z "${OPENAI_API_KEY}" ]]; then
|
||||
print_output "$(indent "ChatGPT-API key not set - ${ORANGE}see https://github.com/e-m-b-a/emba/wiki/AI-supported-firmware-analysis for more information${NC}")" "no_log"
|
||||
# The following if clause is currently not working! We have not loaded the profile in this stage
|
||||
# TODO: Find a workaround!
|
||||
if [[ "${AI_OPTION}" -eq 1 ]]; then
|
||||
DEP_ERROR=1
|
||||
fi
|
||||
else
|
||||
local lRETRIES_=0
|
||||
# on the host we try it only 10 times:
|
||||
local lMAX_RETRIES=10
|
||||
if [[ "${IN_DOCKER}" -eq 1 ]]; then
|
||||
# within the Quest container we can keep trying it as it does not matter if the container starts up later
|
||||
lMAX_RETRIES=200
|
||||
fi
|
||||
local lSLEEPTIME=30
|
||||
while true; do
|
||||
local lHTTP_CODE_=400
|
||||
print_output " OpenAI-API key - \\c" "no_log"
|
||||
lHTTP_CODE_=$(curl -sS https://api.openai.com/v1/chat/completions -H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
|
||||
-d @"${CONFIG_DIR}/gpt_template.json" --write-out "%{http_code}" -o /tmp/chatgpt-test.json 2>/dev/null)
|
||||
|
||||
if [[ "${lHTTP_CODE_}" -eq 200 ]]; then
|
||||
echo -e "${GREEN}""ok""${NC}"
|
||||
rm /tmp/chatgpt-test.json
|
||||
break
|
||||
else
|
||||
if [[ -f /tmp/chatgpt-test.json ]]; then
|
||||
if jq '.error.code' /tmp/chatgpt-test.json | grep -q "rate_limit_exceeded"; then
|
||||
# rate limit handling - if we got a response like:
|
||||
# Please try again in 20s
|
||||
echo -e "${RED}""not ok (rate limit issues)""${NC}"
|
||||
if jq '.error.message' /tmp/chatgpt-test.json | grep -q "Please try again in "; then
|
||||
# print_output "GPT API test #${lRETRIES_} - \\c" "no_log"
|
||||
sleep "${lSLEEPTIME}"s
|
||||
# sleeptime gets adjusted on every failure
|
||||
lSLEEPTIME=$((lSLEEPTIME + 5))
|
||||
((lRETRIES_ += 1))
|
||||
[[ "${lRETRIES_}" -lt "${lMAX_RETRIES}" ]] && continue
|
||||
fi
|
||||
fi
|
||||
if jq '.error.code' /tmp/chatgpt-test.json | grep -q "insufficient_quota"; then
|
||||
echo -e "${RED}""not ok (quota limit issues)""${NC}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
echo -e "${RED}""not ok""${NC}"
|
||||
print_output "[-] ChatGPT error while testing the API-Key: ${OPENAI_API_KEY}" "no_log"
|
||||
if [[ -f /tmp/chatgpt-test.json ]]; then
|
||||
print_output "[-] ERROR response: $(cat /tmp/chatgpt-test.json)" "no_log"
|
||||
fi
|
||||
# Note: we are running into issues in the case where the key can't be verified, but GPT is not enabled at all
|
||||
# In such a case we will fail the check without the need of GPT
|
||||
# DEP_ERROR=1
|
||||
fi
|
||||
if grep -q "Testing phase ended" "${LOG_DIR}"/"${MAIN_LOG_FILE}" 2>/dev/null; then
|
||||
print_output " Testing phase ended - \\c" "no_log"
|
||||
echo -e "${RED}""exit now""${NC}"
|
||||
DEP_ERROR=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
print_output " Isolation - ${GREEN}""ok""${NC}" "no_log"
|
||||
fi
|
||||
|
||||
@@ -116,11 +116,11 @@ add_link_tags() {
|
||||
|
||||
# in some cases we link to files from different modules. Now we check if the html report file is already
|
||||
# generated and we can directly use the already available html report file
|
||||
lORIG_SRC_MODULE_DIR=$(echo "${lREF_LINK}" | tr '/' '\n' | grep -E "^[psqfl][0-9]{2,3}_.*")
|
||||
lORIG_SRC_MODULE_DIR=$(echo "${lREF_LINK}" | tr '/' '\n' | grep -E "^[psqfl][0-9]{2,3}_.*" | head -n 1 || print_error "[-] HTML report linking issue for ${lREF_LINK}")
|
||||
print_debug "[*] REF link ${lREF_LINK} / BACK_LINK ${lBACK_LINK} / lORIG_SRC_MODULE_DIR: ${lORIG_SRC_MODULE_DIR} / lLINK_FILE: ${lLINK_FILE}" "no_log"
|
||||
if [[ -f "${ABS_HTML_PATH%/}/${lORIG_SRC_MODULE_DIR}/${lMD5_REF_LINK}" ]]; then
|
||||
print_debug "[*] Found already generated log file in ${ABS_HTML_PATH%/}/${lORIG_SRC_MODULE_DIR}/${lMD5_REF_LINK}" "no_log"
|
||||
if [[ "$(basename ${lLINK_FILE})" =~ ^(d|p|l|s|q|f){1}[0-9]{2,3}_.*$ ]]; then
|
||||
if [[ "$(basename "${lLINK_FILE}")" =~ ^(d|p|l|s|q|f){1}[0-9]{2,3}_.*$ ]]; then
|
||||
# link to the already available report file without generating a new one:
|
||||
# we need to link to the original module directory of the file if we are in a main module log file
|
||||
lBACK_LINK_NEW="${lORIG_SRC_MODULE_DIR}/${lMD5_REF_LINK}"
|
||||
|
||||
@@ -65,6 +65,8 @@ F05_qs_resolver() {
|
||||
print_output "[*] AI resolver - testing ${ORANGE}${CSV_DIR}/ai_question.csv${NC}"
|
||||
|
||||
gpt_resolver_csv "${lGPT_INPUT_FILE_}" "${lAI_ANCHOR}" "${l_GPT_PRIO_}" "${lGPT_QUESTION_}" "${lGPT_OUTPUT_FILE_}" "${lGPT_TOKENS_}" "${lAI_RESPONSE_FILE}" &
|
||||
lWAIT_PIDS_F05_ARR+=("$!")
|
||||
store_kill_pids "${lWAIT_PIDS_F05_ARR[-1]}"
|
||||
done <"${CSV_DIR}/ai_question.csv"
|
||||
|
||||
wait_for_pid "${lWAIT_PIDS_F05_ARR[@]}"
|
||||
@@ -85,6 +87,7 @@ F05_qs_resolver() {
|
||||
gpt_resolver_csv_tmp "${lGPT_INPUT_FILE_}" "${lAI_ANCHOR}" "${l_GPT_PRIO_}" "${lGPT_QUESTION_}" "${lGPT_OUTPUT_FILE_}" "${lGPT_TOKENS_}" "${lGPT_RESPONSE_}" &
|
||||
local lTMP_PID="$!"
|
||||
lWAIT_PIDS_F05_ARR+=("${lTMP_PID}")
|
||||
store_kill_pids "${lTMP_PID}"
|
||||
# max_pids_protection "${MAX_MOD_THREADS}" "${lWAIT_PIDS_F05_ARR[@]}"
|
||||
done <"${CSV_DIR}/ai_question.csv.tmp"
|
||||
|
||||
@@ -171,9 +174,6 @@ gpt_resolver_csv_tmp() {
|
||||
|
||||
print_output "[*] AI module didn't check ${lGPT_INPUT_FILE_}, linking to the GPT module page instead"
|
||||
|
||||
local lMD5_OF_ORIG_SRC_FILE=""
|
||||
lMD5_OF_ORIG_SRC_FILE=$(md5sum "${lGPT_OUTPUT_FILE_}" | awk '{print $1}')
|
||||
|
||||
readarray -t lGPT_OUTPUT_FILE_HTML_ARR_ < <(grep -r -l "\[ASK_AI\]\ ${lAI_ANCHOR}" "${HTML_PATH}" 2>/dev/null || true)
|
||||
|
||||
for lHTML_FILE_ in "${lGPT_OUTPUT_FILE_HTML_ARR_[@]}"; do
|
||||
|
||||
@@ -95,6 +95,13 @@ output_overview() {
|
||||
fi
|
||||
print_output "[+] EMBA version: ""${ORANGE}""${lSBOM_TOOL_VERS}""${NC}"
|
||||
write_csv_log "EMBA_version" "${lSBOM_TOOL_VERS}" "NA" "NA" "NA" "NA" "NA" "NA" "NA"
|
||||
if [[ -f "${LOG_DIR}/emba_error.log" ]]; then
|
||||
if grep -q Location "${LOG_DIR}/emba_error.log"; then
|
||||
print_output "[-] WARNING: EMBA ${ORANGE}errors${NC} to review" "" ""
|
||||
else
|
||||
print_output "[*] INFO: EMBA ${ORANGE}warnings${NC} to review" "" ""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "${ARCH}" ]] && [[ "${ARCH}" != "NA" ]]; then
|
||||
if [[ -n "${D_END:-"NA"}" ]]; then
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
#!/bin/bash -p
|
||||
|
||||
# EMBA - EMBEDDED LINUX ANALYZER
|
||||
#
|
||||
# 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): Benedikt Kuehne
|
||||
|
||||
# Description: Openai questioning module for container #2
|
||||
# Note: Important requirement for Q-modules is the self termination when a certain phase ends
|
||||
|
||||
Q02_openai_question() {
|
||||
module_log_init "${FUNCNAME[0]}"
|
||||
export CHATGPT_RESULT_CNT=0
|
||||
if [[ "${AI_OPTION}" -gt 0 ]] && [[ -n "${OPENAI_API_KEY}" ]]; then
|
||||
# Prints title to CLI and into log
|
||||
module_title "AI analysis via OpenAI"
|
||||
pre_module_reporter "${FUNCNAME[0]}"
|
||||
|
||||
# we wait until there arer entries in the question csv
|
||||
while ! [[ -f "${LOG_DIR}"/"${MAIN_LOG_FILE}" ]]; do
|
||||
if ! [[ -d "${LOG_DIR}" ]]; then
|
||||
# this usually happens if we automate analysis and remove the logging directory while this module was not finished at all
|
||||
return
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
if [[ -f "${LOG_DIR}"/"${MAIN_LOG_FILE}" ]]; then
|
||||
while ! [[ -f "${CSV_DIR}/ai_question.csv.tmp" ]]; do
|
||||
sleep 3
|
||||
done
|
||||
fi
|
||||
|
||||
export GTP_CHECKED_ARR=()
|
||||
while ! grep -q "Reporting phase started" "${LOG_DIR}"/"${MAIN_LOG_FILE}" && [[ "${lMODULE_RUNTIME}" -le "${LOCAL_AI_MIN_RUNTIME}" ]]; do
|
||||
if [[ "${CHATGPT_RESULT_CNT}" -ge 0 ]]; then
|
||||
ask_chatgpt
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
unset OPENAI_API_KEY
|
||||
fi
|
||||
module_end_log "${FUNCNAME[0]}" "${CHATGPT_RESULT_CNT}"
|
||||
}
|
||||
|
||||
# looks through the modules and finds chatgpt questions inside the csv
|
||||
ask_chatgpt() {
|
||||
local lGPT_FILE_DIR="${LOG_PATH_MODULE}/gpt_files"
|
||||
local lGPT_PRIO=3
|
||||
# default vars
|
||||
local lGPT_QUESTION=""
|
||||
local lCHATGPT_CODE=""
|
||||
local lGPT_RESPONSE=""
|
||||
local lGPT_RESPONSE_CLEANED=""
|
||||
local lGPT_TOKENS=0
|
||||
local lHTTP_CODE=200
|
||||
local lORIGIN_MODULE=""
|
||||
local lGPT_SERVER_ERROR_CNT=0
|
||||
local lELE_INDEX=0
|
||||
local lGPT_ANCHOR=""
|
||||
local lGPT_INPUT_FILE=""
|
||||
local lGPT_INPUT_FILE_mod=""
|
||||
local lGPT_OUTPUT_FILE=""
|
||||
local lSCRIPT_PATH_TMP=""
|
||||
|
||||
print_output "[*] Checking scripts with ChatGPT that have priority ${ORANGE}${MINIMUM_GPT_PRIO}${NC} or lower" "no_log"
|
||||
if ! [[ -d "${lGPT_FILE_DIR}" ]]; then
|
||||
mkdir "${lGPT_FILE_DIR}"
|
||||
fi
|
||||
|
||||
# generating Array for GPT requests - sorting according the prio in field 3
|
||||
# this array gets regenerated on every round
|
||||
readarray -t Q02_OPENAI_QUESTIONS < <(sort -k 3 -t ';' -r "${CSV_DIR}/ai_question.csv.tmp")
|
||||
|
||||
for ((lELE_INDEX = 0; lELE_INDEX < "${#Q02_OPENAI_QUESTIONS[@]}"; lELE_INDEX++)); do
|
||||
local lELEM="${Q02_OPENAI_QUESTIONS["${lELE_INDEX}"]}"
|
||||
lSCRIPT_PATH_TMP="$(echo "${lELEM}" | cut -d\; -f1)"
|
||||
|
||||
# as we always start with the highest rated entry, we need to check if this entry was already tested:
|
||||
if [[ " ${GTP_CHECKED_ARR[*]} " =~ ${lSCRIPT_PATH_TMP} ]]; then
|
||||
# print_output "[*] GPT - Already tested ${lSCRIPT_PATH_TMP}" "no_log"
|
||||
# lets test the next entry
|
||||
continue
|
||||
fi
|
||||
|
||||
lGPT_ANCHOR="$(echo "${lELEM}" | cut -d\; -f2)"
|
||||
lGPT_PRIO="$(echo "${lELEM}" | cut -d\; -f3)"
|
||||
# lGPT_PRIO="${lGPT_PRIO//GPT-Prio-/}"
|
||||
lGPT_QUESTION="$(echo "${lELEM}" | cut -d\; -f4)"
|
||||
lGPT_OUTPUT_FILE="$(echo "${lELEM}" | cut -d\; -f5)"
|
||||
lGPT_TOKENS="$(echo "${lELEM}" | cut -d\; -f6)"
|
||||
lGPT_TOKENS="${lGPT_TOKENS//cost\=/}"
|
||||
lGPT_RESPONSE="$(echo "${lELEM}" | cut -d\; -f7)"
|
||||
lGPT_INPUT_FILE="$(basename "${lSCRIPT_PATH_TMP}")"
|
||||
lGPT_INPUT_FILE_mod="${lGPT_INPUT_FILE//\./}"
|
||||
|
||||
# in case we have nothing we are going to move on
|
||||
[[ -z "${lSCRIPT_PATH_TMP}" ]] && continue
|
||||
|
||||
if [[ "${lSCRIPT_PATH_TMP}" == *"s16_ghidra_decompile_checks"* ]]; then
|
||||
# our ghidra check stores the decompiled code in the log directory. We need to copy it to the gpt log directory for further processing
|
||||
print_output "[*] Ghidra decompiled code found ${lSCRIPT_PATH_TMP}" "no_log"
|
||||
[[ -f "${lSCRIPT_PATH_TMP}" ]] && cp "${lSCRIPT_PATH_TMP}" "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
else
|
||||
# this is currently the usual case for scripts
|
||||
print_output "[*] Identification of ${ORANGE}${lSCRIPT_PATH_TMP} / ${lGPT_INPUT_FILE}${NC} inside ${ORANGE}${LOG_DIR}/firmware${NC}" "no_log"
|
||||
if [[ "${lSCRIPT_PATH_TMP}" == ".""${LOG_DIR}"* ]]; then
|
||||
print_output "[*] Warning: System path is not stripped with the root directory - we try to fix it now" "no_log"
|
||||
# remove the '.'
|
||||
lSCRIPT_PATH_TMP="${lSCRIPT_PATH_TMP:1}"
|
||||
# remove the LOG_DIR
|
||||
# shellcheck disable=SC2001
|
||||
lSCRIPT_PATH_TMP="$(echo "${lSCRIPT_PATH_TMP}" | sed 's#'"${LOG_DIR}"'##')"
|
||||
print_output "[*] Stripped path ${lSCRIPT_PATH_TMP}" "no_log"
|
||||
fi
|
||||
# dirty fix - Todo: use array in future
|
||||
lSCRIPT_PATH_TMP="$(find "${LOG_DIR}/firmware" -wholename "*${lSCRIPT_PATH_TMP}" | head -1)"
|
||||
|
||||
# in case we have nothing we are going to move on
|
||||
! [[ -f "${lSCRIPT_PATH_TMP}" ]] && continue
|
||||
[[ -f "${lSCRIPT_PATH_TMP}" ]] && cp "${lSCRIPT_PATH_TMP}" "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
fi
|
||||
|
||||
print_output "[*] AI-Assisted analysis of script ${ORANGE}${lSCRIPT_PATH_TMP}${NC} with question ${ORANGE}${lGPT_QUESTION}${NC}" "no_log"
|
||||
print_output "[*] Current priority for testing is ${lGPT_PRIO}" "no_log"
|
||||
|
||||
if [[ -z ${lGPT_RESPONSE} ]] && [[ ${lGPT_PRIO} -ge ${MINIMUM_GPT_PRIO} ]] && [[ "${lSCRIPT_PATH_TMP}" != '' ]]; then
|
||||
if [[ -f "${lSCRIPT_PATH_TMP}" ]]; then
|
||||
# add navbar-item for file
|
||||
sub_module_title "AI analysis for ${lGPT_INPUT_FILE}"
|
||||
|
||||
# print_output "[*] AI-Assisted analysis for ${ORANGE}${lGPT_INPUT_FILE}${NC}" "" "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
print_output "[*] AI-Assisted analysis for ${lGPT_INPUT_FILE_mod}" "" "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
print_output "$(indent "$(orange "$(print_path "${lSCRIPT_PATH_TMP}")")")"
|
||||
head -n -2 "${CONFIG_DIR}/gpt_template.json" >"${TMP_DIR}/chat.json" || print_error "[-] Tmp file create error for ${lSCRIPT_PATH_TMP}"
|
||||
if [[ ! -f "${TMP_DIR}/chat.json" ]]; then
|
||||
print_output "[-] Temp file ${TMP_DIR}/chat.json for further analysis of ${lSCRIPT_PATH_TMP} was not created ... some Error occured"
|
||||
return
|
||||
fi
|
||||
|
||||
lCHATGPT_CODE=$(sed 's/\\//g;s/"/\\\"/g' "${lSCRIPT_PATH_TMP}" | tr -d '[:space:]' | sed 's/\[ASK_GPT\].*//')
|
||||
if [[ "${#lCHATGPT_CODE}" -gt 4561 ]]; then
|
||||
print_output "[*] GPT request is too big ... stripping it now" "no_log"
|
||||
lCHATGPT_CODE=$(sed 's/\\//g;s/"/\\\"/g' "${lSCRIPT_PATH_TMP}" | tr -d '[:space:]' | cut -c-4560 | sed 's/\[ASK_GPT\].*//')
|
||||
fi
|
||||
strip_color_codes "$(printf '"%s %s"\n}]}' "${lGPT_QUESTION}" "${lCHATGPT_CODE}")" >>"${TMP_DIR}/chat.json"
|
||||
|
||||
print_output "[*] Testing the following code with ChatGPT:" "no_log"
|
||||
cat "${lSCRIPT_PATH_TMP}"
|
||||
print_ln "no_log"
|
||||
print_output "[*] Adjusted the code under test to send it to ChatGPT:" "no_log"
|
||||
cat "${TMP_DIR}/chat.json"
|
||||
print_ln "no_log"
|
||||
|
||||
print_output "[*] The combined cost of the OpenAI request / the length is: ${ORANGE}${#lGPT_QUESTION} + ${#lCHATGPT_CODE}${NC}" "no_log"
|
||||
|
||||
lHTTP_CODE=$(curl https://api.openai.com/v1/chat/completions -H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
|
||||
-d @"${TMP_DIR}/chat.json" -o "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" --write-out "%{http_code}" || true)
|
||||
|
||||
if [[ "${lHTTP_CODE}" -ne 200 ]]; then
|
||||
print_output "[-] Something went wrong with the ChatGPT requests"
|
||||
if [[ -f "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" ]]; then
|
||||
print_output "[-] ERROR response: $(cat "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json")"
|
||||
|
||||
if jq '.error.type' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" | grep -q "insufficient_quota"; then
|
||||
print_output "[-] Stopping OpenAI requests since the API key has reached its quota limit"
|
||||
CHATGPT_RESULT_CNT=-1
|
||||
sleep 20
|
||||
break
|
||||
elif jq '.error.type' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" | grep -q "server_error"; then
|
||||
((lGPT_SERVER_ERROR_CNT += 1))
|
||||
if [[ "${lGPT_SERVER_ERROR_CNT}" -ge 5 ]]; then
|
||||
# more than 5 failes we stop trying until the newxt round
|
||||
print_output "[-] Stopping OpenAI requests since the Server seems to be overloaded"
|
||||
CHATGPT_RESULT_CNT=-1
|
||||
sleep 20
|
||||
break
|
||||
fi
|
||||
elif jq '.error.code' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" | grep -q "rate_limit_exceeded"; then
|
||||
# rate limit handling - if we got a response like:
|
||||
# Please try again in 7m12s.
|
||||
# then we will wate ~10mins and try it afterwards again
|
||||
# in this time we need to check if the Testing phase is running or not
|
||||
if jq '.error.message' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" | grep -q "Please try again in "; then
|
||||
local lCNT=0
|
||||
while [[ "${lCNT}" -lt 1000 ]]; do
|
||||
lCNT=$((lCNT + 1))
|
||||
local lTEMP_VAR="$(("${lCNT}" % 100))"
|
||||
(("${lTEMP_VAR}" == 0)) && print_output "[*] Rate limit handling ... sleep mode - ${lCNT}" "no_log"
|
||||
if grep -q "Reporting phase started" "${LOG_DIR}"/"${MAIN_LOG_FILE}" && [[ "${lMODULE_RUNTIME}" -ge "${LOCAL_AI_MIN_RUNTIME}" ]]; then
|
||||
break 2
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# TODO: now we should redo the last test
|
||||
else
|
||||
print_output "[-] Stopping OpenAI requests since the API key has reached its rate_limit"
|
||||
CHATGPT_RESULT_CNT=-1
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
cat "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" >>"${lGPT_FILE_DIR}/openai_server_errors.log"
|
||||
readarray -t Q02_OPENAI_QUESTIONS < <(sort -k 3 -t ';' -r "${CSV_DIR}/ai_question.csv.tmp")
|
||||
# reset the array index to start again with the highest rated entry
|
||||
lELE_INDEX=0
|
||||
if grep -q "Reporting phase started" "${LOG_DIR}"/"${MAIN_LOG_FILE}" && [[ "${lMODULE_RUNTIME}" -ge "${LOCAL_AI_MIN_RUNTIME}" ]]; then
|
||||
return
|
||||
fi
|
||||
sleep 30s
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! [[ -f "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json" ]]; then
|
||||
# catches: (56) Recv failure: Connection reset by peer
|
||||
print_output "[-] Something went wrong with the ChatGPT request for ${lGPT_INPUT_FILE}"
|
||||
break
|
||||
fi
|
||||
|
||||
lGPT_RESPONSE=("$(jq '.choices[] | .message.content' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json")")
|
||||
lGPT_RESPONSE_CLEANED="${lGPT_RESPONSE[*]//\;/}" #remove ; from response
|
||||
lGPT_TOKENS=$(jq '.usage.total_tokens' "${TMP_DIR}/${lGPT_INPUT_FILE_mod}_response.json")
|
||||
|
||||
if [[ ${lGPT_TOKENS} -ne 0 ]]; then
|
||||
GTP_CHECKED_ARR+=("${lSCRIPT_PATH_TMP}")
|
||||
# write new into done csv
|
||||
write_csv_AI "${lGPT_INPUT_FILE}" "${lGPT_ANCHOR}" "${lGPT_PRIO}" "${lGPT_QUESTION}" "${lGPT_OUTPUT_FILE}" "cost=${lGPT_TOKENS}" "'${lGPT_RESPONSE_CLEANED//\'/}'"
|
||||
|
||||
# we store the answers in dedicated files for further interlinking within the report
|
||||
if ! [[ -d "${LOG_PATH_MODULE}"/gpt_answers ]]; then
|
||||
mkdir "${LOG_PATH_MODULE}"/gpt_answers || true
|
||||
fi
|
||||
echo "${lGPT_RESPONSE_CLEANED}" >"${LOG_PATH_MODULE}"/gpt_answers/gpt_response_"${lGPT_INPUT_FILE_mod}".log
|
||||
|
||||
# print openai response
|
||||
print_ln
|
||||
# print_output "[*] ${ORANGE}AI-assisted analysis results via OpenAI ChatGPT:${NC}\\n"
|
||||
echo -e "${lGPT_RESPONSE[*]}" | tee -a "${LOG_FILE}"
|
||||
|
||||
# add proper module link
|
||||
if [[ "${lGPT_OUTPUT_FILE}" == *'/csv_logs/'* ]]; then
|
||||
# if we have a csv_logs path we need to adjust the cut
|
||||
lORIGIN_MODULE="$(echo "${lGPT_OUTPUT_FILE}" | cut -d / -f4 | cut -d_ -f1)"
|
||||
elif [[ "${lGPT_OUTPUT_FILE}" == '/logs/'* ]]; then
|
||||
lORIGIN_MODULE="$(echo "${lGPT_OUTPUT_FILE}" | cut -d / -f3 | cut -d_ -f1)"
|
||||
else
|
||||
lORIGIN_MODULE="$(basename "$(dirname "${lGPT_OUTPUT_FILE}")" | cut -d_ -f1)"
|
||||
fi
|
||||
|
||||
print_ln
|
||||
print_output "[+] Further results for ${ORANGE}${lGPT_INPUT_FILE_mod}${GREEN} available in module ${ORANGE}${lORIGIN_MODULE}${NC}" "" "${lORIGIN_MODULE}"
|
||||
print_output "[+] Analysed source file ${ORANGE}${lGPT_INPUT_FILE_mod}${GREEN}" "" "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
# print_output "[+] Analysed source script popup ${ORANGE}${lGPT_INPUT_FILE_mod}${GREEN} script"
|
||||
# write_local_overlay_link "${lGPT_FILE_DIR}/${lGPT_INPUT_FILE_mod}.log"
|
||||
if [[ -f "${LOG_PATH_MODULE}"/gpt_answers/gpt_response_"${lGPT_INPUT_FILE_mod}".log ]]; then
|
||||
print_output "[+] GPT answer file for ${ORANGE}${lGPT_INPUT_FILE_mod}${NC}" "" "${LOG_PATH_MODULE}"/gpt_answers/gpt_response_"${lGPT_INPUT_FILE_mod}".log
|
||||
fi
|
||||
|
||||
print_ln
|
||||
((CHATGPT_RESULT_CNT += 1))
|
||||
fi
|
||||
else
|
||||
print_output "[-] Couldn't find ${ORANGE}$(print_path "${lSCRIPT_PATH_TMP}")${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if grep -q "Reporting phase started" "${LOG_DIR}"/"${MAIN_LOG_FILE}" && [[ "${lMODULE_RUNTIME}" -ge "${LOCAL_AI_MIN_RUNTIME}" ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [[ "${AI_OPTION}" -ne 2 ]]; then
|
||||
sleep 20s
|
||||
fi
|
||||
|
||||
# reload q02 results:
|
||||
print_output "[*] Regenerate analysis array ..." "no_log"
|
||||
readarray -t Q02_OPENAI_QUESTIONS < <(sort -k 3 -t ';' -r "${CSV_DIR}/ai_question.csv.tmp")
|
||||
# reset the array index to start again with the highest rated entry
|
||||
lELE_INDEX=0
|
||||
done
|
||||
|
||||
if [[ -f "${CSV_DIR}/ai_question.csv" ]]; then
|
||||
local lGPT_ENTRY_LINE=""
|
||||
while read -r lGPT_ENTRY_LINE; do
|
||||
lGPT_ANCHOR="$(echo "${lGPT_ENTRY_LINE}" | cut -d ';' -f2)"
|
||||
sed -i "/${lGPT_ANCHOR}/d" "${CSV_DIR}/ai_question.csv.tmp"
|
||||
done <"${CSV_DIR}/ai_question.csv"
|
||||
fi
|
||||
}
|
||||
@@ -66,6 +66,10 @@ Q03_localai_connector() {
|
||||
fi
|
||||
|
||||
export SECONDS=0
|
||||
if [[ "${AI_MIN_RUNTIME}" == *"d" ]]; then
|
||||
AI_MIN_RUNTIME=${AI_MIN_RUNTIME//d/}
|
||||
AI_MIN_RUNTIME=$((AI_MIN_RUNTIME*24*3600))
|
||||
fi
|
||||
if [[ "${AI_MIN_RUNTIME}" == *"h" ]]; then
|
||||
AI_MIN_RUNTIME=${AI_MIN_RUNTIME//h/}
|
||||
AI_MIN_RUNTIME=$((AI_MIN_RUNTIME*3600))
|
||||
@@ -74,9 +78,8 @@ Q03_localai_connector() {
|
||||
AI_MIN_RUNTIME=${AI_MIN_RUNTIME//m/}
|
||||
AI_MIN_RUNTIME=$((AI_MIN_RUNTIME*60))
|
||||
fi
|
||||
if [[ "${AI_MIN_RUNTIME}" == *"d" ]]; then
|
||||
AI_MIN_RUNTIME=${AI_MIN_RUNTIME//d/}
|
||||
AI_MIN_RUNTIME=$((AI_MIN_RUNTIME*24*3600))
|
||||
if [[ "${AI_MIN_RUNTIME}" == *"s" ]]; then
|
||||
AI_MIN_RUNTIME=${AI_MIN_RUNTIME//s/}
|
||||
fi
|
||||
|
||||
export GTP_CHECKED_ARR=()
|
||||
@@ -470,15 +473,20 @@ generate_prompt_script() {
|
||||
print_output "[*] Build prompt for ${lSCRIPT_PATH_TMP} - lSCRIPT_NAME: ${lBINARY_NAME} - script type: ${lSCRIPT_TYPE}" "no_log"
|
||||
|
||||
# Read the file content and remove the ASK_AI marker
|
||||
lCODE_CONTENT_tmp=$(grep -v "ASK_AI" "${lSCRIPT_PATH_TMP}")
|
||||
lCODE_CONTENT_tmp=$(grep -v "ASK_AI" "${lSCRIPT_PATH_TMP}" || true)
|
||||
# remove REF entries for HTML links
|
||||
lCODE_CONTENT_tmp=$(sed '/^\[REF\] .*/d' <<< "${lCODE_CONTENT_tmp}")
|
||||
lCODE_CONTENT_tmp=$(sed '/^\[REF\] .*/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 1")
|
||||
# remove semgrep identifiers
|
||||
lCODE_CONTENT_tmp=$(sed 's/\/\/possible issue identified -.*//' <<< "${lCODE_CONTENT_tmp}")
|
||||
lCODE_CONTENT_tmp=$(sed 's/\/\/possible issue identified -.*//' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 2")
|
||||
# remove color codes
|
||||
lCODE_CONTENT_tmp=$(strip_color_codes "${lCODE_CONTENT_tmp}")
|
||||
# remove shell comments and empty lines:
|
||||
lCODE_CONTENT=$(sed '/^[[:blank:]]*#/d;s/[[:blank:]]*#.*//' <<< "${lCODE_CONTENT_tmp}")
|
||||
|
||||
# remove shell comment lines:
|
||||
lCODE_CONTENT_tmp=$(sed '/^[[:blank:]]*#/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 4")
|
||||
# remove shell comments:
|
||||
lCODE_CONTENT_tmp=$(sed 's/[[:blank:]]*#.*//' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 5")
|
||||
# remove empty lines (includes also empty lines with spaces):
|
||||
lCODE_CONTENT=$(sed -r '/^\s*$/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 3")
|
||||
|
||||
lPROMPT="You are an expert software architect. Analyze the provided source code."
|
||||
lPROMPT+=" The following source code is from a Linux based firmware ${lSCRIPT_TYPE} script called ${lBINARY_NAME}."
|
||||
@@ -495,7 +503,7 @@ generate_prompt_script() {
|
||||
fi
|
||||
lPROMPT="${lPROMPT}\nHere is the code:\n\n${lCODE_CONTENT:0:${AI_MAX_CHARS_TO_ANALYSE}}\n"
|
||||
|
||||
echo -n "${lPROMPT}" | iconv -f ISO-8859-1 -t UTF-8 > "${AI_PROMPT_DIR}/prompt_localai_${lBINARY_NAME}_${lSCRIPT_TYPE}.txt"
|
||||
echo -n "${lPROMPT}" > "${AI_PROMPT_DIR}/prompt_localai_${lBINARY_NAME}_${lSCRIPT_TYPE}.txt"
|
||||
}
|
||||
|
||||
generate_prompt_binary() {
|
||||
@@ -535,14 +543,21 @@ generate_prompt_binary() {
|
||||
fi
|
||||
|
||||
# Read the file content and remove the ASK_AI marker
|
||||
lCODE_CONTENT_tmp=$(grep -v "ASK_AI" "${lSCRIPT_PATH_TMP}")
|
||||
lCODE_CONTENT_tmp=$(grep -v "ASK_AI" "${lSCRIPT_PATH_TMP}" || true)
|
||||
# remove REF entries for HTML links
|
||||
lCODE_CONTENT_tmp=$(sed '/^\[REF\] .*/d' <<< "${lCODE_CONTENT_tmp}")
|
||||
lCODE_CONTENT_tmp=$(sed '/^\[REF\] .*/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 1")
|
||||
# remove semgrep identifiers
|
||||
lCODE_CONTENT_tmp=$(sed 's/\/\/possible issue identified -.*//' <<< "${lCODE_CONTENT_tmp}")
|
||||
lCODE_CONTENT_tmp=$(sed 's/\/\/possible issue identified -.*//' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 2")
|
||||
# remove color codes
|
||||
lCODE_CONTENT=$(strip_color_codes "${lCODE_CONTENT_tmp}")
|
||||
|
||||
# remove shell comment lines:
|
||||
lCODE_CONTENT_tmp=$(sed '/^[[:blank:]]*#/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 4")
|
||||
# remove shell comments:
|
||||
lCODE_CONTENT_tmp=$(sed 's/[[:blank:]]*#.*//' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 5")
|
||||
# remove empty lines (includes also empty lines with spaces):
|
||||
lCODE_CONTENT=$(sed -r '/^\s*$/d' <<< "${lCODE_CONTENT_tmp}" || print_error "[-] Code parsing issue for ${lSCRIPT_PATH_TMP} - 3")
|
||||
|
||||
lPROMPT="You are an expert software architect. Analyze the provided source code."
|
||||
lPROMPT+=" The following source code is from a Linux based firmware binary called ${lBINARY_NAME}."
|
||||
lPROMPT+=" It was automatically generated with the reverse engineering framework Ghidra."
|
||||
@@ -588,5 +603,5 @@ generate_prompt_binary() {
|
||||
|
||||
# print_output "[*] Wrting prompt for ${lSCRIPT_PATH_TMP} - ${lPROMPT} to ${AI_PROMPT_DIR}/prompt_localai_${lBINARY_NAME}_${lFUNCTION_NAME}.txt"
|
||||
|
||||
echo -n "${lPROMPT}" | iconv -f ISO-8859-1 -t UTF-8 > "${AI_PROMPT_DIR}/prompt_localai_${lBINARY_NAME}_${lFUNCTION_NAME}.txt"
|
||||
echo -n "${lPROMPT}" > "${AI_PROMPT_DIR}/prompt_localai_${lBINARY_NAME}_${lFUNCTION_NAME}.txt"
|
||||
}
|
||||
|
||||
@@ -142,10 +142,10 @@ setup_environment() {
|
||||
if [[ "${#ALL_EXEC_FILES_ARR[@]}" -gt "${MAX_MAP_FILES}" ]]; then
|
||||
print_output "[*] INFO: A huge number of files (${#ALL_EXEC_FILES_ARR[@]} -gt ${MAX_MAP_FILES}) detected ... limit the module to a maximum of ${MAX_MAP_FILES} executables only"
|
||||
if [[ -f "${P99_CSV_LOG}" ]]; then
|
||||
mapfile -t ALL_EXEC_FILES_ARR < <(grep "ELF\|executable\|script" "${P99_CSV_LOG}" | cut -d ';' -f2 | grep -v "\.raw" | head -n "${MAX_MAP_FILES}")
|
||||
mapfile -t ALL_EXEC_FILES_ARR < <(grep "ELF\|executable\|script" "${P99_CSV_LOG}" | cut -d ';' -f2 | grep -v "\.raw" | head -n "${MAX_MAP_FILES}" || true)
|
||||
else
|
||||
# quick and dirty backup solution to not handle all the executable files
|
||||
mapfile -t ALL_EXEC_FILES_ARR < <(find "${FIRMWARE_PATH}" -type f -executable ! -name "*.raw" 2>/dev/null | sort -u | head -n "${MAX_MAP_FILES}")
|
||||
mapfile -t ALL_EXEC_FILES_ARR < <(find "${FIRMWARE_PATH}" -type f -executable ! -name "*.raw" 2>/dev/null | sort -u | head -n "${MAX_MAP_FILES}" || true)
|
||||
fi
|
||||
fi
|
||||
print_ln ""
|
||||
|
||||
@@ -259,8 +259,8 @@ s22_vuln_check() {
|
||||
write_csv_AI_tmp "${lS22_SOURCE_DIR}/${lPHP_SCRIPT_NAME}.log" "${lAI_ANCHOR}" "${lGPT_PRIO_}" "${GPT_QUESTION}" "${lPHP_SCRIPT_}" "" ""
|
||||
|
||||
# add AI link
|
||||
printf '%s\n\n' "" >>"${lPHP_SCRIPT_}"
|
||||
write_anchor_AI "${lAI_ANCHOR}" "${lPHP_SCRIPT_}"
|
||||
printf '%s\n\n' "" >>"${lPHP_LOG}"
|
||||
write_anchor_AI "${lAI_ANCHOR}" "${lPHP_LOG}"
|
||||
printf '%s\n\n' "" >>"${lS22_SOURCE_DIR}/${lPHP_SCRIPT_NAME}.log"
|
||||
write_anchor_AI "${lAI_ANCHOR}" "${lS22_SOURCE_DIR}/${lPHP_SCRIPT_NAME}.log"
|
||||
fi
|
||||
|
||||
@@ -696,10 +696,10 @@ final_log_kernel_vulns() {
|
||||
local lCNT_PATHS_FOUND_WRONG_ARCH=0
|
||||
|
||||
if [[ -s "${TMP_DIR}/s25_counting.tmp" ]]; then
|
||||
lCNT_PATHS_UNK=$(grep -c "lCNT_PATHS_UNK" "${TMP_DIR}/s25_counting.tmp")
|
||||
lCNT_PATHS_NOT_FOUND=$(grep -c "lCNT_PATHS_NOT_FOUND" "${TMP_DIR}/s25_counting.tmp")
|
||||
lCNT_PATHS_FOUND=$(grep -c "lCNT_PATHS_FOUND" "${TMP_DIR}/s25_counting.tmp")
|
||||
lCNT_PATHS_FOUND_WRONG_ARCH=$(grep -c "lCNT_PATHS_FOUND_WRONG_ARCH" "${TMP_DIR}/s25_counting.tmp")
|
||||
lCNT_PATHS_UNK=$(grep -c "lCNT_PATHS_UNK" "${TMP_DIR}/s25_counting.tmp" || true)
|
||||
lCNT_PATHS_NOT_FOUND=$(grep -c "lCNT_PATHS_NOT_FOUND" "${TMP_DIR}/s25_counting.tmp" || true)
|
||||
lCNT_PATHS_FOUND=$(grep -c "lCNT_PATHS_FOUND" "${TMP_DIR}/s25_counting.tmp" || true)
|
||||
lCNT_PATHS_FOUND_WRONG_ARCH=$(grep -c "lCNT_PATHS_FOUND_WRONG_ARCH" "${TMP_DIR}/s25_counting.tmp" || true)
|
||||
fi
|
||||
|
||||
print_output "[*] Found ${ORANGE}${lCNT_PATHS_UNK}${NC} advisories with missing vulnerable path details"
|
||||
|
||||
@@ -55,7 +55,7 @@ S27_perl_check() {
|
||||
max_pids_protection "${MAX_MOD_THREADS}" lWAIT_PIDS_S27
|
||||
done
|
||||
|
||||
[[ "${THREADED}" -eq 1 ]] && wait_for_pid "${lWAIT_PIDS_S27[@]}"
|
||||
wait_for_pid "${lWAIT_PIDS_S27[@]}"
|
||||
[[ -d "${TMP_DIR}/s27" ]] && (rm -r "${TMP_DIR}"/s27 || true)
|
||||
|
||||
if [[ -f "${TMP_DIR}/S27_VULNS.tmp" ]]; then
|
||||
|
||||
@@ -29,7 +29,8 @@ S28_java_check() {
|
||||
local lJNAME=""
|
||||
local lJAVA_VULNS_CNT=0
|
||||
local lWAIT_PIDS_S28=()
|
||||
local MAX_MOD_THREADS=$((MAX_MOD_THREADS/2))
|
||||
# shadow the original MAX_MOD_THREADS as adjusted local variable
|
||||
local MAX_MOD_THREADS=$(( MAX_MOD_THREADS > 1 ? MAX_MOD_THREADS / 2 : 1 ))
|
||||
|
||||
export JAVA_DECOMPILER="${EXT_DIR}/vineflower-1.11.2.jar"
|
||||
|
||||
@@ -90,7 +91,7 @@ S28_java_check() {
|
||||
# AI integration
|
||||
local lAI_ANCHOR=""
|
||||
lAI_ANCHOR="$(openssl rand -hex 8)"
|
||||
lAI_PRIO=4
|
||||
local lAI_PRIO=4
|
||||
write_csv_AI_tmp "${lJAVA_SOURCE_FILE}.log" "${lAI_ANCHOR}" "${lAI_PRIO}" "NA" "${lSEMGREP_RESULT}" "" ""
|
||||
printf '%s\n\n' "" >>"${lJAVA_SOURCE_FILE}.log"
|
||||
write_anchor_AI "${lAI_ANCHOR}" "${lJAVA_SOURCE_FILE}.log"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# EMBA - EMBEDDED LINUX ANALYZER
|
||||
#
|
||||
# Copyright 2020-2026 Siemens Energy AG
|
||||
# Copyright 2020-2025 Siemens Energy AG
|
||||
# Copyright 2020-2023 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.
|
||||
@@ -8,10 +9,10 @@
|
||||
#
|
||||
# EMBA is licensed under GPLv3
|
||||
#
|
||||
# Author(s): Benedikt Kuehne
|
||||
# Contributor(s): Michael Messner
|
||||
# Author(s): Michael Messner, Pascal Eckmann
|
||||
#
|
||||
# Description: Profile for AI usage
|
||||
# Description: This is a default EMBA profile. You can Use it as a template for your own profiles
|
||||
# or start emba with "-p default-scan.emba" to use it
|
||||
|
||||
export FORMAT_LOG=1
|
||||
export THREADED=1
|
||||
@@ -20,25 +21,34 @@ export HTML=1
|
||||
|
||||
# QEMULATION - for user-mode emulation to generate an optimised SBOM
|
||||
export QEMULATION=1
|
||||
# 0 -> off, 1-> unpaid GPT plan, 2 -> no GPT rate-limit, 3 -> LocalAI Server
|
||||
export AI_OPTION=3
|
||||
|
||||
# disable yara tests (s110)
|
||||
export YARA=0
|
||||
|
||||
# extended binary tests are now only testing non-linux binaries. With this mechanism we can enable
|
||||
# it in the default profile.
|
||||
export BINARY_EXTENDED=1
|
||||
# we test only the first 10 binaries with cwe_checker and extended semgrep rules
|
||||
export MAX_EXT_CHECK_BINS=15
|
||||
|
||||
# VEX metrics (check for KEV, Exploits, EPSS)
|
||||
export VEX_METRICS=1
|
||||
|
||||
# disable long running modules - enable them if needed
|
||||
export MODULE_BLACKLIST+=( "S10_binaries_basic_check" "S15_radare_decompile_checks" "S26_kernel_vuln_verifier" "S99_grepit" "S110_yara_check" "F20_vul_aggregator" )
|
||||
# the following modules are long running modules which are disabled in the default profile
|
||||
export MODULE_BLACKLIST+=( "S10_binaries_basic_check" "S15_radare_decompile_checks" "S99_grepit" "S110_yara_check" "F20_vul_aggregator" )
|
||||
|
||||
# enable silent mode and status bar
|
||||
export DISABLE_STATUS_BAR=1
|
||||
export SILENT=0
|
||||
export DISABLE_STATUS_BAR=0
|
||||
export SILENT=1
|
||||
|
||||
# enable AI connection:
|
||||
# 0 -> off, 1-> unpaid GPT plan, 2 -> no GPT rate-limit, 3 -> LocalAI Server
|
||||
export AI_OPTION=3
|
||||
|
||||
# enable EMBA binary map dependency generator
|
||||
EMBA_MAP_GENERATOR=0
|
||||
EMBA_MAP_GENERATOR=1
|
||||
MAX_MAP_FILES=1000
|
||||
SVG_BUILD_TIMEOUT="12h"
|
||||
|
||||
# we output the profile only at the beginning - outside the docker environment
|
||||
if [[ $IN_DOCKER -ne 1 ]] ; then
|
||||
@@ -46,7 +56,6 @@ if [[ $IN_DOCKER -ne 1 ]] ; then
|
||||
print_output "$(indent "$(orange "Activate multi threading")")" "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"
|
||||
print_output "$(indent "$(orange "Activates AI checks via OpenAI-API")")" "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
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# EMBA - EMBEDDED LINUX ANALYZER
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Author(s): Benedikt Kuehne
|
||||
# Contributor(s): Michael Messner
|
||||
#
|
||||
# Description: Profile for AI usage
|
||||
|
||||
export FORMAT_LOG=1
|
||||
export THREADED=1
|
||||
export SHORT_PATH=1
|
||||
export HTML=1
|
||||
|
||||
# QEMULATION - for user-mode emulation to generate an optimised SBOM
|
||||
export QEMULATION=1
|
||||
# 0 -> off, 1-> unpaid GPT plan, 2 -> no GPT rate-limit, 3 -> LocalAI Server
|
||||
export AI_OPTION=3
|
||||
|
||||
# extended binary tests are now only testing non-linux binaries. With this mechanism we can enable
|
||||
# it in the default profile.
|
||||
export BINARY_EXTENDED=1
|
||||
|
||||
# VEX metrics (check for KEV, Exploits, EPSS)
|
||||
export VEX_METRICS=1
|
||||
|
||||
# disable long running modules - enable them if needed
|
||||
export MODULE_BLACKLIST+=( "S10_binaries_basic_check" "S15_radare_decompile_checks" "S26_kernel_vuln_verifier" "S99_grepit" "S110_yara_check" "F20_vul_aggregator" )
|
||||
|
||||
# enable silent mode and status bar
|
||||
export DISABLE_STATUS_BAR=1
|
||||
export SILENT=0
|
||||
|
||||
# enable EMBA binary map dependency generator
|
||||
EMBA_MAP_GENERATOR=0
|
||||
|
||||
# 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")")" "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"
|
||||
print_output "$(indent "$(orange "Activates AI checks via OpenAI-API")")" "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 "Disable EMBA module via profile")")" "no_log"
|
||||
for MODULE_ in "${MODULE_BLACKLIST[@]}"; do
|
||||
print_output "$(indent "$(orange "Blacklisted module: $MODULE_")")" "no_log"
|
||||
done
|
||||
export USE_DOCKER=1
|
||||
fi
|
||||
Reference in New Issue
Block a user