Changes that allow to avoid monkey exploitation redundancy: checking if island can see vulnerable port, checking if monkey was started on island and comparing depth vs maximum depth
This commit is contained in:
parent
698a13960e
commit
0e54b78664
|
@ -8,9 +8,6 @@ from itertools import product
|
|||
|
||||
__author__ = 'itamar'
|
||||
|
||||
from infection_monkey.utils.exceptions.planned_shutdown_exception import PlannedShutdownException
|
||||
from infection_monkey.network import info
|
||||
|
||||
GUID = str(uuid.getnode())
|
||||
|
||||
EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin')
|
||||
|
@ -25,14 +22,17 @@ class Configuration(object):
|
|||
for key, value in list(formatted_data.items()):
|
||||
if key.startswith('_'):
|
||||
continue
|
||||
if key in ["name", "id", "current_server"]:
|
||||
if key in ["name", "id", "current_server", "max_depth"]:
|
||||
continue
|
||||
if self._depth_from_commandline and key == "depth":
|
||||
self.max_depth = value
|
||||
continue
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
else:
|
||||
unknown_items.append(key)
|
||||
if not self.max_depth:
|
||||
self.max_depth = self.depth
|
||||
return unknown_items
|
||||
|
||||
def from_json(self, json_data):
|
||||
|
@ -138,6 +138,8 @@ class Configuration(object):
|
|||
|
||||
# depth of propagation
|
||||
depth = 2
|
||||
max_depth = None
|
||||
started_on_island = False
|
||||
current_server = ""
|
||||
|
||||
# Configuration servers to try to connect to, in this order.
|
||||
|
@ -235,6 +237,18 @@ class Configuration(object):
|
|||
cred_list.append(cred)
|
||||
return cred_list
|
||||
|
||||
@staticmethod
|
||||
def hash_sensitive_data(sensitive_data):
|
||||
"""
|
||||
Hash sensitive data (e.g. passwords). Used so the log won't contain sensitive data plain-text, as the log is
|
||||
saved on client machines plain-text.
|
||||
|
||||
:param sensitive_data: the data to hash.
|
||||
:return: the hashed data.
|
||||
"""
|
||||
password_hashed = hashlib.sha512(sensitive_data.encode()).hexdigest()
|
||||
return password_hashed
|
||||
|
||||
exploit_user_list = ['Administrator', 'root', 'user']
|
||||
exploit_password_list = ["Password1!", "1234", "password", "12345678"]
|
||||
exploit_lm_hash_list = []
|
||||
|
@ -262,30 +276,22 @@ class Configuration(object):
|
|||
|
||||
extract_azure_creds = True
|
||||
|
||||
###########################
|
||||
# post breach actions
|
||||
###########################
|
||||
post_breach_actions = []
|
||||
custom_PBA_linux_cmd = ""
|
||||
custom_PBA_windows_cmd = ""
|
||||
PBA_linux_filename = None
|
||||
PBA_windows_filename = None
|
||||
|
||||
@staticmethod
|
||||
def hash_sensitive_data(sensitive_data):
|
||||
"""
|
||||
Hash sensitive data (e.g. passwords). Used so the log won't contain sensitive data plain-text, as the log is
|
||||
saved on client machines plain-text.
|
||||
###########################
|
||||
# testing configuration
|
||||
###########################
|
||||
export_monkey_telems = False
|
||||
|
||||
:param sensitive_data: the data to hash.
|
||||
:return: the hashed data.
|
||||
"""
|
||||
password_hashed = hashlib.sha512(sensitive_data.encode()).hexdigest()
|
||||
return password_hashed
|
||||
|
||||
@staticmethod
|
||||
def should_monkey_run():
|
||||
local_ips = info.local_ips()
|
||||
if set(local_ips).intersection(set(WormConfiguration.blocked_ips)):
|
||||
raise PlannedShutdownException("Monkey shouldn't run on current machine "
|
||||
"(blocked ip or redundant exploitation).")
|
||||
def get_hop_count(self):
|
||||
return self.max_depth - self.depth
|
||||
|
||||
|
||||
WormConfiguration = Configuration()
|
||||
|
|
|
@ -15,6 +15,8 @@ from infection_monkey.transport.tcp import TcpProxy
|
|||
|
||||
__author__ = 'hoffer'
|
||||
|
||||
from infection_monkey.utils.exceptions.planned_shutdown_exception import PlannedShutdownException
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -321,3 +323,28 @@ class ControlClient(object):
|
|||
proxies=ControlClient.proxies)
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def should_monkey_run(port: str) -> bool:
|
||||
if WormConfiguration.get_hop_count() > 1 and \
|
||||
ControlClient.can_island_see_port(port) and \
|
||||
WormConfiguration.started_on_island:
|
||||
raise PlannedShutdownException("Monkey shouldn't run on current machine "
|
||||
"(it will be exploited later with more depth).")
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def can_island_see_port(port):
|
||||
try:
|
||||
url = f"https://{WormConfiguration.current_server}/api/monkey_control/check_remote_port/{port}"
|
||||
response = requests.get(url, verify=False)
|
||||
response = json.loads(response.content.decode())
|
||||
return response['status'] == "port_visible"
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def report_start_on_island():
|
||||
requests.post(f"https://{WormConfiguration.current_server}/api/monkey_control/started_on_island",
|
||||
data=json.dumps({'started_on_island': True}),
|
||||
verify=False)
|
||||
|
|
|
@ -44,6 +44,7 @@ class MonkeyDrops(object):
|
|||
arg_parser.add_argument('-s', '--server')
|
||||
arg_parser.add_argument('-d', '--depth', type=int)
|
||||
arg_parser.add_argument('-l', '--location')
|
||||
arg_parser.add_argument('-vp', '--vulnerable-port')
|
||||
self.monkey_args = args[1:]
|
||||
self.opts, _ = arg_parser.parse_known_args(args)
|
||||
|
||||
|
@ -115,7 +116,11 @@ class MonkeyDrops(object):
|
|||
LOG.warning("Cannot set reference date to destination file")
|
||||
|
||||
monkey_options = \
|
||||
build_monkey_commandline_explicitly(self.opts.parent, self.opts.tunnel, self.opts.server, self.opts.depth)
|
||||
build_monkey_commandline_explicitly(self.opts.parent,
|
||||
self.opts.tunnel,
|
||||
self.opts.server,
|
||||
self.opts.depth,
|
||||
self.opts.vulnerable_port)
|
||||
|
||||
if OperatingSystem.Windows == SystemInfoCollector.get_os():
|
||||
monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': self._config['destination_path']} + monkey_options
|
||||
|
|
|
@ -73,7 +73,8 @@ class HadoopExploiter(WebRCE):
|
|||
|
||||
def build_command(self, path, http_path):
|
||||
# Build command to execute
|
||||
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1,
|
||||
vulnerable_port=HTTPTools.get_port_from_url(http_path))
|
||||
if 'linux' in self.host.os['type']:
|
||||
base_command = HADOOP_LINUX_COMMAND
|
||||
else:
|
||||
|
|
|
@ -133,6 +133,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
# Form monkey's launch command
|
||||
monkey_args = build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
MSSQLExploiter.SQL_DEFAULT_TCP_PORT,
|
||||
dst_path)
|
||||
suffix = ">>{}".format(self.payload_file_path)
|
||||
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
|
||||
|
|
|
@ -329,7 +329,10 @@ class SambaCryExploiter(HostExploiter):
|
|||
return open(get_binary_file_path(self.SAMBACRY_RUNNER_FILENAME_64), "rb")
|
||||
|
||||
def get_monkey_commandline_file(self, location):
|
||||
return BytesIO(DROPPER_ARG + build_monkey_commandline(self.host, get_monkey_depth() - 1, str(location)))
|
||||
return BytesIO(DROPPER_ARG + build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
SambaCryExploiter.SAMBA_PORT,
|
||||
str(location)))
|
||||
|
||||
@staticmethod
|
||||
def is_share_writable(smb_client, share):
|
||||
|
|
|
@ -144,7 +144,11 @@ class ShellShockExploiter(HostExploiter):
|
|||
|
||||
# run the monkey
|
||||
cmdline = "%s %s" % (dropper_target_path_linux, DROPPER_ARG)
|
||||
cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1, dropper_target_path_linux) + ' & '
|
||||
cmdline += build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
HTTPTools.get_port_from_url(url),
|
||||
dropper_target_path_linux)
|
||||
cmdline += ' & '
|
||||
run_path = exploit + cmdline
|
||||
self.attack_page(url, header, run_path)
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class SmbExploiter(HostExploiter):
|
|||
|
||||
def __init__(self, host):
|
||||
super(SmbExploiter, self).__init__(host)
|
||||
self.vulnerable_port = None
|
||||
|
||||
def is_os_supported(self):
|
||||
if super(SmbExploiter, self).is_os_supported():
|
||||
|
@ -36,11 +37,13 @@ class SmbExploiter(HostExploiter):
|
|||
if not self.host.os.get('type'):
|
||||
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
|
||||
if is_smb_open:
|
||||
self.vulnerable_port = 445
|
||||
smb_finger = SMBFinger()
|
||||
smb_finger.get_host_fingerprint(self.host)
|
||||
else:
|
||||
is_nb_open, _ = check_tcp_port(self.host.ip_addr, 139)
|
||||
if is_nb_open:
|
||||
self.vulnerable_port = 139
|
||||
self.host.os['type'] = 'windows'
|
||||
return self.host.os.get('type') in self._TARGET_OS_TYPE
|
||||
return False
|
||||
|
@ -103,10 +106,13 @@ class SmbExploiter(HostExploiter):
|
|||
if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
||||
cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \
|
||||
build_monkey_commandline(self.host, get_monkey_depth() - 1,
|
||||
self.vulnerable_port,
|
||||
self._config.dropper_target_path_win_32)
|
||||
else:
|
||||
cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
|
||||
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
vulnerable_port=self.vulnerable_port)
|
||||
|
||||
smb_conn = False
|
||||
for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
|
||||
|
|
|
@ -179,7 +179,9 @@ class SSHExploiter(HostExploiter):
|
|||
|
||||
try:
|
||||
cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG)
|
||||
cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
cmdline += build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
vulnerable_port=SSH_PORT)
|
||||
cmdline += " > /dev/null 2>&1 &"
|
||||
ssh.exec_command(cmdline)
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ def get_target_monkey_by_os(is_windows, is_32bit):
|
|||
return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit)
|
||||
|
||||
|
||||
def build_monkey_commandline_explicitly(parent=None, tunnel=None, server=None, depth=None, location=None):
|
||||
def build_monkey_commandline_explicitly(parent=None, tunnel=None, server=None, depth=None, location=None,
|
||||
vulnerable_port=None):
|
||||
cmdline = ""
|
||||
|
||||
if parent is not None:
|
||||
|
@ -53,17 +54,19 @@ def build_monkey_commandline_explicitly(parent=None, tunnel=None, server=None, d
|
|||
if depth is not None:
|
||||
if depth < 0:
|
||||
depth = 0
|
||||
cmdline += " -d %d" % depth
|
||||
cmdline += f" -d {depth}"
|
||||
if location is not None:
|
||||
cmdline += " -l %s" % location
|
||||
cmdline += f" -l {location}"
|
||||
if vulnerable_port is not None:
|
||||
cmdline += f" -vp {str(vulnerable_port)}"
|
||||
|
||||
return cmdline
|
||||
|
||||
|
||||
def build_monkey_commandline(target_host, depth, location=None):
|
||||
def build_monkey_commandline(target_host, depth, vulnerable_port, location=None):
|
||||
from infection_monkey.config import GUID
|
||||
return build_monkey_commandline_explicitly(
|
||||
GUID, target_host.default_tunnel, target_host.default_server, depth, location)
|
||||
GUID, target_host.default_tunnel, target_host.default_server, depth, location, vulnerable_port)
|
||||
|
||||
|
||||
def get_monkey_depth():
|
||||
|
|
|
@ -73,6 +73,10 @@ class HTTPTools(object):
|
|||
lock.acquire()
|
||||
return "http://%s:%s/%s" % (local_ip, local_port, urllib.parse.quote(os.path.basename(src_path))), httpd
|
||||
|
||||
@staticmethod
|
||||
def get_port_from_url(url: str) -> int:
|
||||
return urllib.parse.urlparse(url).port
|
||||
|
||||
|
||||
class MonkeyHTTPServer(HTTPTools):
|
||||
def __init__(self, host):
|
||||
|
|
|
@ -132,7 +132,9 @@ class VSFTPDExploiter(HostExploiter):
|
|||
T1222Telem(ScanStatus.USED, change_permission.decode(), self.host).send()
|
||||
|
||||
# Run monkey on the machine
|
||||
parameters = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
parameters = build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
vulnerable_port=FTP_PORT)
|
||||
run_monkey = RUN_MONKEY % {'monkey_path': monkey_path, 'monkey_type': MONKEY_ARG, 'parameters': parameters}
|
||||
|
||||
# Set unlimited to memory
|
||||
|
|
|
@ -42,6 +42,8 @@ class WebRCE(HostExploiter):
|
|||
self.HTTP = [str(port) for port in self._config.HTTP_PORTS]
|
||||
self.skip_exist = self._config.skip_exploit_if_file_exist
|
||||
self.vulnerable_urls = []
|
||||
self.target_url = None
|
||||
self.vulnerable_port = None
|
||||
|
||||
def get_exploit_config(self):
|
||||
"""
|
||||
|
@ -87,27 +89,30 @@ class WebRCE(HostExploiter):
|
|||
if not self.vulnerable_urls:
|
||||
return False
|
||||
|
||||
self.target_url = self.vulnerable_urls[0]
|
||||
self.vulnerable_port = HTTPTools.get_port_from_url(self.target_url)
|
||||
|
||||
# Skip if monkey already exists and this option is given
|
||||
if not exploit_config['blind_exploit'] and self.skip_exist and self.check_remote_files(self.vulnerable_urls[0]):
|
||||
if not exploit_config['blind_exploit'] and self.skip_exist and self.check_remote_files(self.target_url):
|
||||
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 exploit_config['blind_exploit'] and not self.set_host_arch(self.vulnerable_urls[0]):
|
||||
if not exploit_config['blind_exploit'] and not self.set_host_arch(self.target_url):
|
||||
return False
|
||||
|
||||
# Upload the right monkey to target
|
||||
data = self.upload_monkey(self.vulnerable_urls[0], exploit_config['upload_commands'])
|
||||
data = self.upload_monkey(self.target_url, exploit_config['upload_commands'])
|
||||
|
||||
if data is False:
|
||||
return False
|
||||
|
||||
# Change permissions to transform monkey into executable file
|
||||
if self.change_permissions(self.vulnerable_urls[0], data['path']) is False:
|
||||
if self.change_permissions(self.target_url, data['path']) is False:
|
||||
return False
|
||||
|
||||
# Execute remote monkey
|
||||
if self.execute_remote_monkey(self.vulnerable_urls[0], data['path'], exploit_config['dropper']) is False:
|
||||
if self.execute_remote_monkey(self.target_url, data['path'], exploit_config['dropper']) is False:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -403,10 +408,15 @@ class WebRCE(HostExploiter):
|
|||
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)
|
||||
monkey_cmd = build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
self.vulnerable_port,
|
||||
default_path)
|
||||
command = RUN_MONKEY % {'monkey_path': path, 'monkey_type': DROPPER_ARG, 'parameters': monkey_cmd}
|
||||
else:
|
||||
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
monkey_cmd = build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
self.vulnerable_port)
|
||||
command = RUN_MONKEY % {'monkey_path': path, 'monkey_type': MONKEY_ARG, 'parameters': monkey_cmd}
|
||||
try:
|
||||
LOG.info("Trying to execute monkey using command: {}".format(command))
|
||||
|
@ -489,3 +499,6 @@ class WebRCE(HostExploiter):
|
|||
except KeyError:
|
||||
LOG.debug("Target's machine type was not set. Using win-32 dropper path.")
|
||||
return self._config.dropper_target_path_win_32
|
||||
|
||||
def set_vulnerable_port_from_url(self, url):
|
||||
self.vulnerable_port = HTTPTools.get_port_from_url(url)
|
||||
|
|
|
@ -234,11 +234,15 @@ class Ms08_067_Exploiter(HostExploiter):
|
|||
# execute the remote dropper in case the path isn't final
|
||||
if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
||||
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
|
||||
build_monkey_commandline(self.host, get_monkey_depth() - 1,
|
||||
build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
SRVSVC_Exploit.TELNET_PORT,
|
||||
self._config.dropper_target_path_win_32)
|
||||
else:
|
||||
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
|
||||
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
vulnerable_port=SRVSVC_Exploit.TELNET_PORT)
|
||||
|
||||
try:
|
||||
sock.send("start %s\r\n" % (cmdline,))
|
||||
|
|
|
@ -21,6 +21,7 @@ class WmiExploiter(HostExploiter):
|
|||
_TARGET_OS_TYPE = ['windows']
|
||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
||||
_EXPLOITED_SERVICE = 'WMI (Windows Management Instrumentation)'
|
||||
VULNERABLE_PORT = 135
|
||||
|
||||
def __init__(self, host):
|
||||
super(WmiExploiter, self).__init__(host)
|
||||
|
@ -94,11 +95,15 @@ class WmiExploiter(HostExploiter):
|
|||
# execute the remote dropper in case the path isn't final
|
||||
elif remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
||||
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
|
||||
build_monkey_commandline(
|
||||
self.host, get_monkey_depth() - 1, self._config.dropper_target_path_win_32)
|
||||
build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
WmiExploiter.VULNERABLE_PORT,
|
||||
self._config.dropper_target_path_win_32)
|
||||
else:
|
||||
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
|
||||
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
build_monkey_commandline(self.host,
|
||||
get_monkey_depth() - 1,
|
||||
WmiExploiter.VULNERABLE_PORT)
|
||||
|
||||
# execute the remote monkey
|
||||
result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(cmdline,
|
||||
|
|
|
@ -27,7 +27,7 @@ from infection_monkey.telemetry.trace_telem import TraceTelem
|
|||
from infection_monkey.telemetry.tunnel_telem import TunnelTelem
|
||||
from infection_monkey.windows_upgrader import WindowsUpgrader
|
||||
from infection_monkey.post_breach.post_breach_handler import PostBreach
|
||||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.network.tools import get_interface_to_target, is_running_on_server
|
||||
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||
from infection_monkey.telemetry.attack.t1106_telem import T1106Telem
|
||||
from common.utils.attack_utils import ScanStatus, UsageEnum
|
||||
|
@ -71,6 +71,7 @@ class InfectionMonkey(object):
|
|||
arg_parser.add_argument('-t', '--tunnel')
|
||||
arg_parser.add_argument('-s', '--server')
|
||||
arg_parser.add_argument('-d', '--depth', type=int)
|
||||
arg_parser.add_argument('-vp', '--vulnerable-port')
|
||||
self._opts, self._args = arg_parser.parse_known_args(self._args)
|
||||
|
||||
self._parent = self._opts.parent
|
||||
|
@ -116,6 +117,10 @@ class InfectionMonkey(object):
|
|||
|
||||
self.shutdown_by_not_alive_config()
|
||||
|
||||
if self.is_started_on_island():
|
||||
ControlClient.report_start_on_island()
|
||||
ControlClient.should_monkey_run(self._opts.vulnerable_port)
|
||||
|
||||
if firewall.is_enabled():
|
||||
firewall.add_firewall_rule()
|
||||
|
||||
|
@ -126,8 +131,6 @@ class InfectionMonkey(object):
|
|||
StateTelem(is_done=False, version=get_version()).send()
|
||||
TunnelTelem().send()
|
||||
|
||||
WormConfiguration.should_monkey_run()
|
||||
|
||||
LOG.debug("Starting the post-breach phase.")
|
||||
self.collect_system_info_if_configured()
|
||||
PostBreach().execute_all_configured()
|
||||
|
@ -379,3 +382,6 @@ class InfectionMonkey(object):
|
|||
raise PlannedShutdownException("Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel))
|
||||
self._default_server = WormConfiguration.current_server
|
||||
LOG.debug("default server set to: %s" % self._default_server)
|
||||
|
||||
def is_started_on_island(self):
|
||||
return is_running_on_server(self._default_server) and WormConfiguration.depth == WormConfiguration.max_depth
|
||||
|
|
|
@ -7,7 +7,7 @@ import struct
|
|||
import time
|
||||
import re
|
||||
|
||||
from infection_monkey.network.info import get_routes
|
||||
from infection_monkey.network.info import get_routes, local_ips
|
||||
from infection_monkey.pyinstaller_utils import get_binary_file_path
|
||||
from infection_monkey.utils.environment import is_64bit_python
|
||||
|
||||
|
@ -309,3 +309,7 @@ def get_interface_to_target(dst):
|
|||
paths.sort()
|
||||
ret = paths[-1][1]
|
||||
return ret[1]
|
||||
|
||||
|
||||
def is_running_on_server(ip: str) -> bool:
|
||||
return ip in local_ips()
|
||||
|
|
|
@ -16,10 +16,12 @@ from monkey_island.cc.resources.island_logs import IslandLog
|
|||
from monkey_island.cc.resources.monkey import Monkey
|
||||
from monkey_island.cc.resources.monkey_configuration import MonkeyConfiguration
|
||||
from monkey_island.cc.resources.island_configuration import IslandConfiguration
|
||||
from monkey_island.cc.resources.monkey_control.started_on_island import StartedOnIsland
|
||||
from monkey_island.cc.resources.monkey_download import MonkeyDownload
|
||||
from monkey_island.cc.resources.netmap import NetMap
|
||||
from monkey_island.cc.resources.node import Node
|
||||
from monkey_island.cc.resources.node_states import NodeStates
|
||||
from monkey_island.cc.resources.monkey_control.remote_port_check import RemotePortCheck
|
||||
from monkey_island.cc.resources.remote_run import RemoteRun
|
||||
from monkey_island.cc.resources.reporting.report import Report
|
||||
from monkey_island.cc.resources.root import Root
|
||||
|
@ -121,6 +123,8 @@ def init_api_resources(api):
|
|||
api.add_resource(AttackConfiguration, '/api/attack')
|
||||
api.add_resource(AttackReport, '/api/attack/report')
|
||||
api.add_resource(VersionUpdate, '/api/version-update', '/api/version-update/')
|
||||
api.add_resource(RemotePortCheck, '/api/monkey_control/check_remote_port/<string:port>')
|
||||
api.add_resource(StartedOnIsland, '/api/monkey_control/started_on_island')
|
||||
|
||||
api.add_resource(MonkeyTest, '/api/test/monkey')
|
||||
api.add_resource(ClearCaches, '/api/test/clear_caches')
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import flask_restful
|
||||
from flask import request
|
||||
|
||||
from monkey_island.cc.services.remote_port_check import check_tcp_port
|
||||
|
||||
|
||||
class RemotePortCheck(flask_restful.Resource):
|
||||
|
||||
# Used by monkey. can't secure.
|
||||
def get(self, port):
|
||||
if check_tcp_port(request.remote_addr, port):
|
||||
return {"status": "port_visible"}
|
||||
else:
|
||||
return {"status": "port_invisible"}
|
|
@ -0,0 +1,16 @@
|
|||
import json
|
||||
|
||||
import flask_restful
|
||||
from flask import request, make_response
|
||||
|
||||
from monkey_island.cc.services.config import ConfigService
|
||||
|
||||
|
||||
class StartedOnIsland(flask_restful.Resource):
|
||||
|
||||
# Used by monkey. can't secure.
|
||||
def post(self):
|
||||
data = json.loads(request.data)
|
||||
if data['started_on_island']:
|
||||
ConfigService.set_started_on_island(True)
|
||||
return make_response({}, 200)
|
|
@ -321,3 +321,7 @@ class ConfigService:
|
|||
@staticmethod
|
||||
def add_blocked_ip(ip_):
|
||||
ConfigService.append_to_config_array(['basic_network', 'general', 'blocked_ips'], ip_)
|
||||
|
||||
@staticmethod
|
||||
def set_started_on_island(value: bool):
|
||||
ConfigService.set_config_value(['internal', 'general', 'started_on_island'], value)
|
||||
|
|
|
@ -564,6 +564,13 @@ SCHEMA = {
|
|||
"default": r"monkey_dir",
|
||||
"description": "Directory name for the directory which will contain all of the monkey files"
|
||||
},
|
||||
"started_on_island": {
|
||||
"title": "Started on island",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"description": "Was exploitation started from island"
|
||||
"(did monkey with max depth ran on island)"
|
||||
},
|
||||
}
|
||||
},
|
||||
"classes": {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import socket
|
||||
|
||||
|
||||
DEFAULT_TIMEOUT = 5 # Seconds
|
||||
|
||||
|
||||
def check_tcp_port(ip: str, port: str, timeout=DEFAULT_TIMEOUT) -> bool:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
|
||||
try:
|
||||
sock.connect((ip, int(port)))
|
||||
except socket.timeout:
|
||||
return False
|
||||
except socket.error:
|
||||
return False
|
||||
finally:
|
||||
sock.close()
|
||||
return True
|
|
@ -69,7 +69,11 @@ class ConfigurePageComponent extends AuthComponent {
|
|||
cnc: {},
|
||||
network: {},
|
||||
exploits: {},
|
||||
internal: {}
|
||||
internal: {
|
||||
general: {
|
||||
started_on_island: {'ui:widget': 'hidden'}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue