forked from p15670423/monkey
Merge pull request #2006 from guardicore/1968-global-agent-config
1968 global agent config
This commit is contained in:
commit
6f090a4de0
|
@ -41,7 +41,6 @@ class ControlClient(object):
|
|||
"ip_addresses": local_ips(),
|
||||
"networks": get_host_subnets(),
|
||||
"description": " ".join(platform.uname()),
|
||||
"config": WormConfiguration.as_dict(),
|
||||
"parent": parent,
|
||||
"launch_time": agent_process.get_start_time(),
|
||||
}
|
||||
|
@ -50,7 +49,7 @@ class ControlClient(object):
|
|||
monkey["tunnel"] = ControlClient.proxies.get("https")
|
||||
|
||||
requests.post( # noqa: DUO123
|
||||
"https://%s/api/agent" % (WormConfiguration.current_server,),
|
||||
f"https://{WormConfiguration.current_server}/api/agent",
|
||||
data=json.dumps(monkey),
|
||||
headers={"content-type": "application/json"},
|
||||
verify=False,
|
||||
|
@ -173,7 +172,7 @@ class ControlClient(object):
|
|||
return
|
||||
try:
|
||||
reply = requests.get( # noqa: DUO123
|
||||
"https://%s/api/agent/%s/legacy" % (WormConfiguration.current_server, GUID),
|
||||
f"https://{WormConfiguration.current_server}/api/agent/",
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
|
@ -210,7 +209,7 @@ class ControlClient(object):
|
|||
return
|
||||
try:
|
||||
requests.patch( # noqa: DUO123
|
||||
"https://%s/api/agent/%s" % (WormConfiguration.current_server, GUID),
|
||||
f"https://{WormConfiguration.current_server}/api/agent/{GUID}",
|
||||
data=json.dumps({"config_error": True}),
|
||||
headers={"content-type": "application/json"},
|
||||
verify=False,
|
||||
|
|
|
@ -49,7 +49,7 @@ class ControlChannel(IControlChannel):
|
|||
def get_config(self) -> dict:
|
||||
try:
|
||||
response = requests.get( # noqa: DUO123
|
||||
f"https://{self._control_channel_server}/api/agent/{self._agent_id}",
|
||||
f"https://{self._control_channel_server}/api/agent",
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=SHORT_REQUEST_TIMEOUT,
|
||||
|
@ -68,7 +68,7 @@ class ControlChannel(IControlChannel):
|
|||
|
||||
def get_credentials_for_propagation(self) -> PropagationCredentials:
|
||||
propagation_credentials_url = (
|
||||
f"https://{self._control_channel_server}/api/propagation-credentials/{self._agent_id}"
|
||||
f"https://{self._control_channel_server}/api/propagation-credentials"
|
||||
)
|
||||
try:
|
||||
response = requests.get( # noqa: DUO123
|
||||
|
|
|
@ -37,7 +37,6 @@ class Monkey(Document):
|
|||
|
||||
# SCHEMA
|
||||
guid = StringField(required=True)
|
||||
config = EmbeddedDocumentField("Config")
|
||||
should_stop = BooleanField()
|
||||
dead = BooleanField()
|
||||
description = StringField()
|
||||
|
|
|
@ -15,7 +15,7 @@ class IslandConfiguration(AbstractResource):
|
|||
def get(self):
|
||||
return jsonify(
|
||||
schema=ConfigService.get_config_schema(),
|
||||
configuration=ConfigService.get_config(False, True, True),
|
||||
configuration=ConfigService.get_config(True, True),
|
||||
)
|
||||
|
||||
@jwt_required
|
||||
|
|
|
@ -21,28 +21,11 @@ class Monkey(AbstractResource):
|
|||
urls = [
|
||||
"/api/agent",
|
||||
"/api/agent/<string:guid>",
|
||||
# API Spec: Resource names should alternate with IDs (/api/agents/123/config-format/xyz)
|
||||
"/api/agent/<string:guid>/<string:config_format>",
|
||||
]
|
||||
|
||||
# Used by monkey. can't secure.
|
||||
def get(self, guid=None, config_format=None, **kw):
|
||||
if not guid:
|
||||
guid = request.args.get("guid")
|
||||
|
||||
if guid:
|
||||
monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid})
|
||||
# TODO: When the "legacy" format is no longer needed, update this logic and remove the
|
||||
# "/api/agent/<string:guid>/<string:config_format>" route. Also considering not
|
||||
# flattening the config in the first place.
|
||||
if config_format == "legacy":
|
||||
ConfigService.decrypt_flat_config(monkey_json["config"])
|
||||
else:
|
||||
ConfigService.format_flat_config_for_agent(monkey_json["config"])
|
||||
|
||||
return monkey_json
|
||||
|
||||
return {}
|
||||
def get(self):
|
||||
return {"config": ConfigService.format_flat_config_for_agent()}
|
||||
|
||||
# Used by monkey. can't secure.
|
||||
@TestTelemStore.store_exported_telem
|
||||
|
@ -54,8 +37,6 @@ class Monkey(AbstractResource):
|
|||
monkey_json = json.loads(request.data)
|
||||
update = {"$set": {"modifytime": datetime.now()}}
|
||||
monkey = NodeService.get_monkey_by_guid(guid)
|
||||
if "config" in monkey_json:
|
||||
update["$set"]["config"] = monkey_json["config"]
|
||||
if "config_error" in monkey_json:
|
||||
update["$set"]["config_error"] = monkey_json["config_error"]
|
||||
|
||||
|
@ -84,16 +65,9 @@ class Monkey(AbstractResource):
|
|||
|
||||
monkey_json["modifytime"] = datetime.now()
|
||||
|
||||
ConfigService.save_initial_config_if_needed()
|
||||
|
||||
# if new monkey telem, change config according to "new monkeys" config.
|
||||
db_monkey = mongo.db.monkey.find_one({"guid": monkey_json["guid"]})
|
||||
|
||||
# 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")
|
||||
parent_to_add = (monkey_json.get("guid"), None) # default values in case of manual run
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
from monkey_island.cc.database import mongo
|
||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||
from monkey_island.cc.services.config import ConfigService
|
||||
|
||||
|
||||
class PropagationCredentials(AbstractResource):
|
||||
urls = ["/api/propagation-credentials/<string:guid>"]
|
||||
urls = ["/api/propagation-credentials"]
|
||||
|
||||
def get(self, guid: str):
|
||||
monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid})
|
||||
ConfigService.decrypt_flat_config(monkey_json["config"])
|
||||
def get(self):
|
||||
config = ConfigService.get_flat_config(should_decrypt=True)
|
||||
|
||||
propagation_credentials = ConfigService.get_config_propagation_credentials_from_flat_config(
|
||||
monkey_json["config"]
|
||||
config
|
||||
)
|
||||
|
||||
return {"propagation_credentials": propagation_credentials}
|
||||
|
|
|
@ -60,12 +60,10 @@ class ConfigService:
|
|||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_config(is_initial_config=False, should_decrypt=True, is_island=False):
|
||||
def get_config(should_decrypt=True, is_island=False):
|
||||
"""
|
||||
Gets the entire global config.
|
||||
|
||||
:param is_initial_config: If True, the initial config will be returned instead of the \
|
||||
current config. \
|
||||
:param should_decrypt: If True, all config values which are set as encrypted will be \
|
||||
decrypted. \
|
||||
:param is_island: If True, will include island specific configuration parameters. \
|
||||
|
@ -74,12 +72,8 @@ class ConfigService:
|
|||
|
||||
# is_initial_config and should_decrypt are only there to compare if we are on the
|
||||
# default configuration or did user modified it already
|
||||
config = (
|
||||
mongo.db.config.find_one({"name": "initial" if is_initial_config else "newconfig"})
|
||||
or {}
|
||||
)
|
||||
for field in ("name", "_id"):
|
||||
config.pop(field, None)
|
||||
config = mongo.db.config.find_one() or {}
|
||||
config.pop("_id", None)
|
||||
if should_decrypt and len(config) > 0:
|
||||
ConfigService.decrypt_config(config)
|
||||
if not is_island:
|
||||
|
@ -87,14 +81,12 @@ class ConfigService:
|
|||
return config
|
||||
|
||||
@staticmethod
|
||||
def get_config_value(config_key_as_arr, is_initial_config=False, should_decrypt=True):
|
||||
def get_config_value(config_key_as_arr, should_decrypt=True):
|
||||
"""
|
||||
Get a specific config value.
|
||||
|
||||
:param config_key_as_arr: The config key as an array.
|
||||
e.g. ['basic', 'credentials','exploit_password_list'].
|
||||
:param is_initial_config: If True, returns the value of the
|
||||
initial config instead of the current config.
|
||||
:param should_decrypt: If True, the value of the config key will be decrypted
|
||||
(if it's in the list of encrypted config values).
|
||||
:return: The value of the requested config key.
|
||||
|
@ -102,9 +94,7 @@ class ConfigService:
|
|||
config_key = functools.reduce(lambda x, y: x + "." + y, config_key_as_arr)
|
||||
|
||||
# This should just call get_config from repository. If None, then call get_default prob
|
||||
config = mongo.db.config.find_one(
|
||||
{"name": "initial" if is_initial_config else "newconfig"}, {config_key: 1}
|
||||
)
|
||||
config = mongo.db.config.find_one({}, {config_key: 1})
|
||||
|
||||
for config_key_part in config_key_as_arr:
|
||||
config = config[config_key_part]
|
||||
|
@ -124,11 +114,11 @@ class ConfigService:
|
|||
@staticmethod
|
||||
def set_config_value(config_key_as_arr, value):
|
||||
mongo_key = ".".join(config_key_as_arr)
|
||||
mongo.db.config.update({"name": "newconfig"}, {"$set": {mongo_key: value}})
|
||||
mongo.db.config.update({}, {"$set": {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)
|
||||
def get_flat_config(should_decrypt=True):
|
||||
config_json = ConfigService.get_config(should_decrypt)
|
||||
flat_config_json = {}
|
||||
for i in config_json:
|
||||
if i == "ransomware":
|
||||
|
@ -153,7 +143,7 @@ class ConfigService:
|
|||
@staticmethod
|
||||
def add_item_to_config_set_if_dont_exist(item_path_array, item_value, should_encrypt):
|
||||
item_key = ".".join(item_path_array)
|
||||
items_from_config = ConfigService.get_config_value(item_path_array, False, should_encrypt)
|
||||
items_from_config = ConfigService.get_config_value(item_path_array, should_encrypt)
|
||||
if item_value in items_from_config:
|
||||
return
|
||||
if should_encrypt:
|
||||
|
@ -161,13 +151,7 @@ class ConfigService:
|
|||
item_value = encrypt_dict(SENSITIVE_SSH_KEY_FIELDS, item_value)
|
||||
else:
|
||||
item_value = get_datastore_encryptor().encrypt(item_value)
|
||||
mongo.db.config.update(
|
||||
{"name": "newconfig"}, {"$addToSet": {item_key: item_value}}, upsert=False
|
||||
)
|
||||
|
||||
mongo.db.monkey.update(
|
||||
{}, {"$addToSet": {"config." + item_key.split(".")[-1]: item_value}}, multi=True
|
||||
)
|
||||
mongo.db.config.update({}, {"$addToSet": {item_key: item_value}})
|
||||
|
||||
@staticmethod
|
||||
def creds_add_username(username):
|
||||
|
@ -225,7 +209,7 @@ class ConfigService:
|
|||
except KeyError:
|
||||
logger.error("Bad configuration file was submitted.")
|
||||
return False
|
||||
mongo.db.config.update({"name": "newconfig"}, {"$set": config_json}, upsert=True)
|
||||
mongo.db.config.update({}, {"$set": config_json}, upsert=True)
|
||||
logger.info("monkey config was updated")
|
||||
return True
|
||||
|
||||
|
@ -293,17 +277,6 @@ class ConfigService:
|
|||
ISLAND_PORT,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def save_initial_config_if_needed():
|
||||
if mongo.db.config.find_one({"name": "initial"}) is not None:
|
||||
return
|
||||
|
||||
initial_config = mongo.db.config.find_one({"name": "newconfig"})
|
||||
initial_config["name"] = "initial"
|
||||
initial_config.pop("_id")
|
||||
mongo.db.config.insert(initial_config)
|
||||
logger.info("Monkey config was inserted to mongo and saved")
|
||||
|
||||
@staticmethod
|
||||
def _extend_config_with_default(validator_class):
|
||||
validate_properties = validator_class.VALIDATORS["properties"]
|
||||
|
@ -350,34 +323,6 @@ class ConfigService:
|
|||
def encrypt_config(config):
|
||||
ConfigService._encrypt_or_decrypt_config(config, False)
|
||||
|
||||
@staticmethod
|
||||
def decrypt_flat_config(flat_config, is_island=False):
|
||||
"""
|
||||
Same as decrypt_config but for a flat configuration
|
||||
"""
|
||||
keys = [config_arr_as_array[-1] for config_arr_as_array in ENCRYPTED_CONFIG_VALUES]
|
||||
|
||||
for key in keys:
|
||||
if isinstance(flat_config[key], collections.Sequence) and not isinstance(
|
||||
flat_config[key], str
|
||||
):
|
||||
# Check if we are decrypting ssh key pair
|
||||
if (
|
||||
flat_config[key]
|
||||
and isinstance(flat_config[key][0], dict)
|
||||
and "public_key" in flat_config[key][0]
|
||||
):
|
||||
flat_config[key] = [
|
||||
decrypt_dict(SENSITIVE_SSH_KEY_FIELDS, item) for item in flat_config[key]
|
||||
]
|
||||
else:
|
||||
flat_config[key] = [
|
||||
get_datastore_encryptor().decrypt(item) for item in flat_config[key]
|
||||
]
|
||||
else:
|
||||
flat_config[key] = get_datastore_encryptor().decrypt(flat_config[key])
|
||||
return flat_config
|
||||
|
||||
@staticmethod
|
||||
def _encrypt_or_decrypt_config(config, is_decrypt=False):
|
||||
for config_arr_as_array in ENCRYPTED_CONFIG_VALUES:
|
||||
|
@ -427,11 +372,13 @@ class ConfigService:
|
|||
}
|
||||
|
||||
@staticmethod
|
||||
def format_flat_config_for_agent(config: Dict):
|
||||
def format_flat_config_for_agent():
|
||||
config = ConfigService.get_flat_config()
|
||||
ConfigService._remove_credentials_from_flat_config(config)
|
||||
ConfigService._format_payloads_from_flat_config(config)
|
||||
ConfigService._format_pbas_from_flat_config(config)
|
||||
ConfigService._format_propagation_from_flat_config(config)
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def _remove_credentials_from_flat_config(config: Dict):
|
||||
|
|
|
@ -383,11 +383,11 @@ class ReportService:
|
|||
|
||||
@staticmethod
|
||||
def get_config_users():
|
||||
return ConfigService.get_config_value(USER_LIST_PATH, True, True)
|
||||
return ConfigService.get_config_value(USER_LIST_PATH, True)
|
||||
|
||||
@staticmethod
|
||||
def get_config_passwords():
|
||||
return ConfigService.get_config_value(PASSWORD_LIST_PATH, True, True)
|
||||
return ConfigService.get_config_value(PASSWORD_LIST_PATH, True)
|
||||
|
||||
@staticmethod
|
||||
def get_config_exploits():
|
||||
|
@ -395,7 +395,7 @@ class ReportService:
|
|||
default_exploits = ConfigService.get_default_config(False)
|
||||
for namespace in exploits_config_value:
|
||||
default_exploits = default_exploits[namespace]
|
||||
exploits = ConfigService.get_config_value(exploits_config_value, True, True)
|
||||
exploits = ConfigService.get_config_value(exploits_config_value, True)
|
||||
|
||||
if exploits == default_exploits:
|
||||
return ["default"]
|
||||
|
@ -406,11 +406,11 @@ class ReportService:
|
|||
|
||||
@staticmethod
|
||||
def get_config_ips():
|
||||
return ConfigService.get_config_value(SUBNET_SCAN_LIST_PATH, True, True)
|
||||
return ConfigService.get_config_value(SUBNET_SCAN_LIST_PATH, True)
|
||||
|
||||
@staticmethod
|
||||
def get_config_scan():
|
||||
return ConfigService.get_config_value(LOCAL_NETWORK_SCAN_PATH, True, True)
|
||||
return ConfigService.get_config_value(LOCAL_NETWORK_SCAN_PATH, True)
|
||||
|
||||
@staticmethod
|
||||
def get_issue_set(issues, config_users, config_passwords):
|
||||
|
|
|
@ -11,6 +11,13 @@ def mock_port(monkeypatch, PORT):
|
|||
monkeypatch.setattr("monkey_island.cc.services.config.ISLAND_PORT", PORT)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_flat_config(monkeypatch, flat_monkey_config):
|
||||
monkeypatch.setattr(
|
||||
"monkey_island.cc.services.config.ConfigService.get_flat_config", lambda: flat_monkey_config
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.usefixtures("uses_encryptor")
|
||||
def test_set_server_ips_in_config_command_servers(config, IPS, PORT):
|
||||
|
@ -27,8 +34,8 @@ def test_set_server_ips_in_config_current_server(config, IPS, 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)
|
||||
def test_format_config_for_agent__credentials_removed():
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "exploit_lm_hash_list" not in flat_monkey_config
|
||||
assert "exploit_ntlm_hash_list" not in flat_monkey_config
|
||||
|
@ -37,7 +44,7 @@ def test_format_config_for_agent__credentials_removed(flat_monkey_config):
|
|||
assert "exploit_user_list" not in flat_monkey_config
|
||||
|
||||
|
||||
def test_format_config_for_agent__ransomware_payload(flat_monkey_config):
|
||||
def test_format_config_for_agent__ransomware_payload():
|
||||
expected_ransomware_options = {
|
||||
"ransomware": {
|
||||
"encryption": {
|
||||
|
@ -51,7 +58,7 @@ def test_format_config_for_agent__ransomware_payload(flat_monkey_config):
|
|||
}
|
||||
}
|
||||
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "payloads" in flat_monkey_config
|
||||
assert flat_monkey_config["payloads"] == expected_ransomware_options
|
||||
|
@ -59,7 +66,7 @@ def test_format_config_for_agent__ransomware_payload(flat_monkey_config):
|
|||
assert "ransomware" not in flat_monkey_config
|
||||
|
||||
|
||||
def test_format_config_for_agent__pbas(flat_monkey_config):
|
||||
def test_format_config_for_agent__pbas():
|
||||
expected_pbas_config = {
|
||||
"CommunicateAsBackdoorUser": {},
|
||||
"ModifyShellStartupFiles": {},
|
||||
|
@ -67,7 +74,7 @@ def test_format_config_for_agent__pbas(flat_monkey_config):
|
|||
"Timestomping": {},
|
||||
"AccountDiscovery": {},
|
||||
}
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "post_breach_actions" in flat_monkey_config
|
||||
assert flat_monkey_config["post_breach_actions"] == expected_pbas_config
|
||||
|
@ -78,7 +85,7 @@ def test_format_config_for_agent__pbas(flat_monkey_config):
|
|||
assert "PBA_windows_filename" not in flat_monkey_config
|
||||
|
||||
|
||||
def test_format_config_for_custom_pbas(flat_monkey_config):
|
||||
def test_format_config_for_custom_pbas():
|
||||
custom_config = {
|
||||
"linux_command": "bash test.sh",
|
||||
"windows_command": "powershell test.ps1",
|
||||
|
@ -86,7 +93,7 @@ def test_format_config_for_custom_pbas(flat_monkey_config):
|
|||
"windows_filename": "test.ps1",
|
||||
"current_server": "10.197.94.72:5000",
|
||||
}
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert flat_monkey_config["custom_pbas"] == custom_config
|
||||
|
||||
|
@ -104,8 +111,8 @@ def test_get_config_propagation_credentials_from_flat_config(flat_monkey_config)
|
|||
assert creds == expected_creds
|
||||
|
||||
|
||||
def test_format_config_for_agent__propagation(flat_monkey_config):
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
def test_format_config_for_agent__propagation():
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "propagation" in flat_monkey_config
|
||||
assert "targets" in flat_monkey_config["propagation"]
|
||||
|
@ -113,7 +120,7 @@ def test_format_config_for_agent__propagation(flat_monkey_config):
|
|||
assert "exploiters" in flat_monkey_config["propagation"]
|
||||
|
||||
|
||||
def test_format_config_for_agent__propagation_targets(flat_monkey_config):
|
||||
def test_format_config_for_agent__propagation_targets():
|
||||
expected_targets = {
|
||||
"blocked_ips": ["192.168.1.1", "192.168.1.100"],
|
||||
"inaccessible_subnets": ["10.0.0.0/24", "10.0.10.0/24"],
|
||||
|
@ -121,7 +128,7 @@ def test_format_config_for_agent__propagation_targets(flat_monkey_config):
|
|||
"subnet_scan_list": ["192.168.1.50", "192.168.56.0/24", "10.0.33.0/30"],
|
||||
}
|
||||
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert flat_monkey_config["propagation"]["targets"] == expected_targets
|
||||
assert "blocked_ips" not in flat_monkey_config
|
||||
|
@ -130,7 +137,7 @@ def test_format_config_for_agent__propagation_targets(flat_monkey_config):
|
|||
assert "subnet_scan_list" not in flat_monkey_config
|
||||
|
||||
|
||||
def test_format_config_for_agent__network_scan(flat_monkey_config):
|
||||
def test_format_config_for_agent__network_scan():
|
||||
expected_network_scan_config = {
|
||||
"tcp": {
|
||||
"timeout_ms": 3000,
|
||||
|
@ -164,7 +171,7 @@ def test_format_config_for_agent__network_scan(flat_monkey_config):
|
|||
{"name": "ssh", "options": {}},
|
||||
],
|
||||
}
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "propagation" in flat_monkey_config
|
||||
assert "network_scan" in flat_monkey_config["propagation"]
|
||||
|
@ -176,7 +183,7 @@ def test_format_config_for_agent__network_scan(flat_monkey_config):
|
|||
assert "finger_classes" not in flat_monkey_config
|
||||
|
||||
|
||||
def test_format_config_for_agent__exploiters(flat_monkey_config):
|
||||
def test_format_config_for_agent__exploiters():
|
||||
expected_exploiters_config = {
|
||||
"options": {
|
||||
"http_ports": [80, 443, 7001, 8008, 8080, 9200],
|
||||
|
@ -202,7 +209,7 @@ def test_format_config_for_agent__exploiters(flat_monkey_config):
|
|||
{"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}},
|
||||
],
|
||||
}
|
||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||
flat_monkey_config = ConfigService.format_flat_config_for_agent()
|
||||
|
||||
assert "propagation" in flat_monkey_config
|
||||
assert "exploiters" in flat_monkey_config["propagation"]
|
||||
|
|
Loading…
Reference in New Issue