From c6cb4774747e63392eb777727d14eeb3c7ed956b Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 15 Aug 2022 17:54:40 +0200 Subject: [PATCH 01/12] Agent: Add event_queue to the exploit_host in HostExploiter --- monkey/infection_monkey/exploit/HostExploiter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monkey/infection_monkey/exploit/HostExploiter.py b/monkey/infection_monkey/exploit/HostExploiter.py index 602dd338a..4b0c78c21 100644 --- a/monkey/infection_monkey/exploit/HostExploiter.py +++ b/monkey/infection_monkey/exploit/HostExploiter.py @@ -4,6 +4,7 @@ from abc import abstractmethod from datetime import datetime from typing import Dict +from common.event_queue import IEventQueue from common.utils.exceptions import FailedExploitationError from infection_monkey.i_puppet import ExploiterResultData from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger @@ -31,6 +32,7 @@ class HostExploiter: self.exploit_attempts = [] self.host = None self.telemetry_messenger = None + self.event_queue = None self.options = {} self.exploit_result = {} @@ -58,6 +60,7 @@ class HostExploiter: host, current_depth: int, telemetry_messenger: ITelemetryMessenger, + event_queue: IEventQueue, agent_repository: IAgentRepository, options: Dict, interrupt: threading.Event, @@ -65,6 +68,7 @@ class HostExploiter: self.host = host self.current_depth = current_depth self.telemetry_messenger = telemetry_messenger + self.event_queue = event_queue self.agent_repository = agent_repository self.options = options self.interrupt = interrupt From f171e548f3b1cc9e92daed36529490d55dd8a1c2 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 15 Aug 2022 17:55:25 +0200 Subject: [PATCH 02/12] Agent: Modify exploiter wrapper to accept IEventQueue --- monkey/infection_monkey/exploit/exploiter_wrapper.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/exploit/exploiter_wrapper.py b/monkey/infection_monkey/exploit/exploiter_wrapper.py index 540e0b4a4..8e9d4f22f 100644 --- a/monkey/infection_monkey/exploit/exploiter_wrapper.py +++ b/monkey/infection_monkey/exploit/exploiter_wrapper.py @@ -1,6 +1,7 @@ import threading from typing import Dict, Type +from common.event_queue import IEventQueue from infection_monkey.model import VictimHost from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger @@ -21,10 +22,12 @@ class ExploiterWrapper: self, exploit_class: Type[HostExploiter], telemetry_messenger: ITelemetryMessenger, + event_queue: IEventQueue, agent_repository: IAgentRepository, ): self._exploit_class = exploit_class self._telemetry_messenger = telemetry_messenger + self._event_queue = event_queue self._agent_repository = agent_repository def exploit_host( @@ -35,18 +38,23 @@ class ExploiterWrapper: host, current_depth, self._telemetry_messenger, + self._event_queue, self._agent_repository, options, interrupt, ) def __init__( - self, telemetry_messenger: ITelemetryMessenger, agent_repository: IAgentRepository + self, + telemetry_messenger: ITelemetryMessenger, + event_queue: IEventQueue, + agent_repository: IAgentRepository, ): self._telemetry_messenger = telemetry_messenger + self._event_queue = event_queue self._agent_repository = agent_repository def wrap(self, exploit_class: Type[HostExploiter]): return ExploiterWrapper.Inner( - exploit_class, self._telemetry_messenger, self._agent_repository + exploit_class, self._telemetry_messenger, self._event_queue, self._agent_repository ) From 76bbe62c3bee615e577a0d57ad13dd0677d4c234 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 15 Aug 2022 17:58:05 +0200 Subject: [PATCH 03/12] Agent: Modify Zerologon to publish CredentialsStolenEvent --- monkey/infection_monkey/exploit/zerologon.py | 28 ++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 276b0c529..36686a728 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -9,7 +9,8 @@ import os import re import tempfile from binascii import unhexlify -from typing import Dict, List, Optional, Tuple +from time import time +from typing import Dict, List, Optional, Sequence, Tuple import impacket from impacket.dcerpc.v5 import epm, nrpc, rpcrt, transport @@ -17,6 +18,8 @@ from impacket.dcerpc.v5.dtypes import NULL from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT from common.credentials import Credentials, LMHash, NTHash, Username +from common.events import CredentialsStolenEvent +from infection_monkey.config import IGUID from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.tools.wmi_tools import WmiTools from infection_monkey.exploit.zerologon_utils.dump_secrets import DumpSecrets @@ -284,14 +287,23 @@ class ZerologonExploiter(HostExploiter): def send_extracted_creds_as_credential_telemetry( self, user: str, lmhash: str, nthash: str ) -> None: - self.telemetry_messenger.send_telemetry( - CredentialsTelem( - [ - Credentials(Username(user), LMHash(lmhash)), - Credentials(Username(user), NTHash(nthash)), - ] - ) + extracted_credentials = [ + Credentials(Username(user), LMHash(lmhash)), + Credentials(Username(user), NTHash(nthash)), + ] + + self.telemetry_messenger.send_telemetry(CredentialsTelem(extracted_credentials)) + self._publish_credentials_stolen_event(extracted_credentials) + + def _publish_credentials_stolen_event(self, extracted_credentials: Sequence[Credentials]): + credentials_stolen_event = CredentialsStolenEvent( + source=IGUID, + target=None, + timestamp=time(), + tags=({"ZerologonCredentialsStolen"}), + stolen_credentials=extracted_credentials, ) + self.event_queue.publish(credentials_stolen_event) def get_original_pwd_nthash(self, username: str, user_pwd_hashes: List[str]) -> str: if not self.save_HKLM_keys_locally(username, user_pwd_hashes): From aaef2f1f8120bb67458e17f73a482f496345d260 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 15 Aug 2022 17:59:20 +0200 Subject: [PATCH 04/12] UT: Fix Powershell tests to accept IEventQueue --- .../tests/unit_tests/infection_monkey/exploit/test_powershell.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py b/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py index c5d428f47..a764de832 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py @@ -36,6 +36,7 @@ def powershell_arguments(http_and_https_both_enabled_host): "options": options, "current_depth": 2, "telemetry_messenger": MagicMock(), + "event_queue": MagicMock(), "agent_repository": mock_agent_repository, "interrupt": threading.Event(), } From d400fcb2157ee4fa245e0a154da6d9e84e34f0fc Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 12:13:29 +0200 Subject: [PATCH 05/12] Agent: Extract zerologon tags into constant --- monkey/infection_monkey/exploit/zerologon.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 36686a728..ae8eb5d79 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -9,7 +9,6 @@ import os import re import tempfile from binascii import unhexlify -from time import time from typing import Dict, List, Optional, Sequence, Tuple import impacket @@ -19,7 +18,6 @@ from impacket.dcerpc.v5.dtypes import NULL from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT from common.credentials import Credentials, LMHash, NTHash, Username from common.events import CredentialsStolenEvent -from infection_monkey.config import IGUID from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.tools.wmi_tools import WmiTools from infection_monkey.exploit.zerologon_utils.dump_secrets import DumpSecrets @@ -33,6 +31,10 @@ from infection_monkey.utils.threading import interruptible_iter logger = logging.getLogger(__name__) +ZEROLOGON_EXPLOIT_TAG = "ZerologonCredentialsStolen" + +ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG} + class ZerologonExploiter(HostExploiter): _EXPLOITED_SERVICE = "Netlogon" @@ -297,10 +299,8 @@ class ZerologonExploiter(HostExploiter): def _publish_credentials_stolen_event(self, extracted_credentials: Sequence[Credentials]): credentials_stolen_event = CredentialsStolenEvent( - source=IGUID, target=None, - timestamp=time(), - tags=({"ZerologonCredentialsStolen"}), + tags=(ZEROLOGON_EVENT_TAGS), stolen_credentials=extracted_credentials, ) self.event_queue.publish(credentials_stolen_event) From 550c7465fa23a9cca1d8f14589667ab448ad8cb5 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 12:16:20 +0200 Subject: [PATCH 06/12] Agent: Add IEventQueue to ExploitWrapper --- monkey/infection_monkey/monkey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 60ad0524a..24e085e87 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -272,7 +272,7 @@ class InfectionMonkey: agent_repository = CachingAgentRepository( f"https://{self._control_client.server_address}", self._control_client.proxies ) - exploit_wrapper = ExploiterWrapper(self._telemetry_messenger, agent_repository) + exploit_wrapper = ExploiterWrapper(self._telemetry_messenger, event_queue, agent_repository) puppet.load_plugin( "HadoopExploiter", exploit_wrapper.wrap(HadoopExploiter), PluginType.EXPLOITER From b0f76383c44281a3d0fd300232cdc2d0e05bb3d6 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 14:34:21 +0200 Subject: [PATCH 07/12] Agent: Change zerologon tag to `zerologon-exploiter ` --- monkey/infection_monkey/exploit/zerologon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index ae8eb5d79..091664bbb 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -31,7 +31,7 @@ from infection_monkey.utils.threading import interruptible_iter logger = logging.getLogger(__name__) -ZEROLOGON_EXPLOIT_TAG = "ZerologonCredentialsStolen" +ZEROLOGON_EXPLOIT_TAG = "zerologon-exploiter" ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG} From 3c8091d2429c8c4570974c469854019358029554 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 16:25:34 +0200 Subject: [PATCH 08/12] Agent: Add T1003 tag to zerologon exploiter --- monkey/infection_monkey/exploit/zerologon.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 091664bbb..de2633dcf 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -32,8 +32,10 @@ from infection_monkey.utils.threading import interruptible_iter logger = logging.getLogger(__name__) ZEROLOGON_EXPLOIT_TAG = "zerologon-exploiter" +T1003_TAG = "attack-t1003" -ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG} + +ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG, T1003_TAG} class ZerologonExploiter(HostExploiter): From f8b56dd171cd020afef6638614138f2a140304e8 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 23:56:05 +0200 Subject: [PATCH 09/12] Agent: Add T1098 (Account Manipulation) to ZerologonExploiter --- monkey/infection_monkey/exploit/zerologon.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index de2633dcf..504a2080c 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -33,9 +33,10 @@ logger = logging.getLogger(__name__) ZEROLOGON_EXPLOIT_TAG = "zerologon-exploiter" T1003_TAG = "attack-t1003" +T1098_TAG = "attack-t1098" -ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG, T1003_TAG} +ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG, T1003_TAG, T1098_TAG} class ZerologonExploiter(HostExploiter): From 3a9830415c987671100cf778410c9c9b792934d0 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 16 Aug 2022 23:57:49 +0200 Subject: [PATCH 10/12] Agent: Use default target for ZerologonExploiter event --- monkey/infection_monkey/exploit/zerologon.py | 1 - 1 file changed, 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 504a2080c..35dc3faa6 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -302,7 +302,6 @@ class ZerologonExploiter(HostExploiter): def _publish_credentials_stolen_event(self, extracted_credentials: Sequence[Credentials]): credentials_stolen_event = CredentialsStolenEvent( - target=None, tags=(ZEROLOGON_EVENT_TAGS), stolen_credentials=extracted_credentials, ) From 74b9dd58fc0c9b6f7f71fafd131e37de31615e05 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 17 Aug 2022 08:26:36 +0200 Subject: [PATCH 11/12] Agent: Add _ATTACK_TECHNIQUE to zerologon technique tags --- monkey/infection_monkey/exploit/zerologon.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 35dc3faa6..3d6074230 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -31,12 +31,16 @@ from infection_monkey.utils.threading import interruptible_iter logger = logging.getLogger(__name__) -ZEROLOGON_EXPLOIT_TAG = "zerologon-exploiter" -T1003_TAG = "attack-t1003" -T1098_TAG = "attack-t1098" +ZEROLOGON_EXPLOITER_TAG = "zerologon-exploiter" +T1003_ATTACK_TECHNIQUE_TAG = "attack-t1003" +T1098_ATTACK_TECHNIQUE_TAG = "attack-t1098" -ZEROLOGON_EVENT_TAGS = {ZEROLOGON_EXPLOIT_TAG, T1003_TAG, T1098_TAG} +ZEROLOGON_EVENT_TAGS = { + ZEROLOGON_EXPLOITER_TAG, + T1003_ATTACK_TECHNIQUE_TAG, + T1098_ATTACK_TECHNIQUE_TAG, +} class ZerologonExploiter(HostExploiter): From 69e1f21312883e991598adc042aff0359f660a5a Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 17 Aug 2022 13:45:13 +0200 Subject: [PATCH 12/12] Agent: Use frozenset for zerologon event tags --- monkey/infection_monkey/exploit/zerologon.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 3d6074230..f43a61069 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -36,11 +36,13 @@ T1003_ATTACK_TECHNIQUE_TAG = "attack-t1003" T1098_ATTACK_TECHNIQUE_TAG = "attack-t1098" -ZEROLOGON_EVENT_TAGS = { - ZEROLOGON_EXPLOITER_TAG, - T1003_ATTACK_TECHNIQUE_TAG, - T1098_ATTACK_TECHNIQUE_TAG, -} +ZEROLOGON_EVENT_TAGS = frozenset( + { + ZEROLOGON_EXPLOITER_TAG, + T1003_ATTACK_TECHNIQUE_TAG, + T1098_ATTACK_TECHNIQUE_TAG, + } +) class ZerologonExploiter(HostExploiter): @@ -306,7 +308,7 @@ class ZerologonExploiter(HostExploiter): def _publish_credentials_stolen_event(self, extracted_credentials: Sequence[Credentials]): credentials_stolen_event = CredentialsStolenEvent( - tags=(ZEROLOGON_EVENT_TAGS), + tags=ZEROLOGON_EVENT_TAGS, stolen_credentials=extracted_credentials, ) self.event_queue.publish(credentials_stolen_event)