diff --git a/CHANGELOG.md b/CHANGELOG.md index 9864ad9d8..12e94cbbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,12 +59,15 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Struts2 exploiter. #1869 - Drupal exploiter. #1869 - WebLogic exploiter. #1869 +- The /api/t1216-pba/download endpoint. #1864 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 - Windows "run as a user" powershell command for manual agent runs. #1570 - A bug in the "Signed Script Proxy Execution" PBA that downloaded the exe on Linux systems as well. #1557 +- A bug where T1216_random_executable.exe was copied to disk even if the signed + script proxy execution PBA was disabled. #1864 ### Security diff --git a/monkey/common/common_consts/api_url_consts.py b/monkey/common/common_consts/api_url_consts.py deleted file mode 100644 index 91f289218..000000000 --- a/monkey/common/common_consts/api_url_consts.py +++ /dev/null @@ -1 +0,0 @@ -T1216_PBA_FILE_DOWNLOAD_PATH = "/api/t1216-pba/download" diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 985c8e984..52b8e0db8 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -3,13 +3,11 @@ import logging import platform from pprint import pformat from socket import gethostname -from urllib.parse import urljoin import requests from requests.exceptions import ConnectionError import infection_monkey.tunnel as tunnel -from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT, MEDIUM_REQUEST_TIMEOUT from infection_monkey.config import GUID, WormConfiguration from infection_monkey.network.info import get_host_subnets, local_ips @@ -265,19 +263,3 @@ class ControlClient(object): ) except requests.exceptions.RequestException: return False - - @staticmethod - def get_T1216_pba_file(): - try: - return requests.get( # noqa: DUO123 - urljoin( - f"https://{WormConfiguration.current_server}/", - T1216_PBA_FILE_DOWNLOAD_PATH, - ), - verify=False, - proxies=ControlClient.proxies, - stream=True, - timeout=MEDIUM_REQUEST_TIMEOUT, - ) - except requests.exceptions.RequestException: - return False diff --git a/monkey/infection_monkey/monkey.spec b/monkey/infection_monkey/monkey.spec index d79345d0a..5144a8528 100644 --- a/monkey/infection_monkey/monkey.spec +++ b/monkey/infection_monkey/monkey.spec @@ -55,6 +55,8 @@ def process_datas(orig_datas): datas = orig_datas if is_windows(): datas = [i for i in datas if i[0].find('Include') < 0] + else: + datas = [i for i in datas if not i[0].endswith("T1216_random_executable.exe")] return datas diff --git a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py index a9224a977..9699e6628 100644 --- a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py +++ b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py @@ -7,6 +7,7 @@ from common.common_consts.timeouts import MEDIUM_REQUEST_TIMEOUT, SHORT_REQUEST_ from infection_monkey.post_breach.pba import PBA from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import ( cleanup_changes, + copy_executable_to_cwd, get_commands_to_proxy_execution_using_signed_script, ) from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger @@ -29,6 +30,7 @@ class SignedScriptProxyExecution(PBA): original_comspec = "" try: if is_windows_os(): + copy_executable_to_cwd() original_comspec = subprocess.check_output( # noqa: DUO116 "if defined COMSPEC echo %COMSPEC%", shell=True, timeout=SHORT_REQUEST_TIMEOUT ).decode() diff --git a/monkey/infection_monkey/post_breach/custom_pba/custom_pba.py b/monkey/infection_monkey/post_breach/custom_pba/custom_pba.py index 453dfb6ed..ce7dd64f2 100644 --- a/monkey/infection_monkey/post_breach/custom_pba/custom_pba.py +++ b/monkey/infection_monkey/post_breach/custom_pba/custom_pba.py @@ -26,7 +26,9 @@ class CustomPBA(PBA): """ def __init__(self, telemetry_messenger: ITelemetryMessenger): - super(CustomPBA, self).__init__(telemetry_messenger, POST_BREACH_FILE_EXECUTION) + super(CustomPBA, self).__init__( + telemetry_messenger, POST_BREACH_FILE_EXECUTION, timeout=None + ) self.filename = "" def run(self, options: Dict) -> Iterable[PostBreachData]: diff --git a/monkey/infection_monkey/post_breach/signed_script_proxy/T1216_random_executable.exe b/monkey/infection_monkey/post_breach/signed_script_proxy/T1216_random_executable.exe new file mode 100644 index 000000000..88335be70 Binary files /dev/null and b/monkey/infection_monkey/post_breach/signed_script_proxy/T1216_random_executable.exe differ diff --git a/monkey/infection_monkey/post_breach/signed_script_proxy/signed_script_proxy.py b/monkey/infection_monkey/post_breach/signed_script_proxy/signed_script_proxy.py index b172d1ab1..e1292bb99 100644 --- a/monkey/infection_monkey/post_breach/signed_script_proxy/signed_script_proxy.py +++ b/monkey/infection_monkey/post_breach/signed_script_proxy/signed_script_proxy.py @@ -1,5 +1,7 @@ import logging import subprocess +from pathlib import Path +from shutil import copyfile from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT from infection_monkey.post_breach.signed_script_proxy.windows.signed_script_proxy import ( @@ -11,12 +13,21 @@ from infection_monkey.utils.environment import is_windows_os logger = logging.getLogger(__name__) +EXECUTABLE_NAME = "T1216_random_executable.exe" +EXECUTABLE_SRC_PATH = Path(__file__).parent / EXECUTABLE_NAME +TEMP_COMSPEC = Path.cwd() / "T1216_random_executable.exe" + def get_commands_to_proxy_execution_using_signed_script(): - windows_cmds = get_windows_commands_to_proxy_execution_using_signed_script() + windows_cmds = get_windows_commands_to_proxy_execution_using_signed_script(TEMP_COMSPEC) return windows_cmds +def copy_executable_to_cwd(): + logger.debug(f"Copying executable from {EXECUTABLE_SRC_PATH} to {TEMP_COMSPEC}") + copyfile(EXECUTABLE_SRC_PATH, TEMP_COMSPEC) + + def cleanup_changes(original_comspec): if is_windows_os(): try: @@ -26,7 +37,7 @@ def cleanup_changes(original_comspec): timeout=SHORT_REQUEST_TIMEOUT, ) subprocess.run( # noqa: DUO116 - get_windows_commands_to_delete_temp_comspec(), + get_windows_commands_to_delete_temp_comspec(TEMP_COMSPEC), shell=True, timeout=SHORT_REQUEST_TIMEOUT, ) diff --git a/monkey/infection_monkey/post_breach/signed_script_proxy/windows/signed_script_proxy.py b/monkey/infection_monkey/post_breach/signed_script_proxy/windows/signed_script_proxy.py index 414f95e3e..da960e94d 100644 --- a/monkey/infection_monkey/post_breach/signed_script_proxy/windows/signed_script_proxy.py +++ b/monkey/infection_monkey/post_breach/signed_script_proxy/windows/signed_script_proxy.py @@ -1,32 +1,22 @@ import os +from pathlib import WindowsPath -from infection_monkey.control import ControlClient from infection_monkey.utils.environment import is_windows_os -TEMP_COMSPEC = os.path.join(os.getcwd(), "T1216_random_executable.exe") - -def get_windows_commands_to_proxy_execution_using_signed_script(): +def get_windows_commands_to_proxy_execution_using_signed_script(temp_comspec: WindowsPath): signed_script = "" if is_windows_os(): - _download_random_executable() - windir_path = os.environ["WINDIR"] - signed_script = os.path.join(windir_path, "System32", "manage-bde.wsf") + windir_path = WindowsPath(os.environ["WINDIR"]) + signed_script = str(windir_path / "System32" / "manage-bde.wsf") - return [f"set comspec={TEMP_COMSPEC} &&", f"cscript {signed_script}"] - - -def _download_random_executable(): - download = ControlClient.get_T1216_pba_file() - with open(TEMP_COMSPEC, "wb") as random_exe_obj: - random_exe_obj.write(download.content) - random_exe_obj.flush() + return [f"set comspec={temp_comspec} &&", f"cscript {signed_script}"] def get_windows_commands_to_reset_comspec(original_comspec): return f"set comspec={original_comspec}" -def get_windows_commands_to_delete_temp_comspec(): - return f"del {TEMP_COMSPEC} /f" +def get_windows_commands_to_delete_temp_comspec(temp_comspec: WindowsPath): + return f"del {temp_comspec} /f" diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 863a88909..b4413e7a5 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -6,7 +6,6 @@ import flask_restful from flask import Flask, Response, send_from_directory from werkzeug.exceptions import NotFound -from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH from monkey_island.cc.database import database, mongo from monkey_island.cc.resources.agent_controls import StopAgentCheck, StopAllAgents from monkey_island.cc.resources.attack.attack_report import AttackReport @@ -41,7 +40,6 @@ from monkey_island.cc.resources.ransomware_report import RansomwareReport from monkey_island.cc.resources.remote_run import RemoteRun from monkey_island.cc.resources.root import Root from monkey_island.cc.resources.security_report import SecurityReport -from monkey_island.cc.resources.T1216_pba_file_download import T1216PBAFileDownload from monkey_island.cc.resources.telemetry import Telemetry from monkey_island.cc.resources.telemetry_feed import TelemetryFeed from monkey_island.cc.resources.version_update import VersionUpdate @@ -153,7 +151,6 @@ def init_api_resources(api): api.add_resource(Log, "/api/log") api.add_resource(IslandLog, "/api/log/island/download") api.add_resource(PBAFileDownload, "/api/pba/download/") - api.add_resource(T1216PBAFileDownload, T1216_PBA_FILE_DOWNLOAD_PATH) api.add_resource( FileUpload, "/api/fileUpload/", diff --git a/monkey/monkey_island/cc/resources/T1216_pba_file_download.py b/monkey/monkey_island/cc/resources/T1216_pba_file_download.py deleted file mode 100644 index 906d4c97f..000000000 --- a/monkey/monkey_island/cc/resources/T1216_pba_file_download.py +++ /dev/null @@ -1,20 +0,0 @@ -import os - -import flask_restful -from flask import send_from_directory - -from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH - - -class T1216PBAFileDownload(flask_restful.Resource): - """ - File download endpoint used by monkey to download executable file for T1216 ("Signed Script - Proxy Execution" PBA) - """ - - def get(self): - executable_file_name = "T1216_random_executable.exe" - return send_from_directory( - directory=os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", "resources", "pba"), - path=executable_file_name, - )