From 30afe3cc858cf6a96345bf68ae4dead303410db2 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 2 Dec 2021 21:03:45 -0500 Subject: [PATCH] Island: Strip credentials out of config before sending to agent The credentials for credential reuse attacks will now be retrieved by the agent via a new endpoint that returns only credentials in order to reduce unnecessary network traffic (issue #1538). --- CHANGELOG.md | 1 + monkey/monkey_island/cc/resources/monkey.py | 2 +- monkey/monkey_island/cc/services/config.py | 17 +++++++++++++++-- .../monkey_island/cc/services/test_config.py | 14 ++++++++++---- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c2a177e..7f5a59bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Hostname system info collector. #1535 - Max iterations and timeout between iterations config options. #1600 - MITRE ATT&CK configuration screen. #1532 +- Propagation credentials from "GET /api/monkey/" endpoint. #1538 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 diff --git a/monkey/monkey_island/cc/resources/monkey.py b/monkey/monkey_island/cc/resources/monkey.py index fbd093a8e..4e02fc258 100644 --- a/monkey/monkey_island/cc/resources/monkey.py +++ b/monkey/monkey_island/cc/resources/monkey.py @@ -31,7 +31,7 @@ class Monkey(flask_restful.Resource): if config_format == "legacy": ConfigService.decrypt_flat_config(monkey_json["config"]) else: - ConfigService.format_config_for_agent(monkey_json["config"]) + ConfigService.format_flat_config_for_agent(monkey_json["config"]) return monkey_json diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index 13a4cb214..4e5290a19 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -428,5 +428,18 @@ class ConfigService: } @staticmethod - def format_config_for_agent(config: Dict): - ConfigService.decrypt_flat_config(config) + def format_flat_config_for_agent(config: Dict): + ConfigService._remove_credentials_from_flat_config(config) + + @staticmethod + def _remove_credentials_from_flat_config(config: Dict): + fields_to_remove = { + "exploit_lm_hash_list", + "exploit_ntlm_hash_list", + "exploit_password_list", + "exploit_ssh_keys", + "exploit_user_list", + } + + for field in fields_to_remove: + config.pop(field, None) diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py index 751ca98ed..30e56e05e 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py @@ -6,10 +6,6 @@ from monkey_island.cc.services.config import ConfigService # monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js -class MockClass: - pass - - @pytest.fixture(scope="function", autouse=True) def mock_port(monkeypatch, PORT): monkeypatch.setattr("monkey_island.cc.services.config.ISLAND_PORT", PORT) @@ -27,3 +23,13 @@ def test_set_server_ips_in_config_current_server(config, IPS, PORT): ConfigService.set_server_ips_in_config(config) expected_config_current_server = f"{IPS[0]}:{PORT}" assert config["internal"]["island_server"]["current_server"] == expected_config_current_server + + +def test_format_config_for_agent__credentials_removed(flat_monkey_config): + ConfigService.format_flat_config_for_agent(flat_monkey_config) + + assert "exploit_lm_hash_list" not in flat_monkey_config + assert "exploit_ntlm_hash_list" not in flat_monkey_config + assert "exploit_password_list" not in flat_monkey_config + assert "exploit_ssh_keys" not in flat_monkey_config + assert "exploit_user_list" not in flat_monkey_config