diff --git a/envs/monkey_zoo/blackbox/config_templates/grouped/depth_1_a.py b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_1_a.py new file mode 100644 index 000000000..b09123566 --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_1_a.py @@ -0,0 +1,42 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Depth1A(ConfigTemplate): + config_values = copy(BaseTemplate.config_values) + # Tests: + # Hadoop (10.2.2.2, 10.2.2.3) + # Log4shell (10.2.3.55, 10.2.3.56, 10.2.3.49, 10.2.3.50, 10.2.3.51, 10.2.3.52) + # MSSQL (10.2.2.16) + # SMB mimikatz password stealing and brute force (10.2.2.14 and 10.2.2.15) + config_values.update( + { + "basic.exploiters.exploiter_classes": [ + "HadoopExploiter", + "Log4ShellExploiter", + "MSSQLExploiter", + "SmbExploiter", + "SSHExploiter", + ], + "basic_network.scope.subnet_scan_list": [ + "10.2.2.2", + "10.2.2.3", + "10.2.3.55", + "10.2.3.56", + "10.2.3.49", + "10.2.3.50", + "10.2.3.51", + "10.2.3.52", + "10.2.2.16", + "10.2.2.14", + "10.2.2.15", + ], + "basic.credentials.exploit_password_list": ["Ivrrw5zEzs", "Xk8VDTsC"], + "basic.credentials.exploit_user_list": ["m0nk3y"], + "monkey.system_info.system_info_collector_classes": [ + "MimikatzCollector", + ], + } + ) diff --git a/envs/monkey_zoo/blackbox/config_templates/grouped/depth_2_a.py b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_2_a.py new file mode 100644 index 000000000..d9f5168e2 --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_2_a.py @@ -0,0 +1,23 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Depth2A(ConfigTemplate): + config_values = copy(BaseTemplate.config_values) + # SSH password and key brute-force, key stealing (10.2.2.11, 10.2.2.12) + config_values.update( + { + "basic.exploiters.exploiter_classes": [ + "SSHExploiter", + ], + "basic_network.scope.subnet_scan_list": [ + "10.2.2.11", + "10.2.2.12", + ], + "basic_network.scope.depth": 2, + "basic.credentials.exploit_password_list": ["^NgDvY59~8"], + "basic.credentials.exploit_user_list": ["m0nk3y"], + } + ) diff --git a/envs/monkey_zoo/blackbox/config_templates/grouped/depth_3_a.py b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_3_a.py new file mode 100644 index 000000000..6d5261d95 --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/grouped/depth_3_a.py @@ -0,0 +1,48 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Depth3A(ConfigTemplate): + config_values = copy(BaseTemplate.config_values) + + # Tests: + # Powershell (10.2.3.45, 10.2.3.46, 10.2.3.47, 10.2.3.48) + # Tunneling (SSH brute force) (10.2.2.9, 10.2.1.10, 10.2.0.12, 10.2.0.11) + # WMI pass the hash (10.2.2.15) + config_values.update( + { + "basic.exploiters.exploiter_classes": [ + "PowerShellExploiter", + "SSHExploiter", + "WmiExploiter", + ], + "basic_network.scope.subnet_scan_list": [ + "10.2.3.45", + "10.2.3.46", + "10.2.3.47", + "10.2.3.48", + "10.2.2.9", + "10.2.1.10", + "10.2.0.12", + "10.2.0.11", + "10.2.2.15", + ], + "basic.credentials.exploit_password_list": [ + "Passw0rd!", + "3Q=(Ge(+&w]*", + "`))jU7L(w}", + "t67TC5ZDmz", + ], + "basic_network.scope.depth": 3, + "internal.general.keep_tunnel_open_time": 20, + "basic.credentials.exploit_user_list": ["m0nk3y", "m0nk3y-user"], + "internal.network.tcp_scanner.HTTP_PORTS": [], + "internal.exploits.exploit_ntlm_hash_list": [ + "d0f0132b308a0c4e5d1029cc06f48692", + "5da0889ea2081aa79f6852294cba4a5e", + "50c9987a6bf1ac59398df9f911122c9b", + ], + } + ) diff --git a/envs/monkey_zoo/blackbox/config_templates/single_tests/__init__.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/config_templates/hadoop.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/hadoop.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/hadoop.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/hadoop.py diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_logstash.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_logstash.py diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_solr.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/log4j_solr.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_solr.py diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_tomcat.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/log4j_tomcat.py diff --git a/envs/monkey_zoo/blackbox/config_templates/mssql.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/mssql.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/mssql.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/mssql.py diff --git a/envs/monkey_zoo/blackbox/config_templates/performance.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/performance.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/performance.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/performance.py diff --git a/envs/monkey_zoo/blackbox/config_templates/powershell.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/powershell.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/powershell.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/powershell.py diff --git a/envs/monkey_zoo/blackbox/config_templates/powershell_credentials_reuse.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/powershell_credentials_reuse.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/powershell_credentials_reuse.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/powershell_credentials_reuse.py diff --git a/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/smb_mimikatz.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/smb_mimikatz.py diff --git a/envs/monkey_zoo/blackbox/config_templates/smb_pth.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/smb_pth.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/smb_pth.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/smb_pth.py diff --git a/envs/monkey_zoo/blackbox/config_templates/ssh.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/ssh.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/ssh.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/ssh.py diff --git a/envs/monkey_zoo/blackbox/config_templates/tunneling.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/tunneling.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/tunneling.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/tunneling.py diff --git a/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/wmi_mimikatz.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/wmi_mimikatz.py diff --git a/envs/monkey_zoo/blackbox/config_templates/wmi_pth.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/wmi_pth.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/wmi_pth.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/wmi_pth.py diff --git a/envs/monkey_zoo/blackbox/config_templates/zerologon.py b/envs/monkey_zoo/blackbox/config_templates/single_tests/zerologon.py similarity index 100% rename from envs/monkey_zoo/blackbox/config_templates/zerologon.py rename to envs/monkey_zoo/blackbox/config_templates/single_tests/zerologon.py diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 31cbdd379..0a234e991 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -8,39 +8,20 @@ from typing_extensions import Type from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZerologonAnalyzer from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate -from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop -from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash -from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr -from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat -from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql -from envs.monkey_zoo.blackbox.config_templates.performance import Performance -from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell -from envs.monkey_zoo.blackbox.config_templates.powershell_credentials_reuse import ( +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_1_a import Depth1A +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_2_a import Depth2A +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_3_a import Depth3A +from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import ( PowerShellCredentialsReuse, ) -from envs.monkey_zoo.blackbox.config_templates.smb_mimikatz import SmbMimikatz -from envs.monkey_zoo.blackbox.config_templates.smb_pth import SmbPth -from envs.monkey_zoo.blackbox.config_templates.ssh import Ssh -from envs.monkey_zoo.blackbox.config_templates.tunneling import Tunneling -from envs.monkey_zoo.blackbox.config_templates.wmi_mimikatz import WmiMimikatz -from envs.monkey_zoo.blackbox.config_templates.wmi_pth import WmiPth -from envs.monkey_zoo.blackbox.config_templates.zerologon import Zerologon +from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth +from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz +from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon from envs.monkey_zoo.blackbox.gcp_test_machine_list import GCP_TEST_MACHINE_LIST from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest -from envs.monkey_zoo.blackbox.tests.performance.map_generation import MapGenerationTest -from envs.monkey_zoo.blackbox.tests.performance.map_generation_from_telemetries import ( - MapGenerationFromTelemetryTest, -) -from envs.monkey_zoo.blackbox.tests.performance.report_generation import ReportGenerationTest -from envs.monkey_zoo.blackbox.tests.performance.report_generation_from_telemetries import ( - ReportGenerationFromTelemetryTest, -) -from envs.monkey_zoo.blackbox.tests.performance.telemetry_performance_test import ( - TelemetryPerformanceTest, -) from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import ( initialize_gcp_client, start_machines, @@ -48,7 +29,7 @@ from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import ( ) from monkey_island.cc.services.mode.mode_enum import IslandModeEnum -DEFAULT_TIMEOUT_SECONDS = 2 * 60 +DEFAULT_TIMEOUT_SECONDS = 2 * 60 + 30 MACHINE_BOOTUP_WAIT_SECONDS = 30 LOG_DIR_PATH = "./logs" logging.basicConfig(level=logging.INFO) @@ -125,48 +106,20 @@ class TestMonkeyBlackbox: log_handler=log_handler, ).run() - @staticmethod - def run_performance_test( - performance_test_class, - island_client, - config_template, - timeout_in_seconds, - break_on_timeout=False, - ): - raw_config = IslandConfigParser.get_raw_config(config_template, island_client) - log_handler = TestLogsHandler( - performance_test_class.TEST_NAME, island_client, TestMonkeyBlackbox.get_log_dir_path() - ) - analyzers = [ - CommunicationAnalyzer(island_client, IslandConfigParser.get_ips_of_targets(raw_config)) - ] - performance_test_class( - island_client=island_client, - raw_config=raw_config, - analyzers=analyzers, - timeout=timeout_in_seconds, - log_handler=log_handler, - break_on_timeout=break_on_timeout, - ).run() - @staticmethod def get_log_dir_path(): return os.path.abspath(LOG_DIR_PATH) - def test_ssh_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, Ssh, "SSH_exploiter_and_keys") + def test_depth_1_a(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Depth1A, "Depth1A test suite") - def test_hadoop_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, Hadoop, "Hadoop_exploiter", 6 * 60) + def test_depth_2_a(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Depth2A, "Depth2A test suite") - def test_mssql_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, Mssql, "MSSQL_exploiter") - - def test_powershell_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, PowerShell, "PowerShell_Remoting_exploiter" - ) + def test_depth_3_a(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Depth3A, "Depth3A test suite") + # Not grouped because can only be ran on windows @pytest.mark.skip_powershell_reuse def test_powershell_exploiter_credentials_reuse(self, island_client): TestMonkeyBlackbox.run_exploitation_test( @@ -175,42 +128,7 @@ class TestMonkeyBlackbox: "PowerShell_Remoting_exploiter_credentials_reuse", ) - def test_smb_and_mimikatz_exploiters(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, SmbMimikatz, "SMB_exploiter_mimikatz" - ) - - def test_smb_pth(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH") - - def test_log4j_solr_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, Log4jSolr, "Log4Shell_Solr_exploiter" - ) - - def test_log4j_tomcat_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter" - ) - - def test_log4j_logstash_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, Log4jLogstash, "Log4Shell_logstash_exploiter" - ) - - def test_tunneling(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, Tunneling, "Tunneling_exploiter", 3 * 60 - ) - - def test_wmi_and_mimikatz_exploiters(self, island_client): - TestMonkeyBlackbox.run_exploitation_test( - island_client, WmiMimikatz, "WMI_exploiter,_mimikatz" - ) - - def test_wmi_pth(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH") - + # Not grouped because it's slow def test_zerologon_exploiter(self, island_client): test_name = "Zerologon_exploiter" expected_creds = [ @@ -235,47 +153,13 @@ class TestMonkeyBlackbox: log_handler=log_handler, ).run() - @pytest.mark.skip( - reason="Perfomance test that creates env from fake telemetries is faster, use that instead." - ) - def test_report_generation_performance(self, island_client, quick_performance_tests): - """ - This test includes the SSH + Hadoop + MSSQL machines all in one test - for a total of 8 machines including the Monkey Island. + # Not grouped because conflicts with SMB. + # Consider grouping when more depth 1 exploiters collide with group depth_1_a + def test_wmi_and_mimikatz_exploiters(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, WmiMimikatz, "WMI_exploiter,_mimikatz" + ) - Is has 2 analyzers - the regular one which checks all the Monkeys - and the Timing one which checks how long the report took to execute - """ - if not quick_performance_tests: - TestMonkeyBlackbox.run_performance_test( - ReportGenerationTest, island_client, Performance, timeout_in_seconds=10 * 60 - ) - else: - LOGGER.error("This test doesn't support 'quick_performance_tests' option.") - assert False - - @pytest.mark.skip( - reason="Perfomance test that creates env from fake telemetries is faster, use that instead." - ) - def test_map_generation_performance(self, island_client, quick_performance_tests): - if not quick_performance_tests: - TestMonkeyBlackbox.run_performance_test( - MapGenerationTest, island_client, "PERFORMANCE.conf", timeout_in_seconds=10 * 60 - ) - else: - LOGGER.error("This test doesn't support 'quick_performance_tests' option.") - assert False - - @pytest.mark.run_performance_tests - def test_report_generation_from_fake_telemetries(self, island_client, quick_performance_tests): - ReportGenerationFromTelemetryTest(island_client, quick_performance_tests).run() - - @pytest.mark.run_performance_tests - def test_map_generation_from_fake_telemetries(self, island_client, quick_performance_tests): - MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run() - - @pytest.mark.run_performance_tests - def test_telem_performance(self, island_client, quick_performance_tests): - TelemetryPerformanceTest( - island_client, quick_performance_tests - ).test_telemetry_performance() + # Not grouped because it's depth 1 but conflicts with SMB exploiter in group depth_1_a + def test_smb_pth(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH") diff --git a/envs/monkey_zoo/blackbox/test_blackbox_in_depth.py b/envs/monkey_zoo/blackbox/test_blackbox_in_depth.py new file mode 100644 index 000000000..42d2e28b7 --- /dev/null +++ b/envs/monkey_zoo/blackbox/test_blackbox_in_depth.py @@ -0,0 +1,296 @@ +import logging +import os +from time import sleep + +import pytest +from typing_extensions import Type + +from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer +from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZerologonAnalyzer +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate +from envs.monkey_zoo.blackbox.config_templates.single_tests.drupal import Drupal +from envs.monkey_zoo.blackbox.config_templates.single_tests.hadoop import Hadoop +from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_logstash import Log4jLogstash +from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_solr import Log4jSolr +from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_tomcat import Log4jTomcat +from envs.monkey_zoo.blackbox.config_templates.single_tests.mssql import Mssql +from envs.monkey_zoo.blackbox.config_templates.single_tests.performance import Performance +from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell import PowerShell +from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import ( + PowerShellCredentialsReuse, +) +from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_mimikatz import SmbMimikatz +from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth +from envs.monkey_zoo.blackbox.config_templates.single_tests.ssh import Ssh +from envs.monkey_zoo.blackbox.config_templates.single_tests.struts2 import Struts2 +from envs.monkey_zoo.blackbox.config_templates.single_tests.tunneling import Tunneling +from envs.monkey_zoo.blackbox.config_templates.single_tests.weblogic import Weblogic +from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz +from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_pth import WmiPth +from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon +from envs.monkey_zoo.blackbox.gcp_test_machine_list import GCP_TEST_MACHINE_LIST +from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser +from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient +from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler +from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest +from envs.monkey_zoo.blackbox.tests.performance.map_generation import MapGenerationTest +from envs.monkey_zoo.blackbox.tests.performance.map_generation_from_telemetries import ( + MapGenerationFromTelemetryTest, +) +from envs.monkey_zoo.blackbox.tests.performance.report_generation import ReportGenerationTest +from envs.monkey_zoo.blackbox.tests.performance.report_generation_from_telemetries import ( + ReportGenerationFromTelemetryTest, +) +from envs.monkey_zoo.blackbox.tests.performance.telemetry_performance_test import ( + TelemetryPerformanceTest, +) +from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import ( + initialize_gcp_client, + start_machines, + stop_machines, +) +from monkey_island.cc.services.mode.mode_enum import IslandModeEnum + +DEFAULT_TIMEOUT_SECONDS = 2 * 60 +MACHINE_BOOTUP_WAIT_SECONDS = 30 +LOG_DIR_PATH = "./logs" +logging.basicConfig(level=logging.INFO) +LOGGER = logging.getLogger(__name__) + + +@pytest.fixture(autouse=True, scope="session") +def GCPHandler(request, no_gcp): + if not no_gcp: + try: + initialize_gcp_client() + start_machines(GCP_TEST_MACHINE_LIST) + except Exception as e: + LOGGER.error("GCP Handler failed to initialize: %s." % e) + pytest.exit("Encountered an error while starting GCP machines. Stopping the tests.") + wait_machine_bootup() + + def fin(): + stop_machines(GCP_TEST_MACHINE_LIST) + + request.addfinalizer(fin) + + +@pytest.fixture(autouse=True, scope="session") +def delete_logs(): + LOGGER.info("Deleting monkey logs before new tests.") + TestLogsHandler.delete_log_folder_contents(TestMonkeyBlackbox.get_log_dir_path()) + + +def wait_machine_bootup(): + sleep(MACHINE_BOOTUP_WAIT_SECONDS) + + +@pytest.fixture(scope="class") +def island_client(island, quick_performance_tests): + client_established = False + try: + island_client_object = MonkeyIslandClient(island) + client_established = island_client_object.get_api_status() + except Exception: + logging.exception("Got an exception while trying to establish connection to the Island.") + finally: + if not client_established: + pytest.exit("BB tests couldn't establish communication to the island.") + if not quick_performance_tests: + island_client_object.reset_env() + island_client_object.set_scenario(IslandModeEnum.ADVANCED.value) + yield island_client_object + + +@pytest.mark.usefixtures("island_client") +# noinspection PyUnresolvedReferences +class TestMonkeyBlackbox: + @staticmethod + def run_exploitation_test( + island_client: MonkeyIslandClient, + config_template: Type[ConfigTemplate], + test_name: str, + timeout_in_seconds=DEFAULT_TIMEOUT_SECONDS, + ): + raw_config = IslandConfigParser.get_raw_config(config_template, island_client) + analyzer = CommunicationAnalyzer( + island_client, IslandConfigParser.get_ips_of_targets(raw_config) + ) + log_handler = TestLogsHandler( + test_name, island_client, TestMonkeyBlackbox.get_log_dir_path() + ) + ExploitationTest( + name=test_name, + island_client=island_client, + raw_config=raw_config, + analyzers=[analyzer], + timeout=timeout_in_seconds, + log_handler=log_handler, + ).run() + + @staticmethod + def run_performance_test( + performance_test_class, + island_client, + config_template, + timeout_in_seconds, + break_on_timeout=False, + ): + raw_config = IslandConfigParser.get_raw_config(config_template, island_client) + log_handler = TestLogsHandler( + performance_test_class.TEST_NAME, island_client, TestMonkeyBlackbox.get_log_dir_path() + ) + analyzers = [ + CommunicationAnalyzer(island_client, IslandConfigParser.get_ips_of_targets(raw_config)) + ] + performance_test_class( + island_client=island_client, + raw_config=raw_config, + analyzers=analyzers, + timeout=timeout_in_seconds, + log_handler=log_handler, + break_on_timeout=break_on_timeout, + ).run() + + @staticmethod + def get_log_dir_path(): + return os.path.abspath(LOG_DIR_PATH) + + def test_ssh_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Ssh, "SSH_exploiter_and_keys") + + def test_hadoop_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Hadoop, "Hadoop_exploiter", 6 * 60) + + def test_mssql_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Mssql, "MSSQL_exploiter") + + def test_powershell_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, PowerShell, "PowerShell_Remoting_exploiter" + ) + + @pytest.mark.skip_powershell_reuse + def test_powershell_exploiter_credentials_reuse(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, + PowerShellCredentialsReuse, + "PowerShell_Remoting_exploiter_credentials_reuse", + ) + + def test_smb_and_mimikatz_exploiters(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, SmbMimikatz, "SMB_exploiter_mimikatz" + ) + + def test_smb_pth(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH") + + @pytest.mark.skip(reason="Drupal exploiter is deprecated") + def test_drupal_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Drupal, "Drupal_exploiter") + + @pytest.mark.skip(reason="Struts2 exploiter is deprecated") + def test_struts_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Struts2, "Struts2_exploiter") + + @pytest.mark.skip(reason="Weblogic exploiter is deprecated") + def test_weblogic_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, Weblogic, "Weblogic_exploiter") + + def test_log4j_solr_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jSolr, "Log4Shell_Solr_exploiter" + ) + + def test_log4j_tomcat_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter" + ) + + def test_log4j_logstash_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jLogstash, "Log4Shell_logstash_exploiter" + ) + + def test_tunneling(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Tunneling, "Tunneling_exploiter", 3 * 60 + ) + + def test_wmi_and_mimikatz_exploiters(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, WmiMimikatz, "WMI_exploiter,_mimikatz" + ) + + def test_wmi_pth(self, island_client): + TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH") + + def test_zerologon_exploiter(self, island_client): + test_name = "Zerologon_exploiter" + expected_creds = [ + "Administrator", + "aad3b435b51404eeaad3b435b51404ee", + "2864b62ea4496934a5d6e86f50b834a5", + ] + raw_config = IslandConfigParser.get_raw_config(Zerologon, island_client) + zero_logon_analyzer = ZerologonAnalyzer(island_client, expected_creds) + communication_analyzer = CommunicationAnalyzer( + island_client, IslandConfigParser.get_ips_of_targets(raw_config) + ) + log_handler = TestLogsHandler( + test_name, island_client, TestMonkeyBlackbox.get_log_dir_path() + ) + ExploitationTest( + name=test_name, + island_client=island_client, + raw_config=raw_config, + analyzers=[zero_logon_analyzer, communication_analyzer], + timeout=DEFAULT_TIMEOUT_SECONDS, + log_handler=log_handler, + ).run() + + @pytest.mark.skip( + reason="Perfomance test that creates env from fake telemetries is faster, use that instead." + ) + def test_report_generation_performance(self, island_client, quick_performance_tests): + """ + This test includes the SSH + Hadoop + MSSQL machines all in one test + for a total of 8 machines including the Monkey Island. + + Is has 2 analyzers - the regular one which checks all the Monkeys + and the Timing one which checks how long the report took to execute + """ + if not quick_performance_tests: + TestMonkeyBlackbox.run_performance_test( + ReportGenerationTest, island_client, Performance, timeout_in_seconds=10 * 60 + ) + else: + LOGGER.error("This test doesn't support 'quick_performance_tests' option.") + assert False + + @pytest.mark.skip( + reason="Perfomance test that creates env from fake telemetries is faster, use that instead." + ) + def test_map_generation_performance(self, island_client, quick_performance_tests): + if not quick_performance_tests: + TestMonkeyBlackbox.run_performance_test( + MapGenerationTest, island_client, "PERFORMANCE.conf", timeout_in_seconds=10 * 60 + ) + else: + LOGGER.error("This test doesn't support 'quick_performance_tests' option.") + assert False + + @pytest.mark.run_performance_tests + def test_report_generation_from_fake_telemetries(self, island_client, quick_performance_tests): + ReportGenerationFromTelemetryTest(island_client, quick_performance_tests).run() + + @pytest.mark.run_performance_tests + def test_map_generation_from_fake_telemetries(self, island_client, quick_performance_tests): + MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run() + + @pytest.mark.run_performance_tests + def test_telem_performance(self, island_client, quick_performance_tests): + TelemetryPerformanceTest( + island_client, quick_performance_tests + ).test_telemetry_performance() diff --git a/envs/monkey_zoo/blackbox/tests/exploitation.py b/envs/monkey_zoo/blackbox/tests/exploitation.py index 15ad409eb..f439e11db 100644 --- a/envs/monkey_zoo/blackbox/tests/exploitation.py +++ b/envs/monkey_zoo/blackbox/tests/exploitation.py @@ -5,7 +5,7 @@ from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandCo from envs.monkey_zoo.blackbox.tests.basic_test import BasicTest from envs.monkey_zoo.blackbox.utils.test_timer import TestTimer -MAX_TIME_FOR_MONKEYS_TO_DIE = 5 * 60 +MAX_TIME_FOR_MONKEYS_TO_DIE = 2 * 60 WAIT_TIME_BETWEEN_REQUESTS = 1 TIME_FOR_MONKEY_PROCESS_TO_FINISH = 5 DELAY_BETWEEN_ANALYSIS = 1 @@ -89,6 +89,7 @@ class ExploitationTest(BasicTest): if time_passed > MAX_TIME_FOR_MONKEYS_TO_DIE: LOGGER.error("Some monkeys didn't die after the test, failing") assert False + LOGGER.info(f"After {time_passed} seconds all monkeys have died") def parse_logs(self): LOGGER.info("Parsing test logs:") diff --git a/envs/monkey_zoo/blackbox/utils/config_generation_script.py b/envs/monkey_zoo/blackbox/utils/config_generation_script.py index 76abff669..3a5f06c50 100644 --- a/envs/monkey_zoo/blackbox/utils/config_generation_script.py +++ b/envs/monkey_zoo/blackbox/utils/config_generation_script.py @@ -3,20 +3,15 @@ import pathlib from typing import Type from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate -from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop -from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash -from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr -from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat -from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql -from envs.monkey_zoo.blackbox.config_templates.performance import Performance -from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell -from envs.monkey_zoo.blackbox.config_templates.smb_mimikatz import SmbMimikatz -from envs.monkey_zoo.blackbox.config_templates.smb_pth import SmbPth -from envs.monkey_zoo.blackbox.config_templates.ssh import Ssh -from envs.monkey_zoo.blackbox.config_templates.tunneling import Tunneling -from envs.monkey_zoo.blackbox.config_templates.wmi_mimikatz import WmiMimikatz -from envs.monkey_zoo.blackbox.config_templates.wmi_pth import WmiPth -from envs.monkey_zoo.blackbox.config_templates.zerologon import Zerologon +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_1_a import Depth1A +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_2_a import Depth2A +from envs.monkey_zoo.blackbox.config_templates.grouped.depth_3_a import Depth3A +from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import ( + PowerShellCredentialsReuse, +) +from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth +from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz +from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient @@ -33,22 +28,14 @@ parser.add_argument( args = parser.parse_args() island_client = MonkeyIslandClient(args.island_ip) - CONFIG_TEMPLATES = [ - Hadoop, - Mssql, - Performance, - PowerShell, - SmbMimikatz, - SmbPth, - Ssh, - Tunneling, - WmiMimikatz, - WmiPth, + Depth1A, + Depth2A, + Depth3A, Zerologon, - Log4jLogstash, - Log4jTomcat, - Log4jSolr, + SmbPth, + WmiMimikatz, + PowerShellCredentialsReuse, ] diff --git a/envs/monkey_zoo/docs/fullDocs.md b/envs/monkey_zoo/docs/fullDocs.md index 9d5635255..8499e1bb2 100644 --- a/envs/monkey_zoo/docs/fullDocs.md +++ b/envs/monkey_zoo/docs/fullDocs.md @@ -771,7 +771,9 @@ Accessibale through Island using m0nk3y-user. Notes: User: m0nk3y, Password: Passw0rd!
-Accessiable through cached credentials (Windows Island) +Accessible using the same m0nk3y user from island, in other words powershell exploiter can exploit +this machine without credentials as long as the user running the agent is the same on both +machines diff --git a/monkey/monkey_island/Pipfile b/monkey/monkey_island/Pipfile index 06dd0daef..a29ad0384 100644 --- a/monkey/monkey_island/Pipfile +++ b/monkey/monkey_island/Pipfile @@ -38,6 +38,7 @@ pytest-cov = "*" isort = "==5.10.1" coverage = "*" vulture = "==2.3" +tqdm = "*" # Used in BB tests [requires] python_version = "3.7" diff --git a/monkey/monkey_island/Pipfile.lock b/monkey/monkey_island/Pipfile.lock index 196059612..b1cb4660d 100644 --- a/monkey/monkey_island/Pipfile.lock +++ b/monkey/monkey_island/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "260be37685cd94ec3e28773e82834ee6564462ace9b7b1c9242dcf611e33fd25" + "sha256": "48c3a77a6022276d2607c19ae66490310fa8fa99e07e888b416c181e5ec0b534" }, "pipfile-spec": 6, "requires": { @@ -759,11 +759,11 @@ }, "setuptools": { "hashes": [ - "sha256:425ec0e0014c5bcc1104dd1099de6c8f0584854fc9a4f512575f5ed5ee399fb9", - "sha256:6d59c30ce22dd583b42cacf51eebe4c6ea72febaa648aa8b30e5015d23a191fe" + "sha256:7999cbd87f1b6e1f33bf47efa368b224bed5e27b5ef2c4d46580186cbcb1a86a", + "sha256:a65e3802053e99fc64c6b3b29c11132943d5b8c8facbcc461157511546510967" ], "markers": "python_version >= '3.7'", - "version": "==61.3.0" + "version": "==62.0.0" }, "six": { "hashes": [ @@ -791,11 +791,11 @@ }, "werkzeug": { "hashes": [ - "sha256:094ecfc981948f228b30ee09dbfe250e474823b69b9b1292658301b5894bbf08", - "sha256:9b55466a3e99e13b1f0686a66117d39bda85a992166e0a79aedfcf3586328f7a" + "sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6", + "sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74" ], "index": "pypi", - "version": "==2.1.0" + "version": "==2.1.1" }, "wirerope": { "hashes": [ @@ -805,11 +805,11 @@ }, "zipp": { "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad", + "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099" ], "markers": "python_version >= '3.7'", - "version": "==3.7.0" + "version": "==3.8.0" }, "zope.event": { "hashes": [ @@ -1208,6 +1208,14 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "tqdm": { + "hashes": [ + "sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d", + "sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6" + ], + "index": "pypi", + "version": "==4.64.0" + }, "typed-ast": { "hashes": [ "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e", @@ -1272,11 +1280,11 @@ }, "zipp": { "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad", + "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099" ], "markers": "python_version >= '3.7'", - "version": "==3.7.0" + "version": "==3.8.0" } } }