From 70d34cfaaf74940ac36746fba3f965fc58f06a05 Mon Sep 17 00:00:00 2001 From: BenediktMKuehne Date: Wed, 19 Feb 2025 17:03:51 +0000 Subject: [PATCH] make all modules available --- embark/embark/helper.py | 61 ++++++++++++----- embark/embark/settings/dev.py | 104 ++++++++++++++++++++++++++++- embark/uploader/boundedexecutor.py | 21 ++++-- embark/uploader/forms.py | 44 +----------- embark/uploader/models.py | 4 +- 5 files changed, 165 insertions(+), 69 deletions(-) diff --git a/embark/embark/helper.py b/embark/embark/helper.py index 0f6e818a..765e7f2b 100644 --- a/embark/embark/helper.py +++ b/embark/embark/helper.py @@ -63,21 +63,48 @@ def cleanup_charfield(charfield) -> str: return charfield -def count_emba_modules(emba_dir_path): - s_module_cnt, p_module_cnt, q_module_cnt, l_module_cnt, f_module_cnt, d_module_cnt = 0, 0, 0, 0, 0, 0 +def get_emba_modules(emba_dir_path) -> dict: + """ + { + S_Modules: [ + ('s02', 'S02_UEFI_FwHunt'), + ... + ], + P_modules : [...] + } + """ + module_dict = { + "S_Modules": [], + "P_Modules": [], + "Q_Modules": [], + "L_Modules": [], + "F_Modules": [], + "D_Modules": [], + } for mod_file_ in os.listdir(f"{emba_dir_path}/modules"): - if mod_file_.startswith('S'): - s_module_cnt += 1 - elif mod_file_.startswith('P'): - p_module_cnt += 1 - elif mod_file_.startswith('F'): - f_module_cnt += 1 - elif mod_file_.startswith('L'): - l_module_cnt += 1 - elif mod_file_.startswith('Q'): - q_module_cnt += 1 - elif mod_file_.startswith('D'): - d_module_cnt += 1 + if os.path.isfile(os.path.join(f"{emba_dir_path}/modules", mod_file_)): + if mod_file_.startswith('S'): + module_dict["S_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + elif mod_file_.startswith('P'): + module_dict["P_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + elif mod_file_.startswith('F'): + module_dict["F_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + elif mod_file_.startswith('L'): + module_dict["L_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + elif mod_file_.startswith('Q'): + module_dict["Q_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + elif mod_file_.startswith('D'): + module_dict["D_Modules"].append((str(mod_file_.split("_",1)[0]).lower(),str(mod_file_)[:-3])) + return module_dict + + +def count_emba_modules(module_dict): + s_module_cnt = len(module_dict["S_Modules"]) + p_module_cnt = len(module_dict["P_Modules"]) + q_module_cnt = len(module_dict["Q_Modules"]) + l_module_cnt = len(module_dict["L_Modules"]) + f_module_cnt = len(module_dict["F_Modules"]) + d_module_cnt = len(module_dict["D_Modules"]) return s_module_cnt, p_module_cnt, q_module_cnt, l_module_cnt, f_module_cnt, d_module_cnt @@ -122,7 +149,9 @@ def user_is_staff(user): if __name__ == '__main__': + import pprint TEST_STRING = 'Linux / v2.6.33.2' print(cleanup_charfield(TEST_STRING)) - - print(count_emba_modules(emba_dir_path="/home/cylox/embark/emba")) + emba_modle_list = get_emba_modules(emba_dir_path="/home/cylox/embark/emba") + print(pprint.pformat(emba_modle_list, indent=1)) + print(count_emba_modules(emba_modle_list)) diff --git a/embark/embark/settings/dev.py b/embark/embark/settings/dev.py index 570ee1ce..45e15461 100644 --- a/embark/embark/settings/dev.py +++ b/embark/embark/settings/dev.py @@ -8,7 +8,7 @@ from dotenv import load_dotenv -from embark.helper import count_emba_modules, get_version_strings +from embark.helper import get_emba_modules, count_emba_modules, get_version_strings # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent.parent @@ -274,8 +274,106 @@ TEMP_DIR = Path("/tmp/") try: - EMBA_S_MOD_CNT, EMBA_P_MOD_CNT, EMBA_Q_MOD_CNT, EMBA_L_MOD_CNT, EMBA_F_MOD_CNT, EMBA_D_MOD_CNT = count_emba_modules(EMBA_ROOT) + EMBA_MODULE_DICT = get_emba_modules(EMBA_ROOT) except FileNotFoundError as file_error: - EMBA_S_MOD_CNT, EMBA_P_MOD_CNT, EMBA_Q_MOD_CNT, EMBA_L_MOD_CNT, EMBA_F_MOD_CNT, EMBA_D_MOD_CNT = 46, 20, 1, 10, 6, 3 + EMBA_MODULE_DICT = { + 'D_Modules': [ + ('d10', 'D10_firmware_diffing'), + ('d02', 'D02_firmware_diffing_bin_details'), + ('d05', 'D05_firmware_diffing_extractor') + ], + 'F_Modules': [ + ('f02', 'F02_toolchain'), + ('f50', 'F50_base_aggregator'), + ('f15', 'F15_cyclonedx_sbom'), + ('f05', 'F05_qs_resolver'), + ('f10', 'F10_license_summary'), + ('f20', 'F20_vul_aggregator') + ], + 'L_Modules': [ + ('l99', 'L99_cleanup'), + ('l35', 'L35_metasploit_check'), + ('l10', 'L10_system_emulation'), + ('l23', 'L23_vnc_checks'), + ('l25', 'L25_web_checks'), + ('l20', 'L20_snmp_checks'), + ('l22', 'L22_upnp_hnap_checks'), + ('l15', 'L15_emulated_checks_nmap') + ], + 'P_Modules': [ + ('p15', 'P15_ubi_extractor'), + ('p60', 'P60_deep_extractor'), + ('p02', 'P02_firmware_bin_file_check'), + ('p35', 'P35_UEFI_extractor'), + ('p14', 'P14_ext_mounter'), + ('p07', 'P07_windows_exe_extract'), + ('p25', 'P25_android_ota'), + ('p18', 'P18_BMC_decryptor'), + ('p99', 'P99_prepare_analyzer'), + ('p50', 'P50_binwalk_extractor'), + ('p20', 'P20_foscam_decryptor'), + ('p40', 'P40_DJI_extractor'), + ('p22', 'P22_Zyxel_zip_decrypt'), + ('p17', 'P17_gpg_decompress'), + ('p65', 'P65_package_extractor'), + ('p21', 'P21_buffalo_decryptor'), + ('p19', 'P19_bsd_ufs_mounter'), + ('p23', 'P23_qemu_qcow_mounter'), + ('p55', 'P55_unblob_extractor'), + ('p10', 'P10_vmdk_extractor') + ], + 'Q_Modules': [('q02', 'Q02_openai_question')], + 'S_Modules': [ + ('s100', 'S100_command_inj_check'), + ('s99', 'S99_grepit'), + ('s90', 'S90_mail_check'), + ('s03', 'S03_firmware_bin_base_analyzer'), + ('s20', 'S20_shell_check'), + ('s02', 'S02_UEFI_FwHunt'), + ('s45', 'S45_pass_file_check'), + ('s12', 'S12_binary_protection'), + ('s23', 'S23_lua_check'), + ('s110', 'S110_yara_check'), + ('s60', 'S60_cert_file_check'), + ('s35', 'S35_http_file_check'), + ('s24', 'S24_kernel_bin_identifier'), + ('s16', 'S16_ghidra_decompile_checks'), + ('s50', 'S50_authentication_check'), + ('s108', 'S108_stacs_password_search'), + ('s21', 'S21_python_check'), + ('s109', 'S109_jtr_local_pw_cracking'), + ('s17', 'S17_cwe_checker'), + ('s25', 'S25_kernel_check'), + ('s09', 'S09_firmware_base_version_check'), + ('s65', 'S65_config_file_check'), + ('s18', 'S18_capa_checker'), + ('s36', 'S36_lighttpd'), + ('s05', 'S05_firmware_details'), + ('s115', 'S115_usermode_emulator'), + ('s55', 'S55_history_file_check'), + ('s27', 'S27_perl_check'), + ('s80', 'S80_cronjob_check'), + ('s19', 'S19_apk_check'), + ('s95', 'S95_interesting_files_check'), + ('s75', 'S75_network_check'), + ('s106', 'S106_deep_key_search'), + ('s107', 'S107_deep_password_search'), + ('s15', 'S15_radare_decompile_checks'), + ('s07', 'S07_bootloader_check'), + ('s22', 'S22_php_check'), + ('s26', 'S26_kernel_vuln_verifier'), + ('s85', 'S85_ssh_check'), + ('s10', 'S10_binaries_basic_check'), + ('s13', 'S13_weak_func_check'), + ('s08', 'S08_main_package_sbom'), + ('s40', 'S40_weak_perm_check'), + ('s118', 'S118_busybox_verifier'), + ('s14', 'S14_weak_func_radare_check'), + ('s116', 'S116_qemu_version_detection'), + ('s04', 'S04_windows_basic_analysis'), + ('s06', 'S06_distribution_identification') + ] + } +EMBA_S_MOD_CNT, EMBA_P_MOD_CNT, EMBA_Q_MOD_CNT, EMBA_L_MOD_CNT, EMBA_F_MOD_CNT, EMBA_D_MOD_CNT = count_emba_modules(EMBA_MODULE_DICT) VERSION = get_version_strings() diff --git a/embark/uploader/boundedexecutor.py b/embark/uploader/boundedexecutor.py index 54c1a829..0cec38c6 100644 --- a/embark/uploader/boundedexecutor.py +++ b/embark/uploader/boundedexecutor.py @@ -44,8 +44,8 @@ # create semaphore to track queue state semaphore = BoundedSemaphore(MAX_QUEUE) -# emba directories -EMBA_SCRIPT_LOCATION = f"cd {settings.EMBA_ROOT} && sudo ./emba" +# emba command +EMBA_BASE_CMD = f"DISABLE_STATUS_BAR=1 DISABLE_NOTIFICATIONS=1 HTML=1 FORMAT_LOG=1 sudo --preserve-env {settings.EMBA_ROOT}/emba" class BoundedException(Exception): @@ -218,9 +218,6 @@ def submit_firmware(cls, firmware_flags, firmware_file): shutil.rmtree(active_analyzer_dir) return None - # get emba flags from command parser - emba_flags = firmware_flags.get_flags() - # evaluate meta information and safely create log dir emba_log_location = f"{settings.EMBA_LOG_ROOT}/{firmware_flags.id}/emba_logs" @@ -232,11 +229,23 @@ def submit_firmware(cls, firmware_flags, firmware_file): firmware_flags.status["firmware_name"] = firmware_flags.firmware_name firmware_flags.save(update_fields=["status", "path_to_logs"]) + # get emba flags from command parser + emba_flags = firmware_flags.get_flags() + if firmware_flags.sbom_only_test is True: scan_profile = "./scan-profiles/default-sbom.emba" + elif firmware_flags.system_emulation_test is True or firmware_flags.user_emulation_test is True: # if any expert fields are active + scan_profile = None else: scan_profile = "./scan-profiles/default-scan-no-notify.emba" - emba_cmd = f"{EMBA_SCRIPT_LOCATION} -p {scan_profile} -f {image_file_location} -l {emba_log_location} {emba_flags}" + + # building EMBA command + emba_cmd = f"cd {settings.EMBA_ROOT} && {EMBA_BASE_CMD} -f {image_file_location} -l {emba_log_location}" + + if scan_profile: + emba_cmd += f"-p {scan_profile} " + + emba_cmd += f"{emba_flags}" # submit command to executor threadpool emba_fut = BoundedExecutor.submit(cls.run_emba_cmd, emba_cmd, firmware_flags.id, active_analyzer_dir) diff --git a/embark/uploader/forms.py b/embark/uploader/forms.py index b9e27634..c14c6cf9 100644 --- a/embark/uploader/forms.py +++ b/embark/uploader/forms.py @@ -4,6 +4,8 @@ __license__ = 'MIT' import logging + +from django.conf import settings from django import forms from uploader import models @@ -45,47 +47,7 @@ def clean(self): class FirmwareAnalysisForm(forms.ModelForm): - MODULE_CHOICES = [ - ('s02', 'S02_UEFI_FwHunt'), - ('s03', 'S03_firmware_bin_base_analyzer'), - ('s05', 'S05_firmware_details'), - ('s06', 'S06_distribution_identification'), - ('s08', 'S08_package_mgmt_extractor'), - ('s09', 'S09_firmware_base_version_check'), - ('s10', 'S10_binaries_basic_check'), - ('s12', 'S12_binary_protection'), - ('s13', 'S13_weak_func_check'), - ('s14', 'S14_weak_func_radare_check'), - ('s15', 'S15_bootloader_check'), - ('s20', 'S20_shell_check'), - ('s21', 'S21_python_check'), - ('s22', 'S22_php_check'), - ('s24', 'S24_kernel_bin_identifier'), - ('s25', 'S25_kernel_check'), - ('s35', 'S35_http_file_check'), - ('s40', 'S40_weak_perm_check'), - ('s45', 'S45_pass_file_check'), - ('s50', 'S50_authentication_check'), - ('s55', 'S55_history_file_check'), - ('s60', 'S60_cert_file_check'), - ('s65', 'S65_config_file_check'), - ('s70', 'S70_hidden_file_check'), - ('s75', 'S75_network_check'), - ('s80', 'S80_cronjob_check'), - ('s85', 'S85_ssh_check'), - ('s90', 'S90_mail_check'), - ('s95', 'S95_interesting_binaries_check'), - ('s99', 'S99_grepit'), - ('s100', 'S100_command_inj_check'), - ('s106', 'S106_deep_key_search'), - ('s107', 'S107_deep_password_search'), - ('s108', 'S108_stacs_password_search'), - ('s109', 'S109_jtr_local_pw_cracking'), - ('s110', 'S110_yara_check'), - ('s115', 'S115_usermode_emulator'), - ('s116', 'S116_qemu_version_detection'), - ('s120', 'S120_cwe_checker') - ] + MODULE_CHOICES = settings.EMBA_MODULE_DICT['F_Modules'] + settings.EMBA_MODULE_DICT['L_Modules'] + settings.EMBA_MODULE_DICT['P_Modules'] + settings.EMBA_MODULE_DICT['S_Modules'] + settings.EMBA_MODULE_DICT['Q_Modules'] scan_modules = forms.MultipleChoiceField(choices=MODULE_CHOICES, help_text='Enable/disable specific scan-modules for your analysis', widget=forms.CheckboxSelectMultiple, required=False) class Meta: diff --git a/embark/uploader/models.py b/embark/uploader/models.py index c05b4637..dd5a7717 100644 --- a/embark/uploader/models.py +++ b/embark/uploader/models.py @@ -274,13 +274,11 @@ class Firmware help_text='Architecture of the linux firmware [MIPS, ARM, x86, x64, PPC, NIOS2] -a will be added (note: other options are not in use yet)', max_length=MAX_LENGTH, blank=True, expert_mode=True ) - - # expertmode options user_emulation_test = BooleanFieldExpertMode(help_text='Enables automated qemu emulation tests', default=False, expert_mode=True, blank=True) system_emulation_test = BooleanFieldExpertMode(help_text='Enables automated qemu system emulation tests', default=False, expert_mode=True, blank=True) # SBOM mode option - sbom_only_test = models.BooleanField(verbose_name='SBOM only test', help_text='Enables SBOM tests', default=False, blank=True) + sbom_only_test = models.BooleanField(verbose_name='SBOM only test', help_text='Enables SBOM default-profile', default=False, blank=True) # S-modules scan_modules = models.JSONField(blank=True, null=True, default=scan_modules_default_value)