From 4c0321ab9384d0e9f4aa81afb048a293c9251243 Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Sun, 26 Jan 2020 18:47:46 +0200
Subject: [PATCH 001/152] Added collector and submodule
---
.gitmodules | 3 +++
.../common/data/system_info_collectors_names.py | 1 +
.../system_info/collectors/scoutsuite | 1 +
.../collectors/scoutsuite_collector.py | 16 ++++++++++++++++
4 files changed, 21 insertions(+)
create mode 100644 .gitmodules
create mode 160000 monkey/infection_monkey/system_info/collectors/scoutsuite
create mode 100644 monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..bcb7399ee
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "monkey/infection_monkey/system_info/collectors/scoutsuite"]
+ path = monkey/infection_monkey/system_info/collectors/scoutsuite
+ url = git@github.com:ShayNehmad/ScoutSuite.git
diff --git a/monkey/common/data/system_info_collectors_names.py b/monkey/common/data/system_info_collectors_names.py
index 831bbe142..ad8a3fd74 100644
--- a/monkey/common/data/system_info_collectors_names.py
+++ b/monkey/common/data/system_info_collectors_names.py
@@ -2,3 +2,4 @@ AWS_COLLECTOR = "AwsCollector"
HOSTNAME_COLLECTOR = "HostnameCollector"
ENVIRONMENT_COLLECTOR = "EnvironmentCollector"
PROCESS_LIST_COLLECTOR = "ProcessListCollector"
+SCOUTSUITE_COLLECTOR = "ScoutSuiteCollector"
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite b/monkey/infection_monkey/system_info/collectors/scoutsuite
new file mode 160000
index 000000000..e784fc27a
--- /dev/null
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite
@@ -0,0 +1 @@
+Subproject commit e784fc27ae8311c3c610bccd556d2bef3cd54d63
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
new file mode 100644
index 000000000..6645290f5
--- /dev/null
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
@@ -0,0 +1,16 @@
+import logging
+
+from common.data.system_info_collectors_names import SCOUTSUITE_COLLECTOR
+from infection_monkey.system_info.system_info_collector import SystemInfoCollector
+from infection_monkey.system_info.collectors.scoutsuite.ScoutSuite.__main__ import run
+
+logger = logging.getLogger(__name__)
+
+
+class HostnameCollector(SystemInfoCollector):
+ def __init__(self):
+ super().__init__(name=SCOUTSUITE_COLLECTOR)
+
+ def collect(self) -> dict:
+
+ return {}
From a0db78502090bd95b5a75f7c4baee7db53c105fb Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Mon, 27 Jan 2020 12:25:12 +0200
Subject: [PATCH 002/152] Update .gitmodules
---
.gitmodules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitmodules b/.gitmodules
index bcb7399ee..61ec3dae5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "monkey/infection_monkey/system_info/collectors/scoutsuite"]
path = monkey/infection_monkey/system_info/collectors/scoutsuite
- url = git@github.com:ShayNehmad/ScoutSuite.git
+ url = https://github.com/ShayNehmad/ScoutSuite.git
From 87f90b36f084a308820b9665e1c3b1b2eea5a93b Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Mon, 27 Jan 2020 14:28:52 +0200
Subject: [PATCH 003/152] Excluding scoutsuite from flake8
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 6abeb59b1..cb51083e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,7 @@ before_script:
script:
# Check Python code
# Check syntax errors and fail the build if any are found.
-- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
+- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics --exclude=monkey/infection_monkey/system_info/collectors/scoutsuite
# Warn about linter issues.
# --exit-zero forces Flake8 to use the exit status code 0 even if there are errors, which means this will NOT fail the build.
From a26b9114ef0deec3eb0e8aa0ffb118dca94010bc Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Mon, 27 Jan 2020 14:28:57 +0200
Subject: [PATCH 004/152] Update scoutsuite_collector.py
---
.../system_info/collectors/scoutsuite_collector.py | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
index 6645290f5..fdf7ce6fa 100644
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
@@ -1,16 +1,23 @@
import logging
+from common.cloud.environment_names import Environment
from common.data.system_info_collectors_names import SCOUTSUITE_COLLECTOR
from infection_monkey.system_info.system_info_collector import SystemInfoCollector
from infection_monkey.system_info.collectors.scoutsuite.ScoutSuite.__main__ import run
+from system_info.collectors.environment_collector import get_monkey_environment
logger = logging.getLogger(__name__)
-class HostnameCollector(SystemInfoCollector):
+class ScoutSuiteCollector(SystemInfoCollector):
def __init__(self):
super().__init__(name=SCOUTSUITE_COLLECTOR)
def collect(self) -> dict:
-
+ env = get_monkey_environment()
+ if env == Environment.ON_PREMISE.value:
+ logger.info("Monkey is not on cloud; not running ScoutSuite")
+ else:
+ logger.info(f"Attempting to execute ScoutSuite with {env.lower()}")
+ run(env.lower(), debug=True, quiet=False)
return {}
From f49089aed306f1ee155f922110f08fc93c5b804d Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Mon, 27 Jan 2020 14:46:39 +0200
Subject: [PATCH 005/152] Added basic framework for running scoutsuite
---
.travis.yml | 1 +
.../collectors/scoutsuite_collector.py | 8 ++++++--
monkey/monkey_island/cc/services/config_schema.py | 15 ++++++++++++---
.../system_info_collectors/scoutsuite.py | 9 +++++++++
.../system_info_telemetry_dispatcher.py | 6 ++++--
5 files changed, 32 insertions(+), 7 deletions(-)
create mode 100644 monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
diff --git a/.travis.yml b/.travis.yml
index cb51083e4..b83e12eb4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,6 +16,7 @@ install:
- pip install -r monkey/monkey_island/requirements.txt # for unit tests
- pip install flake8 pytest dlint # for next stages
- pip install -r monkey/infection_monkey/requirements.txt # for unit tests
+- pip install -r monkey/infection_monkey/system_info/collectors/scoutsuite/requirements.txt
before_script:
# Set the server config to `testing`. This is required for for the UTs to pass.
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
index fdf7ce6fa..38c6d7c0f 100644
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
@@ -17,7 +17,11 @@ class ScoutSuiteCollector(SystemInfoCollector):
env = get_monkey_environment()
if env == Environment.ON_PREMISE.value:
logger.info("Monkey is not on cloud; not running ScoutSuite")
+ return {}
else:
logger.info(f"Attempting to execute ScoutSuite with {env.lower()}")
- run(env.lower(), debug=True, quiet=False)
- return {}
+ scout_suite_results = run(env.lower(), debug=True, quiet=False)
+ return {
+ "Environment": env,
+ "Results": scout_suite_results
+ }
diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py
index 3d0220ee2..59cd97686 100644
--- a/monkey/monkey_island/cc/services/config_schema.py
+++ b/monkey/monkey_island/cc/services/config_schema.py
@@ -1,5 +1,5 @@
from common.data.system_info_collectors_names \
- import AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR
+ import AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR, SCOUTSUITE_COLLECTOR
WARNING_SIGN = " \u26A0"
@@ -130,7 +130,7 @@ SCHEMA = {
"title": "Collect the machine's hostname",
"attack_techniques": []
},
-{
+ {
"type": "string",
"enum": [
PROCESS_LIST_COLLECTOR
@@ -138,6 +138,14 @@ SCHEMA = {
"title": "Collect running processes on the machine",
"attack_techniques": []
},
+ {
+ "type": "string",
+ "enum": [
+ SCOUTSUITE_COLLECTOR
+ ],
+ "title": "If on cloud, execute ScoutSuite and collect its results",
+ "attack_techniques": []
+ },
],
},
"post_breach_acts": {
@@ -485,7 +493,8 @@ SCHEMA = {
ENVIRONMENT_COLLECTOR,
AWS_COLLECTOR,
HOSTNAME_COLLECTOR,
- PROCESS_LIST_COLLECTOR
+ PROCESS_LIST_COLLECTOR,
+ SCOUTSUITE_COLLECTOR
],
"description": "Determines which system information collectors will collect information."
},
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
new file mode 100644
index 000000000..85d053e47
--- /dev/null
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
@@ -0,0 +1,9 @@
+import logging
+import json
+
+logger = logging.getLogger(__name__)
+
+
+def process_scout_suite_telemetry(collector_results, monkey_guid):
+ # Monkey.get_single_monkey_by_guid(monkey_guid).set_hostname(collector_results["hostname"])
+ logger.info(f"\n\n{json.dumps(collector_results, indent=2)}\n{monkey_guid}")
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
index b5f2d24ea..1c651501d 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
@@ -2,10 +2,11 @@ import logging
import typing
from common.data.system_info_collectors_names \
- import AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR
+ import AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR, SCOUTSUITE_COLLECTOR
from monkey_island.cc.services.telemetry.processing.system_info_collectors.aws import process_aws_telemetry
from monkey_island.cc.services.telemetry.processing.system_info_collectors.environment import process_environment_telemetry
from monkey_island.cc.services.telemetry.processing.system_info_collectors.hostname import process_hostname_telemetry
+from monkey_island.cc.services.telemetry.processing.system_info_collectors.scoutsuite import process_scout_suite_telemetry
from monkey_island.cc.services.telemetry.zero_trust_tests.antivirus_existence import test_antivirus_existence
logger = logging.getLogger(__name__)
@@ -14,7 +15,8 @@ SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = {
AWS_COLLECTOR: [process_aws_telemetry],
ENVIRONMENT_COLLECTOR: [process_environment_telemetry],
HOSTNAME_COLLECTOR: [process_hostname_telemetry],
- PROCESS_LIST_COLLECTOR: [test_antivirus_existence]
+ PROCESS_LIST_COLLECTOR: [test_antivirus_existence],
+ SCOUTSUITE_COLLECTOR: [process_scout_suite_telemetry]
}
From b8b015e84e83ed3f2863e068a6b47b23cdd7235f Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Mon, 27 Jan 2020 14:59:31 +0200
Subject: [PATCH 006/152] Update .travis.yml
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index b83e12eb4..7435a721e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,7 +32,7 @@ script:
# --count will print the total number of errors.
# --statistics Count the number of occurrences of each error/warning code and print a report.
# The output is redirected to a file.
-- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics > flake8_warnings.txt
+- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=monkey/infection_monkey/system_info/collectors/scoutsuite > flake8_warnings.txt
# Display the linter issues
- cat flake8_warnings.txt
# Make sure that we haven't increased the amount of warnings.
From b5f8fbe9f0ddd68792dd958674783582c862fe91 Mon Sep 17 00:00:00 2001
From: Shay Nehmad
Date: Tue, 4 Feb 2020 14:39:38 +0200
Subject: [PATCH 007/152] WIP
---
...tsuite_collector.py => scout_suite_collector.py} | 13 +++++++++++--
.../processing/system_info_collectors/scoutsuite.py | 2 +-
2 files changed, 12 insertions(+), 3 deletions(-)
rename monkey/infection_monkey/system_info/collectors/{scoutsuite_collector.py => scout_suite_collector.py} (74%)
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
similarity index 74%
rename from monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
rename to monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
index 38c6d7c0f..09adf94e4 100644
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
@@ -1,4 +1,5 @@
import logging
+import tempfile
from common.cloud.environment_names import Environment
from common.data.system_info_collectors_names import SCOUTSUITE_COLLECTOR
@@ -15,12 +16,20 @@ class ScoutSuiteCollector(SystemInfoCollector):
def collect(self) -> dict:
env = get_monkey_environment()
+ env = "AWS"
if env == Environment.ON_PREMISE.value:
logger.info("Monkey is not on cloud; not running ScoutSuite")
return {}
else:
- logger.info(f"Attempting to execute ScoutSuite with {env.lower()}")
- scout_suite_results = run(env.lower(), debug=True, quiet=False)
+ tmp_dir_path = tempfile.mkdtemp()
+ logger.info(f"Attempting to execute ScoutSuite with {env.lower()}, saving results in {tmp_dir_path}")
+
+ scout_suite_results = run(
+ env.lower(),
+ debug=True,
+ quiet=False,
+ no_browser=True,
+ report_dir=tmp_dir_path)
return {
"Environment": env,
"Results": scout_suite_results
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
index 85d053e47..c0a2517f2 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/scoutsuite.py
@@ -6,4 +6,4 @@ logger = logging.getLogger(__name__)
def process_scout_suite_telemetry(collector_results, monkey_guid):
# Monkey.get_single_monkey_by_guid(monkey_guid).set_hostname(collector_results["hostname"])
- logger.info(f"\n\n{json.dumps(collector_results, indent=2)}\n{monkey_guid}")
+ logger.info(f"ScoutSuite results:\n{json.dumps(collector_results, indent=2)}")
From a365d2eb3cffeac02f8144e59691c3f21ba2c6ac Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Thu, 3 Sep 2020 12:06:20 +0300
Subject: [PATCH 008/152] Exported telem categories into dict, moved scoutsuite
submodule to a different dir
---
.gitmodules | 2 +-
.../{data => common_consts}/__init__.py | 0
.../{data => common_consts}/api_url_consts.py | 0
.../{data => common_consts}/network_consts.py | 0
.../post_breach_consts.py | 0
.../system_info_collectors_names.py | 0
.../common/common_consts/telem_categories.py | 9 +++++
.../validation_formats.py | 0
.../zero_trust_consts.py | 0
monkey/infection_monkey/control.py | 2 +-
.../infection_monkey/exploit/elasticgroovy.py | 2 +-
.../infection_monkey/network/elasticfinger.py | 2 +-
.../post_breach/actions/add_user.py | 2 +-
.../actions/change_file_privileges.py | 2 +-
.../actions/clear_command_history.py | 2 +-
.../actions/communicate_as_new_user.py | 2 +-
.../post_breach/actions/discover_accounts.py | 2 +-
.../post_breach/actions/hide_files.py | 2 +-
.../actions/modify_shell_startup_files.py | 2 +-
.../post_breach/actions/schedule_jobs.py | 2 +-
.../post_breach/actions/use_signed_scripts.py | 2 +-
.../post_breach/actions/use_trap_command.py | 2 +-
.../post_breach/actions/users_custom_pba.py | 2 +-
.../infection_monkey/system_info/__init__.py | 2 +-
.../system_info/collectors/aws_collector.py | 2 +-
.../collectors/environment_collector.py | 2 +-
.../collectors/hostname_collector.py | 2 +-
.../collectors/process_list_collector.py | 2 +-
.../collectors/scout_suite_collector.py | 36 -------------------
.../system_info/collectors/scoutsuite | 1 -
.../scoutsuite_collector/__init__.py | 0
.../scoutsuite_collector/scoutsuite | 1 +
.../system_info/windows_info_collector.py | 2 +-
.../telemetry/exploit_telem.py | 3 +-
.../telemetry/post_breach_telem.py | 3 +-
.../infection_monkey/telemetry/scan_telem.py | 3 +-
.../infection_monkey/telemetry/state_telem.py | 3 +-
.../telemetry/system_info_telem.py | 3 +-
.../infection_monkey/telemetry/trace_telem.py | 3 +-
.../telemetry/tunnel_telem.py | 3 +-
monkey/monkey_island/cc/app.py | 2 +-
.../cc/models/zero_trust/aggregate_finding.py | 2 +-
.../cc/models/zero_trust/event.py | 2 +-
.../cc/models/zero_trust/finding.py | 2 +-
.../models/zero_trust/segmentation_finding.py | 2 +-
.../zero_trust/test_aggregate_finding.py | 2 +-
.../cc/models/zero_trust/test_event.py | 2 +-
.../cc/models/zero_trust/test_finding.py | 2 +-
.../zero_trust/test_segmentation_finding.py | 2 +-
.../monkey_island/cc/resources/telemetry.py | 3 +-
.../cc/resources/telemetry_feed.py | 15 ++++----
.../attack/technique_reports/T1053.py | 2 +-
.../attack/technique_reports/T1087.py | 2 +-
.../attack/technique_reports/T1136.py | 2 +-
.../attack/technique_reports/T1146.py | 2 +-
.../attack/technique_reports/T1154.py | 2 +-
.../attack/technique_reports/T1156.py | 2 +-
.../attack/technique_reports/T1158.py | 2 +-
.../attack/technique_reports/T1166.py | 2 +-
.../attack/technique_reports/T1168.py | 2 +-
.../attack/technique_reports/T1216.py | 2 +-
.../attack/technique_reports/T1504.py | 2 +-
.../services/config_schema/basic_network.py | 2 +-
.../system_info_collector_classes.py | 12 +++----
.../cc/services/config_schema/monkey.py | 12 +++----
.../reporting/test_zero_trust_service.py | 2 +-
.../services/reporting/zero_trust_service.py | 2 +-
.../telemetry/processing/post_breach.py | 2 +-
.../system_info_telemetry_dispatcher.py | 10 +++---
.../zero_trust_tests/antivirus_existence.py | 2 +-
.../communicate_as_new_user.py | 2 +-
.../zero_trust_tests/data_endpoints.py | 4 +--
.../zero_trust_tests/machine_exploited.py | 2 +-
.../zero_trust_tests/segmentation.py | 2 +-
.../test_segmentation_zt_tests.py | 2 +-
.../telemetry/zero_trust_tests/tunneling.py | 2 +-
76 files changed, 104 insertions(+), 122 deletions(-)
rename monkey/common/{data => common_consts}/__init__.py (100%)
rename monkey/common/{data => common_consts}/api_url_consts.py (100%)
rename monkey/common/{data => common_consts}/network_consts.py (100%)
rename monkey/common/{data => common_consts}/post_breach_consts.py (100%)
rename monkey/common/{data => common_consts}/system_info_collectors_names.py (100%)
create mode 100644 monkey/common/common_consts/telem_categories.py
rename monkey/common/{data => common_consts}/validation_formats.py (100%)
rename monkey/common/{data => common_consts}/zero_trust_consts.py (100%)
delete mode 100644 monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
delete mode 160000 monkey/infection_monkey/system_info/collectors/scoutsuite
create mode 100644 monkey/infection_monkey/system_info/collectors/scoutsuite_collector/__init__.py
create mode 160000 monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
diff --git a/.gitmodules b/.gitmodules
index df2805df9..6f784049d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -5,5 +5,5 @@
path = docs/themes/learn
url = https://github.com/guardicode/hugo-theme-learn.git
[submodule "monkey/infection_monkey/system_info/collectors/scoutsuite"]
- path = monkey/infection_monkey/system_info/collectors/scoutsuite
+ path = monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
url = https://github.com/ShayNehmad/ScoutSuite.git
diff --git a/monkey/common/data/__init__.py b/monkey/common/common_consts/__init__.py
similarity index 100%
rename from monkey/common/data/__init__.py
rename to monkey/common/common_consts/__init__.py
diff --git a/monkey/common/data/api_url_consts.py b/monkey/common/common_consts/api_url_consts.py
similarity index 100%
rename from monkey/common/data/api_url_consts.py
rename to monkey/common/common_consts/api_url_consts.py
diff --git a/monkey/common/data/network_consts.py b/monkey/common/common_consts/network_consts.py
similarity index 100%
rename from monkey/common/data/network_consts.py
rename to monkey/common/common_consts/network_consts.py
diff --git a/monkey/common/data/post_breach_consts.py b/monkey/common/common_consts/post_breach_consts.py
similarity index 100%
rename from monkey/common/data/post_breach_consts.py
rename to monkey/common/common_consts/post_breach_consts.py
diff --git a/monkey/common/data/system_info_collectors_names.py b/monkey/common/common_consts/system_info_collectors_names.py
similarity index 100%
rename from monkey/common/data/system_info_collectors_names.py
rename to monkey/common/common_consts/system_info_collectors_names.py
diff --git a/monkey/common/common_consts/telem_categories.py b/monkey/common/common_consts/telem_categories.py
new file mode 100644
index 000000000..c983786b9
--- /dev/null
+++ b/monkey/common/common_consts/telem_categories.py
@@ -0,0 +1,9 @@
+class TelemCategoryEnum:
+ EXPLOIT = 'exploit'
+ POST_BREACH = 'post_breach'
+ SCAN = 'scan'
+ SCOUTSUITE = 'scoutsuite'
+ STATE = 'state'
+ SYSTEM_INFO = 'system_info'
+ TRACE = 'trace'
+ TUNNEL = 'tunnel'
diff --git a/monkey/common/data/validation_formats.py b/monkey/common/common_consts/validation_formats.py
similarity index 100%
rename from monkey/common/data/validation_formats.py
rename to monkey/common/common_consts/validation_formats.py
diff --git a/monkey/common/data/zero_trust_consts.py b/monkey/common/common_consts/zero_trust_consts.py
similarity index 100%
rename from monkey/common/data/zero_trust_consts.py
rename to monkey/common/common_consts/zero_trust_consts.py
diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py
index 35922286f..912514b8c 100644
--- a/monkey/infection_monkey/control.py
+++ b/monkey/infection_monkey/control.py
@@ -9,7 +9,7 @@ from requests.exceptions import ConnectionError
import infection_monkey.monkeyfs as monkeyfs
import infection_monkey.tunnel as tunnel
-from common.data.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
+from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
from infection_monkey.config import GUID, WormConfiguration
from infection_monkey.network.info import check_internet_access, local_ips
from infection_monkey.transport.http import HTTPConnectProxy
diff --git a/monkey/infection_monkey/exploit/elasticgroovy.py b/monkey/infection_monkey/exploit/elasticgroovy.py
index fff71024d..026ccfdbd 100644
--- a/monkey/infection_monkey/exploit/elasticgroovy.py
+++ b/monkey/infection_monkey/exploit/elasticgroovy.py
@@ -10,7 +10,7 @@ import re
import requests
-from common.data.network_consts import ES_SERVICE
+from common.common_consts.network_consts import ES_SERVICE
from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus
from infection_monkey.exploit.web_rce import WebRCE
from infection_monkey.model import (BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND,
diff --git a/monkey/infection_monkey/network/elasticfinger.py b/monkey/infection_monkey/network/elasticfinger.py
index 5ba95ab93..e7a60be17 100644
--- a/monkey/infection_monkey/network/elasticfinger.py
+++ b/monkey/infection_monkey/network/elasticfinger.py
@@ -6,7 +6,7 @@ import requests
from requests.exceptions import ConnectionError, Timeout
import infection_monkey.config
-from common.data.network_consts import ES_SERVICE
+from common.common_consts.network_consts import ES_SERVICE
from infection_monkey.network.HostFinger import HostFinger
ES_PORT = 9200
diff --git a/monkey/infection_monkey/post_breach/actions/add_user.py b/monkey/infection_monkey/post_breach/actions/add_user.py
index 58be89a1f..a85845840 100644
--- a/monkey/infection_monkey/post_breach/actions/add_user.py
+++ b/monkey/infection_monkey/post_breach/actions/add_user.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_BACKDOOR_USER
+from common.common_consts.post_breach_consts import POST_BREACH_BACKDOOR_USER
from infection_monkey.config import WormConfiguration
from infection_monkey.post_breach.pba import PBA
from infection_monkey.utils.users import get_commands_to_add_user
diff --git a/monkey/infection_monkey/post_breach/actions/change_file_privileges.py b/monkey/infection_monkey/post_breach/actions/change_file_privileges.py
index 1cf5813e3..69f8f34da 100644
--- a/monkey/infection_monkey/post_breach/actions/change_file_privileges.py
+++ b/monkey/infection_monkey/post_breach/actions/change_file_privileges.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_SETUID_SETGID
+from common.common_consts.post_breach_consts import POST_BREACH_SETUID_SETGID
from infection_monkey.post_breach.pba import PBA
from infection_monkey.post_breach.setuid_setgid.setuid_setgid import \
get_commands_to_change_setuid_setgid
diff --git a/monkey/infection_monkey/post_breach/actions/clear_command_history.py b/monkey/infection_monkey/post_breach/actions/clear_command_history.py
index afd26996f..d1fd63537 100644
--- a/monkey/infection_monkey/post_breach/actions/clear_command_history.py
+++ b/monkey/infection_monkey/post_breach/actions/clear_command_history.py
@@ -1,6 +1,6 @@
import subprocess
-from common.data.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
+from common.common_consts.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
from infection_monkey.post_breach.clear_command_history.clear_command_history import \
get_commands_to_clear_command_history
from infection_monkey.post_breach.pba import PBA
diff --git a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
index 83065d20d..bc00c9479 100644
--- a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
+++ b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
@@ -3,7 +3,7 @@ import random
import string
import subprocess
-from common.data.post_breach_consts import POST_BREACH_COMMUNICATE_AS_NEW_USER
+from common.common_consts.post_breach_consts import POST_BREACH_COMMUNICATE_AS_NEW_USER
from infection_monkey.post_breach.pba import PBA
from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
from infection_monkey.utils.auto_new_user_factory import create_auto_new_user
diff --git a/monkey/infection_monkey/post_breach/actions/discover_accounts.py b/monkey/infection_monkey/post_breach/actions/discover_accounts.py
index 8eaab9e38..18d72e642 100644
--- a/monkey/infection_monkey/post_breach/actions/discover_accounts.py
+++ b/monkey/infection_monkey/post_breach/actions/discover_accounts.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
+from common.common_consts.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
from infection_monkey.post_breach.account_discovery.account_discovery import \
get_commands_to_discover_accounts
from infection_monkey.post_breach.pba import PBA
diff --git a/monkey/infection_monkey/post_breach/actions/hide_files.py b/monkey/infection_monkey/post_breach/actions/hide_files.py
index 081a18598..3a8c7860d 100644
--- a/monkey/infection_monkey/post_breach/actions/hide_files.py
+++ b/monkey/infection_monkey/post_breach/actions/hide_files.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_HIDDEN_FILES
+from common.common_consts.post_breach_consts import POST_BREACH_HIDDEN_FILES
from infection_monkey.post_breach.pba import PBA
from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
from infection_monkey.utils.environment import is_windows_os
diff --git a/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py b/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py
index e12e0c446..b6111904d 100644
--- a/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py
+++ b/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py
@@ -1,6 +1,6 @@
import subprocess
-from common.data.post_breach_consts import \
+from common.common_consts.post_breach_consts import \
POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION
from infection_monkey.post_breach.pba import PBA
from infection_monkey.post_breach.shell_startup_files.shell_startup_files_modification import \
diff --git a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py
index d6cdd2765..f5faaa25d 100644
--- a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py
+++ b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_JOB_SCHEDULING
+from common.common_consts.post_breach_consts import POST_BREACH_JOB_SCHEDULING
from infection_monkey.post_breach.job_scheduling.job_scheduling import (
get_commands_to_schedule_jobs, remove_scheduled_jobs)
from infection_monkey.post_breach.pba import PBA
diff --git a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
index 17eb86337..ed9f665f0 100644
--- a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
+++ b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
@@ -1,7 +1,7 @@
import logging
import subprocess
-from common.data.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
+from common.common_consts.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
from infection_monkey.post_breach.pba import PBA
from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import (
cleanup_changes, get_commands_to_proxy_execution_using_signed_script)
diff --git a/monkey/infection_monkey/post_breach/actions/use_trap_command.py b/monkey/infection_monkey/post_breach/actions/use_trap_command.py
index 589baf1d9..9a29b7fa8 100644
--- a/monkey/infection_monkey/post_breach/actions/use_trap_command.py
+++ b/monkey/infection_monkey/post_breach/actions/use_trap_command.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_TRAP_COMMAND
+from common.common_consts.post_breach_consts import POST_BREACH_TRAP_COMMAND
from infection_monkey.post_breach.pba import PBA
from infection_monkey.post_breach.trap_command.trap_command import \
get_trap_commands
diff --git a/monkey/infection_monkey/post_breach/actions/users_custom_pba.py b/monkey/infection_monkey/post_breach/actions/users_custom_pba.py
index 46f09a688..175d6b215 100644
--- a/monkey/infection_monkey/post_breach/actions/users_custom_pba.py
+++ b/monkey/infection_monkey/post_breach/actions/users_custom_pba.py
@@ -1,7 +1,7 @@
import logging
import os
-from common.data.post_breach_consts import POST_BREACH_FILE_EXECUTION
+from common.common_consts.post_breach_consts import POST_BREACH_FILE_EXECUTION
from common.utils.attack_utils import ScanStatus
from infection_monkey.config import WormConfiguration
from infection_monkey.control import ControlClient
diff --git a/monkey/infection_monkey/system_info/__init__.py b/monkey/infection_monkey/system_info/__init__.py
index 05bb3a4d0..452f1bcdd 100644
--- a/monkey/infection_monkey/system_info/__init__.py
+++ b/monkey/infection_monkey/system_info/__init__.py
@@ -4,7 +4,7 @@ from enum import IntEnum
import psutil
-from common.data.system_info_collectors_names import AZURE_CRED_COLLECTOR
+from common.common_consts.system_info_collectors_names import AZURE_CRED_COLLECTOR
from infection_monkey.network.info import get_host_subnets
from infection_monkey.system_info.azure_cred_collector import AzureCollector
from infection_monkey.system_info.netstat_collector import NetstatCollector
diff --git a/monkey/infection_monkey/system_info/collectors/aws_collector.py b/monkey/infection_monkey/system_info/collectors/aws_collector.py
index bdf470735..d31dc1ba6 100644
--- a/monkey/infection_monkey/system_info/collectors/aws_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/aws_collector.py
@@ -1,7 +1,7 @@
import logging
from common.cloud.aws.aws_instance import AwsInstance
-from common.data.system_info_collectors_names import AWS_COLLECTOR
+from common.common_consts.system_info_collectors_names import AWS_COLLECTOR
from infection_monkey.system_info.system_info_collector import \
SystemInfoCollector
diff --git a/monkey/infection_monkey/system_info/collectors/environment_collector.py b/monkey/infection_monkey/system_info/collectors/environment_collector.py
index 9bcd917ee..b49fb18d8 100644
--- a/monkey/infection_monkey/system_info/collectors/environment_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/environment_collector.py
@@ -1,6 +1,6 @@
from common.cloud.all_instances import get_all_cloud_instances
from common.cloud.environment_names import Environment
-from common.data.system_info_collectors_names import ENVIRONMENT_COLLECTOR
+from common.common_consts.system_info_collectors_names import ENVIRONMENT_COLLECTOR
from infection_monkey.system_info.system_info_collector import \
SystemInfoCollector
diff --git a/monkey/infection_monkey/system_info/collectors/hostname_collector.py b/monkey/infection_monkey/system_info/collectors/hostname_collector.py
index ae9560815..7f21c214d 100644
--- a/monkey/infection_monkey/system_info/collectors/hostname_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/hostname_collector.py
@@ -1,7 +1,7 @@
import logging
import socket
-from common.data.system_info_collectors_names import HOSTNAME_COLLECTOR
+from common.common_consts.system_info_collectors_names import HOSTNAME_COLLECTOR
from infection_monkey.system_info.system_info_collector import \
SystemInfoCollector
diff --git a/monkey/infection_monkey/system_info/collectors/process_list_collector.py b/monkey/infection_monkey/system_info/collectors/process_list_collector.py
index b732a4090..c55f40d5b 100644
--- a/monkey/infection_monkey/system_info/collectors/process_list_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/process_list_collector.py
@@ -2,7 +2,7 @@ import logging
import psutil
-from common.data.system_info_collectors_names import PROCESS_LIST_COLLECTOR
+from common.common_consts.system_info_collectors_names import PROCESS_LIST_COLLECTOR
from infection_monkey.system_info.system_info_collector import \
SystemInfoCollector
diff --git a/monkey/infection_monkey/system_info/collectors/scout_suite_collector.py b/monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
deleted file mode 100644
index 09adf94e4..000000000
--- a/monkey/infection_monkey/system_info/collectors/scout_suite_collector.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import logging
-import tempfile
-
-from common.cloud.environment_names import Environment
-from common.data.system_info_collectors_names import SCOUTSUITE_COLLECTOR
-from infection_monkey.system_info.system_info_collector import SystemInfoCollector
-from infection_monkey.system_info.collectors.scoutsuite.ScoutSuite.__main__ import run
-from system_info.collectors.environment_collector import get_monkey_environment
-
-logger = logging.getLogger(__name__)
-
-
-class ScoutSuiteCollector(SystemInfoCollector):
- def __init__(self):
- super().__init__(name=SCOUTSUITE_COLLECTOR)
-
- def collect(self) -> dict:
- env = get_monkey_environment()
- env = "AWS"
- if env == Environment.ON_PREMISE.value:
- logger.info("Monkey is not on cloud; not running ScoutSuite")
- return {}
- else:
- tmp_dir_path = tempfile.mkdtemp()
- logger.info(f"Attempting to execute ScoutSuite with {env.lower()}, saving results in {tmp_dir_path}")
-
- scout_suite_results = run(
- env.lower(),
- debug=True,
- quiet=False,
- no_browser=True,
- report_dir=tmp_dir_path)
- return {
- "Environment": env,
- "Results": scout_suite_results
- }
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite b/monkey/infection_monkey/system_info/collectors/scoutsuite
deleted file mode 160000
index e784fc27a..000000000
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit e784fc27ae8311c3c610bccd556d2bef3cd54d63
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/__init__.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
new file mode 160000
index 000000000..6707e052b
--- /dev/null
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
@@ -0,0 +1 @@
+Subproject commit 6707e052b8573a4f9eaee7f77f6c5de404f3e8fd
diff --git a/monkey/infection_monkey/system_info/windows_info_collector.py b/monkey/infection_monkey/system_info/windows_info_collector.py
index d6b3cbec8..abb8a491e 100644
--- a/monkey/infection_monkey/system_info/windows_info_collector.py
+++ b/monkey/infection_monkey/system_info/windows_info_collector.py
@@ -2,7 +2,7 @@ import logging
import os
import sys
-from common.data.system_info_collectors_names import MIMIKATZ_COLLECTOR
+from common.common_consts.system_info_collectors_names import MIMIKATZ_COLLECTOR
from infection_monkey.system_info.windows_cred_collector.mimikatz_cred_collector import \
MimikatzCredentialCollector
diff --git a/monkey/infection_monkey/telemetry/exploit_telem.py b/monkey/infection_monkey/telemetry/exploit_telem.py
index bb114434f..0a33d1484 100644
--- a/monkey/infection_monkey/telemetry/exploit_telem.py
+++ b/monkey/infection_monkey/telemetry/exploit_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -15,7 +16,7 @@ class ExploitTelem(BaseTelem):
self.exploiter = exploiter
self.result = result
- telem_category = 'exploit'
+ telem_category = TelemCategoryEnum.EXPLOIT
def get_data(self):
return {
diff --git a/monkey/infection_monkey/telemetry/post_breach_telem.py b/monkey/infection_monkey/telemetry/post_breach_telem.py
index e5e443123..15aa41247 100644
--- a/monkey/infection_monkey/telemetry/post_breach_telem.py
+++ b/monkey/infection_monkey/telemetry/post_breach_telem.py
@@ -1,5 +1,6 @@
import socket
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -18,7 +19,7 @@ class PostBreachTelem(BaseTelem):
self.result = result
self.hostname, self.ip = PostBreachTelem._get_hostname_and_ip()
- telem_category = 'post_breach'
+ telem_category = TelemCategoryEnum.POST_BREACH
def get_data(self):
return {
diff --git a/monkey/infection_monkey/telemetry/scan_telem.py b/monkey/infection_monkey/telemetry/scan_telem.py
index b1c58ab1b..a4dac1396 100644
--- a/monkey/infection_monkey/telemetry/scan_telem.py
+++ b/monkey/infection_monkey/telemetry/scan_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -13,7 +14,7 @@ class ScanTelem(BaseTelem):
super(ScanTelem, self).__init__()
self.machine = machine
- telem_category = 'scan'
+ telem_category = TelemCategoryEnum.SCAN
def get_data(self):
return {
diff --git a/monkey/infection_monkey/telemetry/state_telem.py b/monkey/infection_monkey/telemetry/state_telem.py
index 4d4224288..9ecd53c20 100644
--- a/monkey/infection_monkey/telemetry/state_telem.py
+++ b/monkey/infection_monkey/telemetry/state_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -14,7 +15,7 @@ class StateTelem(BaseTelem):
self.is_done = is_done
self.version = version
- telem_category = 'state'
+ telem_category = TelemCategoryEnum.STATE
def get_data(self):
return {
diff --git a/monkey/infection_monkey/telemetry/system_info_telem.py b/monkey/infection_monkey/telemetry/system_info_telem.py
index 69ee7beda..a7ac21456 100644
--- a/monkey/infection_monkey/telemetry/system_info_telem.py
+++ b/monkey/infection_monkey/telemetry/system_info_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -13,7 +14,7 @@ class SystemInfoTelem(BaseTelem):
super(SystemInfoTelem, self).__init__()
self.system_info = system_info
- telem_category = 'system_info'
+ telem_category = TelemCategoryEnum.SYSTEM_INFO
def get_data(self):
return self.system_info
diff --git a/monkey/infection_monkey/telemetry/trace_telem.py b/monkey/infection_monkey/telemetry/trace_telem.py
index 0782affb4..dfe3f762b 100644
--- a/monkey/infection_monkey/telemetry/trace_telem.py
+++ b/monkey/infection_monkey/telemetry/trace_telem.py
@@ -1,5 +1,6 @@
import logging
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "itay.mizeretz"
@@ -18,7 +19,7 @@ class TraceTelem(BaseTelem):
self.msg = msg
LOG.debug("Trace: %s" % msg)
- telem_category = 'trace'
+ telem_category = TelemCategoryEnum.TRACE
def get_data(self):
return {
diff --git a/monkey/infection_monkey/telemetry/tunnel_telem.py b/monkey/infection_monkey/telemetry/tunnel_telem.py
index 64533a252..b4e4a07e6 100644
--- a/monkey/infection_monkey/telemetry/tunnel_telem.py
+++ b/monkey/infection_monkey/telemetry/tunnel_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.control import ControlClient
from infection_monkey.telemetry.base_telem import BaseTelem
@@ -13,7 +14,7 @@ class TunnelTelem(BaseTelem):
super(TunnelTelem, self).__init__()
self.proxy = ControlClient.proxies.get('https')
- telem_category = 'tunnel'
+ telem_category = TelemCategoryEnum.TUNNEL
def get_data(self):
return {'proxy': self.proxy}
diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py
index e8dfd2cfc..4bbf159c8 100644
--- a/monkey/monkey_island/cc/app.py
+++ b/monkey/monkey_island/cc/app.py
@@ -6,7 +6,7 @@ from flask import Flask, Response, send_from_directory
from werkzeug.exceptions import NotFound
import monkey_island.cc.environment.environment_singleton as env_singleton
-from common.data.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
+from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.database import database, mongo
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
diff --git a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py b/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
index c3817313f..c5684abc0 100644
--- a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
diff --git a/monkey/monkey_island/cc/models/zero_trust/event.py b/monkey/monkey_island/cc/models/zero_trust/event.py
index 7ff08305b..d1a0001af 100644
--- a/monkey/monkey_island/cc/models/zero_trust/event.py
+++ b/monkey/monkey_island/cc/models/zero_trust/event.py
@@ -2,7 +2,7 @@ from datetime import datetime
from mongoengine import DateTimeField, EmbeddedDocument, StringField
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
class Event(EmbeddedDocument):
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py
index d6d5c6c3f..d07cb9a45 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/finding.py
@@ -6,7 +6,7 @@ from typing import List
from mongoengine import Document, EmbeddedDocumentListField, StringField
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
# Dummy import for mongoengine.
# noinspection PyUnresolvedReferences
from monkey_island.cc.models.zero_trust.event import Event
diff --git a/monkey/monkey_island/cc/models/zero_trust/segmentation_finding.py b/monkey/monkey_island/cc/models/zero_trust/segmentation_finding.py
index 60262fbfd..903cf3546 100644
--- a/monkey/monkey_island/cc/models/zero_trust/segmentation_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/segmentation_finding.py
@@ -1,6 +1,6 @@
from mongoengine import StringField
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
diff --git a/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py b/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
index 91452dc0e..4b9765f70 100644
--- a/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
@@ -3,7 +3,7 @@ import unittest
import mongomock
from packaging import version
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.aggregate_finding import \
AggregateFinding
from monkey_island.cc.models.zero_trust.event import Event
diff --git a/monkey/monkey_island/cc/models/zero_trust/test_event.py b/monkey/monkey_island/cc/models/zero_trust/test_event.py
index 4a5afba50..4699dd829 100644
--- a/monkey/monkey_island/cc/models/zero_trust/test_event.py
+++ b/monkey/monkey_island/cc/models/zero_trust/test_event.py
@@ -1,6 +1,6 @@
from mongoengine import ValidationError
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
diff --git a/monkey/monkey_island/cc/models/zero_trust/test_finding.py b/monkey/monkey_island/cc/models/zero_trust/test_finding.py
index e221dacb1..c92d4439c 100644
--- a/monkey/monkey_island/cc/models/zero_trust/test_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/test_finding.py
@@ -1,6 +1,6 @@
from mongoengine import ValidationError
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
diff --git a/monkey/monkey_island/cc/models/zero_trust/test_segmentation_finding.py b/monkey/monkey_island/cc/models/zero_trust/test_segmentation_finding.py
index b375d97a9..13583ad40 100644
--- a/monkey/monkey_island/cc/models/zero_trust/test_segmentation_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/test_segmentation_finding.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.segmentation_finding import \
SegmentationFinding
diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py
index efdeb34b3..dd622b140 100644
--- a/monkey/monkey_island/cc/resources/telemetry.py
+++ b/monkey/monkey_island/cc/resources/telemetry.py
@@ -6,6 +6,7 @@ import dateutil
import flask_restful
from flask import request
+from common.common_consts.telem_categories import TelemCategoryEnum
from monkey_island.cc.database import mongo
from monkey_island.cc.models.monkey import Monkey
from monkey_island.cc.resources.auth.auth import jwt_required
@@ -74,7 +75,7 @@ class Telemetry(flask_restful.Resource):
monkey_label = telem_monkey_guid
x["monkey"] = monkey_label
objects.append(x)
- if x['telem_category'] == 'system_info' and 'credentials' in x['data']:
+ if x['telem_category'] == TelemCategoryEnum.SYSTEM_INFO and 'credentials' in x['data']:
for user in x['data']['credentials']:
if -1 != user.find(','):
new_user = user.replace(',', '.')
diff --git a/monkey/monkey_island/cc/resources/telemetry_feed.py b/monkey/monkey_island/cc/resources/telemetry_feed.py
index 17f263320..3da328b99 100644
--- a/monkey/monkey_island/cc/resources/telemetry_feed.py
+++ b/monkey/monkey_island/cc/resources/telemetry_feed.py
@@ -6,6 +6,7 @@ import flask_pymongo
import flask_restful
from flask import request
+from common.common_consts.telem_categories import TelemCategoryEnum
from monkey_island.cc.database import mongo
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.node import NodeService
@@ -109,11 +110,11 @@ class TelemetryFeed(flask_restful.Resource):
TELEM_PROCESS_DICT = \
{
- 'tunnel': TelemetryFeed.get_tunnel_telem_brief,
- 'state': TelemetryFeed.get_state_telem_brief,
- 'exploit': TelemetryFeed.get_exploit_telem_brief,
- 'scan': TelemetryFeed.get_scan_telem_brief,
- 'system_info': TelemetryFeed.get_systeminfo_telem_brief,
- 'trace': TelemetryFeed.get_trace_telem_brief,
- 'post_breach': TelemetryFeed.get_post_breach_telem_brief
+ TelemCategoryEnum.TUNNEL: TelemetryFeed.get_tunnel_telem_brief,
+ TelemCategoryEnum.STATE: TelemetryFeed.get_state_telem_brief,
+ TelemCategoryEnum.EXPLOIT: TelemetryFeed.get_exploit_telem_brief,
+ TelemCategoryEnum.SCAN: TelemetryFeed.get_scan_telem_brief,
+ TelemCategoryEnum.SYSTEM_INFO: TelemetryFeed.get_systeminfo_telem_brief,
+ TelemCategoryEnum.TRACE: TelemetryFeed.get_trace_telem_brief,
+ TelemCategoryEnum.POST_BREACH: TelemetryFeed.get_post_breach_telem_brief
}
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1053.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1053.py
index 511f819e3..9ca289e8f 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1053.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1053.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_JOB_SCHEDULING
+from common.common_consts.post_breach_consts import POST_BREACH_JOB_SCHEDULING
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py
index de0a6a470..2b8bd1374 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
+from common.common_consts.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1136.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1136.py
index 086a1c139..8b299fbce 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1136.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1136.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import (
+from common.common_consts.post_breach_consts import (
POST_BREACH_BACKDOOR_USER, POST_BREACH_COMMUNICATE_AS_NEW_USER)
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1146.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1146.py
index cacbe6789..b9c7863dc 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1146.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1146.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
+from common.common_consts.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1154.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1154.py
index c905fc9ca..22fd107a3 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1154.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1154.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_TRAP_COMMAND
+from common.common_consts.post_breach_consts import POST_BREACH_TRAP_COMMAND
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py
index 2841ed0ad..babbdeeb4 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import \
+from common.common_consts.post_breach_consts import \
POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1158.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1158.py
index 7b0f87358..2be8896f4 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1158.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1158.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_HIDDEN_FILES
+from common.common_consts.post_breach_consts import POST_BREACH_HIDDEN_FILES
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
index e3b74e5c5..9fe5826eb 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_SETUID_SETGID
+from common.common_consts.post_breach_consts import POST_BREACH_SETUID_SETGID
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1168.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1168.py
index 76806806c..f0db6cdd1 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1168.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1168.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_JOB_SCHEDULING
+from common.common_consts.post_breach_consts import POST_BREACH_JOB_SCHEDULING
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
index d4efbd73e..6086194ab 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
+from common.common_consts.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
index 8d8956e6b..842865456 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import \
+from common.common_consts.post_breach_consts import \
POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py
index 33467690a..5ae044d95 100644
--- a/monkey/monkey_island/cc/services/config_schema/basic_network.py
+++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py
@@ -1,4 +1,4 @@
-from common.data.validation_formats import IP, IP_RANGE
+from common.common_consts.validation_formats import IP, IP_RANGE
from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN
BASIC_NETWORK = {
diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
index 5f113f4a7..05bb2d48a 100644
--- a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
+++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
@@ -1,9 +1,9 @@
-from common.data.system_info_collectors_names import (AWS_COLLECTOR,
- AZURE_CRED_COLLECTOR,
- ENVIRONMENT_COLLECTOR,
- HOSTNAME_COLLECTOR,
- MIMIKATZ_COLLECTOR,
- PROCESS_LIST_COLLECTOR)
+from common.common_consts.system_info_collectors_names import (AWS_COLLECTOR,
+ AZURE_CRED_COLLECTOR,
+ ENVIRONMENT_COLLECTOR,
+ HOSTNAME_COLLECTOR,
+ MIMIKATZ_COLLECTOR,
+ PROCESS_LIST_COLLECTOR)
SYSTEM_INFO_COLLECTOR_CLASSES = {
"title": "System Information Collectors",
diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py
index c9fbdde74..dd2348e06 100644
--- a/monkey/monkey_island/cc/services/config_schema/monkey.py
+++ b/monkey/monkey_island/cc/services/config_schema/monkey.py
@@ -1,9 +1,9 @@
-from common.data.system_info_collectors_names import (AWS_COLLECTOR,
- AZURE_CRED_COLLECTOR,
- ENVIRONMENT_COLLECTOR,
- HOSTNAME_COLLECTOR,
- MIMIKATZ_COLLECTOR,
- PROCESS_LIST_COLLECTOR)
+from common.common_consts.system_info_collectors_names import (AWS_COLLECTOR,
+ AZURE_CRED_COLLECTOR,
+ ENVIRONMENT_COLLECTOR,
+ HOSTNAME_COLLECTOR,
+ MIMIKATZ_COLLECTOR,
+ PROCESS_LIST_COLLECTOR)
MONKEY = {
"title": "Monkey",
diff --git a/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py b/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py
index dbadffb55..874eee293 100644
--- a/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
import monkey_island.cc.services.reporting.zero_trust_service
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.services.reporting.zero_trust_service import \
diff --git a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
index 7c31fc59a..a70f4f8b4 100644
--- a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
@@ -2,7 +2,7 @@ from typing import List
from bson.objectid import ObjectId
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
# How many events of a single finding to return to UI.
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
index 367ca87d9..28909f40b 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
@@ -1,6 +1,6 @@
import copy
-from common.data.post_breach_consts import POST_BREACH_COMMUNICATE_AS_NEW_USER
+from common.common_consts.post_breach_consts import POST_BREACH_COMMUNICATE_AS_NEW_USER
from monkey_island.cc.database import mongo
from monkey_island.cc.models import Monkey
from monkey_island.cc.services.telemetry.zero_trust_tests.communicate_as_new_user import \
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
index 38767a01e..5f1b6e641 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
@@ -1,11 +1,11 @@
import logging
import typing
-from common.data.system_info_collectors_names import (AWS_COLLECTOR,
- ENVIRONMENT_COLLECTOR,
- HOSTNAME_COLLECTOR,
- PROCESS_LIST_COLLECTOR,
- SCOUTSUITE_COLLECTOR)
+from common.common_consts.system_info_collectors_names import (AWS_COLLECTOR,
+ ENVIRONMENT_COLLECTOR,
+ HOSTNAME_COLLECTOR,
+ PROCESS_LIST_COLLECTOR,
+ SCOUTSUITE_COLLECTOR)
from monkey_island.cc.services.telemetry.processing.system_info_collectors.aws import \
process_aws_telemetry
from monkey_island.cc.services.telemetry.processing.system_info_collectors.environment import \
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py
index 336567c7c..f16ae7295 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py
@@ -1,6 +1,6 @@
import json
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.aggregate_finding import \
AggregateFinding
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py
index d822206af..c6d8a9570 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.aggregate_finding import \
AggregateFinding
from monkey_island.cc.models.zero_trust.event import Event
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py
index 447b2dee8..024a91522 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py
@@ -1,7 +1,7 @@
import json
-import common.data.zero_trust_consts as zero_trust_consts
-from common.data.network_consts import ES_SERVICE
+import common.common_consts.zero_trust_consts as zero_trust_consts
+from common.common_consts.network_consts import ES_SERVICE
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.aggregate_finding import (
AggregateFinding, add_malicious_activity_to_timeline)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py
index 06d97d66d..51109130a 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.aggregate_finding import (
AggregateFinding, add_malicious_activity_to_timeline)
from monkey_island.cc.models.zero_trust.event import Event
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py
index a46dbc4a3..717f57896 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py
@@ -1,6 +1,6 @@
import itertools
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from common.network.network_range import NetworkRange
from common.network.segmentation_utils import (get_ip_if_in_subnet,
get_ip_in_src_and_not_in_dst)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py
index b2aeaf524..937cc5baf 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py
@@ -1,6 +1,6 @@
import uuid
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py
index f4d508156..341acbf5a 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py
@@ -1,4 +1,4 @@
-import common.data.zero_trust_consts as zero_trust_consts
+import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.aggregate_finding import (
AggregateFinding, add_malicious_activity_to_timeline)
From 3f725c1639d45ecde1e54c9ad239c327fac25bae Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Thu, 3 Sep 2020 12:07:04 +0300
Subject: [PATCH 009/152] Added scoutsuite_api to monkey
---
.../system_info/collectors/aws_collector.py | 3 +++
.../scoutsuite_collector/scoutsuite_api.py | 20 ++++++++++++++++
.../scoutsuite_collector.py | 23 +++++++++++++++++++
.../telemetry/scoutsuite_telem.py | 20 ++++++++++++++++
4 files changed, 66 insertions(+)
create mode 100644 monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_api.py
create mode 100644 monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
create mode 100644 monkey/infection_monkey/telemetry/scoutsuite_telem.py
diff --git a/monkey/infection_monkey/system_info/collectors/aws_collector.py b/monkey/infection_monkey/system_info/collectors/aws_collector.py
index d31dc1ba6..80fbd4f29 100644
--- a/monkey/infection_monkey/system_info/collectors/aws_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/aws_collector.py
@@ -4,6 +4,7 @@ from common.cloud.aws.aws_instance import AwsInstance
from common.common_consts.system_info_collectors_names import AWS_COLLECTOR
from infection_monkey.system_info.system_info_collector import \
SystemInfoCollector
+from infection_monkey.system_info.collectors.scoutsuite_collector.scoutsuite_collector import CLOUD_TYPES, scan_cloud_security
logger = logging.getLogger(__name__)
@@ -25,6 +26,8 @@ class AwsCollector(SystemInfoCollector):
{
'instance_id': aws.get_instance_id()
}
+ # TODO add IF ON ISLAND check
+ scan_cloud_security(cloud_type=CLOUD_TYPES.AWS)
else:
logger.info("Machine is NOT an AWS instance")
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_api.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_api.py
new file mode 100644
index 000000000..9feec3c3d
--- /dev/null
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_api.py
@@ -0,0 +1,20 @@
+import pkgutil
+import sys
+from pathlib import PurePath
+
+_scoutsuite_api_package = pkgutil.get_loader('infection_monkey.system_info.collectors.'
+ 'scoutsuite_collector.scoutsuite.ScoutSuite.__main__')
+
+
+def _add_scoutsuite_to_python_path():
+ scoutsuite_path = PurePath(_scoutsuite_api_package.path).parent.parent.__str__()
+ sys.path.append(scoutsuite_path)
+
+
+_add_scoutsuite_to_python_path()
+
+import infection_monkey.system_info.collectors.scoutsuite_collector.scoutsuite.ScoutSuite.api_run as scoutsuite_api
+
+
+def run(*args, **kwargs):
+ return scoutsuite_api.run(*args, **kwargs)
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
new file mode 100644
index 000000000..fb33cce4b
--- /dev/null
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
@@ -0,0 +1,23 @@
+import infection_monkey.system_info.collectors.scoutsuite_collector.scoutsuite_api as scoutsuite_api
+from infection_monkey.telemetry.scoutsuite_telem import ScoutSuiteTelem
+
+
+class CLOUD_TYPES:
+ AWS = 'aws'
+ AZURE = 'azure'
+ GCP = 'gcp'
+ ALIBABA = 'aliyun'
+ ORACLE = 'oci'
+
+
+def scan_cloud_security(cloud_type: CLOUD_TYPES):
+ results = run_scoutsuite(cloud_type)
+ send_results(results)
+
+
+def run_scoutsuite(cloud_type):
+ return scoutsuite_api.run(provider=cloud_type)
+
+
+def send_results(results):
+ ScoutSuiteTelem.send(results)
diff --git a/monkey/infection_monkey/telemetry/scoutsuite_telem.py b/monkey/infection_monkey/telemetry/scoutsuite_telem.py
new file mode 100644
index 000000000..d606ea3c3
--- /dev/null
+++ b/monkey/infection_monkey/telemetry/scoutsuite_telem.py
@@ -0,0 +1,20 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
+from infection_monkey.telemetry.base_telem import BaseTelem
+
+
+class ScoutSuiteTelem(BaseTelem):
+
+ def __init__(self, data):
+ """
+ Default ScoutSuite telemetry constructor
+ :param data: Data gathered via ScoutSuite (
+ """
+ super().__init__()
+ self.data = data
+
+ telem_category = TelemCategoryEnum.SCOUTSUITE
+
+ def get_data(self):
+ return {
+ 'data': self.data
+ }
From 7538f774eda75ce3e129bc9400c8723aaab0cded Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Thu, 3 Sep 2020 12:38:40 +0300
Subject: [PATCH 010/152] Migrated more hard coded telem category values to use
enum
---
monkey/common/common_consts/telem_categories.py | 1 +
.../scoutsuite_collector.py | 2 +-
.../telemetry/attack/attack_telem.py | 3 ++-
.../services/telemetry/processing/processing.py | 17 +++++++++--------
4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/monkey/common/common_consts/telem_categories.py b/monkey/common/common_consts/telem_categories.py
index c983786b9..70066d290 100644
--- a/monkey/common/common_consts/telem_categories.py
+++ b/monkey/common/common_consts/telem_categories.py
@@ -7,3 +7,4 @@ class TelemCategoryEnum:
SYSTEM_INFO = 'system_info'
TRACE = 'trace'
TUNNEL = 'tunnel'
+ ATTACK = 'attack'
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
index fb33cce4b..f7d6b7ec5 100644
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite_collector.py
@@ -20,4 +20,4 @@ def run_scoutsuite(cloud_type):
def send_results(results):
- ScoutSuiteTelem.send(results)
+ ScoutSuiteTelem(results).send(results)
diff --git a/monkey/infection_monkey/telemetry/attack/attack_telem.py b/monkey/infection_monkey/telemetry/attack/attack_telem.py
index 893f4492a..ba3fae8fd 100644
--- a/monkey/infection_monkey/telemetry/attack/attack_telem.py
+++ b/monkey/infection_monkey/telemetry/attack/attack_telem.py
@@ -1,3 +1,4 @@
+from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
__author__ = "VakarisZ"
@@ -15,7 +16,7 @@ class AttackTelem(BaseTelem):
self.technique = technique
self.status = status
- telem_category = 'attack'
+ telem_category = TelemCategoryEnum.ATTACK
def get_data(self):
return {
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/processing.py b/monkey/monkey_island/cc/services/telemetry/processing/processing.py
index 566c11dcc..960a01517 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/processing.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/processing.py
@@ -1,5 +1,6 @@
import logging
+from common.common_consts.telem_categories import TelemCategoryEnum
from monkey_island.cc.services.telemetry.processing.exploit import \
process_exploit_telemetry
from monkey_island.cc.services.telemetry.processing.post_breach import \
@@ -17,15 +18,15 @@ logger = logging.getLogger(__name__)
TELEMETRY_CATEGORY_TO_PROCESSING_FUNC = \
{
- 'tunnel': process_tunnel_telemetry,
- 'state': process_state_telemetry,
- 'exploit': process_exploit_telemetry,
- 'scan': process_scan_telemetry,
- 'system_info': process_system_info_telemetry,
- 'post_breach': process_post_breach_telemetry,
+ TelemCategoryEnum.TUNNEL: process_tunnel_telemetry,
+ TelemCategoryEnum.STATE: process_state_telemetry,
+ TelemCategoryEnum.EXPLOIT: process_exploit_telemetry,
+ TelemCategoryEnum.SCAN: process_scan_telemetry,
+ TelemCategoryEnum.SYSTEM_INFO: process_system_info_telemetry,
+ TelemCategoryEnum.POST_BREACH: process_post_breach_telemetry,
# `lambda *args, **kwargs: None` is a no-op.
- 'trace': lambda *args, **kwargs: None,
- 'attack': lambda *args, **kwargs: None,
+ TelemCategoryEnum.TRACE: lambda *args, **kwargs: None,
+ TelemCategoryEnum.ATTACK: lambda *args, **kwargs: None,
}
From 3adafd31b06be79a3fd401f06632fd964995141a Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 4 Sep 2020 15:45:48 +0300
Subject: [PATCH 011/152] Small scoutsuite improvement regarding api error
handling
---
.../system_info/collectors/scoutsuite_collector/scoutsuite | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
index 6707e052b..e5f9760a8 160000
--- a/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
+++ b/monkey/infection_monkey/system_info/collectors/scoutsuite_collector/scoutsuite
@@ -1 +1 @@
-Subproject commit 6707e052b8573a4f9eaee7f77f6c5de404f3e8fd
+Subproject commit e5f9760a822cc8856a1be3da691c511ad32ad7dd
From 549e621895ae0d92d4aba40e47b033109eb6dd88 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 4 Sep 2020 15:46:50 +0300
Subject: [PATCH 012/152] Small telemetry refactoring and added ScoutSuite
telem
---
monkey/infection_monkey/control.py | 4 +--
.../infection_monkey/telemetry/base_telem.py | 36 +++++++++++++------
.../telemetry/scoutsuite_telem.py | 3 ++
.../cc/resources/reporting/report.py | 3 +-
.../telemetry/processing/scoutsuite.py | 11 ++++++
5 files changed, 42 insertions(+), 15 deletions(-)
create mode 100644 monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py
index 912514b8c..1f3c1c25e 100644
--- a/monkey/infection_monkey/control.py
+++ b/monkey/infection_monkey/control.py
@@ -128,12 +128,12 @@ class ControlClient(object):
return {}
@staticmethod
- def send_telemetry(telem_category, data):
+ def send_telemetry(telem_category, json_data: str):
if not WormConfiguration.current_server:
LOG.error("Trying to send %s telemetry before current server is established, aborting." % telem_category)
return
try:
- telemetry = {'monkey_guid': GUID, 'telem_category': telem_category, 'data': data}
+ telemetry = {'monkey_guid': GUID, 'telem_category': telem_category, 'data': json_data}
requests.post("https://%s/api/telemetry" % (WormConfiguration.current_server,), # noqa: DUO123
data=json.dumps(telemetry),
headers={'content-type': 'application/json'},
diff --git a/monkey/infection_monkey/telemetry/base_telem.py b/monkey/infection_monkey/telemetry/base_telem.py
index 7617ab4e3..07559491c 100644
--- a/monkey/infection_monkey/telemetry/base_telem.py
+++ b/monkey/infection_monkey/telemetry/base_telem.py
@@ -5,6 +5,7 @@ import logging
from infection_monkey.control import ControlClient
logger = logging.getLogger(__name__)
+LOGGED_DATA_LENGTH = 300 # How many characters of telemetry data will be logged
__author__ = 'itay.mizeretz'
@@ -22,12 +23,25 @@ class BaseTelem(object, metaclass=abc.ABCMeta):
Sends telemetry to island
"""
data = self.get_data()
+ serialized_data = json.dumps(data, cls=self.json_encoder)
+ self.log_telem_sending(serialized_data, log_data)
+ ControlClient.send_telemetry(self.telem_category, serialized_data)
+
+ @abc.abstractmethod
+ def get_data(self) -> dict:
+ """
+ :return: Data of telemetry (should be dict)
+ """
+ pass
+
+ @property
+ def json_encoder(self):
+ return json.JSONEncoder
+
+ def log_telem_sending(self, serialized_data: str, log_data=True):
+ logger.debug(f"Sending {self.telem_category} telemetry.")
if log_data:
- data_to_log = json.dumps(data)
- else:
- data_to_log = 'redacted'
- logger.debug("Sending {} telemetry. Data: {}".format(self.telem_category, data_to_log))
- ControlClient.send_telemetry(self.telem_category, data)
+ logger.debug(f"Telemetry contents: {BaseTelem.truncate_data(serialized_data)}")
@property
@abc.abstractmethod
@@ -37,9 +51,9 @@ class BaseTelem(object, metaclass=abc.ABCMeta):
"""
pass
- @abc.abstractmethod
- def get_data(self) -> dict:
- """
- :return: Data of telemetry (should be dict)
- """
- pass
+ @staticmethod
+ def truncate_data(data: str):
+ if len(data) <= LOGGED_DATA_LENGTH:
+ return data
+ else:
+ return f"{data[:LOGGED_DATA_LENGTH]}..."
diff --git a/monkey/infection_monkey/telemetry/scoutsuite_telem.py b/monkey/infection_monkey/telemetry/scoutsuite_telem.py
index d606ea3c3..743de93e7 100644
--- a/monkey/infection_monkey/telemetry/scoutsuite_telem.py
+++ b/monkey/infection_monkey/telemetry/scoutsuite_telem.py
@@ -1,4 +1,6 @@
from common.common_consts.telem_categories import TelemCategoryEnum
+from infection_monkey.system_info.collectors.scoutsuite_collector.scoutsuite.ScoutSuite.output.result_encoder import \
+ ScoutJsonEncoder
from infection_monkey.telemetry.base_telem import BaseTelem
@@ -12,6 +14,7 @@ class ScoutSuiteTelem(BaseTelem):
super().__init__()
self.data = data
+ json_encoder = ScoutJsonEncoder
telem_category = TelemCategoryEnum.SCOUTSUITE
def get_data(self):
diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py
index a0ea8b0b9..f196fdfb6 100644
--- a/monkey/monkey_island/cc/resources/reporting/report.py
+++ b/monkey/monkey_island/cc/resources/reporting/report.py
@@ -31,8 +31,7 @@ class Report(flask_restful.Resource):
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
"grades": ZeroTrustService.get_pillars_grades()
- }
- )
+ })
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
return jsonify(ZeroTrustService.get_principles_status())
elif report_data == REPORT_DATA_FINDINGS:
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
new file mode 100644
index 000000000..ae63fe508
--- /dev/null
+++ b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
@@ -0,0 +1,11 @@
+from monkey_island.cc.database import mongo
+
+
+def process_scoutsuite_telemetry(telemetry_json):
+ update_data(telemetry_json)
+
+
+def update_data(telemetry_json):
+ mongo.db.scoutsuite.update(
+ {'guid': telemetry_json['monkey_guid']},
+ {'$push': {'results': telemetry_json['data']}})
From 9952f691981e3bdb0df867f8aecc042f1fb0aa0d Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Mon, 7 Sep 2020 13:36:18 +0300
Subject: [PATCH 013/152] Refactoring ZT findings
---
.../cc/models/zero_trust/aggregate_finding.py | 22 +++++++--
.../cc/models/zero_trust/finding.py | 17 +++----
.../cc/models/zero_trust/finding_details.py | 27 +++++++++++
.../models/zero_trust/scoutsuite_finding.py | 17 +++++++
.../cc/resources/reporting/report.py | 2 +-
.../monkey_island/cc/resources/telemetry.py | 1 +
.../services/reporting/zero_trust_service.py | 46 ++++++++++++-------
.../telemetry/processing/processing.py | 3 ++
.../telemetry/processing/scoutsuite.py | 4 ++
9 files changed, 107 insertions(+), 32 deletions(-)
create mode 100644 monkey/monkey_island/cc/models/zero_trust/finding_details.py
create mode 100644 monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
diff --git a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py b/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
index c5684abc0..af7350830 100644
--- a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
@@ -1,5 +1,9 @@
+from typing import List
+
import common.common_consts.zero_trust_consts as zero_trust_consts
+from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
+from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
class AggregateFinding(Finding):
@@ -12,15 +16,25 @@ class AggregateFinding(Finding):
:raises: Assertion error if this is used when there's more then one finding which fits the query - this is not
when this function should be used.
"""
- existing_findings = Finding.objects(test=test, status=status).exclude('events')
+ existing_findings = Finding.objects(test=test, status=status)
assert (len(existing_findings) < 2), "More than one finding exists for {}:{}".format(test, status)
if len(existing_findings) == 0:
- Finding.save_finding(test, status, events)
+ AggregateFinding.create_new_finding(test, status, events)
else:
# Now we know for sure this is the only one
- orig_finding = existing_findings[0]
- orig_finding.add_events(events)
+ AggregateFinding.add_events(existing_findings[0], events)
+
+ @staticmethod
+ def create_new_finding(test: str, status: str, events: List[Event]):
+ details = FindingDetails()
+ details.events = events
+ details.save()
+ Finding.save_finding(test, status, details)
+
+ @staticmethod
+ def add_events(finding: Finding, events: List[Event]):
+ finding.details.fetch().add_events(events)
def add_malicious_activity_to_timeline(events):
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py
index d07cb9a45..b6bbf900d 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/finding.py
@@ -4,12 +4,13 @@ Define a Document Schema for Zero Trust findings.
"""
from typing import List
-from mongoengine import Document, EmbeddedDocumentListField, StringField
+from mongoengine import Document, EmbeddedDocumentListField, StringField, LazyReferenceField
import common.common_consts.zero_trust_consts as zero_trust_consts
# Dummy import for mongoengine.
# noinspection PyUnresolvedReferences
from monkey_island.cc.models.zero_trust.event import Event
+from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
class Finding(Document):
@@ -33,7 +34,7 @@ class Finding(Document):
# SCHEMA
test = StringField(required=True, choices=zero_trust_consts.TESTS)
status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
- events = EmbeddedDocumentListField(document_type=Event)
+ details = LazyReferenceField(document_type=FindingDetails, required=True)
# http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance
meta = {'allow_inheritance': True}
@@ -46,15 +47,11 @@ class Finding(Document):
# Creation methods
@staticmethod
- def save_finding(test, status, events):
- finding = Finding(
- test=test,
- status=status,
- events=events)
+ def save_finding(test: str, status: str, detail_ref):
+ finding = Finding(test=test,
+ status=status,
+ details=detail_ref)
finding.save()
return finding
-
- def add_events(self, events: List) -> None:
- self.update(push_all__events=events)
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding_details.py b/monkey/monkey_island/cc/models/zero_trust/finding_details.py
new file mode 100644
index 000000000..260442781
--- /dev/null
+++ b/monkey/monkey_island/cc/models/zero_trust/finding_details.py
@@ -0,0 +1,27 @@
+from datetime import datetime
+from typing import List
+
+from mongoengine import DateTimeField, Document, StringField, EmbeddedDocumentListField
+
+import common.common_consts.zero_trust_consts as zero_trust_consts
+from monkey_island.cc.models.zero_trust.event import Event
+from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutsuiteFinding
+
+
+class FindingDetails(Document):
+ """
+ This model represents additional information about monkey finding:
+ Events if monkey finding
+ Scoutsuite findings if scoutsuite finding
+ """
+
+ # SCHEMA
+ events = EmbeddedDocumentListField(document_type=Event, required=False)
+ scoutsuite_findings = EmbeddedDocumentListField(document_type=ScoutsuiteFinding, required=False)
+
+ # LOGIC
+ def add_events(self, events: List[Event]) -> None:
+ self.update(push_all__events=events)
+
+ def add_scoutsuite_findings(self, scoutsuite_findings: List[ScoutsuiteFinding]) -> None:
+ self.update(push_all__scoutsuite_findings=scoutsuite_findings)
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
new file mode 100644
index 000000000..f8d0f5042
--- /dev/null
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
@@ -0,0 +1,17 @@
+from datetime import datetime
+
+from mongoengine import DateTimeField, EmbeddedDocument, StringField
+
+
+class ScoutsuiteFinding(EmbeddedDocument):
+ # SCHEMA
+ temp = StringField(required=True)
+
+ # LOGIC
+ @staticmethod
+ def create_scoutsuite_finding(title, message, event_type, timestamp=None):
+ scoutsuite_finding = ScoutsuiteFinding()
+
+ scoutsuite_finding.temp = "temp"
+
+ return scoutsuite_finding
diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py
index f196fdfb6..5c25d1ff6 100644
--- a/monkey/monkey_island/cc/resources/reporting/report.py
+++ b/monkey/monkey_island/cc/resources/reporting/report.py
@@ -35,6 +35,6 @@ class Report(flask_restful.Resource):
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
return jsonify(ZeroTrustService.get_principles_status())
elif report_data == REPORT_DATA_FINDINGS:
- return jsonify(ZeroTrustService.get_all_findings())
+ return jsonify(ZeroTrustService.get_all_monkey_findings())
flask_restful.abort(http.client.NOT_FOUND)
diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py
index dd622b140..2686f08fd 100644
--- a/monkey/monkey_island/cc/resources/telemetry.py
+++ b/monkey/monkey_island/cc/resources/telemetry.py
@@ -46,6 +46,7 @@ class Telemetry(flask_restful.Resource):
@TestTelemStore.store_test_telem
def post(self):
telemetry_json = json.loads(request.data)
+ telemetry_json['data'] = json.loads(telemetry_json['data'])
telemetry_json['timestamp'] = datetime.now()
telemetry_json['command_control_channel'] = {'src': request.remote_addr, 'dst': request.host}
diff --git a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
index a70f4f8b4..bd3f12e16 100644
--- a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
@@ -7,6 +7,8 @@ from monkey_island.cc.models.zero_trust.finding import Finding
# How many events of a single finding to return to UI.
# 50 will return 50 latest and 50 oldest events from a finding
+from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
+
EVENT_FETCH_CNT = 50
@@ -14,7 +16,7 @@ class ZeroTrustService(object):
@staticmethod
def get_pillars_grades():
pillars_grades = []
- all_findings = Finding.objects().exclude('events')
+ all_findings = Finding.objects()
for pillar in zero_trust_consts.PILLARS:
pillars_grades.append(ZeroTrustService.__get_pillar_grade(pillar, all_findings))
return pillars_grades
@@ -41,7 +43,8 @@ class ZeroTrustService(object):
if pillar in test_info[zero_trust_consts.PILLARS_KEY]:
pillar_grade[finding.status] += 1
- pillar_grade[zero_trust_consts.STATUS_UNEXECUTED] = sum(1 for condition in list(test_unexecuted.values()) if condition)
+ pillar_grade[zero_trust_consts.STATUS_UNEXECUTED] = sum(1 for condition in
+ list(test_unexecuted.values()) if condition)
return pillar_grade
@@ -70,7 +73,7 @@ class ZeroTrustService(object):
worst_status = zero_trust_consts.STATUS_UNEXECUTED
all_statuses = set()
for test in principle_tests:
- all_statuses |= set(Finding.objects(test=test).exclude('events').distinct("status"))
+ all_statuses |= set(Finding.objects(test=test).distinct('status'))
for status in all_statuses:
if zero_trust_consts.ORDERED_TEST_STATUSES.index(status) \
@@ -83,7 +86,7 @@ class ZeroTrustService(object):
def __get_tests_status(principle_tests):
results = []
for test in principle_tests:
- test_findings = Finding.objects(test=test).exclude('events')
+ test_findings = Finding.objects(test=test)
results.append(
{
"test": zero_trust_consts.TESTS_MAP[test][zero_trust_consts.TEST_EXPLANATION_KEY],
@@ -108,18 +111,30 @@ class ZeroTrustService(object):
return current_worst_status
@staticmethod
- def get_all_findings():
+ def get_all_monkey_findings():
+ findings = list(Finding.objects)
+ for finding in findings:
+ details = finding.details.fetch()
+ finding.details = details
+ enriched_findings = [ZeroTrustService.__get_enriched_finding(f) for f in findings]
+ all_finding_details = ZeroTrustService._parse_finding_details_for_ui()
+ return enriched_findings
+
+
+ @staticmethod
+ def _parse_finding_details_for_ui() -> List[FindingDetails]:
+ """
+ We don't need to return all events to UI, we only display N first and N last events.
+ This code returns a list of FindingDetails with ONLY the events which are relevant to UI.
+ """
pipeline = [{'$addFields': {'oldest_events': {'$slice': ['$events', EVENT_FETCH_CNT]},
- 'latest_events': {'$slice': ['$events', -1*EVENT_FETCH_CNT]},
+ 'latest_events': {'$slice': ['$events', -1 * EVENT_FETCH_CNT]},
'event_count': {'$size': '$events'}}},
{'$unset': ['events']}]
- all_findings = list(Finding.objects.aggregate(*pipeline))
- for finding in all_findings:
- finding['latest_events'] = ZeroTrustService._get_events_without_overlap(finding['event_count'],
- finding['latest_events'])
-
- enriched_findings = [ZeroTrustService.__get_enriched_finding(f) for f in all_findings]
- return enriched_findings
+ all_details = list(FindingDetails.objects.aggregate(*pipeline))
+ for details in all_details:
+ details['latest_events'] = ZeroTrustService._get_events_without_overlap(details['event_count'],
+ details['latest_events'])
@staticmethod
def _get_events_without_overlap(event_count: int, events: List[object]) -> List[object]:
@@ -140,9 +155,6 @@ class ZeroTrustService(object):
'test_key': finding['test'],
'pillars': test_info[zero_trust_consts.PILLARS_KEY],
'status': finding['status'],
- 'latest_events': finding['latest_events'],
- 'oldest_events': finding['oldest_events'],
- 'event_count': finding['event_count']
}
return enriched_finding
@@ -169,7 +181,7 @@ class ZeroTrustService(object):
@staticmethod
def __get_status_of_single_pillar(pillar):
- all_findings = Finding.objects().exclude('events')
+ all_findings = Finding.objects()
grade = ZeroTrustService.__get_pillar_grade(pillar, all_findings)
for status in zero_trust_consts.ORDERED_TEST_STATUSES:
if grade[status] > 0:
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/processing.py b/monkey/monkey_island/cc/services/telemetry/processing/processing.py
index 960a01517..0038273b1 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/processing.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/processing.py
@@ -13,6 +13,8 @@ from monkey_island.cc.services.telemetry.processing.system_info import \
process_system_info_telemetry
from monkey_island.cc.services.telemetry.processing.tunnel import \
process_tunnel_telemetry
+from monkey_island.cc.services.telemetry.processing.scoutsuite import \
+ process_scoutsuite_telemetry
logger = logging.getLogger(__name__)
@@ -24,6 +26,7 @@ TELEMETRY_CATEGORY_TO_PROCESSING_FUNC = \
TelemCategoryEnum.SCAN: process_scan_telemetry,
TelemCategoryEnum.SYSTEM_INFO: process_system_info_telemetry,
TelemCategoryEnum.POST_BREACH: process_post_breach_telemetry,
+ TelemCategoryEnum.SCOUTSUITE: process_scoutsuite_telemetry,
# `lambda *args, **kwargs: None` is a no-op.
TelemCategoryEnum.TRACE: lambda *args, **kwargs: None,
TelemCategoryEnum.ATTACK: lambda *args, **kwargs: None,
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
index ae63fe508..d0e25aebc 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
@@ -1,7 +1,11 @@
+import json
+
from monkey_island.cc.database import mongo
def process_scoutsuite_telemetry(telemetry_json):
+ # Encode data to json, because mongo can't save it as document (invalid document keys)
+ telemetry_json['data'] = json.dumps(telemetry_json['data'])
update_data(telemetry_json)
From 3490be1d8f499be429ad3ce2a5cdf82cbede1060 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Tue, 8 Sep 2020 12:39:55 +0300
Subject: [PATCH 014/152] Re-structured ZT files and separated class
responsibilities better, also further refactor towards ZT findings being
extendable with different types of details.
---
.../cc/models/zero_trust/aggregate_finding.py | 45 ------------
.../cc/models/zero_trust/finding.py | 7 +-
.../zero_trust/monkey_finding_details.py | 18 +++++
...tails.py => scoutsuite_finding_details.py} | 10 +--
.../zero_trust/test_aggregate_finding.py | 11 ++-
.../cc/resources/reporting/report.py | 2 +-
.../cc/resources/zero_trust/finding_event.py | 5 +-
.../__init__.py | 0
.../cc/services/zero_trust/events_service.py | 34 ++++++++++
.../cc/services/zero_trust/finding_service.py | 23 +++++++
.../zero_trust/monkey_finding_service.py | 68 +++++++++++++++++++
.../zero_trust/scoutsuite_finding_service.py | 3 +
.../test_zero_trust_service.py | 4 +-
.../zero_trust_service.py | 64 +----------------
14 files changed, 162 insertions(+), 132 deletions(-)
delete mode 100644 monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
create mode 100644 monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
rename monkey/monkey_island/cc/models/zero_trust/{finding_details.py => scoutsuite_finding_details.py} (63%)
rename monkey/monkey_island/cc/services/{telemetry/zero_trust_tests => zero_trust}/__init__.py (100%)
create mode 100644 monkey/monkey_island/cc/services/zero_trust/events_service.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/finding_service.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
rename monkey/monkey_island/cc/services/{reporting => zero_trust}/test_zero_trust_service.py (99%)
rename monkey/monkey_island/cc/services/{reporting => zero_trust}/zero_trust_service.py (64%)
diff --git a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py b/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
deleted file mode 100644
index af7350830..000000000
--- a/monkey/monkey_island/cc/models/zero_trust/aggregate_finding.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from typing import List
-
-import common.common_consts.zero_trust_consts as zero_trust_consts
-from monkey_island.cc.models.zero_trust.event import Event
-from monkey_island.cc.models.zero_trust.finding import Finding
-from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
-
-
-class AggregateFinding(Finding):
- @staticmethod
- def create_or_add_to_existing(test, status, events):
- """
- Create a new finding or add the events to an existing one if it's the same (same meaning same status and same
- test).
-
- :raises: Assertion error if this is used when there's more then one finding which fits the query - this is not
- when this function should be used.
- """
- existing_findings = Finding.objects(test=test, status=status)
- assert (len(existing_findings) < 2), "More than one finding exists for {}:{}".format(test, status)
-
- if len(existing_findings) == 0:
- AggregateFinding.create_new_finding(test, status, events)
- else:
- # Now we know for sure this is the only one
- AggregateFinding.add_events(existing_findings[0], events)
-
- @staticmethod
- def create_new_finding(test: str, status: str, events: List[Event]):
- details = FindingDetails()
- details.events = events
- details.save()
- Finding.save_finding(test, status, details)
-
- @staticmethod
- def add_events(finding: Finding, events: List[Event]):
- finding.details.fetch().add_events(events)
-
-
-def add_malicious_activity_to_timeline(events):
- AggregateFinding.create_or_add_to_existing(
- test=zero_trust_consts.TEST_MALICIOUS_ACTIVITY_TIMELINE,
- status=zero_trust_consts.STATUS_VERIFY,
- events=events
- )
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py
index b6bbf900d..8895a7fdb 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/finding.py
@@ -4,13 +4,14 @@ Define a Document Schema for Zero Trust findings.
"""
from typing import List
-from mongoengine import Document, EmbeddedDocumentListField, StringField, LazyReferenceField
+from mongoengine import Document, StringField, GenericLazyReferenceField
import common.common_consts.zero_trust_consts as zero_trust_consts
# Dummy import for mongoengine.
# noinspection PyUnresolvedReferences
from monkey_island.cc.models.zero_trust.event import Event
-from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
+from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
+from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutsuiteFindingDetails
class Finding(Document):
@@ -34,7 +35,7 @@ class Finding(Document):
# SCHEMA
test = StringField(required=True, choices=zero_trust_consts.TESTS)
status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
- details = LazyReferenceField(document_type=FindingDetails, required=True)
+ details = GenericLazyReferenceField(choices=[MonkeyFindingDetails, ScoutsuiteFindingDetails], required=True)
# http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance
meta = {'allow_inheritance': True}
diff --git a/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
new file mode 100644
index 000000000..029136679
--- /dev/null
+++ b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
@@ -0,0 +1,18 @@
+from typing import List
+
+from mongoengine import DateTimeField, Document, StringField, EmbeddedDocumentListField
+
+from monkey_island.cc.models.zero_trust.event import Event
+
+class MonkeyFindingDetails(Document):
+ """
+ This model represents additional information about monkey finding:
+ Events
+ """
+
+ # SCHEMA
+ events = EmbeddedDocumentListField(document_type=Event, required=False)
+
+ # LOGIC
+ def add_events(self, events: List[Event]) -> None:
+ self.update(push_all__events=events)
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding_details.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
similarity index 63%
rename from monkey/monkey_island/cc/models/zero_trust/finding_details.py
rename to monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
index 260442781..ed05f6003 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding_details.py
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
@@ -1,14 +1,11 @@
-from datetime import datetime
from typing import List
from mongoengine import DateTimeField, Document, StringField, EmbeddedDocumentListField
-import common.common_consts.zero_trust_consts as zero_trust_consts
-from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutsuiteFinding
-class FindingDetails(Document):
+class ScoutsuiteFindingDetails(Document):
"""
This model represents additional information about monkey finding:
Events if monkey finding
@@ -16,12 +13,7 @@ class FindingDetails(Document):
"""
# SCHEMA
- events = EmbeddedDocumentListField(document_type=Event, required=False)
scoutsuite_findings = EmbeddedDocumentListField(document_type=ScoutsuiteFinding, required=False)
- # LOGIC
- def add_events(self, events: List[Event]) -> None:
- self.update(push_all__events=events)
-
def add_scoutsuite_findings(self, scoutsuite_findings: List[ScoutsuiteFinding]) -> None:
self.update(push_all__scoutsuite_findings=scoutsuite_findings)
diff --git a/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py b/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
index 4b9765f70..5d042312f 100644
--- a/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/test_aggregate_finding.py
@@ -4,8 +4,7 @@ import mongomock
from packaging import version
import common.common_consts.zero_trust_consts as zero_trust_consts
-from monkey_island.cc.models.zero_trust.aggregate_finding import \
- AggregateFinding
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
@@ -24,12 +23,12 @@ class TestAggregateFinding(IslandTestCase):
events = [Event.create_event("t", "t", zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK)]
self.assertEqual(len(Finding.objects(test=test, status=status)), 0)
- AggregateFinding.create_or_add_to_existing(test, status, events)
+ MonkeyFindingService.create_or_add_to_existing(test, status, events)
self.assertEqual(len(Finding.objects(test=test, status=status)), 1)
self.assertEqual(len(Finding.objects(test=test, status=status)[0].events), 1)
- AggregateFinding.create_or_add_to_existing(test, status, events)
+ MonkeyFindingService.create_or_add_to_existing(test, status, events)
self.assertEqual(len(Finding.objects(test=test, status=status)), 1)
self.assertEqual(len(Finding.objects(test=test, status=status)[0].events), 2)
@@ -51,7 +50,7 @@ class TestAggregateFinding(IslandTestCase):
self.assertEqual(len(Finding.objects(test=test, status=status)), 1)
self.assertEqual(len(Finding.objects(test=test, status=status)[0].events), 1)
- AggregateFinding.create_or_add_to_existing(test, status, events)
+ MonkeyFindingService.create_or_add_to_existing(test, status, events)
self.assertEqual(len(Finding.objects(test=test, status=status)), 1)
self.assertEqual(len(Finding.objects(test=test, status=status)[0].events), 2)
@@ -61,4 +60,4 @@ class TestAggregateFinding(IslandTestCase):
self.assertEqual(len(Finding.objects(test=test, status=status)), 2)
with self.assertRaises(AssertionError):
- AggregateFinding.create_or_add_to_existing(test, status, events)
+ MonkeyFindingService.create_or_add_to_existing(test, status, events)
diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py
index 5c25d1ff6..f1b95607f 100644
--- a/monkey/monkey_island/cc/resources/reporting/report.py
+++ b/monkey/monkey_island/cc/resources/reporting/report.py
@@ -5,7 +5,7 @@ from flask import jsonify
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.reporting.report import ReportService
-from monkey_island.cc.services.reporting.zero_trust_service import \
+from monkey_island.cc.services.zero_trust.zero_trust_service import \
ZeroTrustService
ZERO_TRUST_REPORT_TYPE = "zero_trust"
diff --git a/monkey/monkey_island/cc/resources/zero_trust/finding_event.py b/monkey/monkey_island/cc/resources/zero_trust/finding_event.py
index 8a1879c9c..0e6c09b11 100644
--- a/monkey/monkey_island/cc/resources/zero_trust/finding_event.py
+++ b/monkey/monkey_island/cc/resources/zero_trust/finding_event.py
@@ -3,12 +3,11 @@ import json
import flask_restful
from monkey_island.cc.resources.auth.auth import jwt_required
-from monkey_island.cc.services.reporting.zero_trust_service import \
- ZeroTrustService
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
class ZeroTrustFindingEvent(flask_restful.Resource):
@jwt_required
def get(self, finding_id: str):
- return {'events_json': json.dumps(ZeroTrustService.get_events_by_finding(finding_id), default=str)}
+ return {'events_json': json.dumps(MonkeyFindingService.get_events_by_finding(finding_id), default=str)}
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/__init__.py b/monkey/monkey_island/cc/services/zero_trust/__init__.py
similarity index 100%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/__init__.py
rename to monkey/monkey_island/cc/services/zero_trust/__init__.py
diff --git a/monkey/monkey_island/cc/services/zero_trust/events_service.py b/monkey/monkey_island/cc/services/zero_trust/events_service.py
new file mode 100644
index 000000000..5cccee7f3
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/events_service.py
@@ -0,0 +1,34 @@
+from typing import List
+
+from bson import ObjectId
+
+from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
+
+# How many events of a single finding to return to UI.
+# 50 will return 50 latest and 50 oldest events from a finding
+EVENT_FETCH_CNT = 50
+
+
+class EventsService:
+
+ @staticmethod
+ def fetch_events_for_display(finding_id: ObjectId):
+ pipeline = [{'$match': {'_id': finding_id}},
+ {'$addFields': {'oldest_events': {'$slice': ['$events', EVENT_FETCH_CNT]},
+ 'latest_events': {'$slice': ['$events', -1 * EVENT_FETCH_CNT]},
+ 'event_count': {'$size': '$events'}}},
+ {'$unset': ['events']}]
+ details = MonkeyFindingDetails.objects.aggregate(*pipeline).next()
+ details['latest_events'] = EventsService._get_events_without_overlap(details['event_count'],
+ details['latest_events'])
+ return details
+
+ @staticmethod
+ def _get_events_without_overlap(event_count: int, events: List[object]) -> List[object]:
+ overlap_count = event_count - EVENT_FETCH_CNT
+ if overlap_count >= EVENT_FETCH_CNT:
+ return events
+ elif overlap_count <= 0:
+ return []
+ else:
+ return events[-1 * overlap_count:]
diff --git a/monkey/monkey_island/cc/services/zero_trust/finding_service.py b/monkey/monkey_island/cc/services/zero_trust/finding_service.py
new file mode 100644
index 000000000..2feb02cce
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/finding_service.py
@@ -0,0 +1,23 @@
+from typing import List
+
+from common.common_consts import zero_trust_consts
+from monkey_island.cc.models.zero_trust.finding import Finding
+
+
+class FindingService:
+
+ @staticmethod
+ def get_all_findings() -> List[Finding]:
+ return list(Finding.objects)
+
+ @staticmethod
+ def get_enriched_finding(finding):
+ test_info = zero_trust_consts.TESTS_MAP[finding['test']]
+ enriched_finding = {
+ 'finding_id': str(finding['_id']),
+ 'test': test_info[zero_trust_consts.FINDING_EXPLANATION_BY_STATUS_KEY][finding['status']],
+ 'test_key': finding['test'],
+ 'pillars': test_info[zero_trust_consts.PILLARS_KEY],
+ 'status': finding['status'],
+ }
+ return enriched_finding
diff --git a/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
new file mode 100644
index 000000000..a1e731b14
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
@@ -0,0 +1,68 @@
+from typing import List
+
+from bson import ObjectId
+
+from common.common_consts import zero_trust_consts
+from monkey_island.cc.models.zero_trust.event import Event
+from monkey_island.cc.models.zero_trust.finding import Finding
+from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
+from monkey_island.cc.services.zero_trust.finding_service import FindingService
+
+
+class MonkeyFindingService:
+
+ @staticmethod
+ def create_or_add_to_existing(test, status, events):
+ """
+ Create a new finding or add the events to an existing one if it's the same (same meaning same status and same
+ test).
+
+ :raises: Assertion error if this is used when there's more then one finding which fits the query - this is not
+ when this function should be used.
+ """
+ existing_findings = Finding.objects(test=test, status=status)
+ assert (len(existing_findings) < 2), "More than one finding exists for {}:{}".format(test, status)
+
+ if len(existing_findings) == 0:
+ MonkeyFindingService.create_new_finding(test, status, events)
+ else:
+ # Now we know for sure this is the only one
+ MonkeyFindingService.add_events(existing_findings[0], events)
+
+ @staticmethod
+ def create_new_finding(test: str, status: str, events: List[Event]):
+ details = MonkeyFindingDetails()
+ details.events = events
+ details.save()
+ Finding.save_finding(test, status, details)
+
+ @staticmethod
+ def add_events(finding: Finding, events: List[Event]):
+ finding.details.fetch().add_events(events)
+
+ @staticmethod
+ def get_all_monkey_findings():
+ findings = FindingService.get_all_findings()
+ for i in range(len(findings)):
+ details = MonkeyFindingService.fetch_events_for_display(findings[i].details.id)
+ findings[i] = findings[i].to_mongo()
+ findings[i] = FindingService.get_enriched_finding(findings[i])
+ findings[i]['details'] = details
+ return findings
+
+ @staticmethod
+ def get_events_by_finding(finding_id: str) -> List[object]:
+ finding = Finding.objects.get(id=finding_id)
+ pipeline = [{'$match': {'_id': ObjectId(finding.details.id)}},
+ {'$unwind': '$events'},
+ {'$project': {'events': '$events'}},
+ {'$replaceRoot': {'newRoot': '$events'}}]
+ return list(MonkeyFindingDetails.objects.aggregate(*pipeline))
+
+ @staticmethod
+ def add_malicious_activity_to_timeline(events):
+ MonkeyFindingService.create_or_add_to_existing(
+ test=zero_trust_consts.TEST_MALICIOUS_ACTIVITY_TIMELINE,
+ status=zero_trust_consts.STATUS_VERIFY,
+ events=events
+ )
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
new file mode 100644
index 000000000..12ab2743b
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
@@ -0,0 +1,3 @@
+
+class ScoutsuiteFindingService:
+ pass
diff --git a/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py b/monkey/monkey_island/cc/services/zero_trust/test_zero_trust_service.py
similarity index 99%
rename from monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py
rename to monkey/monkey_island/cc/services/zero_trust/test_zero_trust_service.py
index 874eee293..8b3d33ba2 100644
--- a/monkey/monkey_island/cc/services/reporting/test_zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/test_zero_trust_service.py
@@ -1,7 +1,7 @@
import common.common_consts.zero_trust_consts as zero_trust_consts
-import monkey_island.cc.services.reporting.zero_trust_service
+import monkey_island.cc.services.zero_trust.zero_trust_service
from monkey_island.cc.models.zero_trust.finding import Finding
-from monkey_island.cc.services.reporting.zero_trust_service import \
+from monkey_island.cc.services.zero_trust.zero_trust_service import \
ZeroTrustService
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
diff --git a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py b/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
similarity index 64%
rename from monkey/monkey_island/cc/services/reporting/zero_trust_service.py
rename to monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
index bd3f12e16..613132a54 100644
--- a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
@@ -5,14 +5,8 @@ from bson.objectid import ObjectId
import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
-# How many events of a single finding to return to UI.
-# 50 will return 50 latest and 50 oldest events from a finding
-from monkey_island.cc.models.zero_trust.finding_details import FindingDetails
-EVENT_FETCH_CNT = 50
-
-
-class ZeroTrustService(object):
+class ZeroTrustService:
@staticmethod
def get_pillars_grades():
pillars_grades = []
@@ -110,54 +104,6 @@ class ZeroTrustService(object):
return current_worst_status
- @staticmethod
- def get_all_monkey_findings():
- findings = list(Finding.objects)
- for finding in findings:
- details = finding.details.fetch()
- finding.details = details
- enriched_findings = [ZeroTrustService.__get_enriched_finding(f) for f in findings]
- all_finding_details = ZeroTrustService._parse_finding_details_for_ui()
- return enriched_findings
-
-
- @staticmethod
- def _parse_finding_details_for_ui() -> List[FindingDetails]:
- """
- We don't need to return all events to UI, we only display N first and N last events.
- This code returns a list of FindingDetails with ONLY the events which are relevant to UI.
- """
- pipeline = [{'$addFields': {'oldest_events': {'$slice': ['$events', EVENT_FETCH_CNT]},
- 'latest_events': {'$slice': ['$events', -1 * EVENT_FETCH_CNT]},
- 'event_count': {'$size': '$events'}}},
- {'$unset': ['events']}]
- all_details = list(FindingDetails.objects.aggregate(*pipeline))
- for details in all_details:
- details['latest_events'] = ZeroTrustService._get_events_without_overlap(details['event_count'],
- details['latest_events'])
-
- @staticmethod
- def _get_events_without_overlap(event_count: int, events: List[object]) -> List[object]:
- overlap_count = event_count - EVENT_FETCH_CNT
- if overlap_count >= EVENT_FETCH_CNT:
- return events
- elif overlap_count <= 0:
- return []
- else:
- return events[-1 * overlap_count:]
-
- @staticmethod
- def __get_enriched_finding(finding):
- test_info = zero_trust_consts.TESTS_MAP[finding['test']]
- enriched_finding = {
- 'finding_id': str(finding['_id']),
- 'test': test_info[zero_trust_consts.FINDING_EXPLANATION_BY_STATUS_KEY][finding['status']],
- 'test_key': finding['test'],
- 'pillars': test_info[zero_trust_consts.PILLARS_KEY],
- 'status': finding['status'],
- }
- return enriched_finding
-
@staticmethod
def get_statuses_to_pillars():
results = {
@@ -187,11 +133,3 @@ class ZeroTrustService(object):
if grade[status] > 0:
return status
return zero_trust_consts.STATUS_UNEXECUTED
-
- @staticmethod
- def get_events_by_finding(finding_id: str) -> List[object]:
- pipeline = [{'$match': {'_id': ObjectId(finding_id)}},
- {'$unwind': '$events'},
- {'$project': {'events': '$events'}},
- {'$replaceRoot': {'newRoot': '$events'}}]
- return list(Finding.objects.aggregate(*pipeline))
From 4e1e9907b198f18a0eb92bb3154253877d8c2918 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Tue, 8 Sep 2020 12:41:59 +0300
Subject: [PATCH 015/152] Renamed all zero trust tests to zero trust checks in
back-end. This increases readability, because it differentiates unit test
code from production code
---
.../cc/services/telemetry/processing/exploit.py | 6 +++---
.../cc/services/telemetry/processing/post_breach.py | 6 +++---
.../cc/services/telemetry/processing/scan.py | 12 ++++++------
.../cc/services/telemetry/processing/state.py | 6 +++---
.../system_info_telemetry_dispatcher.py | 6 +++---
.../cc/services/telemetry/processing/tunnel.py | 6 +++---
.../services/telemetry/zero_trust_checks/__init__.py | 0
.../antivirus_existence.py | 9 ++++-----
.../communicate_as_new_user.py | 7 +++----
.../data_endpoints.py | 11 +++++------
.../known_anti_viruses.py | 0
.../machine_exploited.py | 9 ++++-----
.../segmentation.py | 4 ++--
.../test_segmentation.py} | 4 ++--
.../tunneling.py | 9 ++++-----
15 files changed, 45 insertions(+), 50 deletions(-)
create mode 100644 monkey/monkey_island/cc/services/telemetry/zero_trust_checks/__init__.py
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/antivirus_existence.py (85%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/communicate_as_new_user.py (87%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/data_endpoints.py (89%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/known_anti_viruses.py (100%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/machine_exploited.py (78%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/segmentation.py (97%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests/test_segmentation_zt_tests.py => zero_trust_checks/test_segmentation.py} (94%)
rename monkey/monkey_island/cc/services/telemetry/{zero_trust_tests => zero_trust_checks}/tunneling.py (78%)
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/exploit.py b/monkey/monkey_island/cc/services/telemetry/processing/exploit.py
index 69c1e20f6..e88c37dfa 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/exploit.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/exploit.py
@@ -9,8 +9,8 @@ from monkey_island.cc.services.edge.displayed_edge import EdgeService
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.telemetry.processing.utils import \
get_edge_by_scan_or_exploit_telemetry
-from monkey_island.cc.services.telemetry.zero_trust_tests.machine_exploited import \
- test_machine_exploited
+from monkey_island.cc.services.telemetry.zero_trust_checks.machine_exploited import \
+ check_machine_exploited
def process_exploit_telemetry(telemetry_json):
@@ -19,7 +19,7 @@ def process_exploit_telemetry(telemetry_json):
update_network_with_exploit(edge, telemetry_json)
update_node_credentials_from_successful_attempts(edge, telemetry_json)
- test_machine_exploited(
+ check_machine_exploited(
current_monkey=Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid']),
exploit_successful=telemetry_json['data']['result'],
exploiter=telemetry_json['data']['exploiter'],
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
index 28909f40b..dd79fd7c9 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py
@@ -3,8 +3,8 @@ import copy
from common.common_consts.post_breach_consts import POST_BREACH_COMMUNICATE_AS_NEW_USER
from monkey_island.cc.database import mongo
from monkey_island.cc.models import Monkey
-from monkey_island.cc.services.telemetry.zero_trust_tests.communicate_as_new_user import \
- test_new_user_communication
+from monkey_island.cc.services.telemetry.zero_trust_checks.communicate_as_new_user import \
+ check_new_user_communication
EXECUTION_WITHOUT_OUTPUT = "(PBA execution produced no output)"
@@ -13,7 +13,7 @@ def process_communicate_as_new_user_telemetry(telemetry_json):
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
message = telemetry_json['data']['result'][0]
success = telemetry_json['data']['result'][1]
- test_new_user_communication(current_monkey, success, message)
+ check_new_user_communication(current_monkey, success, message)
POST_BREACH_TELEMETRY_PROCESSING_FUNCS = {
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/scan.py b/monkey/monkey_island/cc/services/telemetry/processing/scan.py
index 43446126c..2453223fe 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/scan.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/scan.py
@@ -4,19 +4,19 @@ from monkey_island.cc.services.edge.edge import EdgeService
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.telemetry.processing.utils import \
get_edge_by_scan_or_exploit_telemetry
-from monkey_island.cc.services.telemetry.zero_trust_tests.data_endpoints import \
- test_open_data_endpoints
-from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
- test_segmentation_violation
+from monkey_island.cc.services.telemetry.zero_trust_checks.data_endpoints import \
+ check_open_data_endpoints
+from monkey_island.cc.services.telemetry.zero_trust_checks.segmentation import \
+ check_segmentation_violation
def process_scan_telemetry(telemetry_json):
update_edges_and_nodes_based_on_scan_telemetry(telemetry_json)
- test_open_data_endpoints(telemetry_json)
+ check_open_data_endpoints(telemetry_json)
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
target_ip = telemetry_json['data']['machine']['ip_addr']
- test_segmentation_violation(current_monkey, target_ip)
+ check_segmentation_violation(current_monkey, target_ip)
def update_edges_and_nodes_based_on_scan_telemetry(telemetry_json):
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/state.py b/monkey/monkey_island/cc/services/telemetry/processing/state.py
index 3ac555f3e..4f596fb88 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/state.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/state.py
@@ -2,8 +2,8 @@ import logging
from monkey_island.cc.models import Monkey
from monkey_island.cc.services.node import NodeService
-from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
- test_passed_findings_for_unreached_segments
+from monkey_island.cc.services.telemetry.zero_trust_checks.segmentation import \
+ check_passed_findings_for_unreached_segments
logger = logging.getLogger(__name__)
@@ -18,7 +18,7 @@ def process_state_telemetry(telemetry_json):
if telemetry_json['data']['done']:
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
- test_passed_findings_for_unreached_segments(current_monkey)
+ check_passed_findings_for_unreached_segments(current_monkey)
if telemetry_json['data']['version']:
logger.info(f"monkey {telemetry_json['monkey_guid']} has version {telemetry_json['data']['version']}")
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
index 5f1b6e641..d718df12a 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
@@ -14,8 +14,8 @@ from monkey_island.cc.services.telemetry.processing.system_info_collectors.hostn
process_hostname_telemetry
from monkey_island.cc.services.telemetry.processing.system_info_collectors.scoutsuite import \
process_scout_suite_telemetry
-from monkey_island.cc.services.telemetry.zero_trust_tests.antivirus_existence import \
- test_antivirus_existence
+from monkey_island.cc.services.telemetry.zero_trust_checks.antivirus_existence import \
+ check_antivirus_existence
logger = logging.getLogger(__name__)
@@ -23,7 +23,7 @@ SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = {
AWS_COLLECTOR: [process_aws_telemetry],
ENVIRONMENT_COLLECTOR: [process_environment_telemetry],
HOSTNAME_COLLECTOR: [process_hostname_telemetry],
- PROCESS_LIST_COLLECTOR: [test_antivirus_existence],
+ PROCESS_LIST_COLLECTOR: [check_antivirus_existence],
SCOUTSUITE_COLLECTOR: [process_scout_suite_telemetry]
}
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/tunnel.py b/monkey/monkey_island/cc/services/telemetry/processing/tunnel.py
index ef5ea0ff9..0800e0168 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/tunnel.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/tunnel.py
@@ -1,12 +1,12 @@
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.telemetry.processing.utils import \
get_tunnel_host_ip_from_proxy_field
-from monkey_island.cc.services.telemetry.zero_trust_tests.tunneling import \
- test_tunneling_violation
+from monkey_island.cc.services.telemetry.zero_trust_checks.tunneling import \
+ check_tunneling_violation
def process_tunnel_telemetry(telemetry_json):
- test_tunneling_violation(telemetry_json)
+ check_tunneling_violation(telemetry_json)
monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])["_id"]
if telemetry_json['data']['proxy'] is not None:
tunnel_host_ip = get_tunnel_host_ip_from_proxy_field(telemetry_json)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/__init__.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py
similarity index 85%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py
index f16ae7295..3ed2133f0 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/antivirus_existence.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py
@@ -2,14 +2,13 @@ import json
import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models import Monkey
-from monkey_island.cc.models.zero_trust.aggregate_finding import \
- AggregateFinding
from monkey_island.cc.models.zero_trust.event import Event
-from monkey_island.cc.services.telemetry.zero_trust_tests.known_anti_viruses import \
+from monkey_island.cc.services.telemetry.zero_trust_checks.known_anti_viruses import \
ANTI_VIRUS_KNOWN_PROCESS_NAMES
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
-def test_antivirus_existence(process_list_json, monkey_guid):
+def check_antivirus_existence(process_list_json, monkey_guid):
current_monkey = Monkey.get_single_monkey_by_guid(monkey_guid)
process_list_event = Event.create_event(
@@ -32,7 +31,7 @@ def test_antivirus_existence(process_list_json, monkey_guid):
test_status = zero_trust_consts.STATUS_PASSED
else:
test_status = zero_trust_consts.STATUS_FAILED
- AggregateFinding.create_or_add_to_existing(
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_ENDPOINT_SECURITY_EXISTS, status=test_status, events=events
)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
similarity index 87%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
index c6d8a9570..109efbca0 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/communicate_as_new_user.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
@@ -1,6 +1,5 @@
import common.common_consts.zero_trust_consts as zero_trust_consts
-from monkey_island.cc.models.zero_trust.aggregate_finding import \
- AggregateFinding
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
from monkey_island.cc.models.zero_trust.event import Event
COMM_AS_NEW_USER_FAILED_FORMAT = "Monkey on {} couldn't communicate as new user. Details: {}"
@@ -8,8 +7,8 @@ COMM_AS_NEW_USER_SUCCEEDED_FORMAT = \
"New user created by Monkey on {} successfully tried to communicate with the internet. Details: {}"
-def test_new_user_communication(current_monkey, success, message):
- AggregateFinding.create_or_add_to_existing(
+def check_new_user_communication(current_monkey, success, message):
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_COMMUNICATE_AS_NEW_USER,
# If the monkey succeeded to create a user, then the test failed.
status=zero_trust_consts.STATUS_FAILED if success else zero_trust_consts.STATUS_PASSED,
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
similarity index 89%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
index 024a91522..d4da2d8dd 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/data_endpoints.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
@@ -3,14 +3,13 @@ import json
import common.common_consts.zero_trust_consts as zero_trust_consts
from common.common_consts.network_consts import ES_SERVICE
from monkey_island.cc.models import Monkey
-from monkey_island.cc.models.zero_trust.aggregate_finding import (
- AggregateFinding, add_malicious_activity_to_timeline)
from monkey_island.cc.models.zero_trust.event import Event
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
HTTP_SERVERS_SERVICES_NAMES = ['tcp-80']
-def test_open_data_endpoints(telemetry_json):
+def check_open_data_endpoints(telemetry_json):
services = telemetry_json["data"]["machine"]["services"]
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
found_http_server_status = zero_trust_consts.STATUS_PASSED
@@ -56,16 +55,16 @@ def test_open_data_endpoints(telemetry_json):
event_type=zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK
))
- AggregateFinding.create_or_add_to_existing(
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_DATA_ENDPOINT_HTTP,
status=found_http_server_status,
events=events
)
- AggregateFinding.create_or_add_to_existing(
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_DATA_ENDPOINT_ELASTIC,
status=found_elastic_search_server,
events=events
)
- add_malicious_activity_to_timeline(events)
+ MonkeyFindingService.add_malicious_activity_to_timeline(events)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/known_anti_viruses.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/known_anti_viruses.py
similarity index 100%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/known_anti_viruses.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/known_anti_viruses.py
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/machine_exploited.py
similarity index 78%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/machine_exploited.py
index 51109130a..941bc4643 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/machine_exploited.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/machine_exploited.py
@@ -1,10 +1,9 @@
import common.common_consts.zero_trust_consts as zero_trust_consts
-from monkey_island.cc.models.zero_trust.aggregate_finding import (
- AggregateFinding, add_malicious_activity_to_timeline)
from monkey_island.cc.models.zero_trust.event import Event
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
-def test_machine_exploited(current_monkey, exploit_successful, exploiter, target_ip, timestamp):
+def check_machine_exploited(current_monkey, exploit_successful, exploiter, target_ip, timestamp):
events = [
Event.create_event(
title="Exploit attempt",
@@ -30,10 +29,10 @@ def test_machine_exploited(current_monkey, exploit_successful, exploiter, target
)
status = zero_trust_consts.STATUS_FAILED
- AggregateFinding.create_or_add_to_existing(
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_MACHINE_EXPLOITED,
status=status,
events=events
)
- add_malicious_activity_to_timeline(events)
+ MonkeyFindingService.add_malicious_activity_to_timeline(events)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
similarity index 97%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
index 717f57896..2e40c0698 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/segmentation.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
@@ -19,7 +19,7 @@ SEGMENTATION_VIOLATION_EVENT_TEXT = \
"managed to communicate cross segment to {target_ip} (in segment {target_seg})."
-def test_segmentation_violation(current_monkey, target_ip):
+def check_segmentation_violation(current_monkey, target_ip):
# TODO - lower code duplication between this and report.py.
subnet_groups = get_config_network_segments_as_subnet_groups()
for subnet_group in subnet_groups:
@@ -73,7 +73,7 @@ def get_segmentation_violation_event(current_monkey, source_subnet, target_ip, t
)
-def test_passed_findings_for_unreached_segments(current_monkey):
+def check_passed_findings_for_unreached_segments(current_monkey):
flat_all_subnets = [item for sublist in get_config_network_segments_as_subnet_groups() for item in sublist]
create_or_add_findings_for_all_pairs(flat_all_subnets, current_monkey)
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/test_segmentation.py
similarity index 94%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/test_segmentation.py
index 937cc5baf..9139d05f6 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/test_segmentation_zt_tests.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/test_segmentation.py
@@ -6,7 +6,7 @@ from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.models.zero_trust.segmentation_finding import \
SegmentationFinding
-from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
+from monkey_island.cc.services.telemetry.zero_trust_checks.segmentation import \
create_or_add_findings_for_all_pairs
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
@@ -15,7 +15,7 @@ SECOND_SUBNET = "2.2.2.0/24"
THIRD_SUBNET = "3.3.3.3-3.3.3.200"
-class TestSegmentationTests(IslandTestCase):
+class TestSegmentationChecks(IslandTestCase):
def test_create_findings_for_all_done_pairs(self):
self.fail_if_not_testing_env()
self.clean_finding_db()
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/tunneling.py
similarity index 78%
rename from monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py
rename to monkey/monkey_island/cc/services/telemetry/zero_trust_checks/tunneling.py
index 341acbf5a..dd46ec1eb 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_tests/tunneling.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/tunneling.py
@@ -1,13 +1,12 @@
import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models import Monkey
-from monkey_island.cc.models.zero_trust.aggregate_finding import (
- AggregateFinding, add_malicious_activity_to_timeline)
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.services.telemetry.processing.utils import \
get_tunnel_host_ip_from_proxy_field
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
-def test_tunneling_violation(tunnel_telemetry_json):
+def check_tunneling_violation(tunnel_telemetry_json):
if tunnel_telemetry_json['data']['proxy'] is not None:
# Monkey is tunneling, create findings
tunnel_host_ip = get_tunnel_host_ip_from_proxy_field(tunnel_telemetry_json)
@@ -20,10 +19,10 @@ def test_tunneling_violation(tunnel_telemetry_json):
timestamp=tunnel_telemetry_json['timestamp']
)]
- AggregateFinding.create_or_add_to_existing(
+ MonkeyFindingService.create_or_add_to_existing(
test=zero_trust_consts.TEST_TUNNELING,
status=zero_trust_consts.STATUS_FAILED,
events=tunneling_events
)
- add_malicious_activity_to_timeline(tunneling_events)
+ MonkeyFindingService.add_malicious_activity_to_timeline(tunneling_events)
From d9ba4dd3a42cffb520100f0ab8ad826a06b83151 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Tue, 8 Sep 2020 14:08:36 +0300
Subject: [PATCH 016/152] Small modifications: bug in ZT report resource and
unused imports removed
---
monkey/monkey_island/cc/resources/reporting/report.py | 3 ++-
.../cc/services/zero_trust/zero_trust_service.py | 4 ----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py
index f1b95607f..546f944a3 100644
--- a/monkey/monkey_island/cc/resources/reporting/report.py
+++ b/monkey/monkey_island/cc/resources/reporting/report.py
@@ -5,6 +5,7 @@ from flask import jsonify
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.reporting.report import ReportService
+from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
from monkey_island.cc.services.zero_trust.zero_trust_service import \
ZeroTrustService
@@ -35,6 +36,6 @@ class Report(flask_restful.Resource):
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
return jsonify(ZeroTrustService.get_principles_status())
elif report_data == REPORT_DATA_FINDINGS:
- return jsonify(ZeroTrustService.get_all_monkey_findings())
+ return jsonify(MonkeyFindingService.get_all_monkey_findings())
flask_restful.abort(http.client.NOT_FOUND)
diff --git a/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py b/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
index 613132a54..75af0da0a 100644
--- a/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/zero_trust_service.py
@@ -1,7 +1,3 @@
-from typing import List
-
-from bson.objectid import ObjectId
-
import common.common_consts.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
From 96f3052dc2e85334bc21d9dac920e9e738066c28 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 11 Sep 2020 16:12:18 +0300
Subject: [PATCH 017/152] Bugfix: imports, related to "common_consts renaming"
fixed.
---
monkey/infection_monkey/post_breach/actions/timestomping.py | 2 +-
.../monkey_island/cc/services/attack/technique_reports/T1099.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/monkey/infection_monkey/post_breach/actions/timestomping.py b/monkey/infection_monkey/post_breach/actions/timestomping.py
index 50a940524..b1de27245 100644
--- a/monkey/infection_monkey/post_breach/actions/timestomping.py
+++ b/monkey/infection_monkey/post_breach/actions/timestomping.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_TIMESTOMPING
+from common.common_consts.post_breach_consts import POST_BREACH_TIMESTOMPING
from infection_monkey.post_breach.pba import PBA
from infection_monkey.post_breach.timestomping.timestomping import \
get_timestomping_commands
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py
index 9cd4dc903..9e96a5b2a 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1099.py
@@ -1,4 +1,4 @@
-from common.data.post_breach_consts import POST_BREACH_TIMESTOMPING
+from common.common_consts.post_breach_consts import POST_BREACH_TIMESTOMPING
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
PostBreachTechnique
From 5a6a68fde057d24f64864616872770a1d6490867 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 18 Sep 2020 09:28:31 +0300
Subject: [PATCH 018/152] Changed default flask json encoder so we could encode
objects with custom fields, like field of type ObjectId
---
monkey/monkey_island/cc/app.py | 3 +++
monkey/monkey_island/cc/custom_json_encoder.py | 13 +++++++++++++
2 files changed, 16 insertions(+)
create mode 100644 monkey/monkey_island/cc/custom_json_encoder.py
diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py
index 4bbf159c8..8ed7189f3 100644
--- a/monkey/monkey_island/cc/app.py
+++ b/monkey/monkey_island/cc/app.py
@@ -8,6 +8,7 @@ from werkzeug.exceptions import NotFound
import monkey_island.cc.environment.environment_singleton as env_singleton
from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
+from monkey_island.cc.custom_json_encoder import CustomJSONEncoder
from monkey_island.cc.database import database, mongo
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
from monkey_island.cc.resources.attack.attack_report import AttackReport
@@ -85,6 +86,8 @@ def init_app_config(app, mongo_url):
# configuration. See https://flask.palletsprojects.com/en/1.1.x/config/#JSON_SORT_KEYS.
app.config['JSON_SORT_KEYS'] = False
+ app.json_encoder = CustomJSONEncoder
+
def init_app_services(app):
init_jwt(app)
diff --git a/monkey/monkey_island/cc/custom_json_encoder.py b/monkey/monkey_island/cc/custom_json_encoder.py
new file mode 100644
index 000000000..8c945a224
--- /dev/null
+++ b/monkey/monkey_island/cc/custom_json_encoder.py
@@ -0,0 +1,13 @@
+from bson import ObjectId
+from flask.json import JSONEncoder
+
+
+class CustomJSONEncoder(JSONEncoder):
+
+ def default(self, obj):
+ try:
+ if isinstance(obj, ObjectId):
+ return obj.__str__()
+ except TypeError:
+ pass
+ return JSONEncoder.default(self, obj)
From 0b9b89f63968feadd025e17d8b967b733f47bca1 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 18 Sep 2020 10:01:14 +0300
Subject: [PATCH 019/152] Added rule path creators, which helps to extract
scoutsuite rules from scoutsuite report data
---
monkey/common/utils/exceptions.py | 4 +++
.../zero_trust/scoutsuite/consts/ec2_rules.py | 22 +++++++++++++++
.../scoutsuite/data_parsing/rule_parsing.py | 28 +++++++++++++++++++
.../abstract_rule_path_creator.py | 23 +++++++++++++++
.../ec2_rule_path_creator.py | 11 ++++++++
.../rule_path_creators_list.py | 4 +++
6 files changed, 92 insertions(+)
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/ec2_rules.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parsing.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/abstract_rule_path_creator.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/ec2_rule_path_creator.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
diff --git a/monkey/common/utils/exceptions.py b/monkey/common/utils/exceptions.py
index fa026933c..5103b297e 100644
--- a/monkey/common/utils/exceptions.py
+++ b/monkey/common/utils/exceptions.py
@@ -20,3 +20,7 @@ class CredentialsNotRequiredError(RegistrationNotNeededError):
class AlreadyRegisteredError(RegistrationNotNeededError):
""" Raise to indicate the reason why registration is not required """
+
+
+class RulePathCreatorNotFound(Exception):
+ """ Raise to indicate that ScoutSuite rule doesn't have a path creator"""
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/ec2_rules.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/ec2_rules.py
new file mode 100644
index 000000000..421dbca41
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/ec2_rules.py
@@ -0,0 +1,22 @@
+from enum import Enum
+
+
+class EC2Rules(Enum):
+ SECURITY_GROUP_ALL_PORTS_TO_ALL = 'ec2-security-group-opens-all-ports-to-all'
+ SECURITY_GROUP_OPENS_TCP_PORT_TO_ALL = 'ec2-security-group-opens-TCP-port-to-all'
+ SECURITY_GROUP_OPENS_UDP_PORT_TO_ALL = 'ec2-security-group-opens-UDP-port-to-all'
+ SECURITY_GROUP_OPENS_RDP_PORT_TO_ALL = 'ec2-security-group-opens-RDP-port-to-all'
+ SECURITY_GROUP_OPENS_SSH_PORT_TO_ALL = 'ec2-security-group-opens-SSH-port-to-all'
+ SECURITY_GROUP_OPENS_MYSQL_PORT_TO_ALL = 'ec2-security-group-opens-MySQL-port-to-all'
+ SECURITY_GROUP_OPENS_MSSQL_PORT_TO_ALL = 'ec2-security-group-opens-MsSQL-port-to-all'
+ SECURITY_GROUP_OPENS_MONGODB_PORT_TO_ALL = 'ec2-security-group-opens-MongoDB-port-to-all'
+ SECURITY_GROUP_OPENS_ORACLE_DB_PORT_TO_ALL = 'ec2-security-group-opens-Oracle DB-port-to-all'
+ SECURITY_GROUP_OPENS_POSTGRESQL_PORT_TO_ALL = 'ec2-security-group-opens-PostgreSQL-port-to-all'
+ SECURITY_GROUP_OPENS_NFS_PORT_TO_ALL = 'ec2-security-group-opens-NFS-port-to-all'
+ SECURITY_GROUP_OPENS_SMTP_PORT_TO_ALL = 'ec2-security-group-opens-SMTP-port-to-all'
+ SECURITY_GROUP_OPENS_DNS_PORT_TO_ALL = 'ec2-security-group-opens-DNS-port-to-all'
+ SECURITY_GROUP_OPENS_ALL_PORTS_TO_SELF = 'ec2-security-group-opens-all-ports-to-self'
+ SECURITY_GROUP_OPENS_ALL_PORTS = 'ec2-security-group-opens-all-ports'
+ SECURITY_GROUP_OPENS_PLAINTEXT_PORT_FTP = 'ec2-security-group-opens-plaintext-port-FTP'
+ SECURITY_GROUP_OPENS_PLAINTEXT_PORT_TELNET = 'ec2-security-group-opens-plaintext-port-Telnet'
+ SECURITY_GROUP_OPENS_PORT_RANGE = 'ec2-security-group-opens-port-range'
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parsing.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parsing.py
new file mode 100644
index 000000000..3a9f9b58b
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parsing.py
@@ -0,0 +1,28 @@
+from typing import Union
+
+from common.utils.code_utils import get_object_value_by_path
+from common.utils.exceptions import RulePathCreatorNotFound
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.ec2_rules import EC2Rules
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators_list import \
+ RULE_PATH_CREATORS_LIST
+
+
+class RuleParser:
+
+ @staticmethod
+ def get_rule_data(scoutsuite_data, rule_name: Union[EC2Rules]):
+ rule_path = RuleParser.get_rule_path(rule_name)
+ return get_object_value_by_path(scoutsuite_data, rule_path)
+
+ @staticmethod
+ def get_rule_path(rule_name: Union[EC2Rules]):
+ creator = RuleParser.get_rule_path_creator(rule_name)
+ return creator.build_rule_path(rule_name)
+
+ @staticmethod
+ def get_rule_path_creator(rule_name: Union[EC2Rules]):
+ for rule_path_creator in RULE_PATH_CREATORS_LIST:
+ if rule_name in rule_path_creator.supported_rules:
+ return rule_path_creator
+ raise RulePathCreatorNotFound(f"Rule path creator not found for rule {rule_name.value}. Make sure to assign"
+ f"this rule to any rule path creators.")
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/abstract_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/abstract_rule_path_creator.py
new file mode 100644
index 000000000..f7113fc50
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/abstract_rule_path_creator.py
@@ -0,0 +1,23 @@
+from abc import ABC, abstractmethod
+from typing import List, Union
+
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.ec2_rules import EC2Rules
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICES, FINDINGS, SERVICE_TYPES
+
+
+class AbstractRulePathCreator(ABC):
+
+ @property
+ @abstractmethod
+ def service_type(self) -> SERVICE_TYPES:
+ pass
+
+ @property
+ @abstractmethod
+ def supported_rules(self) -> List[Union[EC2Rules]]:
+ pass
+
+ @classmethod
+ def build_rule_path(cls, rule_name: Union[EC2Rules]) -> List[str]:
+ assert(rule_name in cls.supported_rules)
+ return [SERVICES, cls.service_type.value, FINDINGS, rule_name.value]
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/ec2_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/ec2_rule_path_creator.py
new file mode 100644
index 000000000..4c13325bc
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/ec2_rule_path_creator.py
@@ -0,0 +1,11 @@
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.ec2_rules import EC2Rules
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import \
+ SERVICE_TYPES
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import \
+ AbstractRulePathCreator
+
+
+class EC2RulePathCreator(AbstractRulePathCreator):
+
+ service_type = SERVICE_TYPES.EC2
+ supported_rules = EC2Rules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
new file mode 100644
index 000000000..6c4ff21df
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
@@ -0,0 +1,4 @@
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.ec2_rule_path_creator import \
+ EC2RulePathCreator
+
+RULE_PATH_CREATORS_LIST = [EC2RulePathCreator]
From 4440027699eaf6f7ad99e86069b2ec0b1f675172 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 18 Sep 2020 10:13:27 +0300
Subject: [PATCH 020/152] Backend ScoutSuite backend code, which handles
ScoutSuite data reception, parsing and storing
---
.../common/common_consts/zero_trust_consts.py | 19 +++++-
monkey/common/utils/code_utils.py | 17 +++++
.../cc/models/zero_trust/finding.py | 30 +++++----
.../models/zero_trust/scoutsuite_data_json.py | 19 ++++++
.../models/zero_trust/scoutsuite_finding.py | 17 -----
.../zero_trust/scoutsuite_finding_details.py | 16 ++---
.../cc/models/zero_trust/scoutsuite_rule.py | 26 ++++++++
.../cc/resources/reporting/report.py | 14 +++-
.../telemetry/processing/scoutsuite.py | 21 +++++-
.../cc/services/zero_trust/events_service.py | 8 ++-
.../cc/services/zero_trust/finding_service.py | 14 +++-
.../zero_trust/monkey_finding_service.py | 13 +---
.../zero_trust/scoutsuite/consts/__init__.py | 0
.../zero_trust/scoutsuite/consts/findings.py | 19 ++++++
.../scoutsuite/consts/findings_list.py | 3 +
.../scoutsuite/consts/rule_consts.py | 4 ++
.../scoutsuite/consts/service_consts.py | 9 +++
.../scoutsuite/scoutsuite_finding_service.py | 65 +++++++++++++++++++
.../scoutsuite/scoutsuite_rule_service.py | 30 +++++++++
.../zero_trust/scoutsuite_finding_service.py | 3 -
20 files changed, 286 insertions(+), 61 deletions(-)
create mode 100644 monkey/monkey_island/cc/models/zero_trust/scoutsuite_data_json.py
delete mode 100644 monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
create mode 100644 monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/__init__.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_consts.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py
create mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py
delete mode 100644 monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
diff --git a/monkey/common/common_consts/zero_trust_consts.py b/monkey/common/common_consts/zero_trust_consts.py
index 8d55bc320..edc40d0f2 100644
--- a/monkey/common/common_consts/zero_trust_consts.py
+++ b/monkey/common/common_consts/zero_trust_consts.py
@@ -22,6 +22,11 @@ STATUS_FAILED = "Failed"
# Don't change order! The statuses are ordered by importance/severity.
ORDERED_TEST_STATUSES = [STATUS_FAILED, STATUS_VERIFY, STATUS_PASSED, STATUS_UNEXECUTED]
+MONKEY_FINDING = "monkey_finding"
+SCOUTSUITE_FINDING = "scoutsuite_finding"
+FINDING_TYPES = [MONKEY_FINDING, SCOUTSUITE_FINDING]
+
+
TEST_DATA_ENDPOINT_ELASTIC = "unencrypted_data_endpoint_elastic"
TEST_DATA_ENDPOINT_HTTP = "unencrypted_data_endpoint_http"
TEST_MACHINE_EXPLOITED = "machine_exploited"
@@ -31,6 +36,7 @@ TEST_MALICIOUS_ACTIVITY_TIMELINE = "malicious_activity_timeline"
TEST_SEGMENTATION = "segmentation"
TEST_TUNNELING = "tunneling"
TEST_COMMUNICATE_AS_NEW_USER = "communicate_as_new_user"
+TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES = "scoutsuite_permissive_firewall_rules"
TESTS = (
TEST_SEGMENTATION,
TEST_MALICIOUS_ACTIVITY_TIMELINE,
@@ -40,7 +46,8 @@ TESTS = (
TEST_DATA_ENDPOINT_HTTP,
TEST_DATA_ENDPOINT_ELASTIC,
TEST_TUNNELING,
- TEST_COMMUNICATE_AS_NEW_USER
+ TEST_COMMUNICATE_AS_NEW_USER,
+ TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES
)
PRINCIPLE_DATA_TRANSIT = "data_transit"
@@ -165,6 +172,16 @@ TESTS_MAP = {
PILLARS_KEY: [PEOPLE, NETWORKS, VISIBILITY_ANALYTICS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
},
+ TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES: {
+ TEST_EXPLANATION_KEY: "ScoutSuite assessed cloud firewall rules and settings.",
+ FINDING_EXPLANATION_BY_STATUS_KEY: {
+ STATUS_FAILED: "ScoutSuite found overly permissive firewall rules.",
+ STATUS_PASSED: "ScoutSuite found no problems with cloud firewall rules."
+ },
+ PRINCIPLE_KEY: PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES,
+ PILLARS_KEY: [NETWORKS],
+ POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
+ },
}
EVENT_TYPE_MONKEY_NETWORK = "monkey_network"
diff --git a/monkey/common/utils/code_utils.py b/monkey/common/utils/code_utils.py
index 214e6d108..32f972a76 100644
--- a/monkey/common/utils/code_utils.py
+++ b/monkey/common/utils/code_utils.py
@@ -1,5 +1,10 @@
# abstract, static method decorator
# noinspection PyPep8Naming
+import operator
+from functools import reduce
+from typing import List
+
+
class abstractstatic(staticmethod):
__slots__ = ()
@@ -8,3 +13,15 @@ class abstractstatic(staticmethod):
function.__isabstractmethod__ = True
__isabstractmethod__ = True
+
+
+def _get_value_by_path(data, path: List[str]):
+ return reduce(operator.getitem, path, data)
+
+
+def get_object_value_by_path(data_object: object, path: List[str]):
+ return _get_value_by_path(data_object, path)
+
+
+def get_dict_value_by_path(data_dict: dict, path: List[str]):
+ return _get_value_by_path(data_dict, path)
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py
index 8895a7fdb..6d0827e39 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/finding.py
@@ -2,16 +2,15 @@
"""
Define a Document Schema for Zero Trust findings.
"""
-from typing import List
+from typing import Union
from mongoengine import Document, StringField, GenericLazyReferenceField
import common.common_consts.zero_trust_consts as zero_trust_consts
# Dummy import for mongoengine.
# noinspection PyUnresolvedReferences
-from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
-from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutsuiteFindingDetails
+from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
class Finding(Document):
@@ -35,7 +34,8 @@ class Finding(Document):
# SCHEMA
test = StringField(required=True, choices=zero_trust_consts.TESTS)
status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
- details = GenericLazyReferenceField(choices=[MonkeyFindingDetails, ScoutsuiteFindingDetails], required=True)
+ type = StringField(required=True, choices=zero_trust_consts.FINDING_TYPES)
+ details = GenericLazyReferenceField(choices=[MonkeyFindingDetails, ScoutSuiteFindingDetails], required=True)
# http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance
meta = {'allow_inheritance': True}
@@ -48,11 +48,19 @@ class Finding(Document):
# Creation methods
@staticmethod
- def save_finding(test: str, status: str, detail_ref):
- finding = Finding(test=test,
- status=status,
- details=detail_ref)
+ def save_finding(test: str,
+ status: str,
+ detail_ref: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]):
+ temp_finding = Finding(test=test,
+ status=status,
+ details=detail_ref,
+ type=Finding._get_finding_type_by_details(detail_ref))
+ temp_finding.save()
+ return temp_finding
- finding.save()
-
- return finding
+ @staticmethod
+ def _get_finding_type_by_details(details: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]) -> str:
+ if type(details) == MonkeyFindingDetails:
+ return zero_trust_consts.MONKEY_FINDING
+ else:
+ return zero_trust_consts.SCOUTSUITE_FINDING
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_data_json.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_data_json.py
new file mode 100644
index 000000000..4b493e878
--- /dev/null
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_data_json.py
@@ -0,0 +1,19 @@
+from mongoengine import Document, DynamicField
+
+
+class ScoutSuiteDataJson(Document):
+ """
+ This model is a container for ScoutSuite report data dump.
+ """
+
+ # SCHEMA
+ scoutsuite_data = DynamicField(required=True)
+
+ # LOGIC
+ @staticmethod
+ def add_scoutsuite_data(scoutsuite_data: str) -> None:
+ current_data = ScoutSuiteDataJson.objects()
+ if not current_data:
+ current_data = ScoutSuiteDataJson()
+ current_data.scoutsuite_data = scoutsuite_data
+ current_data.save()
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
deleted file mode 100644
index f8d0f5042..000000000
--- a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from datetime import datetime
-
-from mongoengine import DateTimeField, EmbeddedDocument, StringField
-
-
-class ScoutsuiteFinding(EmbeddedDocument):
- # SCHEMA
- temp = StringField(required=True)
-
- # LOGIC
- @staticmethod
- def create_scoutsuite_finding(title, message, event_type, timestamp=None):
- scoutsuite_finding = ScoutsuiteFinding()
-
- scoutsuite_finding.temp = "temp"
-
- return scoutsuite_finding
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
index ed05f6003..52aa09d17 100644
--- a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
@@ -1,11 +1,9 @@
-from typing import List
+from mongoengine import Document, EmbeddedDocumentListField
-from mongoengine import DateTimeField, Document, StringField, EmbeddedDocumentListField
-
-from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutsuiteFinding
+from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
-class ScoutsuiteFindingDetails(Document):
+class ScoutSuiteFindingDetails(Document):
"""
This model represents additional information about monkey finding:
Events if monkey finding
@@ -13,7 +11,9 @@ class ScoutsuiteFindingDetails(Document):
"""
# SCHEMA
- scoutsuite_findings = EmbeddedDocumentListField(document_type=ScoutsuiteFinding, required=False)
+ scoutsuite_rules = EmbeddedDocumentListField(document_type=ScoutSuiteRule, required=False)
- def add_scoutsuite_findings(self, scoutsuite_findings: List[ScoutsuiteFinding]) -> None:
- self.update(push_all__scoutsuite_findings=scoutsuite_findings)
+ def add_rule(self, rule: ScoutSuiteRule) -> None:
+ if rule not in self.scoutsuite_rules:
+ self.scoutsuite_rules.append(rule)
+ self.save()
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py
new file mode 100644
index 000000000..316a5402e
--- /dev/null
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py
@@ -0,0 +1,26 @@
+from mongoengine import StringField, EmbeddedDocument, ListField, \
+ IntField
+
+from monkey_island.cc.services.zero_trust.scoutsuite.consts import rule_consts
+
+
+class ScoutSuiteRule(EmbeddedDocument):
+ """
+ This model represents additional information about monkey finding:
+ Events if monkey finding
+ Scoutsuite findings if scoutsuite finding
+ """
+
+ # SCHEMA
+ description = StringField(required=True)
+ path = StringField(required=True)
+ level = StringField(required=True, options=rule_consts.RULE_LEVELS)
+ items = ListField()
+ dashboard_name = StringField(required=True)
+ checked_items = IntField(min_value=0)
+ flagged_items = IntField(min_value=0)
+ service = StringField(required=True)
+ rationale = StringField(required=True)
+ remediation = StringField(required=False)
+ compliance = StringField(required=False)
+ references = ListField(required=False)
diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py
index 546f944a3..5273ca810 100644
--- a/monkey/monkey_island/cc/resources/reporting/report.py
+++ b/monkey/monkey_island/cc/resources/reporting/report.py
@@ -1,11 +1,12 @@
import http.client
import flask_restful
-from flask import jsonify
+from flask import jsonify, Response
+from monkey_island.cc.models.zero_trust.scoutsuite_data_json import ScoutSuiteDataJson
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.reporting.report import ReportService
-from monkey_island.cc.services.zero_trust.monkey_finding_service import MonkeyFindingService
+from monkey_island.cc.services.zero_trust.finding_service import FindingService
from monkey_island.cc.services.zero_trust.zero_trust_service import \
ZeroTrustService
@@ -16,6 +17,7 @@ REPORT_TYPES = [SECURITY_REPORT_TYPE, ZERO_TRUST_REPORT_TYPE]
REPORT_DATA_PILLARS = "pillars"
REPORT_DATA_FINDINGS = "findings"
REPORT_DATA_PRINCIPLES_STATUS = "principles"
+REPORT_DATA_SCOUTSUITE = "scoutsuite"
__author__ = ["itay.mizeretz", "shay.nehmad"]
@@ -36,6 +38,12 @@ class Report(flask_restful.Resource):
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
return jsonify(ZeroTrustService.get_principles_status())
elif report_data == REPORT_DATA_FINDINGS:
- return jsonify(MonkeyFindingService.get_all_monkey_findings())
+ return jsonify(FindingService.get_all_findings())
+ elif report_data == REPORT_DATA_SCOUTSUITE:
+ try:
+ data = ScoutSuiteDataJson.objects.get().scoutsuite_data
+ except Exception:
+ data = {}
+ return Response(data, mimetype='application/json')
flask_restful.abort(http.client.NOT_FOUND)
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
index d0e25aebc..c29320535 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/scoutsuite.py
@@ -1,15 +1,32 @@
import json
from monkey_island.cc.database import mongo
+from monkey_island.cc.models.zero_trust.scoutsuite_data_json import ScoutSuiteDataJson
+
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.findings_list import SCOUTSUITE_FINDINGS
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_parsing import RuleParser
+from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_finding_service import ScoutSuiteFindingService
+from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import ScoutSuiteRuleService
def process_scoutsuite_telemetry(telemetry_json):
# Encode data to json, because mongo can't save it as document (invalid document keys)
telemetry_json['data'] = json.dumps(telemetry_json['data'])
+ ScoutSuiteDataJson.add_scoutsuite_data(telemetry_json['data'])
+ scoutsuite_data = json.loads(telemetry_json['data'])['data']
+ create_scoutsuite_findings(scoutsuite_data)
update_data(telemetry_json)
+def create_scoutsuite_findings(scoutsuite_data):
+ for finding in SCOUTSUITE_FINDINGS:
+ for rule in finding.rules:
+ rule_data = RuleParser.get_rule_data(scoutsuite_data, rule)
+ rule = ScoutSuiteRuleService.get_rule_from_rule_data(rule_data)
+ ScoutSuiteFindingService.process_rule(finding, rule)
+
+
def update_data(telemetry_json):
- mongo.db.scoutsuite.update(
+ mongo.db.scoutsuite.insert_one(
{'guid': telemetry_json['monkey_guid']},
- {'$push': {'results': telemetry_json['data']}})
+ {'results': telemetry_json['data']})
diff --git a/monkey/monkey_island/cc/services/zero_trust/events_service.py b/monkey/monkey_island/cc/services/zero_trust/events_service.py
index 5cccee7f3..7f4f9e496 100644
--- a/monkey/monkey_island/cc/services/zero_trust/events_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/events_service.py
@@ -18,9 +18,11 @@ class EventsService:
'latest_events': {'$slice': ['$events', -1 * EVENT_FETCH_CNT]},
'event_count': {'$size': '$events'}}},
{'$unset': ['events']}]
- details = MonkeyFindingDetails.objects.aggregate(*pipeline).next()
- details['latest_events'] = EventsService._get_events_without_overlap(details['event_count'],
- details['latest_events'])
+ details = list(MonkeyFindingDetails.objects.aggregate(*pipeline))
+ if details:
+ details = details[0]
+ details['latest_events'] = EventsService._get_events_without_overlap(details['event_count'],
+ details['latest_events'])
return details
@staticmethod
diff --git a/monkey/monkey_island/cc/services/zero_trust/finding_service.py b/monkey/monkey_island/cc/services/zero_trust/finding_service.py
index 2feb02cce..f6ab4b39a 100644
--- a/monkey/monkey_island/cc/services/zero_trust/finding_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/finding_service.py
@@ -2,13 +2,24 @@ from typing import List
from common.common_consts import zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding
+from monkey_island.cc.services.zero_trust.events_service import EventsService
class FindingService:
@staticmethod
def get_all_findings() -> List[Finding]:
- return list(Finding.objects)
+ findings = list(Finding.objects)
+ details = []
+ for i in range(len(findings)):
+ if findings[i].type == zero_trust_consts.MONKEY_FINDING:
+ details = EventsService.fetch_events_for_display(findings[i].details.id)
+ elif findings[i].type == zero_trust_consts.SCOUTSUITE_FINDING:
+ details = findings[i].details.fetch().to_mongo()
+ findings[i] = findings[i].to_mongo()
+ findings[i] = FindingService.get_enriched_finding(findings[i])
+ findings[i]['details'] = details
+ return findings
@staticmethod
def get_enriched_finding(finding):
@@ -19,5 +30,6 @@ class FindingService:
'test_key': finding['test'],
'pillars': test_info[zero_trust_consts.PILLARS_KEY],
'status': finding['status'],
+ 'type': finding['type']
}
return enriched_finding
diff --git a/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
index a1e731b14..1ee60b117 100644
--- a/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/monkey_finding_service.py
@@ -6,7 +6,6 @@ from common.common_consts import zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
-from monkey_island.cc.services.zero_trust.finding_service import FindingService
class MonkeyFindingService:
@@ -38,17 +37,7 @@ class MonkeyFindingService:
@staticmethod
def add_events(finding: Finding, events: List[Event]):
- finding.details.fetch().add_events(events)
-
- @staticmethod
- def get_all_monkey_findings():
- findings = FindingService.get_all_findings()
- for i in range(len(findings)):
- details = MonkeyFindingService.fetch_events_for_display(findings[i].details.id)
- findings[i] = findings[i].to_mongo()
- findings[i] = FindingService.get_enriched_finding(findings[i])
- findings[i]['details'] = details
- return findings
+ finding.details.fetch().add_events(events).save()
@staticmethod
def get_events_by_finding(finding_id: str) -> List[object]:
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/__init__.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py
new file mode 100644
index 000000000..792c92e80
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py
@@ -0,0 +1,19 @@
+from common.common_consts import zero_trust_consts
+from common.common_consts.zero_trust_consts import NETWORKS
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.ec2_rules import EC2Rules
+
+
+class PERMISSIVE_FIREWALL_RULES:
+ rules = [EC2Rules.SECURITY_GROUP_ALL_PORTS_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_TCP_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_UDP_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_RDP_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_SSH_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_MYSQL_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_MSSQL_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_MONGODB_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_ORACLE_DB_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_POSTGRESQL_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_NFS_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_SMTP_PORT_TO_ALL,
+ EC2Rules.SECURITY_GROUP_OPENS_DNS_PORT_TO_ALL, EC2Rules.SECURITY_GROUP_OPENS_ALL_PORTS_TO_SELF,
+ EC2Rules.SECURITY_GROUP_OPENS_ALL_PORTS, EC2Rules.SECURITY_GROUP_OPENS_PLAINTEXT_PORT_FTP,
+ EC2Rules.SECURITY_GROUP_OPENS_PLAINTEXT_PORT_TELNET, EC2Rules.SECURITY_GROUP_OPENS_PORT_RANGE]
+
+ pillars = [NETWORKS]
+
+ test = zero_trust_consts.TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py
new file mode 100644
index 000000000..bf54ac8ce
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py
@@ -0,0 +1,3 @@
+from monkey_island.cc.services.zero_trust.scoutsuite.consts.findings import PERMISSIVE_FIREWALL_RULES
+
+SCOUTSUITE_FINDINGS = [PERMISSIVE_FIREWALL_RULES]
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_consts.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_consts.py
new file mode 100644
index 000000000..732852174
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_consts.py
@@ -0,0 +1,4 @@
+RULE_LEVEL_DANGER = 'danger'
+RULE_LEVEL_WARNING = 'warning'
+
+RULE_LEVELS = (RULE_LEVEL_DANGER, RULE_LEVEL_WARNING)
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py
new file mode 100644
index 000000000..5c0338c26
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py
@@ -0,0 +1,9 @@
+from enum import Enum
+
+
+SERVICES = 'services'
+FINDINGS = 'findings'
+
+
+class SERVICE_TYPES(Enum):
+ EC2 = 'ec2'
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py
new file mode 100644
index 000000000..6f8e64e87
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py
@@ -0,0 +1,65 @@
+from typing import List
+
+from common.common_consts import zero_trust_consts
+from monkey_island.cc.models.zero_trust.finding import Finding
+from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
+from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
+from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import ScoutSuiteRuleService
+
+
+class ScoutSuiteFindingService:
+
+ @staticmethod
+ # TODO add type hinting like finding: Union[SCOUTSUITE_FINDINGS]?
+ def process_rule(finding, rule: ScoutSuiteRule):
+ existing_findings = Finding.objects(test=finding.test, type=zero_trust_consts.SCOUTSUITE_FINDING)
+ assert (len(existing_findings) < 2), "More than one finding exists for {}".format(finding.test)
+
+ if len(existing_findings) == 0:
+ ScoutSuiteFindingService.create_new_finding_from_rule(finding, rule)
+ else:
+ ScoutSuiteFindingService.add_rule(existing_findings[0], rule)
+
+ @staticmethod
+ def create_new_finding_from_rule(finding, rule: ScoutSuiteRule):
+ details = ScoutSuiteFindingDetails()
+ details.scoutsuite_rules = [rule]
+ details.save()
+ status = ScoutSuiteFindingService.get_finding_status_from_rules(details.scoutsuite_rules)
+ Finding.save_finding(finding.test, status, details)
+
+ @staticmethod
+ def get_finding_status_from_rules(rules: List[ScoutSuiteRule]) -> str:
+ if len(rules) == 0:
+ return zero_trust_consts.STATUS_UNEXECUTED
+ elif filter(lambda x: ScoutSuiteRuleService.is_rule_dangerous(x), rules):
+ return zero_trust_consts.STATUS_FAILED
+ elif filter(lambda x: ScoutSuiteRuleService.is_rule_warning(x), rules):
+ return zero_trust_consts.STATUS_VERIFY
+ else:
+ return zero_trust_consts.STATUS_PASSED
+
+ @staticmethod
+ def add_rule(finding: Finding, rule: ScoutSuiteRule):
+ ScoutSuiteFindingService.change_finding_status_by_rule(finding, rule)
+ finding.save()
+ finding.details.fetch().add_rule(rule)
+
+ @staticmethod
+ def change_finding_status_by_rule(finding: Finding, rule: ScoutSuiteRule):
+ rule_status = ScoutSuiteFindingService.get_finding_status_from_rules([rule])
+ finding_status = finding.status
+ new_finding_status = ScoutSuiteFindingService.get_finding_status_from_rule_status(finding_status, rule_status)
+ if finding_status != new_finding_status:
+ finding.status = new_finding_status
+
+ @staticmethod
+ def get_finding_status_from_rule_status(finding_status: str, rule_status: str) -> str:
+ if finding_status == zero_trust_consts.STATUS_FAILED or rule_status == zero_trust_consts.STATUS_FAILED:
+ return zero_trust_consts.STATUS_FAILED
+ elif finding_status == zero_trust_consts.STATUS_VERIFY or rule_status == zero_trust_consts.STATUS_VERIFY:
+ return zero_trust_consts.STATUS_VERIFY
+ elif finding_status == zero_trust_consts.STATUS_PASSED or rule_status == zero_trust_consts.STATUS_PASSED:
+ return zero_trust_consts.STATUS_PASSED
+ else:
+ return zero_trust_consts.STATUS_UNEXECUTED
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py
new file mode 100644
index 000000000..3b76194af
--- /dev/null
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py
@@ -0,0 +1,30 @@
+from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
+from monkey_island.cc.services.zero_trust.scoutsuite.consts import rule_consts
+
+
+class ScoutSuiteRuleService:
+
+ @staticmethod
+ def get_rule_from_rule_data(rule_data: dict) -> ScoutSuiteRule:
+ rule = ScoutSuiteRule()
+ rule.description = rule_data['description']
+ rule.path = rule_data['path']
+ rule.level = rule_data['level']
+ rule.items = rule_data['items']
+ rule.dashboard_name = rule_data['dashboard_name']
+ rule.checked_items = rule_data['checked_items']
+ rule.flagged_items = rule_data['flagged_items']
+ rule.service = rule_data['service']
+ rule.rationale = rule_data['rationale']
+ rule.remediation = rule_data['remediation']
+ rule.compliance = rule_data['compliance']
+ rule.references = rule_data['references']
+ return rule
+
+ @staticmethod
+ def is_rule_dangerous(rule: ScoutSuiteRule):
+ return rule.level == rule_consts.RULE_LEVEL_DANGER and len(rule.items) != 0
+
+ @staticmethod
+ def is_rule_warning(rule: ScoutSuiteRule):
+ return rule.level == rule_consts.RULE_LEVEL_WARNING and len(rule.items) != 0
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
deleted file mode 100644
index 12ab2743b..000000000
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite_finding_service.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-class ScoutsuiteFindingService:
- pass
From c66cb11e79c14b89a73db49dc283feacbaa03792 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 18 Sep 2020 10:26:25 +0300
Subject: [PATCH 021/152] Added ScoutSuite UI code
---
.../zero_trust/monkey_finding_details.py | 3 +-
.../cc/ui/src/components/pages/ReportPage.js | 7 +-
.../report-components/ZeroTrustReport.js | 9 +-
.../consts/ScoutSuiteConsts/RuleLevels.js | 6 ++
.../common/consts/StatusConsts.js | 8 ++
.../zerotrust/FindingsSection.js | 12 ++-
.../zerotrust/FindingsTable.js | 81 +++++++++--------
.../zerotrust/scoutsuite/ResourceDropdown.js | 75 ++++++++++++++++
.../zerotrust/scoutsuite/RuleDisplay.js | 56 ++++++++++++
.../scoutsuite/ScoutSuiteDataParser.js | 58 ++++++++++++
.../scoutsuite/ScoutSuiteRuleButton.js | 45 ++++++++++
.../scoutsuite/ScoutSuiteRuleModal.js | 58 ++++++++++++
.../ScoutSuiteSingleRuleDropdown.js | 90 +++++++++++++++++++
.../monkey_island/cc/ui/src/styles/Main.scss | 1 +
.../cc/ui/src/styles/components/Collapse.scss | 9 ++
.../scoutsuite/ResourceDropdown.scss | 20 +++++
.../components/scoutsuite/RuleDisplay.scss | 21 +++++
.../components/scoutsuite/RuleModal.scss | 5 ++
18 files changed, 519 insertions(+), 45 deletions(-)
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/common/consts/ScoutSuiteConsts/RuleLevels.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/common/consts/StatusConsts.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ResourceDropdown.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleButton.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleModal.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteSingleRuleDropdown.js
create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/ResourceDropdown.scss
create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleDisplay.scss
create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleModal.scss
diff --git a/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
index 029136679..bcd19f593 100644
--- a/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
+++ b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
@@ -1,9 +1,10 @@
from typing import List
-from mongoengine import DateTimeField, Document, StringField, EmbeddedDocumentListField
+from mongoengine import Document, EmbeddedDocumentListField
from monkey_island.cc.models.zero_trust.event import Event
+
class MonkeyFindingDetails(Document):
"""
This model represents additional information about monkey finding:
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
index cb30ba117..e0b458c8b 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -60,7 +60,7 @@ class ReportPageComponent extends AuthComponent {
}
getZeroTrustReportFromServer = async () => {
- let ztReport = {findings: {}, principles: {}, pillars: {}};
+ let ztReport = {findings: {}, principles: {}, pillars: {}, scoutsuite_data: {}};
await this.authFetch('/api/report/zero_trust/findings')
.then(res => res.json())
.then(res => {
@@ -76,6 +76,11 @@ class ReportPageComponent extends AuthComponent {
.then(res => {
ztReport.pillars = res;
});
+ await this.authFetch('/api/report/zero_trust/scoutsuite')
+ .then(res => res.json())
+ .then(res => {
+ ztReport.scoutsuite_data = res;
+ });
return ztReport
};
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/ZeroTrustReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/ZeroTrustReport.js
index 772802c9d..b400b3418 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/ZeroTrustReport.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/ZeroTrustReport.js
@@ -16,7 +16,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
componentDidUpdate(prevProps) {
if (this.props.report !== prevProps.report) {
- this.setState(this.props.report)
+ this.setState(this.props.report)
}
}
@@ -29,7 +29,9 @@ class ZeroTrustReportPageComponent extends AuthComponent {
-
+
;
}
@@ -57,7 +59,8 @@ class ZeroTrustReportPageComponent extends AuthComponent {
stillLoadingDataFromServer() {
return typeof this.state.findings === 'undefined'
|| typeof this.state.pillars === 'undefined'
- || typeof this.state.principles === 'undefined';
+ || typeof this.state.principles === 'undefined'
+ || typeof this.state.scoutsuite_data === 'undefined';
}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/ScoutSuiteConsts/RuleLevels.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/ScoutSuiteConsts/RuleLevels.js
new file mode 100644
index 000000000..20b92a3eb
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/ScoutSuiteConsts/RuleLevels.js
@@ -0,0 +1,6 @@
+const RULE_LEVELS = {
+ LEVEL_WARNING: 'warning',
+ LEVEL_DANGER: 'danger'
+}
+
+export default RULE_LEVELS
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/StatusConsts.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/StatusConsts.js
new file mode 100644
index 000000000..472b045ae
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/consts/StatusConsts.js
@@ -0,0 +1,8 @@
+const STATUSES = {
+ STATUS_UNEXECUTED: 'Unexecuted',
+ STATUS_PASSED: 'Passed',
+ STATUS_VERIFY: 'Verify',
+ STATUS_FAILED: 'Failed'
+}
+
+export default STATUSES
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsSection.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsSection.js
index 5fa3a4a80..eb8231441 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsSection.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsSection.js
@@ -32,9 +32,15 @@ class FindingsSection extends Component {
insight as to what exactly happened during this test.
-
-
-
+
+
+
);
}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js
index f83921dae..10e546767 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js
@@ -4,52 +4,59 @@ import PaginatedTable from '../common/PaginatedTable';
import * as PropTypes from 'prop-types';
import PillarLabel from './PillarLabel';
import EventsButton from './EventsButton';
+import ScoutSuiteRuleButton from './scoutsuite/ScoutSuiteRuleButton';
-const EVENTS_COLUMN_MAX_WIDTH = 170;
+const EVENTS_COLUMN_MAX_WIDTH = 250;
const PILLARS_COLUMN_MAX_WIDTH = 200;
-const columns = [
- {
- columns: [
- {
- Header: 'Finding', accessor: 'test',
- style: {'whiteSpace': 'unset'} // This enables word wrap
- },
-
- {
- Header: 'Events', id: 'events',
- accessor: x => {
- return ;
- },
- maxWidth: EVENTS_COLUMN_MAX_WIDTH
- },
-
- {
- Header: 'Pillars', id: 'pillars',
- accessor: x => {
- const pillars = x.pillars;
- const pillarLabels = pillars.map((pillar) =>
-
- );
- return {pillarLabels}
;
- },
- maxWidth: PILLARS_COLUMN_MAX_WIDTH,
- style: {'whiteSpace': 'unset'}
- }
- ]
- }
-];
export class FindingsTable extends Component {
+ columns = [
+ {
+ columns: [
+ {
+ Header: 'Finding', accessor: 'test',
+ style: {'whiteSpace': 'unset'} // This enables word wrap
+ },
+
+ {
+ Header: 'Details', id: 'details',
+ accessor: x => {
+ if (x.type === 'scoutsuite_finding') {
+ return ;
+ } else if (x.type === 'monkey_finding') {
+ return ;
+ }
+ },
+ maxWidth: EVENTS_COLUMN_MAX_WIDTH
+ },
+
+ {
+ Header: 'Pillars', id: 'pillars',
+ accessor: x => {
+ const pillars = x.pillars;
+ const pillarLabels = pillars.map((pillar) =>
+
+ );
+ return {pillarLabels}
;
+ },
+ maxWidth: PILLARS_COLUMN_MAX_WIDTH,
+ style: {'whiteSpace': 'unset'}
+ }
+ ]
+ }
+ ];
+
render() {
return
{
} tests' findings
-
+
}
}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ResourceDropdown.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ResourceDropdown.js
new file mode 100644
index 000000000..996f62590
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ResourceDropdown.js
@@ -0,0 +1,75 @@
+import React, {useState} from 'react';
+import * as PropTypes from 'prop-types';
+import '../../../../styles/components/scoutsuite/RuleDisplay.scss'
+import classNames from 'classnames';
+import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
+import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown';
+import {faChevronUp} from '@fortawesome/free-solid-svg-icons/faChevronUp';
+import ScoutSuiteDataParser from './ScoutSuiteDataParser';
+import Collapse from '@kunukn/react-collapse';
+import {faArrowRight} from '@fortawesome/free-solid-svg-icons';
+
+export default function ResourceDropdown(props) {
+
+ const [isCollapseOpen, setIsCollapseOpen] = useState(false);
+
+ function getResourceDropdown() {
+ return (
+
+
+
+
+ );
+ }
+
+ function replacePathDotsWithArrows(resourcePath) {
+ let path_vars = resourcePath.split('.')
+ let display_path = []
+ for(let i = 0; i < path_vars.length; i++){
+ display_path.push(path_vars[i])
+ if( i !== path_vars.length - 1) {
+ display_path.push()
+ }
+ }
+ return display_path;
+ }
+
+ function prettyPrintJson(data) {
+ return JSON.stringify(data, null, 4);
+ }
+
+ function getResourceDropdownContents() {
+ let parser = new ScoutSuiteDataParser(props.scoutsuite_data.data.services);
+ return (
+
+
+
Path:
+
{replacePathDotsWithArrows(props.resource_path)}
+
+
+
Value:
+
{prettyPrintJson(parser.getValueAt(props.resource_path))}
+
+
+ );
+ }
+
+ return getResourceDropdown();
+}
+
+ResourceDropdown.propTypes = {
+ resource_path: PropTypes.object,
+ scoutsuite_data: PropTypes.object
+};
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js
new file mode 100644
index 000000000..6078b3855
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js
@@ -0,0 +1,56 @@
+import React from 'react';
+import * as PropTypes from 'prop-types';
+import '../../../../styles/components/scoutsuite/RuleDisplay.scss'
+import ResourceDropdown from './ResourceDropdown';
+
+export default function RuleDisplay(props) {
+
+ return (
+
+
+
{props.rule.description}({props.rule.service})
+
+
+
{props.rule.rationale}
+
+
+
Resources checked:
+
{props.rule.checked_items}
+
+
+
Resources flagged:
+
{props.rule.flagged_items}
+
+ {props.rule.references.length !== 0 ? getReferences() : ''}
+ {props.rule.items.length !== 0 ? getResources() : ''}
+
);
+
+ function getReferences() {
+ let references = []
+ props.rule.references.forEach(reference => {
+ references.push({reference})
+ })
+ return (
+
+
References:
+ {references}
+
)
+ }
+
+ function getResources() {
+ let resources = []
+ props.rule.items.forEach(item => {
+ resources.push()
+ })
+ return (
+
+
Resources:
+ {resources}
+
)
+ }
+}
+
+RuleDisplay.propTypes = {
+ rule: PropTypes.object,
+ scoutsuite_data: PropTypes.object
+};
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js
new file mode 100644
index 000000000..0129804f8
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js
@@ -0,0 +1,58 @@
+export default class ScoutSuiteDataParser {
+ constructor(runResults) {
+ this.runResults = runResults
+ }
+
+ getValueAt(path) {
+ return this.getValueAtRecursive(path, this.runResults)
+ }
+
+ getValueAtRecursive(path, source) {
+ let value = source;
+ let current_path = path;
+ let key;
+ // iterate over each path elements
+ while (current_path) {
+ // check if there are more elements to the path
+ if (current_path.indexOf('.') != -1) {
+ key = current_path.substr(0, current_path.indexOf('.'));
+ }
+ // last element
+ else {
+ key = current_path;
+ }
+
+ try {
+ // path containing an ".id"
+ if (key == 'id') {
+ let v = [];
+ let w;
+ for (let k in value) {
+ // process recursively
+ w = this.getValueAtRecursive(k + current_path.substr(current_path.indexOf('.'), current_path.length), value);
+ v = v.concat(
+ Object.values(w) // get values from array, otherwise it will be an array of key/values
+ );
+ }
+ return v;
+ }
+ // simple path, just return element in value
+ else {
+ value = value[key];
+ }
+ } catch (err) {
+ console.log('Error: ' + err)
+ }
+
+ // check if there are more elements to process
+ if (current_path.indexOf('.') != -1) {
+ current_path = current_path.substr(current_path.indexOf('.') + 1, current_path.length);
+ }
+ // otherwise we're done
+ else {
+ current_path = false;
+ }
+ }
+ return value;
+ }
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleButton.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleButton.js
new file mode 100644
index 000000000..97c5f861a
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleButton.js
@@ -0,0 +1,45 @@
+import React, {Component} from 'react';
+import {Badge, Button} from 'react-bootstrap';
+import * as PropTypes from 'prop-types';
+
+import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
+import {faList} from '@fortawesome/free-solid-svg-icons/faList';
+import ScoutSuiteRuleModal from './ScoutSuiteRuleModal';
+
+export default class ScoutSuiteRuleButton extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ isModalOpen: false
+ }
+ }
+
+ toggleModal = () => {
+ this.setState({isModalOpen: !this.state.isModalOpen});
+ };
+
+ render() {
+ return (
+ <>
+
+
+
+
+ >);
+ }
+
+ createRuleCountBadge() {
+ const ruleCount = this.props.scoutsuite_rules.length > 9 ? '9+' : this.props.scoutsuite_rules.length;
+ return {ruleCount};
+ }
+}
+
+ScoutSuiteRuleButton.propTypes = {
+ scoutsuite_rules: PropTypes.array,
+ scoutsuite_data: PropTypes.object
+};
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleModal.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleModal.js
new file mode 100644
index 000000000..92fd430da
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteRuleModal.js
@@ -0,0 +1,58 @@
+import React, {useState} from 'react';
+import {Modal} from 'react-bootstrap';
+import * as PropTypes from 'prop-types';
+import Pluralize from 'pluralize';
+import ScoutSuiteSingleRuleDropdown from './ScoutSuiteSingleRuleDropdown';
+import '../../../../styles/components/scoutsuite/RuleModal.scss';
+
+
+export default function ScoutSuiteRuleModal(props) {
+ const [openRuleId, setOpenRuleId] = useState(null)
+
+ function toggleRuleDropdown(ruleId) {
+ if (openRuleId === ruleId) {
+ setOpenRuleId(null);
+ } else {
+ setOpenRuleId(ruleId);
+ }
+ }
+
+ function renderRuleDropdowns() {
+ let dropdowns = [];
+ props.scoutsuite_rules.forEach(rule => {
+ let dropdown = ( toggleRuleDropdown(rule.description)}
+ rule={rule}
+ scoutsuite_data={props.scoutsuite_data}/>)
+ dropdowns.push(dropdown)
+ });
+ return dropdowns;
+ }
+
+ return (
+
+
props.hideCallback()} className={'scoutsuite-rule-modal'}>
+
+
+
ScoutSuite rules
+
+
+
+ There {Pluralize('is', props.scoutsuite_rules.length)} {
+
{props.scoutsuite_rules.length}
+ } ScoutSuite {Pluralize('rule', props.scoutsuite_rules.length)} associated with finding.
+
+ {renderRuleDropdowns()}
+
+
+
+ );
+
+}
+
+ScoutSuiteRuleModal.propTypes = {
+ isModalOpen: PropTypes.bool,
+ scoutsuite_rules: PropTypes.array,
+ scoutsuite_data: PropTypes.object,
+ hideCallback: PropTypes.func
+};
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteSingleRuleDropdown.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteSingleRuleDropdown.js
new file mode 100644
index 000000000..1a931b154
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteSingleRuleDropdown.js
@@ -0,0 +1,90 @@
+import React from 'react';
+import Collapse from '@kunukn/react-collapse';
+import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
+import {faChevronUp} from '@fortawesome/free-solid-svg-icons/faChevronUp'
+import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown'
+
+import classNames from 'classnames';
+import * as PropTypes from 'prop-types';
+import RULE_LEVELS from '../../common/consts/ScoutSuiteConsts/RuleLevels';
+import STATUSES from '../../common/consts/StatusConsts';
+import {faCheckCircle, faCircle, faExclamationCircle} from '@fortawesome/free-solid-svg-icons';
+import RuleDisplay from './RuleDisplay';
+
+export default function ScoutSuiteSingleRuleDropdown(props) {
+
+ function getRuleCollapse() {
+ return (
+
+
+
+
+ );
+ }
+
+ function getRuleIcon() {
+ let ruleStatus = getRuleStatus()
+ switch(ruleStatus) {
+ case STATUSES.STATUS_PASSED:
+ return faCheckCircle;
+ case STATUSES.STATUS_VERIFY:
+ return faExclamationCircle;
+ case STATUSES.STATUS_FAILED:
+ return faExclamationCircle;
+ case STATUSES.STATUS_UNEXECUTED:
+ return faCircle;
+ }
+ }
+
+ function getDropdownClass(){
+ let ruleStatus = getRuleStatus()
+ switch(ruleStatus) {
+ case STATUSES.STATUS_PASSED:
+ return "collapse-success";
+ case STATUSES.STATUS_VERIFY:
+ return "collapse-warning";
+ case STATUSES.STATUS_FAILED:
+ return "collapse-danger";
+ case STATUSES.STATUS_UNEXECUTED:
+ return "collapse-default";
+ }
+ }
+
+ function getRuleStatus(){
+ if(props.rule.checked_items === 0) {
+ return STATUSES.STATUS_UNEXECUTED
+ } else if (props.rule.items.length === 0) {
+ return STATUSES.STATUS_PASSED
+ } else if (props.rule.level === RULE_LEVELS.LEVEL_WARNING) {
+ return STATUSES.STATUS_VERIFY
+ } else {
+ return STATUSES.STATUS_FAILED
+ }
+ }
+
+ function renderRule() {
+ return
+ }
+
+ return getRuleCollapse();
+}
+
+ScoutSuiteSingleRuleDropdown.propTypes = {
+ isCollapseOpen: PropTypes.bool,
+ rule: PropTypes.object,
+ scoutsuite_data: PropTypes.object,
+ toggleCallback: PropTypes.func
+};
diff --git a/monkey/monkey_island/cc/ui/src/styles/Main.scss b/monkey/monkey_island/cc/ui/src/styles/Main.scss
index e26220d0d..16cb1cab8 100644
--- a/monkey/monkey_island/cc/ui/src/styles/Main.scss
+++ b/monkey/monkey_island/cc/ui/src/styles/Main.scss
@@ -12,6 +12,7 @@
@import 'components/PreviewPane';
@import 'components/AdvancedMultiSelect';
@import 'components/particle-component/ParticleBackground';
+@import 'components/scoutsuite/ResourceDropdown';
// Define custom elements after bootstrap import
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss b/monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss
index 3e578d45c..369c93685 100644
--- a/monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss
+++ b/monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss
@@ -5,6 +5,7 @@ $disabled-color: #f2f2f2;
$info-color: #ade3eb;
$default-color: #8c8c8c;
$warning-color: #ffe28d;
+$success-color: #adf6a9;
.collapse-item button {
font-size: inherit;
@@ -39,6 +40,10 @@ $warning-color: #ffe28d;
}
}
+.collapse-success {
+ background-color: $success-color !important;
+}
+
.collapse-danger {
background-color: $danger-color !important;
}
@@ -99,3 +104,7 @@ $warning-color: #ffe28d;
display: inline-block;
min-width: 6em;
}
+
+.rule-collapse svg{
+ margin-right: 10px;
+}
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/ResourceDropdown.scss b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/ResourceDropdown.scss
new file mode 100644
index 000000000..a5be0a4ae
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/ResourceDropdown.scss
@@ -0,0 +1,20 @@
+.resource-display {
+ margin-top: 10px;
+}
+
+.resource-display .resource-value-json {
+ background-color: $gray-200;
+ padding: 4px;
+}
+
+.resource-display .resource-path-contents svg {
+ margin-left: 5px;
+ margin-right: 5px;
+ width: 10px;
+}
+
+.resource-display .resource-value-title,
+.resource-display .resource-path-title {
+ font-weight: 500;
+ margin-bottom: 0;
+}
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleDisplay.scss b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleDisplay.scss
new file mode 100644
index 000000000..703e27370
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleDisplay.scss
@@ -0,0 +1,21 @@
+.scoutsuite-rule-display .description h3{
+ font-size: 1.2em;
+ margin-top: 10px;
+}
+
+.scoutsuite-rule-display p{
+ display: inline-block;
+}
+
+.scoutsuite-rule-display .checked-resources-title,
+.scoutsuite-rule-display .flagged-resources-title,
+.scoutsuite-rule-display .reference-list-title{
+ font-weight: 500;
+ margin-right: 5px;
+ margin-bottom: 0;
+}
+
+.scoutsuite-rule-display .reference-list a {
+ display: block;
+ margin-left: 10px;
+}
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleModal.scss b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleModal.scss
new file mode 100644
index 000000000..f201da303
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/RuleModal.scss
@@ -0,0 +1,5 @@
+.scoutsuite-rule-modal .modal-dialog{
+ max-width: 1000px;
+ top: 0;
+ padding: 30px;
+}
From b8f7064582c19d8af4ef7812e005f618410f27e3 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Fri, 18 Sep 2020 16:43:03 +0300
Subject: [PATCH 022/152] Fixed conflicting dependencies that require botocore
>= 1.18.0
---
monkey/monkey_island/requirements.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/monkey/monkey_island/requirements.txt b/monkey/monkey_island/requirements.txt
index 057ea6de2..2ab3b48a7 100644
--- a/monkey/monkey_island/requirements.txt
+++ b/monkey/monkey_island/requirements.txt
@@ -2,8 +2,8 @@ Flask-JWT-Extended==3.24.1
Flask-Pymongo>=2.3.0
Flask-Restful>=0.3.8
PyInstaller==3.6
-awscli>=1.18.131
-boto3>=1.14.54
+awscli==1.18.131
+boto3==1.14.54
botocore>=1.17.54,<1.18.0
cffi>=1.8,!=1.11.3
dpath>=2.0
@@ -26,4 +26,4 @@ virtualenv>=20.0.26
werkzeug>=1.0.1
wheel>=0.34.2
-pyjwt>=1.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
\ No newline at end of file
+pyjwt>=1.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
From c3fde1898c0124c57841b15bcbc3799a27bf32b5 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Mon, 21 Sep 2020 11:05:20 +0300
Subject: [PATCH 023/152] Added ScoutSuite scan setup guide to run monkey page.
---
.../pages/RunMonkeyPage/RunOptions.js | 11 +++-
.../scoutsuite-setup/AWSSetup.js | 56 +++++++++++++++++++
.../scoutsuite-setup/CloudOptions.js | 31 ++++++++++
.../inline-selection/InlineSelection.js | 3 +-
.../ui-components/inline-selection/utils.js | 16 ++++++
.../components/scoutsuite/AWSSetup.scss | 17 ++++++
6 files changed, 132 insertions(+), 2 deletions(-)
create mode 100644 monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/CloudOptions.js
create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/utils.js
create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/AWSSetup.scss
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js
index a9fe1f8cf..fa724d6f6 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js
@@ -5,8 +5,10 @@ import AuthComponent from '../../AuthComponent';
import {faLaptopCode} from '@fortawesome/free-solid-svg-icons/faLaptopCode';
import InlineSelection from '../../ui-components/inline-selection/InlineSelection';
import {cloneDeep} from 'lodash';
-import {faExpandArrowsAlt} from '@fortawesome/free-solid-svg-icons';
+import {faCloud, faExpandArrowsAlt} from '@fortawesome/free-solid-svg-icons';
import RunOnIslandButton from './RunOnIslandButton';
+import AWSSetup from './scoutsuite-setup/AWSSetup';
+import CloudOptions from './scoutsuite-setup/CloudOptions';
function RunOptions(props) {
@@ -61,6 +63,13 @@ function RunOptions(props) {
setComponent(LocalManualRunOptions,
{ips: ips, setComponent: setComponent})
}}/>
+ {
+ setComponent(CloudOptions,
+ {ips: ips, setComponent: setComponent})
+ }}/>
>
);
}
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
new file mode 100644
index 000000000..6c184aabd
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
@@ -0,0 +1,56 @@
+import {Button} from 'react-bootstrap';
+import React from 'react';
+import InlineSelection from '../../../ui-components/inline-selection/InlineSelection';
+import CloudOptions from './CloudOptions';
+import {COLUMN_SIZES} from '../../../ui-components/inline-selection/utils';
+import '../../../../styles/components/scoutsuite/AWSSetup.scss';
+
+export default function AWSSetup(props) {
+ return InlineSelection(getContents, {
+ ...props,
+ collumnSize: COLUMN_SIZES.LARGE,
+ onBackButtonClick: () => {
+ props.setComponent(CloudOptions, props)
+ }
+ })
+}
+
+
+const getContents = (props) => {
+ return (
+
+
ScoutSuite configuration for AWS
+
To assess your AWS infrastructure security do the following:
+
+ -
+ 1. Configure AWS CLI on Monkey Island Server (if you already have a configured CLI you can skip this step).
+
+ -
+ 1. Download and
+ install it on Monkey Island server (machine running this page).
+
+ -
+ 2. Run aws configure. It's important to configure credentials, which
+ allows ScoutSuite to get information about your cloud configuration. The most trivial way to do so is to
+ provide .
+
+
+
+ -
+ 2. If you change the configuration, make sure not to disable AWS system info collector.
+
+ -
+ 3. Go back and run Monkey on the Island server.
+
+ -
+ 4. Assess results in Zero Trust report.
+
+
+
+ );
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/CloudOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/CloudOptions.js
new file mode 100644
index 000000000..1605a0eaa
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/CloudOptions.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import InlineSelection from '../../../ui-components/inline-selection/InlineSelection';
+import NextSelectionButton from '../../../ui-components/inline-selection/NextSelectionButton';
+import {faCloud} from '@fortawesome/free-solid-svg-icons';
+import AWSSetup from './AWSSetup';
+
+
+const CloudOptions = (props) => {
+ return InlineSelection(getContents, {
+ ...props,
+ onBackButtonClick: () => {
+ props.setComponent()
+ }
+ })
+}
+
+const getContents = (props) => {
+ return (
+ <>
+ {
+ props.setComponent(AWSSetup,
+ {setComponent: props.setComponent})
+ }}/>
+ >
+ )
+}
+
+export default CloudOptions;
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js
index a699b7d7f..51bf341bd 100644
--- a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js
@@ -2,13 +2,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import BackButton from './BackButton';
import {Col, Row, Container} from 'react-bootstrap';
+import {getColumnSize} from './utils';
export default function InlineSelection(WrappedComponent, props) {
return (
-
+
{renderBackButton(props)}
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/utils.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/utils.js
new file mode 100644
index 000000000..16974f193
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/utils.js
@@ -0,0 +1,16 @@
+export const COLUMN_SIZES = {
+ LARGE: 'large',
+ STANDARD: 'standard',
+ SMALL: 'small'
+}
+
+
+export function getColumnSize (size) {
+ if(size === undefined || size === COLUMN_SIZES.STANDARD){
+ return {lg: 9, md: 10, sm: 12}
+ } else if(size === COLUMN_SIZES.LARGE) {
+ return {lg: 12, md: 12, sm: 12}
+ } else if(size === COLUMN_SIZES.SMALL) {
+ return {lg: 7, md: 7, sm: 7}
+ }
+}
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/AWSSetup.scss b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/AWSSetup.scss
new file mode 100644
index 000000000..c1546ac81
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/styles/components/scoutsuite/AWSSetup.scss
@@ -0,0 +1,17 @@
+.aws-scoutsuite-configuration a{
+ display: inline-block;
+ padding: 0 0 3px 0;
+}
+
+.aws-scoutsuite-configuration ol{
+ padding-left: 15px;
+ margin-bottom: 30px;
+}
+
+.aws-scoutsuite-configuration ol.nested-ol{
+ margin-bottom: 0;
+}
+
+.aws-scoutsuite-configuration li{
+ margin-bottom: 5px;
+}
From 2c87784a48c45c33d3c79e7d81024a667a2ccd54 Mon Sep 17 00:00:00 2001
From: VakarisZ
Date: Mon, 21 Sep 2020 11:12:23 +0300
Subject: [PATCH 024/152] Minor typos and improvements on AWS scoutsutie setup
run option
---
.../pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
index 6c184aabd..6fe85936e 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/scoutsuite-setup/AWSSetup.js
@@ -20,7 +20,7 @@ const getContents = (props) => {
return (
ScoutSuite configuration for AWS
-
To assess your AWS infrastructure security do the following:
+
To assess your AWS infrastructure's security do the following:
-
1. Configure AWS CLI on Monkey Island Server (if you already have a configured CLI you can skip this step).
@@ -28,10 +28,10 @@ const getContents = (props) => {
-
1. Download and
- install it on Monkey Island server (machine running this page).
+ install it on the Monkey Island server (machine running this page).
-
- 2. Run aws configure. It's important to configure credentials, which
+ 2. Run
aws configure
. It's important to configure credentials, which
allows ScoutSuite to get information about your cloud configuration. The most trivial way to do so is to
provide