forked from p34709852/monkey
Merge branch '2000-configuration-resource' into 1960-configuration-object
PR #2038
This commit is contained in:
commit
d079d74b2c
|
@ -1,7 +1,4 @@
|
||||||
from marshmallow import Schema, fields, post_load
|
from marshmallow import Schema, fields, post_load
|
||||||
from marshmallow_enum import EnumField
|
|
||||||
|
|
||||||
from common import OperatingSystems
|
|
||||||
|
|
||||||
from .agent_sub_configurations import (
|
from .agent_sub_configurations import (
|
||||||
CustomPBAConfiguration,
|
CustomPBAConfiguration,
|
||||||
|
@ -87,7 +84,6 @@ class ExploitationOptionsConfigurationSchema(Schema):
|
||||||
class ExploiterConfigurationSchema(Schema):
|
class ExploiterConfigurationSchema(Schema):
|
||||||
name = fields.Str()
|
name = fields.Str()
|
||||||
options = fields.Mapping()
|
options = fields.Mapping()
|
||||||
supported_os = fields.List(EnumField(OperatingSystems))
|
|
||||||
|
|
||||||
@post_load
|
@post_load
|
||||||
def _make_exploiter_configuration(self, data, **kwargs):
|
def _make_exploiter_configuration(self, data, **kwargs):
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from common import OperatingSystems
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class CustomPBAConfiguration:
|
class CustomPBAConfiguration:
|
||||||
|
@ -54,7 +52,6 @@ class ExploitationOptionsConfiguration:
|
||||||
class ExploiterConfiguration:
|
class ExploiterConfiguration:
|
||||||
name: str
|
name: str
|
||||||
options: Dict
|
options: Dict
|
||||||
supported_os: List[OperatingSystems]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|
|
@ -157,60 +157,44 @@ DEFAULT_AGENT_CONFIGURATION_JSON = """{
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{
|
{
|
||||||
"name": "MSSQLExploiter",
|
"name": "MSSQLExploiter",
|
||||||
"options": {},
|
"options": {}
|
||||||
"supported_os": [
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PowerShellExploiter",
|
"name": "PowerShellExploiter",
|
||||||
"options": {},
|
"options": {}
|
||||||
"supported_os": [
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SSHExploiter",
|
"name": "SSHExploiter",
|
||||||
"options": {},
|
"options": {}
|
||||||
"supported_os": [
|
|
||||||
"LINUX"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SmbExploiter",
|
"name": "SmbExploiter",
|
||||||
"options": {
|
"options": {
|
||||||
"smb_download_timeout": 30
|
"smb_download_timeout": 30
|
||||||
},
|
}
|
||||||
"supported_os": [
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WmiExploiter",
|
"name": "WmiExploiter",
|
||||||
"options": {
|
"options": {
|
||||||
"smb_download_timeout": 30
|
"smb_download_timeout": 30
|
||||||
},
|
}
|
||||||
"supported_os": [
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{
|
{
|
||||||
"name": "HadoopExploiter",
|
"name": "HadoopExploiter",
|
||||||
"options": {},
|
"options": {}
|
||||||
"supported_os": [
|
|
||||||
"LINUX",
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Log4ShellExploiter",
|
"name": "Log4ShellExploiter",
|
||||||
"options": {},
|
"options": {}
|
||||||
"supported_os": [
|
|
||||||
"LINUX",
|
|
||||||
"WINDOWS"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ from queue import Queue
|
||||||
from threading import Event
|
from threading import Event
|
||||||
from typing import Callable, Dict, List, Mapping
|
from typing import Callable, Dict, List, Mapping
|
||||||
|
|
||||||
|
from common import OperatingSystems
|
||||||
from infection_monkey.custom_types import PropagationCredentials
|
from infection_monkey.custom_types import PropagationCredentials
|
||||||
from infection_monkey.i_puppet import ExploiterResultData, IPuppet
|
from infection_monkey.i_puppet import ExploiterResultData, IPuppet
|
||||||
from infection_monkey.model import VictimHost
|
from infection_monkey.model import VictimHost
|
||||||
|
@ -20,6 +21,18 @@ ExploiterName = str
|
||||||
Callback = Callable[[ExploiterName, VictimHost, ExploiterResultData], None]
|
Callback = Callable[[ExploiterName, VictimHost, ExploiterResultData], None]
|
||||||
|
|
||||||
|
|
||||||
|
SUPPORTED_OS = {
|
||||||
|
"HadoopExploiter": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
||||||
|
"Log4ShellExploiter": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
||||||
|
"MSSQLExploiter": [OperatingSystems.WINDOWS],
|
||||||
|
"PowerShellExploiter": [OperatingSystems.WINDOWS],
|
||||||
|
"SSHExploiter": [OperatingSystems.LINUX],
|
||||||
|
"SmbExploiter": [OperatingSystems.WINDOWS],
|
||||||
|
"WmiExploiter": [OperatingSystems.WINDOWS],
|
||||||
|
"ZerologonExploiter": [OperatingSystems.WINDOWS],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Exploiter:
|
class Exploiter:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -118,7 +131,8 @@ class Exploiter:
|
||||||
victim_os = victim_host.os.get("type")
|
victim_os = victim_host.os.get("type")
|
||||||
|
|
||||||
# We want to try all exploiters if the victim's OS is unknown
|
# We want to try all exploiters if the victim's OS is unknown
|
||||||
if victim_os is not None and victim_os not in exploiter["supported_os"]:
|
print(victim_os)
|
||||||
|
if victim_os is not None and victim_os not in SUPPORTED_OS[exploiter_name]:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Skipping {exploiter_name} because it does not support "
|
f"Skipping {exploiter_name} because it does not support "
|
||||||
f"the victim's OS ({victim_os})"
|
f"the victim's OS ({victim_os})"
|
||||||
|
|
|
@ -12,6 +12,7 @@ from common import DIContainer
|
||||||
from monkey_island.cc.database import database, mongo
|
from monkey_island.cc.database import database, mongo
|
||||||
from monkey_island.cc.resources import AgentBinaries, RemoteRun
|
from monkey_island.cc.resources import AgentBinaries, RemoteRun
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
|
from monkey_island.cc.resources.agent_configuration import AgentConfiguration
|
||||||
from monkey_island.cc.resources.agent_controls import StopAgentCheck, StopAllAgents
|
from monkey_island.cc.resources.agent_controls import StopAgentCheck, StopAllAgents
|
||||||
from monkey_island.cc.resources.attack.attack_report import AttackReport
|
from monkey_island.cc.resources.attack.attack_report import AttackReport
|
||||||
from monkey_island.cc.resources.auth.auth import Authenticate, init_jwt
|
from monkey_island.cc.resources.auth.auth import Authenticate, init_jwt
|
||||||
|
@ -155,6 +156,7 @@ def init_api_resources(api: FlaskDIWrapper):
|
||||||
api.add_resource(IslandConfiguration)
|
api.add_resource(IslandConfiguration)
|
||||||
api.add_resource(ConfigurationExport)
|
api.add_resource(ConfigurationExport)
|
||||||
api.add_resource(ConfigurationImport)
|
api.add_resource(ConfigurationImport)
|
||||||
|
api.add_resource(AgentConfiguration)
|
||||||
api.add_resource(AgentBinaries)
|
api.add_resource(AgentBinaries)
|
||||||
api.add_resource(NetMap)
|
api.add_resource(NetMap)
|
||||||
api.add_resource(Edge)
|
api.add_resource(Edge)
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
import marshmallow
|
||||||
|
from flask import make_response, request
|
||||||
|
|
||||||
|
from common.configuration.agent_configuration import AgentConfigurationSchema
|
||||||
|
from monkey_island.cc.repository import IAgentConfigurationRepository
|
||||||
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
|
|
||||||
|
|
||||||
|
class AgentConfiguration(AbstractResource):
|
||||||
|
urls = ["/api/agent-configuration"]
|
||||||
|
|
||||||
|
def __init__(self, agent_configuration_repository: IAgentConfigurationRepository):
|
||||||
|
self._agent_configuration_repository = agent_configuration_repository
|
||||||
|
self._schema = AgentConfigurationSchema()
|
||||||
|
|
||||||
|
@jwt_required
|
||||||
|
def get(self):
|
||||||
|
configuration = self._agent_configuration_repository.get_configuration()
|
||||||
|
configuration_json = self._schema.dumps(configuration)
|
||||||
|
return make_response(configuration_json, 200)
|
||||||
|
|
||||||
|
@jwt_required
|
||||||
|
def post(self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
configuration_object = self._schema.loads(request.data)
|
||||||
|
self._agent_configuration_repository.store_configuration(configuration_object)
|
||||||
|
return make_response({}, 200)
|
||||||
|
except (marshmallow.exceptions.ValidationError, json.JSONDecodeError) as err:
|
||||||
|
return make_response(
|
||||||
|
{"message": f"Invalid configuration supplied: {err}"},
|
||||||
|
400,
|
||||||
|
)
|
|
@ -3,12 +3,10 @@ import copy
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from itertools import chain
|
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from jsonschema import Draft4Validator, validators
|
from jsonschema import Draft4Validator, validators
|
||||||
|
|
||||||
from common import OperatingSystems
|
|
||||||
from common.config_value_paths import (
|
from common.config_value_paths import (
|
||||||
LM_HASH_LIST_PATH,
|
LM_HASH_LIST_PATH,
|
||||||
NTLM_HASH_LIST_PATH,
|
NTLM_HASH_LIST_PATH,
|
||||||
|
@ -580,7 +578,7 @@ class ConfigService:
|
||||||
formatted_exploiters_config = ConfigService._add_smb_download_timeout_to_exploiters(
|
formatted_exploiters_config = ConfigService._add_smb_download_timeout_to_exploiters(
|
||||||
formatted_exploiters_config
|
formatted_exploiters_config
|
||||||
)
|
)
|
||||||
return ConfigService._add_supported_os_to_exploiters(formatted_exploiters_config)
|
return formatted_exploiters_config
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_smb_download_timeout_to_exploiters(
|
def _add_smb_download_timeout_to_exploiters(
|
||||||
|
@ -593,23 +591,3 @@ class ConfigService:
|
||||||
exploiter["options"]["smb_download_timeout"] = SMB_DOWNLOAD_TIMEOUT
|
exploiter["options"]["smb_download_timeout"] = SMB_DOWNLOAD_TIMEOUT
|
||||||
|
|
||||||
return new_config
|
return new_config
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _add_supported_os_to_exploiters(
|
|
||||||
formatted_config: Dict,
|
|
||||||
) -> Dict[str, List[Dict[str, Any]]]:
|
|
||||||
supported_os = {
|
|
||||||
"HadoopExploiter": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
|
||||||
"Log4ShellExploiter": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
|
||||||
"MSSQLExploiter": [OperatingSystems.WINDOWS],
|
|
||||||
"PowerShellExploiter": [OperatingSystems.WINDOWS],
|
|
||||||
"SSHExploiter": [OperatingSystems.LINUX],
|
|
||||||
"SmbExploiter": [OperatingSystems.WINDOWS],
|
|
||||||
"WmiExploiter": [OperatingSystems.WINDOWS],
|
|
||||||
"ZerologonExploiter": [OperatingSystems.WINDOWS],
|
|
||||||
}
|
|
||||||
new_config = copy.deepcopy(formatted_config)
|
|
||||||
for exploiter in chain(new_config["brute_force"], new_config["vulnerability"]):
|
|
||||||
exploiter["supported_os"] = supported_os.get(exploiter["name"], [])
|
|
||||||
|
|
||||||
return new_config
|
|
||||||
|
|
|
@ -39,18 +39,16 @@ NETWORK_SCAN_CONFIGURATION = {
|
||||||
}
|
}
|
||||||
|
|
||||||
BRUTE_FORCE = [
|
BRUTE_FORCE = [
|
||||||
{"name": "ex1", "options": {}, "supported_os": ["LINUX"]},
|
{"name": "ex1", "options": {}},
|
||||||
{
|
{
|
||||||
"name": "ex2",
|
"name": "ex2",
|
||||||
"options": {"smb_download_timeout": 10},
|
"options": {"smb_download_timeout": 10},
|
||||||
"supported_os": ["LINUX", "WINDOWS"],
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
VULNERABILITY = [
|
VULNERABILITY = [
|
||||||
{
|
{
|
||||||
"name": "ex3",
|
"name": "ex3",
|
||||||
"options": {"smb_download_timeout": 10},
|
"options": {"smb_download_timeout": 10},
|
||||||
"supported_os": ["WINDOWS"],
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
EXPLOITATION_CONFIGURATION = {
|
EXPLOITATION_CONFIGURATION = {
|
||||||
|
|
|
@ -47,16 +47,16 @@
|
||||||
"exploiters": {
|
"exploiters": {
|
||||||
"options": {},
|
"options": {},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{"name": "MSSQLExploiter", "supported_os": ["windows"], "options": {}},
|
{"name": "MSSQLExploiter", "options": {}},
|
||||||
{"name": "PowerShellExploiter", "supported_os": ["windows"], "options": {}},
|
{"name": "PowerShellExploiter", "options": {}},
|
||||||
{"name": "SmbExploiter", "supported_os": ["windows"], "options": {}},
|
{"name": "SmbExploiter", "options": {}},
|
||||||
{"name": "SSHExploiter", "supported_os": ["linux"], "options": {}},
|
{"name": "SSHExploiter", "options": {}},
|
||||||
{"name": "WmiExploiter", "supported_os": ["windows"], "options": {}}
|
{"name": "WmiExploiter", "options": {}}
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{"name": "HadoopExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
{"name": "HadoopExploiter", "options": {}},
|
||||||
{"name": "ShellShockExploiter", "supported_os": ["linux"], "options": {}},
|
{"name": "ShellShockExploiter", "options": {}},
|
||||||
{"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}}
|
{"name": "ZerologonExploiter", "options": {}}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from .single_file_repository import SingleFileRepository
|
from .single_file_repository import SingleFileRepository
|
||||||
from .mock_file_repository import MockFileRepository, FILE_CONTENTS, FILE_NAME
|
from .mock_file_repository import MockFileRepository, FILE_CONTENTS, FILE_NAME
|
||||||
from .open_error_file_repository import OpenErrorFileRepository
|
from .open_error_file_repository import OpenErrorFileRepository
|
||||||
|
from .in_memory_agent_configuration_repository import InMemoryAgentConfigurationRepository
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
from tests.common.example_agent_configuration import AGENT_CONFIGURATION
|
||||||
|
|
||||||
|
from common.configuration.agent_configuration import AgentConfigurationSchema
|
||||||
|
from monkey_island.cc.repository import IAgentConfigurationRepository
|
||||||
|
|
||||||
|
|
||||||
|
class InMemoryAgentConfigurationRepository(IAgentConfigurationRepository):
|
||||||
|
def __init__(self):
|
||||||
|
self._configuration = AgentConfigurationSchema().load(AGENT_CONFIGURATION)
|
||||||
|
|
||||||
|
def get_configuration(self):
|
||||||
|
return self._configuration
|
||||||
|
|
||||||
|
def store_configuration(self, agent_configuration):
|
||||||
|
self._configuration = agent_configuration
|
|
@ -23,7 +23,6 @@ from tests.common.example_agent_configuration import (
|
||||||
WINDOWS_FILENAME,
|
WINDOWS_FILENAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
from common import OperatingSystems
|
|
||||||
from common.configuration import (
|
from common.configuration import (
|
||||||
DEFAULT_AGENT_CONFIGURATION_JSON,
|
DEFAULT_AGENT_CONFIGURATION_JSON,
|
||||||
AgentConfiguration,
|
AgentConfiguration,
|
||||||
|
@ -126,16 +125,12 @@ def test_exploitation_options_configuration_schema():
|
||||||
def test_exploiter_configuration_schema():
|
def test_exploiter_configuration_schema():
|
||||||
name = "bond"
|
name = "bond"
|
||||||
options = {"gun": "Walther PPK", "car": "Aston Martin DB5"}
|
options = {"gun": "Walther PPK", "car": "Aston Martin DB5"}
|
||||||
supported_os = [OperatingSystems.LINUX, OperatingSystems.WINDOWS]
|
|
||||||
schema = ExploiterConfigurationSchema()
|
schema = ExploiterConfigurationSchema()
|
||||||
|
|
||||||
config = schema.load(
|
config = schema.load({"name": name, "options": options})
|
||||||
{"name": name, "options": options, "supported_os": [os_.name for os_ in supported_os]}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert config.name == name
|
assert config.name == name
|
||||||
assert config.options == options
|
assert config.options == options
|
||||||
assert config.supported_os == supported_os
|
|
||||||
|
|
||||||
|
|
||||||
def test_exploitation_configuration():
|
def test_exploitation_configuration():
|
||||||
|
|
|
@ -2,6 +2,7 @@ from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from common import OperatingSystems
|
||||||
from infection_monkey.exploit.tools.helpers import (
|
from infection_monkey.exploit.tools.helpers import (
|
||||||
AGENT_BINARY_PATH_LINUX,
|
AGENT_BINARY_PATH_LINUX,
|
||||||
AGENT_BINARY_PATH_WIN64,
|
AGENT_BINARY_PATH_WIN64,
|
||||||
|
@ -13,22 +14,28 @@ from infection_monkey.exploit.tools.helpers import (
|
||||||
def _get_host(os):
|
def _get_host(os):
|
||||||
host = Mock()
|
host = Mock()
|
||||||
host.os = {"type": os}
|
host.os = {"type": os}
|
||||||
|
host.is_windows = lambda: os == OperatingSystems.WINDOWS
|
||||||
return host
|
return host
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"os, path", [("linux", AGENT_BINARY_PATH_LINUX), ("windows", AGENT_BINARY_PATH_WIN64)]
|
"os, path",
|
||||||
|
[
|
||||||
|
(OperatingSystems.LINUX, AGENT_BINARY_PATH_LINUX),
|
||||||
|
(OperatingSystems.WINDOWS, AGENT_BINARY_PATH_WIN64),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
def test_get_agent_dst_path(os, path):
|
def test_get_agent_dst_path(os, path):
|
||||||
host = _get_host(os)
|
host = _get_host(os)
|
||||||
rand_path = get_agent_dst_path(host)
|
rand_path = get_agent_dst_path(host)
|
||||||
|
print(f"{os}: {rand_path}")
|
||||||
|
|
||||||
# Assert that filename got longer by RAND_SUFFIX_LEN and one dash
|
# Assert that filename got longer by RAND_SUFFIX_LEN and one dash
|
||||||
assert len(str(rand_path)) == (len(str(path)) + RAND_SUFFIX_LEN + 1)
|
assert len(str(rand_path)) == (len(str(path)) + RAND_SUFFIX_LEN + 1)
|
||||||
|
|
||||||
|
|
||||||
def test_get_agent_dst_path_randomness():
|
def test_get_agent_dst_path_randomness():
|
||||||
host = _get_host("windows")
|
host = _get_host(OperatingSystems.WINDOWS)
|
||||||
|
|
||||||
path1 = get_agent_dst_path(host)
|
path1 = get_agent_dst_path(host)
|
||||||
path2 = get_agent_dst_path(host)
|
path2 = get_agent_dst_path(host)
|
||||||
|
@ -37,7 +44,7 @@ def test_get_agent_dst_path_randomness():
|
||||||
|
|
||||||
|
|
||||||
def test_get_agent_dst_path_str_place():
|
def test_get_agent_dst_path_str_place():
|
||||||
host = _get_host("windows")
|
host = _get_host(OperatingSystems.WINDOWS)
|
||||||
|
|
||||||
rand_path = get_agent_dst_path(host)
|
rand_path = get_agent_dst_path(host)
|
||||||
|
|
||||||
|
|
|
@ -39,24 +39,12 @@ def exploiter_config():
|
||||||
return {
|
return {
|
||||||
"options": {"dropper_path_linux": "/tmp/monkey"},
|
"options": {"dropper_path_linux": "/tmp/monkey"},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{
|
{"name": "MSSQLExploiter", "options": {"timeout": 10}},
|
||||||
"name": "HadoopExploiter",
|
{"name": "SSHExploiter", "options": {}},
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
{"name": "WmiExploiter", "options": {"timeout": 10}},
|
||||||
"options": {"timeout": 10},
|
|
||||||
},
|
|
||||||
{"name": "SSHExploiter", "supported_os": [OperatingSystems.LINUX], "options": {}},
|
|
||||||
{
|
|
||||||
"name": "WmiExploiter",
|
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {"timeout": 10},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{
|
{"name": "ZerologonExploiter", "options": {}},
|
||||||
"name": "ZerologonExploiter",
|
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +106,11 @@ def test_exploiter(callback, hosts, hosts_to_exploit, run_exploiters):
|
||||||
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("HadoopExploiter", hosts[0]) in host_exploit_combos
|
assert ("MSSQLExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("SSHExploiter", hosts[0]) in host_exploit_combos
|
assert ("SSHExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("ZerologonExploiter", hosts[1]) in host_exploit_combos
|
assert ("ZerologonExploiter", hosts[1]) in host_exploit_combos
|
||||||
assert ("HadoopExploiter", hosts[1]) in host_exploit_combos
|
assert ("MSSQLExploiter", hosts[1]) in host_exploit_combos
|
||||||
assert ("WmiExploiter", hosts[1]) in host_exploit_combos
|
assert ("WmiExploiter", hosts[1]) in host_exploit_combos
|
||||||
assert ("SSHExploiter", hosts[1]) in host_exploit_combos
|
assert ("SSHExploiter", hosts[1]) in host_exploit_combos
|
||||||
|
|
||||||
|
@ -209,6 +197,6 @@ def test_all_exploiters_run_on_unknown_host(callback, hosts, hosts_to_exploit, r
|
||||||
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("HadoopExploiter", hosts[0]) in host_exploit_combos
|
assert ("MSSQLExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("SSHExploiter", host) in host_exploit_combos
|
assert ("SSHExploiter", host) in host_exploit_combos
|
||||||
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from tests.common import StubDIContainer
|
||||||
|
from tests.common.example_agent_configuration import AGENT_CONFIGURATION
|
||||||
|
from tests.monkey_island import InMemoryAgentConfigurationRepository
|
||||||
|
from tests.unit_tests.monkey_island.conftest import get_url_for_resource
|
||||||
|
|
||||||
|
from monkey_island.cc.repository import IAgentConfigurationRepository
|
||||||
|
from monkey_island.cc.resources.agent_configuration import AgentConfiguration
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def flask_client(build_flask_client):
|
||||||
|
container = StubDIContainer()
|
||||||
|
|
||||||
|
container.register(IAgentConfigurationRepository, InMemoryAgentConfigurationRepository)
|
||||||
|
|
||||||
|
with build_flask_client(container) as flask_client:
|
||||||
|
yield flask_client
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_configuration_endpoint(flask_client):
|
||||||
|
agent_configuration_url = get_url_for_resource(AgentConfiguration)
|
||||||
|
|
||||||
|
flask_client.post(
|
||||||
|
agent_configuration_url, data=json.dumps(AGENT_CONFIGURATION), follow_redirects=True
|
||||||
|
)
|
||||||
|
resp = flask_client.get(agent_configuration_url)
|
||||||
|
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert json.loads(resp.data) == AGENT_CONFIGURATION
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_configuration_invalid_config(flask_client):
|
||||||
|
agent_configuration_url = get_url_for_resource(AgentConfiguration)
|
||||||
|
|
||||||
|
resp = flask_client.post(
|
||||||
|
agent_configuration_url, data=json.dumps({"invalid_config": "invalid_stuff"})
|
||||||
|
)
|
||||||
|
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_configuration_invalid_json(flask_client):
|
||||||
|
agent_configuration_url = get_url_for_resource(AgentConfiguration)
|
||||||
|
|
||||||
|
resp = flask_client.post(agent_configuration_url, data="InvalidJson!")
|
||||||
|
|
||||||
|
assert resp.status_code == 400
|
|
@ -1,6 +1,5 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from common import OperatingSystems
|
|
||||||
from monkey_island.cc.services.config import ConfigService
|
from monkey_island.cc.services.config import ConfigService
|
||||||
|
|
||||||
# If tests fail because config path is changed, sync with
|
# If tests fail because config path is changed, sync with
|
||||||
|
@ -172,38 +171,32 @@ def test_format_config_for_agent__exploiters():
|
||||||
"http_ports": [80, 443, 7001, 8008, 8080, 9200],
|
"http_ports": [80, 443, 7001, 8008, 8080, 9200],
|
||||||
},
|
},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{"name": "MSSQLExploiter", "supported_os": [OperatingSystems.WINDOWS], "options": {}},
|
{"name": "MSSQLExploiter", "options": {}},
|
||||||
{
|
{
|
||||||
"name": "PowerShellExploiter",
|
"name": "PowerShellExploiter",
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {},
|
"options": {},
|
||||||
},
|
},
|
||||||
{"name": "SSHExploiter", "supported_os": [OperatingSystems.LINUX], "options": {}},
|
{"name": "SSHExploiter", "options": {}},
|
||||||
{
|
{
|
||||||
"name": "SmbExploiter",
|
"name": "SmbExploiter",
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {"smb_download_timeout": 30},
|
"options": {"smb_download_timeout": 30},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WmiExploiter",
|
"name": "WmiExploiter",
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {"smb_download_timeout": 30},
|
"options": {"smb_download_timeout": 30},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{
|
{
|
||||||
"name": "HadoopExploiter",
|
"name": "HadoopExploiter",
|
||||||
"supported_os": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
|
||||||
"options": {},
|
"options": {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Log4ShellExploiter",
|
"name": "Log4ShellExploiter",
|
||||||
"supported_os": [OperatingSystems.LINUX, OperatingSystems.WINDOWS],
|
|
||||||
"options": {},
|
"options": {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ZerologonExploiter",
|
"name": "ZerologonExploiter",
|
||||||
"supported_os": [OperatingSystems.WINDOWS],
|
|
||||||
"options": {},
|
"options": {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue