forked from p15670423/monkey
Merge pull request #1900 from guardicore/1763-fix-windows-exe-removal
This commit is contained in:
commit
d1ac07b7a4
|
@ -79,7 +79,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
script proxy execution PBA was disabled. #1864
|
script proxy execution PBA was disabled. #1864
|
||||||
- Unnecessary collection of kerberos credentials. #1771
|
- Unnecessary collection of kerberos credentials. #1771
|
||||||
- A bug where bogus users were collected by Mimikatz and added to the config. #1860
|
- A bug where bogus users were collected by Mimikatz and added to the config. #1860
|
||||||
|
- A bug where windows executable was not self deleting. #1763
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
- Change SSH exploiter so that it does not set the permissions of the agent
|
- Change SSH exploiter so that it does not set the permissions of the agent
|
||||||
|
|
|
@ -28,10 +28,6 @@ MONKEY_CMDLINE_DETACHED_WINDOWS = "%s start cmd /c %%(monkey_path)s %s" % (
|
||||||
CMD_PREFIX,
|
CMD_PREFIX,
|
||||||
MONKEY_ARG,
|
MONKEY_ARG,
|
||||||
)
|
)
|
||||||
DELAY_DELETE_CMD = (
|
|
||||||
"cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & "
|
|
||||||
"if not exist %(file_path)s exit)) > NUL 2>&1 "
|
|
||||||
)
|
|
||||||
|
|
||||||
# Commands used for downloading monkeys
|
# Commands used for downloading monkeys
|
||||||
POWERSHELL_HTTP_UPLOAD = (
|
POWERSHELL_HTTP_UPLOAD = (
|
||||||
|
|
|
@ -3,6 +3,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import infection_monkey.tunnel as tunnel
|
import infection_monkey.tunnel as tunnel
|
||||||
|
@ -28,7 +29,7 @@ from infection_monkey.exploit.zerologon import ZerologonExploiter
|
||||||
from infection_monkey.i_puppet import IPuppet, PluginType
|
from infection_monkey.i_puppet import IPuppet, PluginType
|
||||||
from infection_monkey.master import AutomatedMaster
|
from infection_monkey.master import AutomatedMaster
|
||||||
from infection_monkey.master.control_channel import ControlChannel
|
from infection_monkey.master.control_channel import ControlChannel
|
||||||
from infection_monkey.model import DELAY_DELETE_CMD, VictimHostFactory
|
from infection_monkey.model import VictimHostFactory
|
||||||
from infection_monkey.network import NetworkInterface
|
from infection_monkey.network import NetworkInterface
|
||||||
from infection_monkey.network.firewall import app as firewall
|
from infection_monkey.network.firewall import app as firewall
|
||||||
from infection_monkey.network.info import get_local_network_interfaces
|
from infection_monkey.network.info import get_local_network_interfaces
|
||||||
|
@ -401,35 +402,77 @@ class InfectionMonkey:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _self_delete() -> bool:
|
def _self_delete() -> bool:
|
||||||
|
InfectionMonkey._remove_monkey_dir()
|
||||||
|
|
||||||
|
if "python" in Path(sys.executable).name:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if "win32" == sys.platform:
|
||||||
|
InfectionMonkey._self_delete_windows()
|
||||||
|
else:
|
||||||
|
InfectionMonkey._self_delete_linux()
|
||||||
|
|
||||||
|
T1107Telem(ScanStatus.USED, sys.executable).send()
|
||||||
|
return True
|
||||||
|
except Exception as exc:
|
||||||
|
logger.error("Exception in self delete: %s", exc)
|
||||||
|
T1107Telem(ScanStatus.SCANNED, sys.executable).send()
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _remove_monkey_dir():
|
||||||
status = ScanStatus.USED if remove_monkey_dir() else ScanStatus.SCANNED
|
status = ScanStatus.USED if remove_monkey_dir() else ScanStatus.SCANNED
|
||||||
T1107Telem(status, get_monkey_dir_path()).send()
|
T1107Telem(status, get_monkey_dir_path()).send()
|
||||||
deleted = False
|
|
||||||
|
|
||||||
if -1 == sys.executable.find("python"):
|
@staticmethod
|
||||||
try:
|
def _self_delete_windows():
|
||||||
status = None
|
delay_delete_cmd = InfectionMonkey._build_windows_delete_command()
|
||||||
if "win32" == sys.platform:
|
startupinfo = InfectionMonkey._get_startup_info()
|
||||||
from subprocess import CREATE_NEW_CONSOLE, STARTF_USESHOWWINDOW, SW_HIDE
|
|
||||||
|
|
||||||
startupinfo = subprocess.STARTUPINFO()
|
subprocess.Popen(
|
||||||
startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
|
delay_delete_cmd,
|
||||||
startupinfo.wShowWindow = SW_HIDE
|
stdin=None,
|
||||||
subprocess.Popen(
|
stdout=None,
|
||||||
DELAY_DELETE_CMD % {"file_path": sys.executable},
|
stderr=None,
|
||||||
stdin=None,
|
close_fds=True,
|
||||||
stdout=None,
|
startupinfo=startupinfo,
|
||||||
stderr=None,
|
)
|
||||||
close_fds=True,
|
|
||||||
startupinfo=startupinfo,
|
@staticmethod
|
||||||
)
|
def _build_windows_delete_command() -> str:
|
||||||
deleted = True
|
agent_pid = os.getpid()
|
||||||
else:
|
agent_file_path = sys.executable
|
||||||
os.remove(sys.executable)
|
|
||||||
status = ScanStatus.USED
|
# Returns 1 if the process is running and 0 otherwise
|
||||||
deleted = True
|
check_running_agent_cmd = f'tasklist /fi "PID eq {agent_pid}" ^| find /C "{agent_pid}"'
|
||||||
except Exception as exc:
|
|
||||||
logger.error("Exception in self delete: %s", exc)
|
sleep_seconds = 5
|
||||||
status = ScanStatus.SCANNED
|
delete_file_and_exit_cmd = f"del /f /q {agent_file_path} & exit"
|
||||||
if status:
|
|
||||||
T1107Telem(status, sys.executable).send()
|
# Checks if the agent process is still running.
|
||||||
return deleted
|
# If the agent is still running, it sleeps for 'sleep_seconds' before checking again.
|
||||||
|
# If the agent is not running, it deletes the executable and exits the loop.
|
||||||
|
# The check runs up to 20 times to give the agent ample time to shutdown.
|
||||||
|
delete_agent_cmd = (
|
||||||
|
f'cmd /c (for /l %i in (1,1,20) do (for /F "delims=" %j IN '
|
||||||
|
f'(\'{check_running_agent_cmd}\') DO if "%j"=="1" (timeout {sleep_seconds}) else '
|
||||||
|
f"({delete_file_and_exit_cmd})) ) > NUL 2>&1"
|
||||||
|
)
|
||||||
|
|
||||||
|
return delete_agent_cmd
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_startup_info():
|
||||||
|
from subprocess import CREATE_NEW_CONSOLE, STARTF_USESHOWWINDOW, SW_HIDE
|
||||||
|
|
||||||
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
|
||||||
|
startupinfo.wShowWindow = SW_HIDE
|
||||||
|
|
||||||
|
return startupinfo
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _self_delete_linux():
|
||||||
|
os.remove(sys.executable)
|
||||||
|
|
Loading…
Reference in New Issue