From 73832bd0cb3de53d11b5886e4111846b8e664fa5 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 7 May 2020 17:12:48 +0300 Subject: [PATCH 01/21] Updated PERFORMANCE.conf to include all machines and a lot of segmentation tests --- .../blackbox/island_configs/PERFORMANCE.conf | 88 ++++++++++++++----- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/envs/monkey_zoo/blackbox/island_configs/PERFORMANCE.conf b/envs/monkey_zoo/blackbox/island_configs/PERFORMANCE.conf index ebe3d8814..23d5ce379 100644 --- a/envs/monkey_zoo/blackbox/island_configs/PERFORMANCE.conf +++ b/envs/monkey_zoo/blackbox/island_configs/PERFORMANCE.conf @@ -2,14 +2,15 @@ "basic": { "credentials": { "exploit_password_list": [ - "Password1!", - "12345678", - "^NgDvY59~8" + "Xk8VDTsC", + "^NgDvY59~8", + "Ivrrw5zEzs", + "3Q=(Ge(+&w]*", + "`))jU7L(w}", + "t67TC5ZDmz" ], "exploit_user_list": [ - "Administrator", - "m0nk3y", - "user" + "m0nk3y" ] }, "general": { @@ -23,11 +24,38 @@ "local_network_scan": false, "subnet_scan_list": [ "10.2.2.2", - "10.2.2.4" + "10.2.2.3", + "10.2.2.4", + "10.2.2.5", + "10.2.2.8", + "10.2.2.9", + "10.2.1.10", + "10.2.0.11", + "10.2.0.12", + "10.2.2.11", + "10.2.2.12", + "10.2.2.14", + "10.2.2.15", + "10.2.2.16", + "10.2.2.18", + "10.2.2.19", + "10.2.2.20", + "10.2.2.21", + "10.2.2.23", + "10.2.2.24" ] }, "network_analysis": { - "inaccessible_subnets": [] + "inaccessible_subnets": [ + "10.2.2.0/30", + "10.2.2.8/30", + "10.2.2.24/32", + "10.2.2.23/32", + "10.2.2.21/32", + "10.2.2.19/32", + "10.2.2.18/32", + "10.2.2.17/32" + ] } }, "cnc": { @@ -45,10 +73,17 @@ "exploits": { "general": { "exploiter_classes": [ + "SmbExploiter", + "WmiExploiter", "SSHExploiter", - "MSSQLExploiter", + "ShellShockExploiter", + "SambaCryExploiter", "ElasticGroovyExploiter", - "HadoopExploiter" + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter", + "MSSQLExploiter" ], "skip_exploit_if_file_exist": false }, @@ -57,9 +92,6 @@ "remote_user_pass": "Password1!", "user_to_add": "Monkey_IUSER_SUPPORT" }, - "rdp_grinder": { - "rdp_use_vbs_download": true - }, "sambacry": { "sambacry_folder_paths_to_guess": [ "/", @@ -109,7 +141,7 @@ "exploit_ssh_keys": [] }, "general": { - "keep_tunnel_open_time": 1, + "keep_tunnel_open_time": 60, "monkey_dir_name": "monkey_dir", "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" }, @@ -123,6 +155,9 @@ "monkey_log_path_linux": "/tmp/user-1563", "monkey_log_path_windows": "%temp%\\~df1563.tmp", "send_log_to_server": true + }, + "testing": { + "export_monkey_telems": true } }, "monkey": { @@ -137,24 +172,32 @@ }, "general": { "alive": true, - "post_breach_actions": [] + "post_breach_actions": [ + "CommunicateAsNewUser" + ] }, "life_cycle": { "max_iterations": 1, "retry_failed_explotation": true, "timeout_between_iterations": 100, - "victims_max_exploit": 7, - "victims_max_find": 30 + "victims_max_exploit": 15, + "victims_max_find": 100 }, "system_info": { "collect_system_info": true, - "extract_azure_creds": false, - "should_use_mimikatz": true + "extract_azure_creds": true, + "should_use_mimikatz": true, + "system_info_collectors_classes": [ + "EnvironmentCollector", + "AwsCollector", + "HostnameCollector", + "ProcessListCollector" + ] } }, "network": { "ping_scanner": { - "ping_scan_timeout": 500 + "ping_scan_timeout": 1000 }, "tcp_scanner": { "HTTP_PORTS": [ @@ -166,7 +209,7 @@ ], "tcp_scan_get_banner": true, "tcp_scan_interval": 0, - "tcp_scan_timeout": 1000, + "tcp_scan_timeout": 3000, "tcp_target_ports": [ 22, 2222, @@ -179,7 +222,8 @@ 8008, 3306, 9200, - 7001 + 7001, + 8088 ] } } From 991cbec7ff9f8ef483d8b7508d3dca6d5568bb5e Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 13 May 2020 10:44:04 +0300 Subject: [PATCH 02/21] Added cmd options to disable interaction with GCP and run quick performance tests. --- envs/monkey_zoo/blackbox/README.md | 8 ++- envs/monkey_zoo/blackbox/conftest.py | 18 +++++- envs/monkey_zoo/blackbox/test_blackbox.py | 61 +++++++++++-------- .../map_generation_from_telemetries.py | 5 +- .../telemetry_performance_test_workflow.py | 9 ++- 5 files changed, 69 insertions(+), 32 deletions(-) diff --git a/envs/monkey_zoo/blackbox/README.md b/envs/monkey_zoo/blackbox/README.md index b31fbdcab..dbdd54b41 100644 --- a/envs/monkey_zoo/blackbox/README.md +++ b/envs/monkey_zoo/blackbox/README.md @@ -10,7 +10,13 @@ In order to execute the entire test suite, you must know the external IP of the this information in the GCP Console `Compute Engine/VM Instances` under _External IP_. #### Running in command line -Run the following command: +Blackbox tests have following parameters: +- `--island=IP` Sets island's IP +- `--no-gcp` (Optional) Use for no interaction with the cloud (local test). +- `--quick-performance-tests` (Optional) If enabled performance tests won't reset island and won't send telemetries, +instead will just test performance of endpoints in already present island state. + +Example run command: `monkey\envs\monkey_zoo\blackbox>python -m pytest -s --island=35.207.152.72:5000 test_blackbox.py` diff --git a/envs/monkey_zoo/blackbox/conftest.py b/envs/monkey_zoo/blackbox/conftest.py index 13aabf5b6..0444a4101 100644 --- a/envs/monkey_zoo/blackbox/conftest.py +++ b/envs/monkey_zoo/blackbox/conftest.py @@ -4,8 +4,24 @@ import pytest def pytest_addoption(parser): parser.addoption("--island", action="store", default="", help="Specify the Monkey Island address (host+port).") + parser.addoption("--no-gcp", action="store_true", default=False, + help="Use for no interaction with the cloud.") + parser.addoption("--quick-performance-tests", action="store_true", default=False, + help="If enabled performance tests won't reset island and won't send telemetries, " + "instead will just test performance of already present island state.") -@pytest.fixture(scope='module') +@pytest.fixture(scope='session') def island(request): return request.config.getoption("--island") + + +@pytest.fixture(scope='session') +def no_gcp(request): + return request.config.getoption("--no-gcp") + + +@pytest.fixture(scope='session') +def quick_performance_tests(request): + return request.config.getoption("--quick-performance-tests") + diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 2408d79be..870b81868 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -27,15 +27,16 @@ LOGGER = logging.getLogger(__name__) @pytest.fixture(autouse=True, scope='session') -def GCPHandler(request): - GCPHandler = gcp_machine_handlers.GCPHandler() - GCPHandler.start_machines(" ".join(GCP_TEST_MACHINE_LIST)) - wait_machine_bootup() +def GCPHandler(request, no_gcp): + if not no_gcp: + GCPHandler = gcp_machine_handlers.GCPHandler() + GCPHandler.start_machines(" ".join(GCP_TEST_MACHINE_LIST)) + wait_machine_bootup() - def fin(): - GCPHandler.stop_machines(" ".join(GCP_TEST_MACHINE_LIST)) + def fin(): + GCPHandler.stop_machines(" ".join(GCP_TEST_MACHINE_LIST)) - request.addfinalizer(fin) + request.addfinalizer(fin) @pytest.fixture(autouse=True, scope='session') @@ -49,9 +50,10 @@ def wait_machine_bootup(): @pytest.fixture(scope='class') -def island_client(island): +def island_client(island, quick_performance_tests): island_client_object = MonkeyIslandClient(island) - island_client_object.reset_env() + if not quick_performance_tests: + island_client_object.reset_env() yield island_client_object @@ -130,7 +132,7 @@ class TestMonkeyBlackbox(object): def test_wmi_pth(self, island_client): TestMonkeyBlackbox.run_exploitation_test(island_client, "WMI_PTH.conf", "WMI_PTH") - def test_report_generation_performance(self, island_client): + def test_report_generation_performance(self, island_client, quick_performance_tests): """ This test includes the SSH + Elastic + Hadoop + MSSQL machines all in one test for a total of 8 machines including the Monkey Island. @@ -138,22 +140,31 @@ class TestMonkeyBlackbox(object): 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 """ - TestMonkeyBlackbox.run_performance_test(ReportGenerationTest, - island_client, - "PERFORMANCE.conf", - timeout_in_seconds=10*60) + if not quick_performance_tests: + TestMonkeyBlackbox.run_performance_test(ReportGenerationTest, + island_client, + "PERFORMANCE.conf", + timeout_in_seconds=10*60) + else: + LOGGER.error("This test doesn't support 'quick_performance_tests' option.") + assert False - def test_map_generation_performance(self, island_client): - TestMonkeyBlackbox.run_performance_test(MapGenerationTest, - island_client, - "PERFORMANCE.conf", - timeout_in_seconds=10*60) + 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 - def test_report_generation_from_fake_telemetries(self, island_client): - ReportGenerationFromTelemetryTest(island_client).run() + def test_report_generation_from_fake_telemetries(self, island_client, quick_performance_tests): + ReportGenerationFromTelemetryTest(island_client, quick_performance_tests).run() - def test_map_generation_from_fake_telemetries(self, island_client): - MapGenerationFromTelemetryTest(island_client).run() + def test_map_generation_from_fake_telemetries(self, island_client, quick_performance_tests): + MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run() - def test_telem_performance(self, island_client): - TelemetryPerformanceTest(island_client).test_telemetry_performance() + def test_telem_performance(self, island_client, quick_performance_tests): + if not quick_performance_tests: + TelemetryPerformanceTest(island_client).test_telemetry_performance() diff --git a/envs/monkey_zoo/blackbox/tests/performance/map_generation_from_telemetries.py b/envs/monkey_zoo/blackbox/tests/performance/map_generation_from_telemetries.py index c5344d8f7..1b31a8962 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/map_generation_from_telemetries.py +++ b/envs/monkey_zoo/blackbox/tests/performance/map_generation_from_telemetries.py @@ -17,7 +17,7 @@ class MapGenerationFromTelemetryTest(PerformanceTest): TEST_NAME = "Map generation from fake telemetries test" - def __init__(self, island_client, break_on_timeout=False): + def __init__(self, island_client, quick_performance_test: bool, break_on_timeout=False): self.island_client = island_client performance_config = PerformanceTestConfig(max_allowed_single_page_time=MAX_ALLOWED_SINGLE_PAGE_TIME, max_allowed_total_time=MAX_ALLOWED_TOTAL_TIME, @@ -25,7 +25,8 @@ class MapGenerationFromTelemetryTest(PerformanceTest): break_on_timeout=break_on_timeout) self.performance_test_workflow = TelemetryPerformanceTestWorkflow(MapGenerationFromTelemetryTest.TEST_NAME, self.island_client, - performance_config) + performance_config, + quick_performance_test) def run(self): self.performance_test_workflow.run() diff --git a/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test_workflow.py b/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test_workflow.py index b5acf4a9e..e8bef33d8 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test_workflow.py +++ b/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test_workflow.py @@ -6,15 +6,18 @@ from envs.monkey_zoo.blackbox.tests.performance.telemetry_performance_test impor class TelemetryPerformanceTestWorkflow(BasicTest): - def __init__(self, name, island_client, performance_config: PerformanceTestConfig): + def __init__(self, name, island_client, performance_config: PerformanceTestConfig, quick_performance_test): self.name = name self.island_client = island_client self.performance_config = performance_config + self.quick_performance_test = quick_performance_test def run(self): try: - TelemetryPerformanceTest(island_client=self.island_client).test_telemetry_performance() + if not self.quick_performance_test: + TelemetryPerformanceTest(island_client=self.island_client).test_telemetry_performance() performance_test = EndpointPerformanceTest(self.name, self.performance_config, self.island_client) assert performance_test.run() finally: - self.island_client.reset_env() + if not self.quick_performance_test: + self.island_client.reset_env() From a360e8514e72d9cb40233e02663d054f703417f7 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 13 May 2020 16:39:47 +0300 Subject: [PATCH 03/21] Fixed a bug of multiple telemetry exports in a single island run. --- monkey/monkey_island/cc/resources/test/utils/telem_store.py | 3 +++ monkey/monkey_island/cc/services/infection_lifecycle.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/resources/test/utils/telem_store.py b/monkey/monkey_island/cc/resources/test/utils/telem_store.py index 18ebfd244..ed15ae22e 100644 --- a/monkey/monkey_island/cc/resources/test/utils/telem_store.py +++ b/monkey/monkey_island/cc/resources/test/utils/telem_store.py @@ -19,6 +19,8 @@ logger = logging.getLogger(__name__) class TestTelemStore: + TELEMS_EXPORTED = False + @staticmethod def store_test_telem(f): @wraps(f) @@ -46,6 +48,7 @@ class TestTelemStore: for test_telem in TestTelem.objects(): with open(TestTelemStore.get_unique_file_path_for_test_telem(TELEM_SAMPLE_DIR, test_telem), 'w') as file: file.write(test_telem.to_json(indent=2)) + TestTelemStore.TELEMS_EXPORTED = True logger.info("Telemetries exported!") @staticmethod diff --git a/monkey/monkey_island/cc/services/infection_lifecycle.py b/monkey/monkey_island/cc/services/infection_lifecycle.py index e79cfe947..425937c7b 100644 --- a/monkey/monkey_island/cc/services/infection_lifecycle.py +++ b/monkey/monkey_island/cc/services/infection_lifecycle.py @@ -47,5 +47,5 @@ class InfectionLifecycle: # we want to skip and reply. if not is_report_being_generated() and not ReportService.is_latest_report_exists(): safe_generate_reports() - if ConfigService.is_test_telem_export_enabled(): + if ConfigService.is_test_telem_export_enabled() and not TestTelemStore.TELEMS_EXPORTED: TestTelemStore.export_test_telems() From 87e50d37f1dc1d8818cb7ecbe0ee0ac6c37746f8 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 14 May 2020 10:55:59 +0300 Subject: [PATCH 04/21] Small fixes: island reset added to telemetry performance test, fixed a bug on report generation test --- envs/monkey_zoo/blackbox/test_blackbox.py | 3 +-- .../blackbox/tests/performance/endpoint_performance_test.py | 3 --- .../blackbox/tests/performance/performance_test_workflow.py | 2 ++ .../tests/performance/report_generation_from_telemetries.py | 5 +++-- .../blackbox/tests/performance/telemetry_performance_test.py | 5 ++++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 870b81868..88f5c12a8 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -166,5 +166,4 @@ class TestMonkeyBlackbox(object): MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run() def test_telem_performance(self, island_client, quick_performance_tests): - if not quick_performance_tests: - TelemetryPerformanceTest(island_client).test_telemetry_performance() + TelemetryPerformanceTest(island_client, quick_performance_tests).test_telemetry_performance() diff --git a/envs/monkey_zoo/blackbox/tests/performance/endpoint_performance_test.py b/envs/monkey_zoo/blackbox/tests/performance/endpoint_performance_test.py index 798f490af..b4f8f35c8 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/endpoint_performance_test.py +++ b/envs/monkey_zoo/blackbox/tests/performance/endpoint_performance_test.py @@ -17,9 +17,6 @@ class EndpointPerformanceTest(BasicTest): self.island_client = island_client def run(self) -> bool: - if not self.island_client.is_all_monkeys_dead(): - raise RuntimeError("Can't test report times since not all Monkeys have died.") - # Collect timings for all pages self.island_client.clear_caches() endpoint_timings = {} diff --git a/envs/monkey_zoo/blackbox/tests/performance/performance_test_workflow.py b/envs/monkey_zoo/blackbox/tests/performance/performance_test_workflow.py index cdb4f08ac..4e708ed9d 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/performance_test_workflow.py +++ b/envs/monkey_zoo/blackbox/tests/performance/performance_test_workflow.py @@ -23,6 +23,8 @@ class PerformanceTestWorkflow(BasicTest): self.island_client.kill_all_monkeys() self.exploitation_test.wait_until_monkeys_die() self.exploitation_test.wait_for_monkey_process_to_finish() + if not self.island_client.is_all_monkeys_dead(): + raise RuntimeError("Can't test report times since not all Monkeys have died.") performance_test = EndpointPerformanceTest(self.name, self.performance_config, self.island_client) try: if not self.island_client.is_all_monkeys_dead(): diff --git a/envs/monkey_zoo/blackbox/tests/performance/report_generation_from_telemetries.py b/envs/monkey_zoo/blackbox/tests/performance/report_generation_from_telemetries.py index a08bbda70..abc2b35c2 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/report_generation_from_telemetries.py +++ b/envs/monkey_zoo/blackbox/tests/performance/report_generation_from_telemetries.py @@ -21,7 +21,7 @@ class ReportGenerationFromTelemetryTest(PerformanceTest): TEST_NAME = "Map generation from fake telemetries test" - def __init__(self, island_client, break_on_timeout=False): + def __init__(self, island_client, quick_performance_test, break_on_timeout=False): self.island_client = island_client performance_config = PerformanceTestConfig(max_allowed_single_page_time=MAX_ALLOWED_SINGLE_PAGE_TIME, max_allowed_total_time=MAX_ALLOWED_TOTAL_TIME, @@ -29,7 +29,8 @@ class ReportGenerationFromTelemetryTest(PerformanceTest): break_on_timeout=break_on_timeout) self.performance_test_workflow = TelemetryPerformanceTestWorkflow(ReportGenerationFromTelemetryTest.TEST_NAME, self.island_client, - performance_config) + performance_config, + quick_performance_test) def run(self): self.performance_test_workflow.run() diff --git a/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test.py b/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test.py index 4de77e41a..699876cce 100644 --- a/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test.py +++ b/envs/monkey_zoo/blackbox/tests/performance/telemetry_performance_test.py @@ -18,8 +18,9 @@ MAX_ALLOWED_TOTAL_TIME = timedelta(seconds=60) class TelemetryPerformanceTest: - def __init__(self, island_client: MonkeyIslandClient): + def __init__(self, island_client: MonkeyIslandClient, quick_performance_test: bool): self.island_client = island_client + self.quick_performance_test = quick_performance_test def test_telemetry_performance(self): LOGGER.info("Starting telemetry performance test.") @@ -36,6 +37,8 @@ class TelemetryPerformanceTest: telemetry_parse_times[telemetry_endpoint] = self.get_telemetry_time(telemetry) test_config = PerformanceTestConfig(MAX_ALLOWED_SINGLE_TELEM_PARSE_TIME, MAX_ALLOWED_TOTAL_TIME) PerformanceAnalyzer(test_config, telemetry_parse_times).analyze_test_results() + if not self.quick_performance_test: + self.island_client.reset_env() def get_telemetry_time(self, telemetry): content = telemetry['content'] From 54ac059d5ef705ea85fa553cba0014e8637fc921 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 15 May 2020 10:42:03 +0300 Subject: [PATCH 05/21] Prototype changes that fix redundant exploitations, but break multiple iterations --- monkey/infection_monkey/config.py | 10 ++++++++++ monkey/infection_monkey/monkey.py | 7 +++---- .../exceptions/planned_shutdown_exception.py | 2 ++ monkey/monkey_island/cc/resources/monkey.py | 15 +++++---------- monkey/monkey_island/cc/services/config.py | 10 ++++++++++ .../telemetry/processing/system_info.py | 18 ++++++++++++++++++ 6 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 monkey/infection_monkey/utils/exceptions/planned_shutdown_exception.py diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 5c5b5a392..e41b8a8a6 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -8,6 +8,9 @@ from itertools import product __author__ = 'itamar' +from infection_monkey.utils.exceptions.planned_shutdown_exception import PlannedShutdownException +from infection_monkey.network import info + GUID = str(uuid.getnode()) EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin') @@ -277,5 +280,12 @@ class Configuration(object): password_hashed = hashlib.sha512(sensitive_data.encode()).hexdigest() return password_hashed + @staticmethod + def should_monkey_run(): + local_ips = info.local_ips() + if set(local_ips).intersection(set(WormConfiguration.blocked_ips)): + raise PlannedShutdownException("Monkey shouldn't run on current machine " + "(blocked ip or redundant exploitation).") + WormConfiguration = Configuration() diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index c96599844..8e0763dc5 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -10,6 +10,7 @@ from infection_monkey.network.HostFinger import HostFinger from infection_monkey.utils.monkey_dir import create_monkey_dir, get_monkey_dir_path, remove_monkey_dir from infection_monkey.utils.monkey_log_path import get_monkey_log_path from infection_monkey.utils.environment import is_windows_os +from infection_monkey.utils.exceptions.planned_shutdown_exception import PlannedShutdownException from infection_monkey.config import WormConfiguration from infection_monkey.control import ControlClient from infection_monkey.model import DELAY_DELETE_CMD @@ -40,10 +41,6 @@ __author__ = 'itamar' LOG = logging.getLogger(__name__) -class PlannedShutdownException(Exception): - pass - - class InfectionMonkey(object): def __init__(self, args): self._keep_running = False @@ -129,6 +126,8 @@ class InfectionMonkey(object): StateTelem(is_done=False, version=get_version()).send() TunnelTelem().send() + WormConfiguration.should_monkey_run() + LOG.debug("Starting the post-breach phase.") self.collect_system_info_if_configured() PostBreach().execute_all_configured() diff --git a/monkey/infection_monkey/utils/exceptions/planned_shutdown_exception.py b/monkey/infection_monkey/utils/exceptions/planned_shutdown_exception.py new file mode 100644 index 000000000..f0147e1e5 --- /dev/null +++ b/monkey/infection_monkey/utils/exceptions/planned_shutdown_exception.py @@ -0,0 +1,2 @@ +class PlannedShutdownException(Exception): + pass diff --git a/monkey/monkey_island/cc/resources/monkey.py b/monkey/monkey_island/cc/resources/monkey.py index dcdc5bc12..e61765376 100644 --- a/monkey/monkey_island/cc/resources/monkey.py +++ b/monkey/monkey_island/cc/resources/monkey.py @@ -74,16 +74,11 @@ class Monkey(flask_restful.Resource): # if new monkey telem, change config according to "new monkeys" config. db_monkey = mongo.db.monkey.find_one({"guid": monkey_json["guid"]}) - if not db_monkey: - # we pull it encrypted because we then decrypt it for the monkey in get - new_config = ConfigService.get_flat_config(False, False) - monkey_json['config'] = monkey_json.get('config', {}) - monkey_json['config'].update(new_config) - else: - db_config = db_monkey.get('config', {}) - if 'current_server' in db_config: - del db_config['current_server'] - monkey_json.get('config', {}).update(db_config) + + # Update monkey configuration + new_config = ConfigService.get_flat_config(False, False) + monkey_json['config'] = monkey_json.get('config', {}) + monkey_json['config'].update(new_config) # try to find new monkey parent parent = monkey_json.get('parent') diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index e9ed3b0f6..f8d9df0de 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -74,6 +74,12 @@ class ConfigService: mongo.db.config.update({'name': 'newconfig'}, {"$set": {mongo_key: value}}) + @staticmethod + def append_to_config_array(config_key_as_arr, value): + mongo_key = ".".join(config_key_as_arr) + mongo.db.config.update({'name': 'newconfig'}, + {"$push": {mongo_key: value}}) + @staticmethod def get_flat_config(is_initial_config=False, should_decrypt=True): config_json = ConfigService.get_config(is_initial_config, should_decrypt) @@ -311,3 +317,7 @@ class ConfigService: @staticmethod def is_test_telem_export_enabled(): return ConfigService.get_config_value(['internal', 'testing', 'export_monkey_telems']) + + @staticmethod + def add_blocked_ip(ip_): + ConfigService.append_to_config_array(['basic_network', 'general', 'blocked_ips'], ip_) diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info.py index 5b842df0b..7f11c1fd3 100644 --- a/monkey/monkey_island/cc/services/telemetry/processing/system_info.py +++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info.py @@ -1,4 +1,5 @@ import logging +from ipaddress import ip_address from monkey_island.cc.encryptor import encryptor from monkey_island.cc.services import mimikatz_utils @@ -17,6 +18,7 @@ def process_system_info_telemetry(telemetry_json): process_ssh_info, process_credential_info, process_mimikatz_and_wmi_info, + try_process_network_info, dispatcher.dispatch_collector_results_to_relevant_processors ] @@ -101,3 +103,19 @@ def process_mimikatz_and_wmi_info(telemetry_json): monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid']).get('_id') wmi_handler = WMIHandler(monkey_id, telemetry_json['data']['wmi'], users_secrets) wmi_handler.process_and_handle_wmi_info() + + +def try_process_network_info(telemetry_json): + try: + process_network_info(telemetry_json) + except KeyError: + pass + + +def process_network_info(telemetry_json): + interfaces = telemetry_json['data']['network_info']['networks'] + for interface in interfaces: + ip_ = ip_address(interface['addr']) + if not ip_.is_loopback: + ConfigService.add_blocked_ip(ip_.exploded) + From 698a13960ea08ed6b91a437df5fa84ea7716444c Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 19 May 2020 11:31:52 +0300 Subject: [PATCH 06/21] Removed unnecessary UI warning about config change not working if monkeys already ran --- .../ui/src/components/pages/ConfigurePage.js | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 172751a01..79e71b792 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -30,7 +30,6 @@ class ConfigurePageComponent extends AuthComponent { lastAction: 'none', sections: [], selectedSection: 'attack', - monkeysRan: false, PBAwinFile: [], PBAlinuxFile: [], showAttackAlert: false @@ -108,7 +107,6 @@ class ConfigurePageComponent extends AuthComponent { selectedSection: 'attack' }) }); - this.updateMonkeysRunning(); }; updateConfig = () => { @@ -359,14 +357,6 @@ class ConfigurePageComponent extends AuthComponent { event.target.value = null; }; - updateMonkeysRunning = () => { - this.authFetch('/api') - .then(res => res.json()) - .then(res => { - this.setState({monkeysRan: res['completed_steps']['run_monkey']}); - }); - }; - PBAwindows = () => { return () }; - renderConfigWontChangeWarning = () => { - return (
- {this.state.monkeysRan ? -
- - Changed configuration will only apply to new infections. - "Start over" to run again with different configuration. -
- : '' - } -
) - }; - renderBasicNetworkWarning = () => { if (this.state.selectedSection === 'basic_network') { return (
@@ -514,7 +491,6 @@ class ConfigurePageComponent extends AuthComponent { {this.renderAttackAlertModal()}

Monkey Configuration

{this.renderNav()} - {this.renderConfigWontChangeWarning()} {content}