forked from p15670423/monkey
Added ZeroLogon test to the BlackBox infrastructure.
This commit is contained in:
parent
3f687f6aea
commit
f6b0682297
|
@ -4,5 +4,5 @@ from abc import ABCMeta, abstractmethod
|
||||||
class Analyzer(object, metaclass=ABCMeta):
|
class Analyzer(object, metaclass=ABCMeta):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def analyze_test_results(self):
|
def analyze_test_results(self) -> bool:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
import dpath.util
|
||||||
|
|
||||||
|
from common.config_value_paths import USER_LIST_PATH, PASSWORD_LIST_PATH, NTLM_HASH_LIST_PATH, LM_HASH_LIST_PATH
|
||||||
|
from envs.monkey_zoo.blackbox.analyzers.analyzer import Analyzer
|
||||||
|
from envs.monkey_zoo.blackbox.analyzers.analyzer_log import AnalyzerLog
|
||||||
|
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient
|
||||||
|
|
||||||
|
# Query for telemetry collection to see if password restoration was successful
|
||||||
|
TELEM_QUERY = {'telem_category': 'exploit',
|
||||||
|
'data.exploiter': 'ZerologonExploiter',
|
||||||
|
'data.info.password_restored': True}
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroLogonAnalyzer(Analyzer):
|
||||||
|
|
||||||
|
def __init__(self, island_client: MonkeyIslandClient, expected_credentials: List[str]):
|
||||||
|
self.island_client = island_client
|
||||||
|
self.expected_credentials = expected_credentials
|
||||||
|
self.log = AnalyzerLog(self.__class__.__name__)
|
||||||
|
|
||||||
|
def analyze_test_results(self):
|
||||||
|
self.log.clear()
|
||||||
|
return self._analyze_credential_gathering() and self._analyze_credential_restore()
|
||||||
|
|
||||||
|
def _analyze_credential_gathering(self) -> bool:
|
||||||
|
credentials_on_island = []
|
||||||
|
config = self.island_client.get_config()
|
||||||
|
credentials_on_island.extend(dpath.util.get(config['configuration'], USER_LIST_PATH))
|
||||||
|
credentials_on_island.extend(dpath.util.get(config['configuration'], NTLM_HASH_LIST_PATH))
|
||||||
|
credentials_on_island.extend(dpath.util.get(config['configuration'], LM_HASH_LIST_PATH))
|
||||||
|
return ZeroLogonAnalyzer._is_all_credentials_in_list(self.expected_credentials,
|
||||||
|
credentials_on_island)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_all_credentials_in_list(expected_creds: List[str],
|
||||||
|
all_creds: List[str]) -> bool:
|
||||||
|
return all((cred in all_creds) for cred in expected_creds)
|
||||||
|
|
||||||
|
def _analyze_credential_restore(self) -> bool:
|
||||||
|
return bool(self.island_client.find_telems_in_db(TELEM_QUERY))
|
|
@ -0,0 +1,13 @@
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
|
from envs.monkey_zoo.blackbox.island_configs.base_template import BaseTemplate
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroLogon(BaseTemplate):
|
||||||
|
|
||||||
|
config_values = copy(BaseTemplate.config_values)
|
||||||
|
|
||||||
|
config_values.update({
|
||||||
|
"basic.exploiters.exploiter_classes": ["ZerologonExploiter"],
|
||||||
|
"basic_network.scope.subnet_scan_list": ["10.2.2.25"]
|
||||||
|
})
|
|
@ -7,6 +7,7 @@ from typing_extensions import Type
|
||||||
|
|
||||||
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import \
|
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import \
|
||||||
CommunicationAnalyzer
|
CommunicationAnalyzer
|
||||||
|
from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZeroLogonAnalyzer
|
||||||
from envs.monkey_zoo.blackbox.island_client.island_config_parser import \
|
from envs.monkey_zoo.blackbox.island_client.island_config_parser import \
|
||||||
IslandConfigParser
|
IslandConfigParser
|
||||||
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import \
|
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import \
|
||||||
|
@ -25,6 +26,7 @@ from envs.monkey_zoo.blackbox.island_configs.tunneling import Tunneling
|
||||||
from envs.monkey_zoo.blackbox.island_configs.weblogic import Weblogic
|
from envs.monkey_zoo.blackbox.island_configs.weblogic import Weblogic
|
||||||
from envs.monkey_zoo.blackbox.island_configs.wmi_mimikatz import WmiMimikatz
|
from envs.monkey_zoo.blackbox.island_configs.wmi_mimikatz import WmiMimikatz
|
||||||
from envs.monkey_zoo.blackbox.island_configs.wmi_pth import WmiPth
|
from envs.monkey_zoo.blackbox.island_configs.wmi_pth import WmiPth
|
||||||
|
from envs.monkey_zoo.blackbox.island_configs.zerologon import ZeroLogon
|
||||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import \
|
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import \
|
||||||
TestLogsHandler
|
TestLogsHandler
|
||||||
from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest
|
from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest
|
||||||
|
@ -160,6 +162,21 @@ class TestMonkeyBlackbox:
|
||||||
def test_wmi_pth(self, island_client):
|
def test_wmi_pth(self, island_client):
|
||||||
TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH")
|
TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH")
|
||||||
|
|
||||||
|
def test_zerologon_exploiter(self, island_client):
|
||||||
|
test_name = "ZeroLogon_exploiter"
|
||||||
|
expected_creds = ["test_username", "test_ntlm_hash"]
|
||||||
|
raw_config = IslandConfigParser.get_raw_config(ZeroLogon, island_client)
|
||||||
|
analyzer = ZeroLogonAnalyzer(island_client, expected_creds)
|
||||||
|
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=DEFAULT_TIMEOUT_SECONDS,
|
||||||
|
log_handler=log_handler).run()
|
||||||
|
TestMonkeyBlackbox.run_exploitation_test(island_client, ZeroLogon, "ZeroLogon_exploiter")
|
||||||
|
|
||||||
@pytest.mark.skip(reason="Perfomance test that creates env from fake telemetries is faster, use that instead.")
|
@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):
|
def test_report_generation_performance(self, island_client, quick_performance_tests):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue