Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add python runner module S28 #1320

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions modules/S28_python_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2024-2024 Thomas Gingele <b1tc0r3@proton.me>
#
# 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): Thomas Gingele
#
# Description: This is an experimental EMBA module. It is designed to run user-defined python
# scripts during the analysis.
#

S28_python_run() {
module_log_init "${FUNCNAME[0]}"
module_title "Python Runner"
pre_module_reporter "${FUNCNAME[0]}"

local lSCRIPT_DIR="${MOD_DIR}/${FUNCNAME[0]}"
local lPYTHON_SCRIPT_COUNT=${#PYTHON_SCRIPTS[@]}
local lCOUNT_SUBMODULE_FINDINGS=0
local lCOUNT_TOTAL_FINDINGS=0
local lSCRIPT=""

if [[ ${lPYTHON_SCRIPT_COUNT} -gt 0 ]]; then
print_output "[*] ${lPYTHON_SCRIPT_COUNT} Python script/s queued for execution."

for lSCRIPT in "${PYTHON_SCRIPTS[@]}"; do
sub_module_title "Execution of Python runner for ${ORANGE}${lSCRIPT}${NC}"
print_output "[*] Executing: ${ORANGE}${lSCRIPT_DIR}/${lSCRIPT}.py${NC}"

lCOUNT_SUBMODULE_FINDINGS=$(python3 "${lSCRIPT_DIR}/${lSCRIPT}.py" | grep "FINDINGS" | sed "s/FINDINGS://")
lCOUNT_TOTAL_FINDINGS=$((lCOUNT_TOTAL_FINDINGS + lCOUNT_SUBMODULE_FINDINGS))

cat "${LOG_PATH_MODULE}/${lSCRIPT}.txt" >> "${LOG_FILE}"
print_output "[*] Python module ${ORANGE}${lSCRIPT}${NC} reported a total of ${ORANGE}${lCOUNT_SUBMODULE_FINDINGS}${NC} findings."
done

else
print_output "[*] No Python scripts queued for execution."
fi

sub_module_title "Final results for ${FUNCNAME[0]}"
print_output "Total results count: ${lCOUNT_TOTAL_FINDINGS}"
module_end_log "${FUNCNAME[0]}" "${lCOUNT_TOTAL_FINDINGS}"
}
110 changes: 110 additions & 0 deletions modules/S28_python_run/embamodule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/python3
"""
EMBA - EMBEDDED LINUX ANALYZER

Copyright 2024-2024 Thomas Gingele <b1tc0r3@proton.me>

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): Thomas Gingele

Description: This file contains wrapper code for custom Python modules.
"""
from os import _Environ


class EmbaModule():
"""
Module handling class for EMBA python scripts.

Functions:
__init__:
Create a new instance of the class and set up logging.

__del__:
Close module files and destroy the class instance.

__write_formatted_log:
Base method for logging. Should not be called by Python modules directly.

log:
Log a new message into the module log files.

add_finding:
Add a new finding to the module. This will later be used during report generation.

panic:
Ensures propper logging when throwing exceptions.
"""

def __init__(self, argv: list, env: _Environ):
self.findings = []
self.filename = argv[0].split("/")[-1].split('.')[0]

try:
self.logfile_dir = env.get('LOG_PATH_MODULE')
except:
self.panic(f"Unable to determine log path for python module '{self.filename}'.", Exception)

try:
self.logfile = open(f"{self.logfile_dir}/{self.filename}.txt", "w")
except:
self.panic("Unable to open log files for '{self.filename}'.", Exception)


def __del__(self):
self.logfile.close()


def __write_formatted_log(self, operator: str, text: str):
lines = text.split('\n')
for line in lines:
self.logfile.write(f"[{operator}] {line}\n")


def log(self, text: str):
self.__write_formatted_log("*", text)


def add_finding(self, description: str):
self.findings.append(description)
self.__write_formatted_log(f"F{len(self.findings)}", description)


def panic(self, description: str, except_type: type[Exception]):
self.__write_formatted_log("!", description)
raise except_type(description)


def setup_module(argv: list, env: _Environ):
"""
Creates a new emba module wrapper.

Parameters:
argv (list): The list of arguments used to start the Python process.
env (_Environ): The environment variables of the Python process.

Returns:
A new EmbaModule class instance.
"""
return EmbaModule(argv, env)


def shutdown_module(module: EmbaModule):
"""
Shut down an emba python module.
This will also print the amount of findings as an interger so EMBA can parse the number.

Parameters:
module (EmbaModule): A class instance of EmbaModule.

Returns:
none
"""
print(f"FINDINGS:{len(module.findings)}", end="")
del module
38 changes: 38 additions & 0 deletions modules/S28_python_run/example_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/python3
"""
EMBA - EMBEDDED LINUX ANALYZER

Copyright 2024-2024 Thomas Gingele <b1tc0r3@proton.me>

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): Thomas Gingele

Description: This python script serves as an example of a Python module. It echoes passed parameters and then exits.
"""
from embamodule import setup_module, shutdown_module
from sys import argv
from os import environ


def main():
# Setup module and logging.
# This line is required.
module = setup_module(argv, environ)

# This is just some example code.
# The module logic would go here.
module.log("Received arguments a total of {len(environ)} environment variables.")
for key in environ.keys():
module.add_finding(f"Found envvar: {key}={environ[key]}")

# Shutdown module and report results.
# This line is required
shutdown_module(module)

main()
61 changes: 61 additions & 0 deletions scan-profiles/default-scan-python-runner.emba
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2024 Thomas Gingele <b1tc0r3@proton.me>
#
# 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): Thomas Gingele
#
# Description: Perform a default EMBA scan and run additional, user-supplied python scripts as
# modules.

export SELECT_MODULES+=( "S28" )
export PYTHON_SCRIPTS=( "example_script" )

export FORMAT_LOG=1
export THREADED=1
export SHORT_PATH=1
export HTML=1

# 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

# 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" )

# enable silent mode and status bar
export DISABLE_STATUS_BAR=0
export SILENT=1

# enable GPT connection:
export GPT_OPTION=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"
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
for MODULE_ in "${SELECT_MODULES[@]}"; do
print_output "$(indent "$(green "Enabled module: $MODULE_")")" "no_log"
done
export USE_DOCKER=1
fi
Loading