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

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

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

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

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

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

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

@ -6,7 +6,6 @@
"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": { "handlers": {
"console": { "console": {
"class": "logging.StreamHandler", "class": "logging.StreamHandler",
@ -14,7 +13,6 @@
"formatter": "simple", "formatter": "simple",
"stream": "ext://sys.stdout" "stream": "ext://sys.stdout"
}, },
"info_file_handler": { "info_file_handler": {
"class": "logging.handlers.RotatingFileHandler", "class": "logging.handlers.RotatingFileHandler",
"level": "INFO", "level": "INFO",
@ -25,9 +23,11 @@
"encoding": "utf8" "encoding": "utf8"
} }
}, },
"root": { "root": {
"level": "DEBUG", "level": "DEBUG",
"handlers": ["console", "info_file_handler"] "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

View File

@ -23,7 +23,7 @@ class TelemetryFeed(flask_restful.Resource):
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

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

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

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

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 = \
[ [

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

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

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

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

@ -26,16 +26,21 @@ export function renderMachineFromSystemData(data) {
export function getUsageColumns() { export function getUsageColumns() {
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'},
width: 300}, width: 300
{Header: 'Usage', },
{
Header: 'Usage',
id: 'usage', id: 'usage',
accessor: x => x.usage, accessor: x => x.usage,
style: { 'whiteSpace': 'unset' }}] 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.

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: '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: 'Type', id: 'type', accessor: x => x.gathered_data_type, style: {'whiteSpace': 'unset'}},
{Header: 'Info', id: 'info', accessor: x => x.info, style: {'whiteSpace': 'unset'}}, {Header: 'Info', id: 'info', accessor: x => x.info, style: {'whiteSpace': 'unset'}},
]}])}; ]
}])
};
render() { render() {
return ( return (

View File

@ -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: '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: 'Network info', id: 'info', accessor: x => renderUsageFields(x.info), style: {'whiteSpace': 'unset'}},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -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: 'Machine',
id: 'machine',
accessor: x => renderMachineFromSystemData(x.monkey),
style: {'whiteSpace': 'unset'}
},
{Header: 'First scan', id: 'started', accessor: x => x.started, 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: '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' }}, {
Header: 'Systems found',
id: 'systems',
accessor: x => T1018.renderMachines(x.machines),
style: {'whiteSpace': 'unset'}
},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -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),
style: {'whiteSpace': 'unset'}, width: 160
},
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}, width: 100}, {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' }}, {
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

@ -15,7 +15,9 @@ class T1041 extends React.Component {
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 (

View File

@ -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: '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: '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'}}, {Header: 'Command', id: 'command', accessor: x => x.data.info.executed_cmds.cmd, style: {'whiteSpace': 'unset'}},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -27,7 +27,8 @@ class T1075 extends React.Component {
{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 (

View File

@ -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: '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: 'Gathered info', id: 'info', accessor: x => renderUsageFields(x.collections), style: {'whiteSpace': 'unset'}},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -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: '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: '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'}}, {Header: 'Command', id: 'command', accessor: x => x.data[0].info.executed_cmds[0].cmd, style: {'whiteSpace': 'unset'}},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

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

View File

@ -18,7 +18,8 @@ class T1105 extends React.Component {
{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 (

View File

@ -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: '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: '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}] Header: 'Deleted?', id: 'deleted', accessor: x => this.renderDelete(x._id.status),
}])}; style: {'whiteSpace': 'unset'}, width: 160
}]
}])
};
render() { render() {
return ( return (

View File

@ -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),
style: {'whiteSpace': 'unset'}, width: 160
},
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}, width: 100}, {Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: {'whiteSpace': 'unset'}, width: 100},
{Header: 'Started', id: 'started', accessor: x => x.info.started, style: {'whiteSpace': 'unset'}}, {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: '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: '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' }}, {
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

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

View File

@ -14,20 +14,27 @@ class T1188 extends React.Component {
return ([{ return ([{
Header: "Communications through multi-hop proxies", Header: "Communications through multi-hop proxies",
columns: [ columns: [
{Header: 'From', {
Header: 'From',
id: 'from', id: 'from',
accessor: x => renderMachineFromSystemData(x.from), accessor: x => renderMachineFromSystemData(x.from),
style: { 'whiteSpace': 'unset' }}, style: {'whiteSpace': 'unset'}
{Header: 'To', },
{
Header: 'To',
id: 'to', id: 'to',
accessor: x => renderMachineFromSystemData(x.to), accessor: x => renderMachineFromSystemData(x.to),
style: { 'whiteSpace': 'unset' }}, style: {'whiteSpace': 'unset'}
{Header: 'Hops', },
{
Header: 'Hops',
id: 'hops', id: 'hops',
accessor: x => x.count, accessor: x => x.count,
style: { 'whiteSpace': 'unset' }}, style: {'whiteSpace': 'unset'}
},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -8,17 +8,23 @@ class T1210 extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.columns = [ {Header: 'Machine', this.columns = [{
Header: 'Machine',
id: 'machine', accessor: x => renderMachine(x), id: 'machine', accessor: x => renderMachine(x),
style: {'whiteSpace': 'unset'}, style: {'whiteSpace': 'unset'},
width: 200}, width: 200
{Header: 'Time', },
{
Header: 'Time',
id: 'time', accessor: x => x.time, id: 'time', accessor: x => x.time,
style: {'whiteSpace': 'unset'}, style: {'whiteSpace': 'unset'},
width: 170}, width: 170
{Header: 'Usage', },
{
Header: 'Usage',
id: 'usage', accessor: x => x.usage, id: 'usage', accessor: x => x.usage,
style: { 'whiteSpace': 'unset' }} style: {'whiteSpace': 'unset'}
}
] ]
} }

View File

@ -14,26 +14,34 @@ class T1210 extends React.Component {
return ([{ return ([{
Header: "Found services", Header: "Found services",
columns: [ columns: [
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), {
style: { 'whiteSpace': 'unset' }, width: 200}, Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
style: {'whiteSpace': 'unset'}, width: 200
},
{Header: 'Time', id: 'time', accessor: x => x.time, style: {'whiteSpace': 'unset'}}, {Header: 'Time', id: 'time', accessor: x => x.time, style: {'whiteSpace': 'unset'}},
{Header: 'Port', id: 'port', accessor: x => x.service.port, style: {'whiteSpace': 'unset'}, width: 100}, {Header: 'Port', id: 'port', accessor: x => x.service.port, style: {'whiteSpace': 'unset'}, width: 100},
{Header: 'Service', id: 'service', accessor: x => x.service.display_name, style: {'whiteSpace': 'unset'}} {Header: 'Service', id: 'service', accessor: x => x.service.display_name, style: {'whiteSpace': 'unset'}}
] ]
}])} }])
}
static getExploitColumns() { static getExploitColumns() {
return ([{ return ([{
Header: "Exploited services", Header: "Exploited services",
columns: [ columns: [
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), {
style: { 'whiteSpace': 'unset' }, width: 200}, Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
style: {'whiteSpace': 'unset'}, width: 200
},
{Header: 'Time', id: 'time', accessor: x => x.time, style: {'whiteSpace': 'unset'}}, {Header: 'Time', id: 'time', accessor: x => x.time, style: {'whiteSpace': 'unset'}},
{Header: 'Port/url', id: 'port', accessor: x =>this.renderEndpoint(x.service), style: { 'whiteSpace': 'unset' }, {
width: 170}, Header: 'Port/url', id: 'port', accessor: x => this.renderEndpoint(x.service), style: {'whiteSpace': 'unset'},
width: 170
},
{Header: 'Service', id: 'service', accessor: x => x.service.display_name, style: {'whiteSpace': 'unset'}} {Header: 'Service', id: 'service', accessor: x => x.service.display_name, style: {'whiteSpace': 'unset'}}
] ]
}])}; }])
};
static renderEndpoint(val) { static renderEndpoint(val) {
return ( return (
@ -44,10 +52,14 @@ class T1210 extends React.Component {
static formatScanned(data) { static formatScanned(data) {
let result = []; let result = [];
for (let service in data.machine.services) { for (let service in data.machine.services) {
let scanned_service = {'machine': data.machine, let scanned_service = {
'machine': data.machine,
'time': data.time, 'time': data.time,
'service': {'port': [data.machine.services[service].port], 'service': {
'display_name': data.machine.services[service].display_name}}; 'port': [data.machine.services[service].port],
'display_name': data.machine.services[service].display_name
}
};
result.push(scanned_service) result.push(scanned_service)
} }
return result return result

View File

@ -17,7 +17,8 @@ class T1222 extends React.Component {
{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: 'Command', id: 'command', accessor: x => x.command, style: {'whiteSpace': 'unset'}}, {Header: 'Command', id: 'command', accessor: x => x.command, style: {'whiteSpace': 'unset'}},
] ]
}])}; }])
};
render() { render() {
return ( return (

View File

@ -94,8 +94,11 @@ class ConfigurePageComponent extends AuthComponent {
this.setInitialConfig(monkeyConfig.configuration); this.setInitialConfig(monkeyConfig.configuration);
this.setInitialAttackConfig(attackConfig.configuration); this.setInitialAttackConfig(attackConfig.configuration);
for (let sectionKey of this.sectionsOrder) { for (let sectionKey of this.sectionsOrder) {
if (sectionKey === 'attack') {sections.push({key:sectionKey, title: "ATT&CK"})} if (sectionKey === 'attack') {
else {sections.push({key: sectionKey, title: monkeyConfig.schema.properties[sectionKey].title});} sections.push({key: sectionKey, title: "ATT&CK"})
} else {
sections.push({key: sectionKey, title: monkeyConfig.schema.properties[sectionKey].title});
}
} }
this.setState({ this.setState({
schema: monkeyConfig.schema, schema: monkeyConfig.schema,
@ -134,13 +137,14 @@ class ConfigurePageComponent extends AuthComponent {
body: JSON.stringify(this.state.attackConfig) body: JSON.stringify(this.state.attackConfig)
}) })
.then(res => { .then(res => {
if (!res.ok) if (!res.ok) {
{
throw Error() throw Error()
} }
return res; return res;
}) })
.then(() => {this.setInitialAttackConfig(this.state.attackConfig);}) .then(() => {
this.setInitialAttackConfig(this.state.attackConfig);
})
.then(this.updateConfig()) .then(this.updateConfig())
.then(this.setState({lastAction: 'saved'})) .then(this.setState({lastAction: 'saved'}))
.catch(error => { .catch(error => {
@ -207,9 +211,13 @@ class ConfigurePageComponent extends AuthComponent {
}; };
renderAttackAlertModal = () => { renderAttackAlertModal = () => {
return (<Modal show={this.state.showAttackAlert} onHide={() => {this.setState({showAttackAlert: false})}}> return (<Modal show={this.state.showAttackAlert} onHide={() => {
this.setState({showAttackAlert: false})
}}>
<Modal.Body> <Modal.Body>
<h2><div className="text-center">Warning</div></h2> <h2>
<div className="text-center">Warning</div>
</h2>
<p className="text-center" style={{'fontSize': '1.2em', 'marginBottom': '2em'}}> <p className="text-center" style={{'fontSize': '1.2em', 'marginBottom': '2em'}}>
You have unsubmitted changes. Submit them before proceeding. You have unsubmitted changes. Submit them before proceeding.
</p> </p>
@ -217,7 +225,9 @@ class ConfigurePageComponent extends AuthComponent {
<button type="button" <button type="button"
className="btn btn-success btn-lg" className="btn btn-success btn-lg"
style={{margin: '5px'}} style={{margin: '5px'}}
onClick={() => {this.setState({showAttackAlert: false})}} > onClick={() => {
this.setState({showAttackAlert: false})
}}>
Cancel Cancel
</button> </button>
</div> </div>
@ -270,9 +280,11 @@ class ConfigurePageComponent extends AuthComponent {
this.setInitialConfig(res.configuration); this.setInitialConfig(res.configuration);
this.props.onStatusChange(); this.props.onStatusChange();
}); });
this.authFetch(ATTACK_URL,{ method: 'POST', this.authFetch(ATTACK_URL, {
method: 'POST',
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},
body: JSON.stringify('reset_attack_matrix')}) body: JSON.stringify('reset_attack_matrix')
})
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
this.setState({attackConfig: res.configuration}); this.setState({attackConfig: res.configuration});
@ -288,8 +300,10 @@ class ConfigurePageComponent extends AuthComponent {
if (this.PBAlinuxPond !== null) { if (this.PBAlinuxPond !== null) {
this.PBAlinuxPond.removeFile(); this.PBAlinuxPond.removeFile();
} }
let request_options = {method: 'DELETE', let request_options = {
headers: {'Content-Type': 'text/plain'}}; method: 'DELETE',
headers: {'Content-Type': 'text/plain'}
};
this.authFetch('/api/fileUpload/PBAlinux', request_options); this.authFetch('/api/fileUpload/PBAlinux', request_options);
this.authFetch('/api/fileUpload/PBAwindows', request_options); this.authFetch('/api/fileUpload/PBAwindows', request_options);
this.setState({PBAlinuxFile: [], PBAwinFile: []}); this.setState({PBAlinuxFile: [], PBAwinFile: []});
@ -300,7 +314,10 @@ class ConfigurePageComponent extends AuthComponent {
this.setState({ this.setState({
configuration: JSON.parse(event.target.result), configuration: JSON.parse(event.target.result),
lastAction: 'import_success' lastAction: 'import_success'
}, () => {this.sendConfig(); this.setInitialConfig(JSON.parse(event.target.result))}); }, () => {
this.sendConfig();
this.setInitialConfig(JSON.parse(event.target.result))
});
this.currentFormData = {}; this.currentFormData = {};
} catch (SyntaxError) { } catch (SyntaxError) {
this.setState({lastAction: 'import_failure'}); this.setState({lastAction: 'import_failure'});
@ -321,8 +338,7 @@ class ConfigurePageComponent extends AuthComponent {
body: JSON.stringify(this.state.configuration) body: JSON.stringify(this.state.configuration)
}) })
.then(res => { .then(res => {
if (!res.ok) if (!res.ok) {
{
throw Error() throw Error()
} }
return res; return res;
@ -355,7 +371,8 @@ class ConfigurePageComponent extends AuthComponent {
PBAwindows = () => { PBAwindows = () => {
return (<FilePond return (<FilePond
server={{ url:'/api/fileUpload/PBAwindows', server={{
url: '/api/fileUpload/PBAwindows',
process: {headers: {'Authorization': this.jwtHeader}}, process: {headers: {'Authorization': this.jwtHeader}},
revert: {headers: {'Authorization': this.jwtHeader}}, revert: {headers: {'Authorization': this.jwtHeader}},
restore: {headers: {'Authorization': this.jwtHeader}}, restore: {headers: {'Authorization': this.jwtHeader}},
@ -374,7 +391,8 @@ class ConfigurePageComponent extends AuthComponent {
PBAlinux = () => { PBAlinux = () => {
return (<FilePond return (<FilePond
server={{ url:'/api/fileUpload/PBAlinux', server={{
url: '/api/fileUpload/PBAlinux',
process: {headers: {'Authorization': this.jwtHeader}}, process: {headers: {'Authorization': this.jwtHeader}},
revert: {headers: {'Authorization': this.jwtHeader}}, revert: {headers: {'Authorization': this.jwtHeader}},
restore: {headers: {'Authorization': this.jwtHeader}}, restore: {headers: {'Authorization': this.jwtHeader}},

View File

@ -71,8 +71,7 @@ class MapPageComponent extends AuthComponent {
this.authFetch('/api/netmap/node?id=' + event.nodes[0]) this.authFetch('/api/netmap/node?id=' + event.nodes[0])
.then(res => res.json()) .then(res => res.json())
.then(res => this.setState({selected: res, selectedType: 'node'})); .then(res => this.setState({selected: res, selectedType: 'node'}));
} } else if (event.edges.length === 1) {
else if (event.edges.length === 1) {
let displayedEdge = this.state.graph.edges.find( let displayedEdge = this.state.graph.edges.find(
function (edge) { function (edge) {
return edge['id'] === event.edges[0]; return edge['id'] === event.edges[0];
@ -84,8 +83,7 @@ class MapPageComponent extends AuthComponent {
.then(res => res.json()) .then(res => res.json())
.then(res => this.setState({selected: res.edge, selectedType: 'edge'})); .then(res => this.setState({selected: res.edge, selectedType: 'edge'}));
} }
} } else {
else {
this.setState({selected: null, selectedType: null}); this.setState({selected: null, selectedType: null});
} }
} }
@ -100,7 +98,9 @@ class MapPageComponent extends AuthComponent {
return ( return (
<Modal show={this.state.showKillDialog} onHide={() => this.setState({showKillDialog: false})}> <Modal show={this.state.showKillDialog} onHide={() => this.setState({showKillDialog: false})}>
<Modal.Body> <Modal.Body>
<h2><div className="text-center">Are you sure you want to kill all monkeys?</div></h2> <h2>
<div className="text-center">Are you sure you want to kill all monkeys?</div>
</h2>
<p style={{'fontSize': '1.2em', 'marginBottom': '2em'}}> <p style={{'fontSize': '1.2em', 'marginBottom': '2em'}}>
This might take a few moments... This might take a few moments...
</p> </p>
@ -174,7 +174,8 @@ class MapPageComponent extends AuthComponent {
<div style={{'overflow': 'auto', 'marginBottom': '1em'}}> <div style={{'overflow': 'auto', 'marginBottom': '1em'}}>
<Link to="/infection/telemetry" className="btn btn-default pull-left" style={{'width': '48%'}}>Monkey <Link to="/infection/telemetry" className="btn btn-default pull-left" style={{'width': '48%'}}>Monkey
Telemetry</Link> Telemetry</Link>
<button onClick={() => this.setState({showKillDialog: true})} className="btn btn-danger pull-right" style={{'width': '48%'}}> <button onClick={() => this.setState({showKillDialog: true})} className="btn btn-danger pull-right"
style={{'width': '48%'}}>
<Icon name="stop-circle" style={{'marginRight': '0.5em'}}/> <Icon name="stop-circle" style={{'marginRight': '0.5em'}}/>
Kill All Monkeys Kill All Monkeys
</button> </button>

View File

@ -29,15 +29,13 @@ class PassTheHashMapPageComponent extends AuthComponent {
return node['id'] === event.nodes[0]; return node['id'] === event.nodes[0];
}); });
this.setState({selected: displayedNode, selectedType: 'node'}) this.setState({selected: displayedNode, selectedType: 'node'})
} } else if (event.edges.length === 1) {
else if (event.edges.length === 1) {
let displayedEdge = this.state.graph.edges.find( let displayedEdge = this.state.graph.edges.find(
function (edge) { function (edge) {
return edge['id'] === event.edges[0]; return edge['id'] === event.edges[0];
}); });
this.setState({selected: displayedEdge, selectedType: 'edge'}); this.setState({selected: displayedEdge, selectedType: 'edge'});
} } else {
else {
this.setState({selected: null, selectedType: null}); this.setState({selected: null, selectedType: null});
} }
} }

View File

@ -147,7 +147,9 @@ class ReportPageComponent extends AuthComponent {
return ( return (
<Fragment> <Fragment>
<div style={{marginBottom: '20px'}}> <div style={{marginBottom: '20px'}}>
<PrintReportButton onClick={() => {print();}} /> <PrintReportButton onClick={() => {
print();
}}/>
</div> </div>
<div className="report-page"> <div className="report-page">
<ReportHeader report_type={ReportTypes.security}/> <ReportHeader report_type={ReportTypes.security}/>
@ -155,7 +157,9 @@ class ReportPageComponent extends AuthComponent {
{content} {content}
</div> </div>
<div style={{marginTop: '20px'}}> <div style={{marginTop: '20px'}}>
<PrintReportButton onClick={() => {print();}} /> <PrintReportButton onClick={() => {
print();
}}/>
</div> </div>
</Fragment> </Fragment>
); );
@ -315,7 +319,8 @@ class ReportPageComponent extends AuthComponent {
{this.state.report.overview.issues[this.Issue.HADOOP] ? {this.state.report.overview.issues[this.Issue.HADOOP] ?
<li>Hadoop/Yarn servers are vulnerable to remote code execution.</li> : null} <li>Hadoop/Yarn servers are vulnerable to remote code execution.</li> : null}
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ? {this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ?
<li>Mimikatz found login credentials of a user who has admin access to a server defined as critical.</li>: null } <li>Mimikatz found login credentials of a user who has admin access to a server defined as
critical.</li> : null}
{this.state.report.overview.issues[this.Issue.MSSQL] ? {this.state.report.overview.issues[this.Issue.MSSQL] ?
<li>MS-SQL servers are vulnerable to remote code execution via xp_cmdshell command.</li> : null} <li>MS-SQL servers are vulnerable to remote code execution via xp_cmdshell command.</li> : null}
</ul> </ul>
@ -344,7 +349,8 @@ class ReportPageComponent extends AuthComponent {
{this.state.report.overview.warnings[this.Warning.TUNNEL] ? {this.state.report.overview.warnings[this.Warning.TUNNEL] ?
<li>Weak segmentation - Machines were able to communicate over unused ports.</li> : null} <li>Weak segmentation - Machines were able to communicate over unused ports.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ? {this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ?
<li>Shared local administrator account - Different machines have the same account as a local administrator.</li> : null} <li>Shared local administrator account - Different machines have the same account as a local
administrator.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ? {this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ?
<li>Multiple users have the same password</li> : null} <li>Multiple users have the same password</li> : null}
</ul> </ul>
@ -463,11 +469,13 @@ class ReportPageComponent extends AuthComponent {
Credentials Map Credentials Map
</h3> </h3>
<p> <p>
This map visualizes possible attack paths through the network using credential compromise. Paths represent lateral movement opportunities by attackers. This map visualizes possible attack paths through the network using credential compromise. Paths represent lateral
movement opportunities by attackers.
</p> </p>
<div className="map-legend"> <div className="map-legend">
<b>Legend: </b> <b>Legend: </b>
<span>Access credentials <i className="fa fa-lg fa-minus" style={{color: '#0158aa'}}/></span> <b style={{color: '#aeaeae'}}> | </b> <span>Access credentials <i className="fa fa-lg fa-minus" style={{color: '#0158aa'}}/></span> <b
style={{color: '#aeaeae'}}> | </b>
</div> </div>
<div> <div>
<PassTheHashMapPageComponent graph={this.state.report.glance.pth_map}/> <PassTheHashMapPageComponent graph={this.state.report.glance.pth_map}/>
@ -664,10 +672,13 @@ class ReportPageComponent extends AuthComponent {
className="label label-danger">6200</span>. className="label label-danger">6200</span>.
<br/> <br/>
The attack was made possible because the VSFTPD server was not patched against CVE-2011-2523. The attack was made possible because the VSFTPD server was not patched against CVE-2011-2523.
<br/><br/>In July 2011, it was discovered that vsftpd version 2.3.4 downloadable from the master site had been compromised. <br/><br/>In July 2011, it was discovered that vsftpd version 2.3.4 downloadable from the master site had been
Users logging into a compromised vsftpd-2.3.4 server may issue a ":)" smileyface as the username and gain a command shell on port 6200. compromised.
Users logging into a compromised vsftpd-2.3.4 server may issue a ":)" smileyface as the username and gain a command
shell on port 6200.
<br/><br/> <br/><br/>
The Monkey executed commands by first logging in with ":)" in the username and then sending commands to the backdoor at port 6200. The Monkey executed commands by first logging in with ":)" in the username and then sending commands to the backdoor
at port 6200.
<br/><br/>Read more about the security issue and remediation <a <br/><br/>Read more about the security issue and remediation <a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523" href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523"
>here</a>. >here</a>.
@ -781,7 +792,8 @@ class ReportPageComponent extends AuthComponent {
generateSharedLocalAdminsIssue(issue) { generateSharedLocalAdminsIssue(issue) {
return ( return (
<li> <li>
Make sure the right administrator accounts are managing the right machines, and that there isnt an unintentional local admin sharing. Make sure the right administrator accounts are managing the right machines, and that there isnt an unintentional local
admin sharing.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Here is a list of machines which the account <span Here is a list of machines which the account <span
className="label label-primary">{issue.username}</span> is defined as an administrator: className="label label-primary">{issue.username}</span> is defined as an administrator:
@ -856,7 +868,8 @@ class ReportPageComponent extends AuthComponent {
generateHadoopIssue(issue) { generateHadoopIssue(issue) {
return ( return (
<li> <li>
Run Hadoop in secure mode (<a href="http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html"> Run Hadoop in secure mode (<a
href="http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html">
add Kerberos authentication</a>). add Kerberos authentication</a>).
<CollapsibleWellComponent> <CollapsibleWellComponent>
The Hadoop server at <span className="label label-primary">{issue.machine}</span> (<span The Hadoop server at <span className="label label-primary">{issue.machine}</span> (<span

View File

@ -83,7 +83,12 @@ class RunMonkeyPageComponent extends AuthComponent {
let is_error_while_collecting_aws_machines = (res['error'] != null); let is_error_while_collecting_aws_machines = (res['error'] != null);
if (is_error_while_collecting_aws_machines) { if (is_error_while_collecting_aws_machines) {
// There was an error. Finish loading, and display error message. // There was an error. Finish loading, and display error message.
this.setState({isOnAws: true, isErrorWhileCollectingAwsMachines: true, awsMachineCollectionErrorMsg: res['error'], isLoadingAws: false}); this.setState({
isOnAws: true,
isErrorWhileCollectingAwsMachines: true,
awsMachineCollectionErrorMsg: res['error'],
isLoadingAws: false
});
} else { } else {
// No error! Finish loading and display machines for user // No error! Finish loading and display machines for user
this.setState({isOnAws: true, awsMachines: res['instances'], isLoadingAws: false}); this.setState({isOnAws: true, awsMachines: res['instances'], isLoadingAws: false});
@ -219,6 +224,7 @@ class RunMonkeyPageComponent extends AuthComponent {
}); });
}); });
}; };
fetchConfig() { fetchConfig() {
return this.authFetch('/api/configuration/island') return this.authFetch('/api/configuration/island')
.then(res => res.json()) .then(res => res.json())
@ -226,6 +232,7 @@ class RunMonkeyPageComponent extends AuthComponent {
return res.configuration; return res.configuration;
}) })
} }
instanceIdToInstance = (instance_id) => { instanceIdToInstance = (instance_id) => {
let instance = this.state.awsMachines.find( let instance = this.state.awsMachines.find(
function (inst) { function (inst) {
@ -241,7 +248,9 @@ class RunMonkeyPageComponent extends AuthComponent {
<div style={{'marginTop': '1em', 'marginBottom': '1em'}}> <div style={{'marginTop': '1em', 'marginBottom': '1em'}}>
<p className="alert alert-info"> <p className="alert alert-info">
<i className="glyphicon glyphicon-info-sign" style={{'marginRight': '5px'}}/> <i className="glyphicon glyphicon-info-sign" style={{'marginRight': '5px'}}/>
Not sure what this is? Not seeing your AWS EC2 instances? <a href="https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS-EC2-instances" target="_blank">Read the documentation</a>! Not sure what this is? Not seeing your AWS EC2 instances? <a
href="https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS-EC2-instances"
target="_blank">Read the documentation</a>!
</p> </p>
</div> </div>
{ {
@ -269,6 +278,7 @@ class RunMonkeyPageComponent extends AuthComponent {
</div> </div>
) )
} }
render() { render() {
return ( return (
<Col xs={12} lg={8}> <Col xs={12} lg={8}>
@ -302,7 +312,8 @@ class RunMonkeyPageComponent extends AuthComponent {
OR OR
</p> </p>
<p style={this.state.showManual || !this.state.isOnAws ? {'marginBottom': '2em'} : {}}> <p style={this.state.showManual || !this.state.isOnAws ? {'marginBottom': '2em'} : {}}>
<button onClick={this.toggleManual} className={'btn btn-default btn-lg center-block' + (this.state.showManual ? ' active' : '')}> <button onClick={this.toggleManual}
className={'btn btn-default btn-lg center-block' + (this.state.showManual ? ' active' : '')}>
Run on machine of your choice Run on machine of your choice
</button> </button>
</p> </p>
@ -357,7 +368,8 @@ class RunMonkeyPageComponent extends AuthComponent {
{ {
this.state.isOnAws ? this.state.isOnAws ?
<p style={{'marginBottom': '2em'}}> <p style={{'marginBottom': '2em'}}>
<button onClick={this.toggleAws} className={'btn btn-default btn-lg center-block' + (this.state.showAws ? ' active' : '')}> <button onClick={this.toggleAws}
className={'btn btn-default btn-lg center-block' + (this.state.showAws ? ' active' : '')}>
Run on AWS machine of your choice Run on AWS machine of your choice
</button> </button>
</p> </p>
@ -370,9 +382,12 @@ class RunMonkeyPageComponent extends AuthComponent {
<div style={{'marginTop': '1em'}}> <div style={{'marginTop': '1em'}}>
<p class="alert alert-danger"> <p class="alert alert-danger">
<i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/> <i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/>
Error while collecting AWS machine data. Error message: <code>{this.state.awsMachineCollectionErrorMsg}</code><br/> Error while collecting AWS machine data. Error
message: <code>{this.state.awsMachineCollectionErrorMsg}</code><br/>
Are you sure you've set the correct role on your Island AWS machine?<br/> Are you sure you've set the correct role on your Island AWS machine?<br/>
Not sure what this is? <a href="https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS-EC2-instances">Read the documentation</a>! Not sure what this is? <a
href="https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS-EC2-instances">Read
the documentation</a>!
</p> </p>
</div> </div>
: :

View File

@ -29,7 +29,9 @@ class StartOverPageComponent extends AuthComponent {
return ( return (
<Modal show={this.state.showCleanDialog} onHide={() => this.setState({showCleanDialog: false})}> <Modal show={this.state.showCleanDialog} onHide={() => this.setState({showCleanDialog: false})}>
<Modal.Body> <Modal.Body>
<h2><div className="text-center">Reset environment</div></h2> <h2>
<div className="text-center">Reset environment</div>
</h2>
<p style={{'fontSize': '1.2em', 'marginBottom': '2em'}}> <p style={{'fontSize': '1.2em', 'marginBottom': '2em'}}>
Are you sure you want to reset the environment? Are you sure you want to reset the environment?
</p> </p>
@ -75,7 +77,8 @@ class StartOverPageComponent extends AuthComponent {
<button className="btn btn-danger btn-lg center-block" <button className="btn btn-danger btn-lg center-block"
onClick={() => { onClick={() => {
this.setState({showCleanDialog: true}); this.setState({showCleanDialog: true});
this.updateMonkeysRunning();} this.updateMonkeysRunning();
}
}> }>
Reset the Environment Reset the Environment
</button> </button>

View File

@ -18,8 +18,7 @@ class PaginatedTable extends Component {
/> />
</div> </div>
); );
} } else {
else {
return ( return (
<div/> <div/>
); );

View File

@ -177,8 +177,7 @@ class AttackReportPageComponent extends AuthComponent {
render() { render() {
let content; let content;
if (! this.state.runStarted) if (!this.state.runStarted) {
{
content = content =
<p className="alert alert-warning"> <p className="alert alert-warning">
<i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/> <i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/>

View File

@ -14,8 +14,10 @@ const columns = [
Header: 'Breached Servers', Header: 'Breached Servers',
columns: [ columns: [
{Header: 'Machine', accessor: 'label'}, {Header: 'Machine', accessor: 'label'},
{Header: 'IP Addresses', id: 'ip_addresses', {
accessor: x => renderIpAddresses(x)}, Header: 'IP Addresses', id: 'ip_addresses',
accessor: x => renderIpAddresses(x)
},
{Header: 'Exploits', id: 'exploits', accessor: x => renderArray(x.exploits)} {Header: 'Exploits', id: 'exploits', accessor: x => renderArray(x.exploits)}
] ]
} }

View File

@ -14,8 +14,10 @@ const columns = [
Header: 'Scanned Servers', Header: 'Scanned Servers',
columns: [ columns: [
{Header: 'Machine', accessor: 'label'}, {Header: 'Machine', accessor: 'label'},
{ Header: 'IP Addresses', id: 'ip_addresses', {
accessor: x => renderIpAddresses(x)}, Header: 'IP Addresses', id: 'ip_addresses',
accessor: x => renderIpAddresses(x)
},
{Header: 'Accessible From', id: 'accessible_from_nodes', accessor: x => renderArray(x.accessible_from_nodes)}, {Header: 'Accessible From', id: 'accessible_from_nodes', accessor: x => renderArray(x.accessible_from_nodes)},
{Header: 'Services', id: 'services', accessor: x => renderArray(x.services)} {Header: 'Services', id: 'services', accessor: x => renderArray(x.services)}
] ]

View File

@ -22,7 +22,9 @@ export default class EventsModal extends Component {
</h3> </h3>
<hr/> <hr/>
<p> <p>
There {Pluralize('is', this.props.events.length)} {<div className={"label label-primary"}>{this.props.events.length}</div>} {Pluralize('event', this.props.events.length)} associated with this finding. There {Pluralize('is', this.props.events.length)} {<div
className={"label label-primary"}>{this.props.events.length}</div>} {Pluralize('event', this.props.events.length)} associated
with this finding.
</p> </p>
{this.props.events.length > 5 ? this.renderButtons() : null} {this.props.events.length > 5 ? this.renderButtons() : null}
<EventsTimeline events={this.props.events}/> <EventsTimeline events={this.props.events}/>

View File

@ -15,7 +15,8 @@ const pillarToIcon = {
export default class PillarLabel extends Component { export default class PillarLabel extends Component {
render() { render() {
const className = "label " + statusToLabelType[this.props.status]; const className = "label " + statusToLabelType[this.props.status];
return <div className={className} style={{margin: '2px', display: 'inline-block'}}><i className={pillarToIcon[this.props.pillar]}/> {this.props.pillar}</div> return <div className={className} style={{margin: '2px', display: 'inline-block'}}><i
className={pillarToIcon[this.props.pillar]}/> {this.props.pillar}</div>
} }
} }

View File

@ -10,16 +10,19 @@ const MAX_WIDTH_STATUS_COLUMN = 80;
const columns = [ const columns = [
{ {
columns: [ columns: [
{ Header: 'Status', id: 'status', {
Header: 'Status', id: 'status',
accessor: x => { accessor: x => {
return <StatusLabel status={x.status} size="fa-3x" showText={false}/>; return <StatusLabel status={x.status} size="fa-3x" showText={false}/>;
}, },
maxWidth: MAX_WIDTH_STATUS_COLUMN maxWidth: MAX_WIDTH_STATUS_COLUMN
}, },
{ Header: 'Zero Trust Principle', accessor: 'principle', {
Header: 'Zero Trust Principle', accessor: 'principle',
style: {'whiteSpace': 'unset'} // This enables word wrap style: {'whiteSpace': 'unset'} // This enables word wrap
}, },
{ Header: 'Monkey Tests', id: 'tests', {
Header: 'Monkey Tests', id: 'tests',
style: {'whiteSpace': 'unset'}, // This enables word wrap style: {'whiteSpace': 'unset'}, // This enables word wrap
accessor: x => { accessor: x => {
return <TestsStatus tests={x.tests}/>; return <TestsStatus tests={x.tests}/>;

View File

@ -32,7 +32,8 @@ class ZeroTrustReportLegend extends Component {
<div style={{display: "inline-block"}}> <div style={{display: "inline-block"}}>
<StatusLabel showText={true} status={ZeroTrustStatuses.failed}/> <StatusLabel showText={true} status={ZeroTrustStatuses.failed}/>
</div> </div>
{"\t"}At least one of the tests related to this component failed. This means that the Infection Monkey detected an unmet Zero Trust requirement. {"\t"}At least one of the tests related to this component failed. This means that the Infection Monkey detected an
unmet Zero Trust requirement.
</li> </li>
<li> <li>
<div style={{display: "inline-block"}}> <div style={{display: "inline-block"}}>
@ -50,7 +51,8 @@ class ZeroTrustReportLegend extends Component {
<div style={{display: "inline-block"}}> <div style={{display: "inline-block"}}>
<StatusLabel showText={true} status={ZeroTrustStatuses.unexecuted}/> <StatusLabel showText={true} status={ZeroTrustStatuses.unexecuted}/>
</div> </div>
{"\t"}This status means the test wasn't executed.To activate more tests, refer to the Monkey <NavLink to="/configuration"><u>configuration</u></NavLink> page. {"\t"}This status means the test wasn't executed.To activate more tests, refer to the Monkey <NavLink
to="/configuration"><u>configuration</u></NavLink> page.
</li> </li>
</ul> </ul>
</div>; </div>;

View File

@ -9,14 +9,14 @@ export default class SinglePillarPrinciplesStatus extends AuthComponent {
render() { render() {
if (this.props.principlesStatus.length === 0) { if (this.props.principlesStatus.length === 0) {
return null; return null;
} } else {
else {
return ( return (
<Panel> <Panel>
<Panel.Heading> <Panel.Heading>
<Panel.Title toggle> <Panel.Title toggle>
<h3 style={{textAlign: "center", marginTop: "1px", marginBottom: "1px"}}> <h3 style={{textAlign: "center", marginTop: "1px", marginBottom: "1px"}}>
<i className="fa fa-chevron-down" /> <PillarLabel pillar={this.props.pillar} status={this.props.pillarsToStatuses[this.props.pillar]} /> <i className="fa fa-chevron-down"/> <PillarLabel pillar={this.props.pillar}
status={this.props.pillarsToStatuses[this.props.pillar]}/>
</h3> </h3>
</Panel.Title> </Panel.Title>
</Panel.Heading> </Panel.Heading>

View File

@ -14,7 +14,8 @@ export default class SummarySection extends Component {
<Col xs={12} sm={12} md={12} lg={12}> <Col xs={12} sm={12} md={12} lg={12}>
<MonkeysStillAliveWarning allMonkeysAreDead={this.props.allMonkeysAreDead}/> <MonkeysStillAliveWarning allMonkeysAreDead={this.props.allMonkeysAreDead}/>
<p> <p>
Get a quick glance at how your network aligns with the <a href="https://www.forrester.com/report/The+Zero+Trust+eXtended+ZTX+Ecosystem/-/E-RES137210"> Get a quick glance at how your network aligns with the <a
href="https://www.forrester.com/report/The+Zero+Trust+eXtended+ZTX+Ecosystem/-/E-RES137210">
Zero Trust eXtended (ZTX) framework Zero Trust eXtended (ZTX) framework
</a>. </a>.
</p> </p>

View File

@ -29,11 +29,15 @@ class CheckboxComponent extends React.PureComponent {
//Toggles component. //Toggles component.
toggleChecked() { toggleChecked() {
if (this.state.isAnimating) {return false;} if (this.state.isAnimating) {
return false;
}
this.setState({ this.setState({
checked: !this.state.checked, checked: !this.state.checked,
isAnimating: true, isAnimating: true,
}, () => { this.props.changeHandler ? this.props.changeHandler(this.props.name, this.state.checked) : null}); }, () => {
this.props.changeHandler ? this.props.changeHandler(this.props.name, this.state.checked) : null
});
} }
// Stops ping animation on checkbox after click // Stops ping animation on checkbox after click
@ -47,10 +51,15 @@ class CheckboxComponent extends React.PureComponent {
if (this.state.necessary) { if (this.state.necessary) {
return result + ' blocked' return result + ' blocked'
} }
if (this.state.checked) { result += ' is-checked'; } if (this.state.checked) {
else { result += ' is-unchecked' } result += ' is-checked';
} else {
result += ' is-unchecked'
}
if (this.state.isAnimating) { result += ' do-ping'; } if (this.state.isAnimating) {
result += ' do-ping';
}
return result; return result;
} }

View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
// Settings configured here will be merged into the final config object. // Settings configured here will be merged into the final config object.
export default { export default {}
}

View File

@ -8,24 +8,39 @@
</defs> </defs>
<title>14cbedff-3eed-4f8f-abb7-fffe92867ded</title> <title>14cbedff-3eed-4f8f-abb7-fffe92867ded</title>
<g> <g>
<path class="cls-1" d="M89.22,6.874l1.819-.159a3.153,3.153,0,1,1,.124-1.065,2.306,2.306,0,0,1-.005.492l-4.489.393a1.257,1.257,0,0,0,1.414.989,1.417,1.417,0,0,0,1.06-.56A.6.6,0,0,1,89.22,6.874Zm.087-1.767a1.311,1.311,0,0,0-1.443-.916,1.282,1.282,0,0,0-1.249,1.151Z"/> <path class="cls-1"
<path class="cls-1" d="M67.715,4.191a1.622,1.622,0,1,1-1.622,1.622,1.624,1.624,0,0,1,1.622-1.622m0-1.542a3.164,3.164,0,1,0,3.164,3.164A3.164,3.164,0,0,0,67.715,2.65Z"/> d="M89.22,6.874l1.819-.159a3.153,3.153,0,1,1,.124-1.065,2.306,2.306,0,0,1-.005.492l-4.489.393a1.257,1.257,0,0,0,1.414.989,1.417,1.417,0,0,0,1.06-.56A.6.6,0,0,1,89.22,6.874Zm.087-1.767a1.311,1.311,0,0,0-1.443-.916,1.282,1.282,0,0,0-1.249,1.151Z"/>
<path class="cls-1" d="M54.893,8.808,55.53.648A6.958,6.958,0,0,1,56.736.564a6.743,6.743,0,0,1,1.193.084L58.7,3.7q.324,1.332.456,2.148h.071q.132-.816.456-2.148L60.45.648a6.914,6.914,0,0,1,1.2-.084,6.7,6.7,0,0,1,1.188.084l.636,8.16a3.218,3.218,0,0,1-.863.1,5.125,5.125,0,0,1-.864-.06l-.192-3.48q-.1-1.656-.1-2.724h-.084L60.126,7.62a5.447,5.447,0,0,1-.93.06,5.9,5.9,0,0,1-.954-.06L57.006,2.64h-.084q-.023,1.464-.1,2.724l-.192,3.48a5.125,5.125,0,0,1-.864.06A3.366,3.366,0,0,1,54.893,8.808Z"/> <path class="cls-1"
<path class="cls-1" d="M77.094,4.86v2.5a2.089,2.089,0,0,0,.288,1.188,1.611,1.611,0,0,1-1.05.384.983.983,0,0,1-.8-.276,1.321,1.321,0,0,1-.223-.84V5.2a1.33,1.33,0,0,0-.12-.648.446.446,0,0,0-.42-.2,1.386,1.386,0,0,0-.983.468v4.02A4.716,4.716,0,0,1,72.9,8.9a5.113,5.113,0,0,1-.906-.072V2.856l.084-.084h.672a.9.9,0,0,1,.948.72,2.669,2.669,0,0,1,1.7-.744,1.477,1.477,0,0,1,1.26.576A2.5,2.5,0,0,1,77.094,4.86Z"/> d="M67.715,4.191a1.622,1.622,0,1,1-1.622,1.622,1.624,1.624,0,0,1,1.622-1.622m0-1.542a3.164,3.164,0,1,0,3.164,3.164A3.164,3.164,0,0,0,67.715,2.65Z"/>
<path class="cls-1" d="M81.3,6.408l-.4.012V8.832a4.606,4.606,0,0,1-.864.072,5,5,0,0,1-.888-.072V.084L79.241,0h.7a.973.973,0,0,1,.75.246,1.243,1.243,0,0,1,.222.834V4.944h.216a.369.369,0,0,0,.336-.216l.685-1.26a1.062,1.062,0,0,1,1.008-.66q.347,0,1,.024l.071.1-.972,1.824a1.885,1.885,0,0,1-.6.672,1.7,1.7,0,0,1,1.02,1.044l.3.888a4.932,4.932,0,0,0,.307.708.941.941,0,0,0,.27.3,1.512,1.512,0,0,1-1.2.564.839.839,0,0,1-.582-.18,1.534,1.534,0,0,1-.354-.636l-.36-1.056a1.225,1.225,0,0,0-.306-.516A.675.675,0,0,0,81.3,6.408Z"/> <path class="cls-1"
<path class="cls-1" d="M97.577,3.036l-1.5,5.628a5.042,5.042,0,0,1-1,2.1,2.437,2.437,0,0,1-1.9.7,4.322,4.322,0,0,1-1.416-.24V11a2.268,2.268,0,0,1,.09-.51,1.213,1.213,0,0,1,.27-.54,3.946,3.946,0,0,0,1.057.18,1.231,1.231,0,0,0,1.212-1.044l.048-.168q-1.008-.024-1.2-.744L91.805,2.988a2.4,2.4,0,0,1,.989-.24,1.049,1.049,0,0,1,.666.168,1.108,1.108,0,0,1,.313.6l.6,2.376q.1.348.288,1.6a.094.094,0,0,0,.108.084l1.08-4.716a3.485,3.485,0,0,1,.786-.072,2.786,2.786,0,0,1,.882.132Z"/> d="M54.893,8.808,55.53.648A6.958,6.958,0,0,1,56.736.564a6.743,6.743,0,0,1,1.193.084L58.7,3.7q.324,1.332.456,2.148h.071q.132-.816.456-2.148L60.45.648a6.914,6.914,0,0,1,1.2-.084,6.7,6.7,0,0,1,1.188.084l.636,8.16a3.218,3.218,0,0,1-.863.1,5.125,5.125,0,0,1-.864-.06l-.192-3.48q-.1-1.656-.1-2.724h-.084L60.126,7.62a5.447,5.447,0,0,1-.93.06,5.9,5.9,0,0,1-.954-.06L57.006,2.64h-.084q-.023,1.464-.1,2.724l-.192,3.48a5.125,5.125,0,0,1-.864.06A3.366,3.366,0,0,1,54.893,8.808Z"/>
<path class="cls-1"
d="M77.094,4.86v2.5a2.089,2.089,0,0,0,.288,1.188,1.611,1.611,0,0,1-1.05.384.983.983,0,0,1-.8-.276,1.321,1.321,0,0,1-.223-.84V5.2a1.33,1.33,0,0,0-.12-.648.446.446,0,0,0-.42-.2,1.386,1.386,0,0,0-.983.468v4.02A4.716,4.716,0,0,1,72.9,8.9a5.113,5.113,0,0,1-.906-.072V2.856l.084-.084h.672a.9.9,0,0,1,.948.72,2.669,2.669,0,0,1,1.7-.744,1.477,1.477,0,0,1,1.26.576A2.5,2.5,0,0,1,77.094,4.86Z"/>
<path class="cls-1"
d="M81.3,6.408l-.4.012V8.832a4.606,4.606,0,0,1-.864.072,5,5,0,0,1-.888-.072V.084L79.241,0h.7a.973.973,0,0,1,.75.246,1.243,1.243,0,0,1,.222.834V4.944h.216a.369.369,0,0,0,.336-.216l.685-1.26a1.062,1.062,0,0,1,1.008-.66q.347,0,1,.024l.071.1-.972,1.824a1.885,1.885,0,0,1-.6.672,1.7,1.7,0,0,1,1.02,1.044l.3.888a4.932,4.932,0,0,0,.307.708.941.941,0,0,0,.27.3,1.512,1.512,0,0,1-1.2.564.839.839,0,0,1-.582-.18,1.534,1.534,0,0,1-.354-.636l-.36-1.056a1.225,1.225,0,0,0-.306-.516A.675.675,0,0,0,81.3,6.408Z"/>
<path class="cls-1"
d="M97.577,3.036l-1.5,5.628a5.042,5.042,0,0,1-1,2.1,2.437,2.437,0,0,1-1.9.7,4.322,4.322,0,0,1-1.416-.24V11a2.268,2.268,0,0,1,.09-.51,1.213,1.213,0,0,1,.27-.54,3.946,3.946,0,0,0,1.057.18,1.231,1.231,0,0,0,1.212-1.044l.048-.168q-1.008-.024-1.2-.744L91.805,2.988a2.4,2.4,0,0,1,.989-.24,1.049,1.049,0,0,1,.666.168,1.108,1.108,0,0,1,.313.6l.6,2.376q.1.348.288,1.6a.094.094,0,0,0,.108.084l1.08-4.716a3.485,3.485,0,0,1,.786-.072,2.786,2.786,0,0,1,.882.132Z"/>
</g> </g>
<g> <g>
<path class="cls-1" d="M0,8.937V.741A1.882,1.882,0,0,1,.414.705,2.229,2.229,0,0,1,.852.741v8.2a2.231,2.231,0,0,1-.432.036A2.056,2.056,0,0,1,0,8.937Z"/> <path class="cls-1"
<path class="cls-1" d="M8.232,4.809V7.833a2.871,2.871,0,0,0,.12,1,.7.7,0,0,1-.517.18q-.42,0-.42-.54V5.085a2.2,2.2,0,0,0-.191-1.074.747.747,0,0,0-.7-.318,2.332,2.332,0,0,0-1.044.27,2.7,2.7,0,0,0-.888.69V8.937a1.994,1.994,0,0,1-.408.036,1.987,1.987,0,0,1-.408-.036V3.093l.072-.072h.312a.384.384,0,0,1,.348.132.831.831,0,0,1,.085.432v.24a2.983,2.983,0,0,1,.966-.636A2.908,2.908,0,0,1,6.7,2.949a1.335,1.335,0,0,1,1.17.516A2.272,2.272,0,0,1,8.232,4.809Z"/> d="M0,8.937V.741A1.882,1.882,0,0,1,.414.705,2.229,2.229,0,0,1,.852.741v8.2a2.231,2.231,0,0,1-.432.036A2.056,2.056,0,0,1,0,8.937Z"/>
<path class="cls-1" d="M11.147,8.937V3.669l-1.031.012a1.473,1.473,0,0,1-.036-.312,1.639,1.639,0,0,1,.036-.324l1,.024q-.085-1.115-.084-1.272A1.769,1.769,0,0,1,11.472.555,1.538,1.538,0,0,1,12.666.069a3.728,3.728,0,0,1,1.386.252.818.818,0,0,1-.2.564A3.881,3.881,0,0,0,12.756.693a.883.883,0,0,0-.708.294,1.226,1.226,0,0,0-.252.822,9.977,9.977,0,0,0,.1,1.26l1.776-.024a1.716,1.716,0,0,1,.036.324,1.54,1.54,0,0,1-.036.312l-1.716-.012V8.937a2.258,2.258,0,0,1-.8,0Z"/> <path class="cls-1"
<path class="cls-1" d="M32.352,3.045a1.716,1.716,0,0,1,.036.324,1.54,1.54,0,0,1-.036.312l-1.524-.012v4.14q0,.492.468.492h.925a1,1,0,0,1,.071.372,1.405,1.405,0,0,1-.012.24,8.879,8.879,0,0,1-1.122.072,1.268,1.268,0,0,1-.846-.246.87.87,0,0,1-.288-.7V3.669l-.828.012a1.336,1.336,0,0,1-.036-.306,1.664,1.664,0,0,1,.036-.33l.828.012v-1.3a.794.794,0,0,1,.09-.432.4.4,0,0,1,.354-.132h.288l.072.072v1.8Z"/> d="M8.232,4.809V7.833a2.871,2.871,0,0,0,.12,1,.7.7,0,0,1-.517.18q-.42,0-.42-.54V5.085a2.2,2.2,0,0,0-.191-1.074.747.747,0,0,0-.7-.318,2.332,2.332,0,0,0-1.044.27,2.7,2.7,0,0,0-.888.69V8.937a1.994,1.994,0,0,1-.408.036,1.987,1.987,0,0,1-.408-.036V3.093l.072-.072h.312a.384.384,0,0,1,.348.132.831.831,0,0,1,.085.432v.24a2.983,2.983,0,0,1,.966-.636A2.908,2.908,0,0,1,6.7,2.949a1.335,1.335,0,0,1,1.17.516A2.272,2.272,0,0,1,8.232,4.809Z"/>
<path class="cls-1" d="M35.472,3.837v5.1a2.324,2.324,0,0,1-.816,0V4.257a.7.7,0,0,0-.108-.456.5.5,0,0,0-.384-.12h-.107a1.288,1.288,0,0,1-.036-.294,1.616,1.616,0,0,1,.036-.318,4.4,4.4,0,0,1,.575-.048h.1a.7.7,0,0,1,.546.216A.856.856,0,0,1,35.472,3.837ZM34.379,1.881a.986.986,0,0,1-.084-.438.837.837,0,0,1,.084-.414.853.853,0,0,1,.511-.12.8.8,0,0,1,.5.12.837.837,0,0,1,.084.414.986.986,0,0,1-.084.438A.707.707,0,0,1,34.9,2,.874.874,0,0,1,34.379,1.881Z"/> <path class="cls-1"
<path class="cls-1" d="M49.139,4.809V7.833a2.871,2.871,0,0,0,.12,1,.7.7,0,0,1-.517.18q-.42,0-.42-.54V5.085a2.2,2.2,0,0,0-.191-1.074.747.747,0,0,0-.7-.318,2.332,2.332,0,0,0-1.044.27,2.7,2.7,0,0,0-.888.69V8.937a2.324,2.324,0,0,1-.816,0V3.093l.072-.072h.312a.384.384,0,0,1,.348.132.831.831,0,0,1,.085.432v.24a2.983,2.983,0,0,1,.966-.636,2.908,2.908,0,0,1,1.134-.24,1.335,1.335,0,0,1,1.17.516A2.272,2.272,0,0,1,49.139,4.809Z"/> d="M11.147,8.937V3.669l-1.031.012a1.473,1.473,0,0,1-.036-.312,1.639,1.639,0,0,1,.036-.324l1,.024q-.085-1.115-.084-1.272A1.769,1.769,0,0,1,11.472.555,1.538,1.538,0,0,1,12.666.069a3.728,3.728,0,0,1,1.386.252.818.818,0,0,1-.2.564A3.881,3.881,0,0,0,12.756.693a.883.883,0,0,0-.708.294,1.226,1.226,0,0,0-.252.822,9.977,9.977,0,0,0,.1,1.26l1.776-.024a1.716,1.716,0,0,1,.036.324,1.54,1.54,0,0,1-.036.312l-1.716-.012V8.937a2.258,2.258,0,0,1-.8,0Z"/>
<path class="cls-1" d="M40.075,3.555a2.364,2.364,0,1,1-2.364,2.364,2.367,2.367,0,0,1,2.364-2.364m0-.8a3.164,3.164,0,1,0,3.164,3.164,3.164,3.164,0,0,0-3.164-3.164Z"/> <path class="cls-1"
<path class="cls-1" d="M25.315,8.285a2.349,2.349,0,0,1-2.04-1.18,2.335,2.335,0,0,1,0-2.36,2.344,2.344,0,0,1,4.08,0l.7-.4a3.16,3.16,0,1,0,0,3.16l-.7-.4A2.35,2.35,0,0,1,25.315,8.285Z"/> d="M32.352,3.045a1.716,1.716,0,0,1,.036.324,1.54,1.54,0,0,1-.036.312l-1.524-.012v4.14q0,.492.468.492h.925a1,1,0,0,1,.071.372,1.405,1.405,0,0,1-.012.24,8.879,8.879,0,0,1-1.122.072,1.268,1.268,0,0,1-.846-.246.87.87,0,0,1-.288-.7V3.669l-.828.012a1.336,1.336,0,0,1-.036-.306,1.664,1.664,0,0,1,.036-.33l.828.012v-1.3a.794.794,0,0,1,.09-.432.4.4,0,0,1,.354-.132h.288l.072.072v1.8Z"/>
<path class="cls-1"
d="M35.472,3.837v5.1a2.324,2.324,0,0,1-.816,0V4.257a.7.7,0,0,0-.108-.456.5.5,0,0,0-.384-.12h-.107a1.288,1.288,0,0,1-.036-.294,1.616,1.616,0,0,1,.036-.318,4.4,4.4,0,0,1,.575-.048h.1a.7.7,0,0,1,.546.216A.856.856,0,0,1,35.472,3.837ZM34.379,1.881a.986.986,0,0,1-.084-.438.837.837,0,0,1,.084-.414.853.853,0,0,1,.511-.12.8.8,0,0,1,.5.12.837.837,0,0,1,.084.414.986.986,0,0,1-.084.438A.707.707,0,0,1,34.9,2,.874.874,0,0,1,34.379,1.881Z"/>
<path class="cls-1"
d="M49.139,4.809V7.833a2.871,2.871,0,0,0,.12,1,.7.7,0,0,1-.517.18q-.42,0-.42-.54V5.085a2.2,2.2,0,0,0-.191-1.074.747.747,0,0,0-.7-.318,2.332,2.332,0,0,0-1.044.27,2.7,2.7,0,0,0-.888.69V8.937a2.324,2.324,0,0,1-.816,0V3.093l.072-.072h.312a.384.384,0,0,1,.348.132.831.831,0,0,1,.085.432v.24a2.983,2.983,0,0,1,.966-.636,2.908,2.908,0,0,1,1.134-.24,1.335,1.335,0,0,1,1.17.516A2.272,2.272,0,0,1,49.139,4.809Z"/>
<path class="cls-1"
d="M40.075,3.555a2.364,2.364,0,1,1-2.364,2.364,2.367,2.367,0,0,1,2.364-2.364m0-.8a3.164,3.164,0,1,0,3.164,3.164,3.164,3.164,0,0,0-3.164-3.164Z"/>
<path class="cls-1"
d="M25.315,8.285a2.349,2.349,0,0,1-2.04-1.18,2.335,2.335,0,0,1,0-2.36,2.344,2.344,0,0,1,4.08,0l.7-.4a3.16,3.16,0,1,0,0,3.16l-.7-.4A2.35,2.35,0,0,1,25.315,8.285Z"/>
<g> <g>
<path class="cls-1" d="M17.87,8.285a2.365,2.365,0,1,1,2.36-2.37h.8a3.162,3.162,0,0,0-5.9-1.58,3.018,3.018,0,0,0-.43,1.58,3.165,3.165,0,0,0,5.91,1.58l-.69-.39A2.378,2.378,0,0,1,17.87,8.285Z"/> <path class="cls-1"
d="M17.87,8.285a2.365,2.365,0,1,1,2.36-2.37h.8a3.162,3.162,0,0,0-5.9-1.58,3.018,3.018,0,0,0-.43,1.58,3.165,3.165,0,0,0,5.91,1.58l-.69-.39A2.378,2.378,0,0,1,17.87,8.285Z"/>
<polygon class="cls-1" points="15.286 5.718 20.514 5.261 21.03 5.915 15.347 6.412 15.286 5.718"/> <polygon class="cls-1" points="15.286 5.718 20.514 5.261 21.03 5.915 15.347 6.412 15.286 5.718"/>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More