Merge pull request #1699 from guardicore/1669-remove-scoutsuite-integration

Remove scoutsuite
This commit is contained in:
Shreya Malviya 2022-02-09 01:15:30 -08:00 committed by GitHub
commit 5a64db4ce9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
108 changed files with 553 additions and 4012 deletions

View File

@ -42,6 +42,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
- MySQL fingerprinter. #1648
- MS08-067 (Conficker) exploiter. #1677
- Agent bootloader. #1676
- Zero Trust integration with ScoutSuite. #1669
### Fixed
- A bug in network map page that caused delay of telemetry log loading. #1545

View File

@ -4,7 +4,7 @@ date: 2020-07-14T08:09:53+03:00
draft: false
pre: '<i class="fas fa-laptop"></i> '
weight: 10
tags: ["setup", "reference", "windows", "linux"]
tags: ["setup", "reference", "windows", "linux"]
---
The Infection Monkey project supports many popular OSes (but we are always interested in supporting more).

View File

@ -1,67 +0,0 @@
---
title: "Scoutsuite"
date: 2021-03-02T16:23:06+02:00
draft: false
description: "Scout Suite is an open-source cloud security-auditing tool."
weight: 10
---
### About ScoutSuite
<a href="https://github.com/nccgroup/ScoutSuite" target="_blank" >Scout Suite</a> is an open-source cloud security-auditing tool.
It queries the cloud API to gather configuration data. Based on configuration
data gathered, ScoutSuite shows security issues and risks present in your infrastructure.
### Supported cloud providers
Currently, ScoutSuite integration only supports AWS environments.
### Enabling ScoutSuite
First, Infection Monkey needs access to your cloud API. You can provide access
in the following ways:
- Provide access keys:
- Create a new user with ReadOnlyAccess and SecurityAudit policies and generate keys
- Generate keys for your current user (faster but less secure)
- Configure AWS CLI:
- If the command-line interface is available on the Island, it will be used to access
the cloud API
More details about configuring ScoutSuite can be found in the tool itself, by choosing
"Cloud Security Scan" in the "Run Monkey" options.
![Cloud scan option in run page](/images/usage/integrations/scoutsuite_run_page.png
"Successful setup indicator")
After you're done with the setup, make sure that a checkmark appears next to the AWS option. This
verifies that ScoutSuite can access the API.
![Successfull setup indicator](/images/usage/integrations/scoutsuite_aws_configured.png
"Successful setup indicator")
### Running a cloud security scan
If you have successfully configured the cloud scan, Infection Monkey will scan
your cloud infrastructure when the Monkey Agent is run **on the Island**. You
can simply click on "From Island" in the run options to start the scan. The
scope of the network scan and other activities you may have configured the Agent
to perform are ignored by the ScoutSuite integration, except **Monkey
Configuration -> System info collectors -> AWS collector**, which needs to
remain **enabled**.
### Assessing scan results
After the scan is done, ScoutSuite results will be categorized according to the
ZeroTrust Extended framework and displayed as a part of the ZeroTrust report.
The main difference between Infection Monkey findings and ScoutSuite findings
is that ScoutSuite findings contain security rules. To see which rules were
checked, click on the "Rules" button next to the relevant test. You'll see a
list of rule dropdowns that are color coded according to their status. Expand a
rule to see its description, remediation and more details about resources
flagged. Each flagged resource has a path so you can easily locate it in the
cloud and remediate the issue.
![Open ScoutSuite rule](/images/usage/integrations/scoutsuite_report_rule.png
"Successful setup indicator")

View File

@ -11,8 +11,6 @@ weight: 1
Want to assess your progress in achieving a Zero Trust network? The Infection Monkey can automatically evaluate your readiness across the different
[Zero Trust Extended Framework](https://www.forrester.com/report/The+Zero+Trust+eXtended+ZTX+Ecosystem/-/E-RES137210) principles.
You can additionally scan your cloud infrastructure's compliance to ZeroTrust principles using [ScoutSuite integration.]({{< ref "/usage/integrations/scoutsuite" >}})
## Configuration
- **Exploits -> Credentials** This configuration value will be used for brute-forcing. The Infection Monkey uses the most popular default passwords and usernames, but feel free to adjust it according to the default passwords common in your network. Keep in mind a longer list means longer scanning times.

View File

@ -1,5 +0,0 @@
from enum import Enum
class CloudProviders(Enum):
AWS = "aws"

View File

@ -1,4 +1,5 @@
import logging
import time
from common.cloud.aws.aws_service import AwsService
from common.cmd.aws.aws_cmd_result import AwsCmdResult
@ -20,6 +21,7 @@ class AwsCmdRunner(CmdRunner):
self.ssm = AwsService.get_client("ssm", region)
def query_command(self, command_id):
time.sleep(2)
return self.ssm.get_command_invocation(CommandId=command_id, InstanceId=self.instance_id)
def get_command_result(self, command_info):

View File

@ -2,7 +2,6 @@ class TelemCategoryEnum:
EXPLOIT = "exploit"
POST_BREACH = "post_breach"
SCAN = "scan"
SCOUTSUITE = "scoutsuite"
STATE = "state"
SYSTEM_INFO = "system_info"
TRACE = "trace"

View File

@ -41,13 +41,6 @@ TEST_MALICIOUS_ACTIVITY_TIMELINE = "malicious_activity_timeline"
TEST_SEGMENTATION = "segmentation"
TEST_TUNNELING = "tunneling"
TEST_COMMUNICATE_AS_BACKDOOR_USER = "communicate_as_backdoor_user"
TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES = "scoutsuite_permissive_firewall_rules"
TEST_SCOUTSUITE_UNENCRYPTED_DATA = "scoutsuite_unencrypted_data"
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION = "scoutsuite_data_loss_prevention"
TEST_SCOUTSUITE_SECURE_AUTHENTICATION = "scoutsuite_secure_authentication"
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES = "scoutsuite_unrestrictive_policies"
TEST_SCOUTSUITE_LOGGING = "scoutsuite_logging"
TEST_SCOUTSUITE_SERVICE_SECURITY = "scoutsuite_service_security"
TESTS = (
TEST_SEGMENTATION,
@ -59,13 +52,6 @@ TESTS = (
TEST_DATA_ENDPOINT_ELASTIC,
TEST_TUNNELING,
TEST_COMMUNICATE_AS_BACKDOOR_USER,
TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES,
TEST_SCOUTSUITE_UNENCRYPTED_DATA,
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION,
TEST_SCOUTSUITE_SECURE_AUTHENTICATION,
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES,
TEST_SCOUTSUITE_LOGGING,
TEST_SCOUTSUITE_SERVICE_SECURITY,
)
PRINCIPLE_DATA_CONFIDENTIALITY = "data_transit"
@ -219,77 +205,6 @@ 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],
},
TEST_SCOUTSUITE_UNENCRYPTED_DATA: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for resources containing " "unencrypted data.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found resources with unencrypted data.",
STATUS_PASSED: "ScoutSuite found no resources with unencrypted data.",
},
PRINCIPLE_KEY: PRINCIPLE_DATA_CONFIDENTIALITY,
PILLARS_KEY: [DATA],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for resources which are not "
"protected against data loss.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found resources not protected against data loss.",
STATUS_PASSED: "ScoutSuite found that all resources are secured against data loss.",
},
PRINCIPLE_KEY: PRINCIPLE_DISASTER_RECOVERY,
PILLARS_KEY: [DATA],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_SECURE_AUTHENTICATION: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for issues related to users' " "authentication.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found issues related to users' authentication.",
STATUS_PASSED: "ScoutSuite found no issues related to users' authentication.",
},
PRINCIPLE_KEY: PRINCIPLE_SECURE_AUTHENTICATION,
PILLARS_KEY: [PEOPLE, WORKLOADS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for permissive user access " "policies.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found permissive user access policies.",
STATUS_PASSED: "ScoutSuite found no issues related to user access policies.",
},
PRINCIPLE_KEY: PRINCIPLE_USERS_MAC_POLICIES,
PILLARS_KEY: [PEOPLE, WORKLOADS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_LOGGING: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for issues, related to logging.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found logging issues.",
STATUS_PASSED: "ScoutSuite found no logging issues.",
},
PRINCIPLE_KEY: PRINCIPLE_MONITORING_AND_LOGGING,
PILLARS_KEY: [AUTOMATION_ORCHESTRATION, VISIBILITY_ANALYTICS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_SERVICE_SECURITY: {
TEST_EXPLANATION_KEY: "ScoutSuite searched for service security issues.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found service security issues.",
STATUS_PASSED: "ScoutSuite found no service security issues.",
},
PRINCIPLE_KEY: PRINCIPLE_MONITORING_AND_LOGGING,
PILLARS_KEY: [DEVICES, NETWORKS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
}
EVENT_TYPE_MONKEY_NETWORK = "monkey_network"

View File

@ -3,19 +3,6 @@ from typing import Optional, Tuple
from urllib.parse import urlparse
def get_host_from_network_location(network_location: str) -> str:
"""
URL structure is "<scheme>://<net_loc>/<path>;<params>?<query>#<fragment>" (
https://tools.ietf.org/html/rfc1808.html)
And the net_loc is "<user>:<password>@<host>:<port>" (
https://tools.ietf.org/html/rfc1738#section-3.1)
:param network_location: server network location
:return: host part of the network location
"""
url = urlparse("http://" + network_location)
return str(url.hostname)
def remove_port(url):
parsed = urlparse(url)
with_port = f"{parsed.scheme}://{parsed.netloc}"

View File

@ -22,10 +22,6 @@ class IncorrectCredentialsError(Exception):
""" Raise to indicate that authentication failed """
class RulePathCreatorNotFound(Exception):
""" Raise to indicate that ScoutSuite rule doesn't have a path creator"""
class InvalidAWSKeys(Exception):
""" Raise to indicate that AWS API keys are invalid"""
@ -34,10 +30,6 @@ class NoInternetError(Exception):
""" Raise to indicate problems caused when no internet connection is present"""
class ScoutSuiteScanError(Exception):
""" Raise to indicate problems ScoutSuite encountered during scanning"""
class UnknownFindingError(Exception):
""" Raise when provided finding is of unknown type"""

View File

@ -18,7 +18,6 @@ pypykatz = "==0.3.12"
requests = ">=2.24"
urllib3 = "==1.26.5"
WMI = {version = "==1.5.1", sys_platform = "== 'win32'"}
ScoutSuite = {git = "git://github.com/guardicode/ScoutSuite"}
pyopenssl = "==19.0.0" # We can't build 32bit ubuntu12 binary with newer versions of pyopenssl
pypsrp = "*"
typing-extensions = "*" # Allows us to use 3.9 typing features on 3.7 project

View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "250fc3013e7083083999fbf289f8898d63ceffc95a02e87920d254950832ea68"
"sha256": "90dbc7b9edaacc7324c3e1cc9ab1bd618dd62951216cf993225937b20f657779"
},
"pipfile-spec": 6,
"requires": {
@ -38,20 +38,13 @@
],
"version": "==1.4.0"
},
"asyncio-throttle": {
"hashes": [
"sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe"
],
"markers": "python_version >= '3.5'",
"version": "==0.1.1"
},
"asysocks": {
"hashes": [
"sha256:5ec0582252b0085d9337d13c6b03ab7fd062e487070667f9140e6972bd9db256",
"sha256:b97ac905cd4ca1e7a8e7c295f9cb22ced5dfd3f17e888e71cbf05a1d67a4d393"
"sha256:23d5fcfae71a75826c3ed787bd9b1bc3b189ec37658961bce83c9e99455e354c",
"sha256:731eda25d41783c5243153d3cb4f9357fef337c7317135488afab9ecd6b7f1a1"
],
"markers": "python_version >= '3.6'",
"version": "==0.1.6"
"version": "==0.1.7"
},
"attrs": {
"hashes": [
@ -84,22 +77,6 @@
"markers": "python_version >= '3.6'",
"version": "==3.2.0"
},
"boto3": {
"hashes": [
"sha256:1903e4462b08f7696a8d0977361fe9e35e7a50d9e70d7abd72a3a17012741938",
"sha256:34e5ae33ef65b1c4e2e197009e88df5dc217386699939ae897d7fcdb5a6ff295"
],
"markers": "python_version >= '3.6'",
"version": "==1.20.47"
},
"botocore": {
"hashes": [
"sha256:82da38e309bd6fd6303394e6e9d1ea50626746f2911e3fec996f9046c5d85085",
"sha256:a89b1be0a7f235533d8279d90b0b15dc2130d0552a9f7654ba302b564ab5688a"
],
"markers": "python_version >= '3.6'",
"version": "==1.23.47"
},
"certifi": {
"hashes": [
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
@ -178,30 +155,6 @@
"markers": "python_version >= '3'",
"version": "==2.0.11"
},
"cheroot": {
"hashes": [
"sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25",
"sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==8.6.0"
},
"cherrypy": {
"hashes": [
"sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038",
"sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495"
],
"markers": "python_version >= '3.5'",
"version": "==18.6.1"
},
"cherrypy-cors": {
"hashes": [
"sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5",
"sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513"
],
"markers": "python_version >= '2.7'",
"version": "==1.6"
},
"click": {
"hashes": [
"sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3",
@ -210,12 +163,13 @@
"markers": "python_version >= '3.6'",
"version": "==8.0.3"
},
"coloredlogs": {
"colorama": {
"hashes": [
"sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8",
"sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36"
"sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
"sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"
],
"version": "==10.0"
"markers": "platform_system == 'Windows'",
"version": "==0.4.4"
},
"constantly": {
"hashes": [
@ -272,20 +226,6 @@
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.18.2"
},
"httpagentparser": {
"hashes": [
"sha256:a190dfdc5e63b2f1c87729424b19cbc49263d6a1fb585a16ac1c9d9ce127a4bf"
],
"version": "==1.9.2"
},
"humanfriendly": {
"hashes": [
"sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477",
"sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==10.0"
},
"hyperlink": {
"hashes": [
"sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
@ -316,14 +256,6 @@
"markers": "python_version < '3.8'",
"version": "==4.10.1"
},
"importlib-resources": {
"hashes": [
"sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45",
"sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b"
],
"markers": "python_version < '3.9'",
"version": "==5.4.0"
},
"incremental": {
"hashes": [
"sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57",
@ -347,46 +279,6 @@
"markers": "python_version >= '3.6'",
"version": "==2.0.1"
},
"jaraco.classes": {
"hashes": [
"sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d",
"sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34"
],
"markers": "python_version >= '3.6'",
"version": "==3.2.1"
},
"jaraco.collections": {
"hashes": [
"sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88",
"sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70"
],
"markers": "python_version >= '3.7'",
"version": "==3.5.1"
},
"jaraco.context": {
"hashes": [
"sha256:17b909da2fb37ad237ca7ff9523977f8665a47a25b90aec6a99a3e0959c86141",
"sha256:f0d4d82ffbbbff680384eba48a32a3167f12a91a30a7db56fd97b87e73a87241"
],
"markers": "python_version >= '3.6'",
"version": "==4.1.1"
},
"jaraco.functools": {
"hashes": [
"sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa",
"sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0"
],
"markers": "python_version >= '3.7'",
"version": "==3.5.0"
},
"jaraco.text": {
"hashes": [
"sha256:17b43aa0bd46e97c368ccd8a4c8fef2719ca121b6d39ce4be9d9e0143832479a",
"sha256:a7f9cc1b44a5f3096a216cbd130b650c7a6b2c9f8005b000ae97f329239a7c00"
],
"markers": "python_version >= '3.6'",
"version": "==3.7.0"
},
"jinja2": {
"hashes": [
"sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8",
@ -395,14 +287,6 @@
"markers": "python_version >= '3.6'",
"version": "==3.0.3"
},
"jmespath": {
"hashes": [
"sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9",
"sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.0"
},
"ldap3": {
"hashes": [
"sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6",
@ -514,19 +398,11 @@
},
"minikerberos": {
"hashes": [
"sha256:eba89d5c649241a3367839ebd1c0333b9a9e4fe514746e246a6a1f2cb7bde26e",
"sha256:f556a6015904147c3302e9038b49f766c975df6aeb1725027cd7fc68ba993864"
"sha256:a1596916c93910910e65ab43e2b0e770c9af0d2da77505c089ed8bc3ee40e872",
"sha256:ca83d44f0a6c93cc2298df435c5173e99262d6d234b8055c7c08b9062c2c7c93"
],
"markers": "python_version >= '3.6'",
"version": "==0.2.16"
},
"more-itertools": {
"hashes": [
"sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b",
"sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"
],
"markers": "python_version >= '3.5'",
"version": "==8.12.0"
"version": "==0.2.17"
},
"msldap": {
"hashes": [
@ -536,13 +412,6 @@
"markers": "python_version >= '3.7'",
"version": "==0.3.30"
},
"netaddr": {
"hashes": [
"sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac",
"sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"
],
"version": "==0.8.0"
},
"netifaces": {
"hashes": [
"sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32",
@ -608,28 +477,20 @@
],
"version": "==1.7.4"
},
"policyuniverse": {
"pefile": {
"hashes": [
"sha256:116b808554d7ea75efc97b4cb904085546db45934ef315175cb4755c7a4489de",
"sha256:7440ac520bb791e0318e3d99f9b0e76b7b2b604e7160f1d8341ded060f9ff1cd"
"sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"
],
"version": "==1.4.0.20220110"
},
"portend": {
"hashes": [
"sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4",
"sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61"
],
"markers": "python_version >= '3.7'",
"version": "==3.1.0"
"markers": "sys_platform == 'win32'",
"version": "==2021.9.3"
},
"prompt-toolkit": {
"hashes": [
"sha256:4bcf119be2200c17ed0d518872ef922f1de336eb6d1ddbd1e089ceb6447d97c6",
"sha256:a51d41a6a45fd9def54365bca8f0402c8f182f2b6f7e29c74d55faeb9fb38ac4"
"sha256:cb7dae7d2c59188c85a1d6c944fad19aded6a26bd9c8ae115a4e1c20eb90b713",
"sha256:f2b6a8067a4fb959d3677d1ed764cc4e63e0f6f565b9a4fc7edc2b18bf80217b"
],
"markers": "python_full_version >= '3.6.2'",
"version": "==3.0.26"
"version": "==3.0.27"
},
"psutil": {
"hashes": [
@ -715,39 +576,36 @@
},
"pycryptodomex": {
"hashes": [
"sha256:00eb17ee2b8eb9d84df37d54bc7070ff45903b90535558c2e0ddb5e6957521d3",
"sha256:05b36726ce5521ce0feb25ea11e866261089edd7fad44df4ced9f7f45a9d4c3b",
"sha256:110b319189915a66d14df13d233a2dbb54f00df21f3167de1cad340bf4dd88bd",
"sha256:15e6f5b4a81109eb8e9a02c954fe119f6c57836fd55a9891ba703ddfbd690587",
"sha256:1b07a13ed73d00a97af7c3733b807007d2249cd236a33955a7dec1939c232b28",
"sha256:2040a22a30780da743835c7c71307558688065d6c22e18ac3e44082dc3323d8f",
"sha256:264a701bb6e8aedf4b71bcb9eb83b93020041e96112ccfe873a16964d41ade74",
"sha256:2d8bda8f949b79b78b293706aa7fc1e5c171c62661252bfdd5d12c70acd03282",
"sha256:2e2da1eabb426cbeb4922c981bb843f36427f8365ef7e46bc581a55d7ea67643",
"sha256:3ad75e24a0e25396901273a9a2aaba0286fa74703e5b61731942f6914a1e1cbe",
"sha256:3c06abf17c68cf87c4e81e1745f0afbe4427413684a122a9d044a8a1d3c6d959",
"sha256:3c195eecd43e48d0a06267df6945958f5f566eef160a5b01c519434cfa6d368a",
"sha256:3c9ee5e77dd9cb19fe09765b6c02e3784cdbd2e5ecfbc67c8e9628073f79b981",
"sha256:484ad0f50fd49bec4d2b8c0e5a3ad70e278ed3390bfd5c4515dc896f31b45d6c",
"sha256:4b046c3d50fe4bb57386567ff47a588b1bbe1ddf3d9e2b23aede09fa97511f5f",
"sha256:50684f16b12f1dcca8018d2711fb87044c74038ce9322d36f6ee9d09fcda7e6f",
"sha256:6940b6730bab7128c993b562abf018560aa5b861da92854cf050b5f96d4713df",
"sha256:76fe9ad943480507952cd7c96c20f6c8af78145f944cb66bbba63f2872d9988e",
"sha256:7bcc5d3904abe5cfac5acc67679e330b0402473e839f94b59e13efdc2c2945d5",
"sha256:8310782ac84fa1df93703081af6791549451a380ad88670c2484f75e26c6485f",
"sha256:88eb239d6af71ba2098a4cfea516add37881d55b76b38d9e297f77a65bb9a8cf",
"sha256:9afea78c31f3714b06673d2c5b8874f31c19c03258645733546a320da2e6df23",
"sha256:a11884621c2a5fe241ccf2adf34e4fdde162e91fbc3207f0a0db122ad2b7a061",
"sha256:b0277a201196b7825b21a405e0a70167f277b8d5666031e65c9af7a715cb0833",
"sha256:b5ff95687c4008f76091849e5333692e6a54a93399cd8fda7e1ba523734136f4",
"sha256:c565b89fb91ecb60273b2dcedb5149b48a1ec4227cef8c63fd77ec0f33eaf75a",
"sha256:d689b368ca8b3ec1e60cc609eae14d4e352d10fe807ca9906f77f0712ab05a37",
"sha256:f3bb1e722ad57de1999c8db54b58507b47771de4a294115c00f785f1d5913ec1",
"sha256:fbff384c2080106b3f5f7cfa96728f02e627be7f7cd1657d9cf63300a16d0864",
"sha256:fd2657134b633523db551b96b095387083a459d77e93b9cc888c9f13edb7a6f6"
"sha256:1ca8e1b4c62038bb2da55451385246f51f412c5f5eabd64812c01766a5989b4a",
"sha256:298c00ea41a81a491d5b244d295d18369e5aac4b61b77b2de5b249ca61cd6659",
"sha256:2aa887683eee493e015545bd69d3d21ac8d5ad582674ec98f4af84511e353e45",
"sha256:2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2",
"sha256:3da13c2535b7aea94cc2a6d1b1b37746814c74b6e80790daddd55ca5c120a489",
"sha256:406ec8cfe0c098fadb18d597dc2ee6de4428d640c0ccafa453f3d9b2e58d29e2",
"sha256:4d0db8df9ffae36f416897ad184608d9d7a8c2b46c4612c6bc759b26c073f750",
"sha256:530756d2faa40af4c1f74123e1d889bd07feae45bac2fd32f259a35f7aa74151",
"sha256:77931df40bb5ce5e13f4de2bfc982b2ddc0198971fbd947776c8bb5050896eb2",
"sha256:797a36bd1f69df9e2798e33edb4bd04e5a30478efc08f9428c087f17f65a7045",
"sha256:8085bd0ad2034352eee4d4f3e2da985c2749cb7344b939f4d95ead38c2520859",
"sha256:8536bc08d130cae6dcba1ea689f2913dfd332d06113904d171f2f56da6228e89",
"sha256:a4d412eba5679ede84b41dbe48b1bed8f33131ab9db06c238a235334733acc5e",
"sha256:aebecde2adc4a6847094d3bd6a8a9538ef3438a5ea84ac1983fcb167db614461",
"sha256:b276cc4deb4a80f9dfd47a41ebb464b1fe91efd8b1b8620cf5ccf8b824b850d6",
"sha256:b5a185ae79f899b01ca49f365bdf15a45d78d9856f09b0de1a41b92afce1a07f",
"sha256:c4d8977ccda886d88dc3ca789de2f1adc714df912ff3934b3d0a3f3d777deafb",
"sha256:c5dd3ffa663c982d7f1be9eb494a8924f6d40e2e2f7d1d27384cfab1b2ac0662",
"sha256:ca88f2f7020002638276439a01ffbb0355634907d1aa5ca91f3dc0c2e44e8f3b",
"sha256:d2cce1c82a7845d7e2e8a0956c6b7ed3f1661c9acf18eb120fc71e098ab5c6fe",
"sha256:d709572d64825d8d59ea112e11cc7faf6007f294e9951324b7574af4251e4de8",
"sha256:da8db8374295fb532b4b0c467e66800ef17d100e4d5faa2bbbd6df35502da125",
"sha256:e36c7e3b5382cd5669cf199c4a04a0279a43b2a3bdd77627e9b89778ac9ec08c",
"sha256:e95a4a6c54d27a84a4624d2af8bb9ee178111604653194ca6880c98dcad92f48",
"sha256:ee835def05622e0c8b1435a906491760a43d0c462f065ec9143ec4b8d79f8bff",
"sha256:f75009715dcf4a3d680c2338ab19dac5498f8121173a929872950f4fb3a48fbf",
"sha256:f8524b8bc89470cec7ac51734907818d3620fb1637f8f8b542d650ebec42a126"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==3.14.0"
"version": "==3.14.1"
},
"pyinstaller": {
"hashes": [
@ -871,20 +729,30 @@
"markers": "python_version >= '3.6'",
"version": "==0.3.1"
},
"python-dateutil": {
"pywin32": {
"hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
"sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559",
"sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51",
"sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b",
"sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb",
"sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba",
"sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34",
"sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352",
"sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9",
"sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e",
"sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca",
"sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee",
"sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.8.0"
"version": "==303"
},
"pytz": {
"pywin32-ctypes": {
"hashes": [
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c",
"sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
],
"version": "==2021.3"
"markers": "sys_platform == 'win32'",
"version": "==0.2.0"
},
"requests": {
"hashes": [
@ -894,18 +762,6 @@
"index": "pypi",
"version": "==2.27.1"
},
"s3transfer": {
"hashes": [
"sha256:25c140f5c66aa79e1ac60be50dcd45ddc59e83895f062a3aab263b870102911f",
"sha256:69d264d3e760e569b78aaa0f22c97e955891cd22e32b10c51f784eeda4d9d10a"
],
"markers": "python_version >= '3.6'",
"version": "==0.5.1"
},
"scoutsuite": {
"git": "git://github.com/guardicode/ScoutSuite",
"ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003"
},
"service-identity": {
"hashes": [
"sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34",
@ -929,20 +785,6 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0"
},
"sqlitedict": {
"hashes": [
"sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56"
],
"version": "==1.7.0"
},
"tempora": {
"hashes": [
"sha256:cba0f197a64883bf3e73657efbc0324d5bf17179e7769b1385b4d75d26cd9127",
"sha256:fbca6a229af666ea4ea8b2f9f80ac9a074f7cf53a97987855b1d15b6e93fd63b"
],
"markers": "python_version >= '3.7'",
"version": "==5.0.1"
},
"tqdm": {
"hashes": [
"sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c",
@ -956,11 +798,29 @@
"tls"
],
"hashes": [
"sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b",
"sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006"
"sha256:b7971ec9805b0f80e1dcb1a3721d7bfad636d5f909de687430ce373979d67b61",
"sha256:ccd638110d9ccfdc003042aa3e1b6d6af272eaca45d36e083359560549e3e848"
],
"markers": "python_full_version >= '3.6.7'",
"version": "==21.7.0"
"version": "==22.1.0"
},
"twisted-iocpsupport": {
"hashes": [
"sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41",
"sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d",
"sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9",
"sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf",
"sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323",
"sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32",
"sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4",
"sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f",
"sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546",
"sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878",
"sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565",
"sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415"
],
"markers": "platform_system == 'Windows'",
"version": "==1.0.2"
},
"typing-extensions": {
"hashes": [
@ -987,11 +847,11 @@
},
"werkzeug": {
"hashes": [
"sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f",
"sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"
"sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8",
"sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"
],
"markers": "python_version >= '3.6'",
"version": "==2.0.2"
"version": "==2.0.3"
},
"winacl": {
"hashes": [
@ -1021,16 +881,10 @@
"sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942",
"sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6"
],
"index": "pypi",
"markers": "sys_platform == 'win32'",
"version": "==1.5.1"
},
"zc.lockfile": {
"hashes": [
"sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b",
"sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f"
],
"version": "==2.0"
},
"zipp": {
"hashes": [
"sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d",

View File

@ -5,13 +5,10 @@ import sys
from PyInstaller.utils.hooks import collect_data_files
block_cipher = None
def main():
print(collect_data_files('policyuniverse'))
a = Analysis(['main.py'],
pathex=['..'],
hiddenimports=get_hidden_imports(),

View File

@ -4,9 +4,7 @@ import socket
import struct
import sys
from common.network.network_utils import get_host_from_network_location
from infection_monkey.config import WormConfiguration
from infection_monkey.network.info import get_routes, local_ips
from infection_monkey.network.info import get_routes
DEFAULT_TIMEOUT = 10
BANNER_READ = 1024
@ -117,13 +115,3 @@ def get_interface_to_target(dst):
paths.sort()
ret = paths[-1][1]
return ret[1]
def is_running_on_island():
current_server_without_port = get_host_from_network_location(WormConfiguration.current_server)
running_on_island = is_running_on_server(current_server_without_port)
return running_on_island and WormConfiguration.depth == WormConfiguration.max_depth
def is_running_on_server(ip: str) -> bool:
return ip in local_ips()

View File

@ -1,12 +1,7 @@
import logging
from common.cloud.aws.aws_instance import AwsInstance
from common.cloud.scoutsuite_consts import CloudProviders
from common.common_consts.system_info_collectors_names import AWS_COLLECTOR
from infection_monkey.network.tools import is_running_on_island
from infection_monkey.system_info.collectors.scoutsuite_collector.scoutsuite_collector import (
scan_cloud_security,
)
from infection_monkey.system_info.system_info_collector import SystemInfoCollector
logger = logging.getLogger(__name__)
@ -22,11 +17,6 @@ class AwsCollector(SystemInfoCollector):
def collect(self) -> dict:
logger.info("Collecting AWS info")
if is_running_on_island():
logger.info("Attempting to scan AWS security with ScoutSuite.")
scan_cloud_security(cloud_type=CloudProviders.AWS)
else:
logger.info("Didn't scan AWS security with ScoutSuite, because not on island.")
aws = AwsInstance()
info = {}
if aws.is_instance():

View File

@ -1,35 +0,0 @@
import logging
from typing import Union
import ScoutSuite.api_run
from ScoutSuite.providers.base.provider import BaseProvider
from common.cloud.scoutsuite_consts import CloudProviders
from common.utils.exceptions import ScoutSuiteScanError
from infection_monkey.config import WormConfiguration
from infection_monkey.telemetry.scoutsuite_telem import ScoutSuiteTelem
logger = logging.getLogger(__name__)
def scan_cloud_security(cloud_type: CloudProviders):
try:
results = run_scoutsuite(cloud_type.value)
if isinstance(results, dict) and "error" in results and results["error"]:
raise ScoutSuiteScanError(results["error"])
send_scoutsuite_run_results(results)
except (Exception, ScoutSuiteScanError) as e:
logger.error(f"ScoutSuite didn't scan {cloud_type.value} security because: {e}")
def run_scoutsuite(cloud_type: str) -> Union[BaseProvider, dict]:
return ScoutSuite.api_run.run(
provider=cloud_type,
aws_access_key_id=WormConfiguration.aws_access_key_id,
aws_secret_access_key=WormConfiguration.aws_secret_access_key,
aws_session_token=WormConfiguration.aws_session_token,
)
def send_scoutsuite_run_results(run_results: BaseProvider):
ScoutSuiteTelem(run_results).send()

View File

@ -1,17 +0,0 @@
from ScoutSuite.output.result_encoder import ScoutJsonEncoder
from ScoutSuite.providers.base.provider import BaseProvider
from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
class ScoutSuiteTelem(BaseTelem):
def __init__(self, provider: BaseProvider):
super().__init__()
self.provider_data = provider
json_encoder = ScoutJsonEncoder
telem_category = TelemCategoryEnum.SCOUTSUITE
def get_data(self):
return {"data": self.provider_data}

View File

@ -22,7 +22,6 @@ Flask-PyMongo = ">=2.3.0"
Flask-RESTful = ">=0.3.8"
Flask = ">=1.1"
Werkzeug = ">=1.0.1"
ScoutSuite = {git = "https://github.com/guardicode/ScoutSuite"}
pyaescrypt = "*"
python-dateutil = "*"
cffi = "*" # Without explicit install: ModuleNotFoundError: No module named '_cffi_backend'

File diff suppressed because it is too large Load Diff

View File

@ -46,8 +46,6 @@ from monkey_island.cc.resources.telemetry import Telemetry
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
from monkey_island.cc.resources.version_update import VersionUpdate
from monkey_island.cc.resources.zero_trust.finding_event import ZeroTrustFindingEvent
from monkey_island.cc.resources.zero_trust.scoutsuite_auth.aws_keys import AWSKeys
from monkey_island.cc.resources.zero_trust.scoutsuite_auth.scoutsuite_auth import ScoutSuiteAuth
from monkey_island.cc.resources.zero_trust.zero_trust_report import ZeroTrustReport
from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.server_utils.custom_json_encoder import CustomJSONEncoder
@ -168,8 +166,6 @@ def init_api_resources(api):
api.add_resource(VersionUpdate, "/api/version-update")
api.add_resource(StopAgentCheck, "/api/monkey_control/needs-to-stop/<int:monkey_guid>")
api.add_resource(StopAllAgents, "/api/monkey_control/stop-all-agents")
api.add_resource(ScoutSuiteAuth, "/api/scoutsuite_auth/<string:provider>")
api.add_resource(AWSKeys, "/api/aws_keys")
# Resources used by black box tests
api.add_resource(MonkeyBlackboxEndpoint, "/api/test/monkey")

View File

@ -1,20 +0,0 @@
from mongoengine import Document, DynamicField
class ScoutSuiteRawDataJson(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:
try:
current_data = ScoutSuiteRawDataJson.objects()[0]
except IndexError:
current_data = ScoutSuiteRawDataJson()
current_data.scoutsuite_data = scoutsuite_data
current_data.save()

View File

@ -1,20 +0,0 @@
from __future__ import annotations
from mongoengine import LazyReferenceField
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
class ScoutSuiteFinding(Finding):
# We put additional info into a lazy reference field, because this info should be only
# pulled when explicitly needed due to performance
details = LazyReferenceField(ScoutSuiteFindingDetails, required=True)
@staticmethod
def save_finding(
test: str, status: str, detail_ref: ScoutSuiteFindingDetails
) -> ScoutSuiteFinding:
finding = ScoutSuiteFinding(test=test, status=status, details=detail_ref)
finding.save()
return finding

View File

@ -1,13 +0,0 @@
from mongoengine import Document, EmbeddedDocumentListField
from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
class ScoutSuiteFindingDetails(Document):
# SCHEMA
scoutsuite_rules = EmbeddedDocumentListField(document_type=ScoutSuiteRule, required=False)
def add_rule(self, rule: ScoutSuiteRule) -> None:
if rule not in self.scoutsuite_rules:
self.scoutsuite_rules.append(rule)
self.save()

View File

@ -1,25 +0,0 @@
from mongoengine import DynamicField, EmbeddedDocument, IntField, ListField, StringField
from monkey_island.cc.services.zero_trust.scoutsuite.consts import rule_consts
class ScoutSuiteRule(EmbeddedDocument):
"""
This model represents ScoutSuite security rule check results:
how many resources break the security rule
security rule description and remediation and etc.
"""
# 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 = DynamicField(required=False)
references = ListField(required=False)

View File

@ -1,10 +0,0 @@
import flask_restful
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_auth_service import get_aws_keys
class AWSKeys(flask_restful.Resource):
@jwt_required
def get(self):
return get_aws_keys()

View File

@ -1,37 +0,0 @@
import json
import flask_restful
from flask import request
from common.cloud.scoutsuite_consts import CloudProviders
from common.utils.exceptions import InvalidAWSKeys
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_auth_service import (
is_cloud_authentication_setup,
set_aws_keys,
)
class ScoutSuiteAuth(flask_restful.Resource):
@jwt_required
def get(self, provider: CloudProviders):
if provider == CloudProviders.AWS.value:
is_setup, message = is_cloud_authentication_setup(provider)
return {"is_setup": is_setup, "message": message}
else:
return {"is_setup": False, "message": ""}
@jwt_required
def post(self, provider: CloudProviders):
key_info = json.loads(request.data)
error_msg = ""
if provider == CloudProviders.AWS.value:
try:
set_aws_keys(
access_key_id=key_info["accessKeyId"],
secret_access_key=key_info["secretAccessKey"],
session_token=key_info["sessionToken"],
)
except InvalidAWSKeys as e:
error_msg = str(e)
return {"error_msg": error_msg}

View File

@ -1,7 +1,7 @@
import http.client
import flask_restful
from flask import Response, jsonify
from flask import jsonify
from monkey_island.cc.resources.auth.auth import jwt_required
from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService
@ -9,14 +9,10 @@ from monkey_island.cc.services.zero_trust.zero_trust_report.pillar_service impor
from monkey_island.cc.services.zero_trust.zero_trust_report.principle_service import (
PrincipleService,
)
from monkey_island.cc.services.zero_trust.zero_trust_report.scoutsuite_raw_data_service import (
ScoutSuiteRawDataService,
)
REPORT_DATA_PILLARS = "pillars"
REPORT_DATA_FINDINGS = "findings"
REPORT_DATA_PRINCIPLES_STATUS = "principles"
REPORT_DATA_SCOUTSUITE = "scoutsuite"
class ZeroTrustReport(flask_restful.Resource):
@ -28,10 +24,5 @@ class ZeroTrustReport(flask_restful.Resource):
return jsonify(PrincipleService.get_principles_status())
elif report_data == REPORT_DATA_FINDINGS:
return jsonify(FindingService.get_all_findings_for_ui())
elif report_data == REPORT_DATA_SCOUTSUITE:
# Raw ScoutSuite data is already solved as json, no need to jsonify
return Response(
ScoutSuiteRawDataService.get_scoutsuite_data_json(), mimetype="application/json"
)
flask_restful.abort(http.client.NOT_FOUND)

View File

@ -4,7 +4,6 @@ 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 process_post_breach_telemetry
from monkey_island.cc.services.telemetry.processing.scan import process_scan_telemetry
from monkey_island.cc.services.telemetry.processing.scoutsuite import process_scoutsuite_telemetry
from monkey_island.cc.services.telemetry.processing.state import process_state_telemetry
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
@ -18,7 +17,6 @@ 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,

View File

@ -1,38 +0,0 @@
import json
from monkey_island.cc.database import mongo
from monkey_island.cc.models.zero_trust.scoutsuite_data_json import ScoutSuiteRawDataJson
from monkey_island.cc.services.zero_trust.scoutsuite.consts.scoutsuite_findings_list import (
SCOUTSUITE_FINDINGS,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICES
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_parser import RuleParser
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import (
ScoutSuiteRuleService,
)
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_zt_finding_service import (
ScoutSuiteZTFindingService,
)
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"])
ScoutSuiteRawDataJson.add_scoutsuite_data(telemetry_json["data"])
scoutsuite_data = json.loads(telemetry_json["data"])["data"]
create_scoutsuite_findings(scoutsuite_data[SERVICES])
update_data(telemetry_json)
def create_scoutsuite_findings(cloud_services: dict):
for finding in SCOUTSUITE_FINDINGS:
for rule in finding.rules:
rule_data = RuleParser.get_rule_data(cloud_services, rule)
rule = ScoutSuiteRuleService.get_rule_from_rule_data(rule_data)
ScoutSuiteZTFindingService.process_rule(finding, rule)
def update_data(telemetry_json):
mongo.db.scoutsuite.insert_one(
{"guid": telemetry_json["monkey_guid"]}, {"results": telemetry_json["data"]}
)

View File

@ -1,4 +0,0 @@
RULE_LEVEL_DANGER = "danger"
RULE_LEVEL_WARNING = "warning"
RULE_LEVELS = (RULE_LEVEL_DANGER, RULE_LEVEL_WARNING)

View File

@ -1,8 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class CloudformationRules(RuleNameEnum):
# Service Security
CLOUDFORMATION_STACK_WITH_ROLE = "cloudformation-stack-with-role"

View File

@ -1,13 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class CloudTrailRules(RuleNameEnum):
# Logging
CLOUDTRAIL_DUPLICATED_GLOBAL_SERVICES_LOGGING = "cloudtrail-duplicated-global-services-logging"
CLOUDTRAIL_NO_DATA_LOGGING = "cloudtrail-no-data-logging"
CLOUDTRAIL_NO_GLOBAL_SERVICES_LOGGING = "cloudtrail-no-global-services-logging"
CLOUDTRAIL_NO_LOG_FILE_VALIDATION = "cloudtrail-no-log-file-validation"
CLOUDTRAIL_NO_LOGGING = "cloudtrail-no-logging"
CLOUDTRAIL_NOT_CONFIGURED = "cloudtrail-not-configured"

View File

@ -1,8 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class CloudWatchRules(RuleNameEnum):
# Logging
CLOUDWATCH_ALARM_WITHOUT_ACTIONS = "cloudwatch-alarm-without-actions"

View File

@ -1,8 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class ConfigRules(RuleNameEnum):
# Logging
CONFIG_RECORDER_NOT_CONFIGURED = "config-recorder-not-configured"

View File

@ -1,37 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class EC2Rules(RuleNameEnum):
# Permissive firewall rules
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"
EC2_SECURITY_GROUP_WHITELISTS_AWS = "ec2-security-group-whitelists-aws"
# Encryption
EBS_SNAPSHOT_NOT_ENCRYPTED = "ec2-ebs-snapshot-not-encrypted"
EBS_VOLUME_NOT_ENCRYPTED = "ec2-ebs-volume-not-encrypted"
EC2_INSTANCE_WITH_USER_DATA_SECRETS = "ec2-instance-with-user-data-secrets"
# Permissive policies
AMI_PUBLIC = "ec2-ami-public"
EC2_DEFAULT_SECURITY_GROUP_IN_USE = "ec2-default-security-group-in-use"
EC2_DEFAULT_SECURITY_GROUP_WITH_RULES = "ec2-default-security-group-with-rules"
EC2_EBS_SNAPSHOT_PUBLIC = "ec2-ebs-snapshot-public"

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class ELBRules(RuleNameEnum):
# Logging
ELB_NO_ACCESS_LOGS = "elb-no-access-logs"
# Encryption
ELB_LISTENER_ALLOWING_CLEARTEXT = "elb-listener-allowing-cleartext"
ELB_OLDER_SSL_POLICY = "elb-older-ssl-policy"

View File

@ -1,18 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class ELBv2Rules(RuleNameEnum):
# Encryption
ELBV2_LISTENER_ALLOWING_CLEARTEXT = "elbv2-listener-allowing-cleartext"
ELBV2_OLDER_SSL_POLICY = "elbv2-older-ssl-policy"
# Logging
ELBV2_NO_ACCESS_LOGS = "elbv2-no-access-logs"
# Data loss prevention
ELBV2_NO_DELETION_PROTECTION = "elbv2-no-deletion-protection"
# Service security
ELBV2_HTTP_REQUEST_SMUGGLING = "elbv2-http-request-smuggling"

View File

@ -1,41 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class IAMRules(RuleNameEnum):
# Authentication/authorization
IAM_USER_NO_ACTIVE_KEY_ROTATION = "iam-user-no-Active-key-rotation"
IAM_PASSWORD_POLICY_MINIMUM_LENGTH = "iam-password-policy-minimum-length"
IAM_PASSWORD_POLICY_NO_EXPIRATION = "iam-password-policy-no-expiration"
IAM_PASSWORD_POLICY_REUSE_ENABLED = "iam-password-policy-reuse-enabled"
IAM_USER_WITH_PASSWORD_AND_KEY = "iam-user-with-password-and-key"
IAM_ASSUME_ROLE_LACKS_EXTERNAL_ID_AND_MFA = "iam-assume-role-lacks-external-id-and-mfa"
IAM_USER_WITHOUT_MFA = "iam-user-without-mfa"
IAM_ROOT_ACCOUNT_NO_MFA = "iam-root-account-no-mfa"
IAM_ROOT_ACCOUNT_WITH_ACTIVE_KEYS = "iam-root-account-with-active-keys"
IAM_USER_NO_INACTIVE_KEY_ROTATION = "iam-user-no-Inactive-key-rotation"
IAM_USER_WITH_MULTIPLE_ACCESS_KEYS = "iam-user-with-multiple-access-keys"
# Least privilege
IAM_ASSUME_ROLE_POLICY_ALLOWS_ALL = "iam-assume-role-policy-allows-all"
IAM_EC2_ROLE_WITHOUT_INSTANCES = "iam-ec2-role-without-instances"
IAM_GROUP_WITH_INLINE_POLICIES = "iam-group-with-inline-policies"
IAM_GROUP_WITH_NO_USERS = "iam-group-with-no-users"
IAM_INLINE_GROUP_POLICY_ALLOWS_IAM_PASSROLE = "iam-inline-group-policy-allows-iam-PassRole"
IAM_INLINE_GROUP_POLICY_ALLOWS_NOTACTIONS = "iam-inline-group-policy-allows-NotActions"
IAM_INLINE_GROUP_POLICY_ALLOWS_STS_ASSUMEROLE = "iam-inline-group-policy-allows-sts-AssumeRole"
IAM_INLINE_ROLE_POLICY_ALLOWS_IAM_PASSROLE = "iam-inline-role-policy-allows-iam-PassRole"
IAM_INLINE_ROLE_POLICY_ALLOWS_NOTACTIONS = "iam-inline-role-policy-allows-NotActions"
IAM_INLINE_ROLE_POLICY_ALLOWS_STS_ASSUMEROLE = "iam-inline-role-policy-allows-sts-AssumeRole"
IAM_INLINE_USER_POLICY_ALLOWS_IAM_PASSROLE = "iam-inline-user-policy-allows-iam-PassRole"
IAM_INLINE_USER_POLICY_ALLOWS_NOTACTIONS = "iam-inline-user-policy-allows-NotActions"
IAM_INLINE_USER_POLICY_ALLOWS_STS_ASSUMEROLE = "iam-inline-user-policy-allows-sts-AssumeRole"
IAM_MANAGED_POLICY_ALLOWS_IAM_PASSROLE = "iam-managed-policy-allows-iam-PassRole"
IAM_MANAGED_POLICY_ALLOWS_NOTACTIONS = "iam-managed-policy-allows-NotActions"
IAM_MANAGED_POLICY_ALLOWS_STS_ASSUMEROLE = "iam-managed-policy-allows-sts-AssumeRole"
IAM_MANAGED_POLICY_NO_ATTACHMENTS = "iam-managed-policy-no-attachments"
IAM_ROLE_WITH_INLINE_POLICIES = "iam-role-with-inline-policies"
IAM_ROOT_ACCOUNT_USED_RECENTLY = "iam-root-account-used-recently"
IAM_ROOT_ACCOUNT_WITH_ACTIVE_CERTS = "iam-root-account-with-active-certs"
IAM_USER_WITH_INLINE_POLICIES = "iam-user-with-inline-policies"

View File

@ -1,21 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class RDSRules(RuleNameEnum):
# Encryption
RDS_INSTANCE_STORAGE_NOT_ENCRYPTED = "rds-instance-storage-not-encrypted"
# Data loss prevention
RDS_INSTANCE_BACKUP_DISABLED = "rds-instance-backup-disabled"
RDS_INSTANCE_SHORT_BACKUP_RETENTION_PERIOD = "rds-instance-short-backup-retention-period"
RDS_INSTANCE_SINGLE_AZ = "rds-instance-single-az"
# Firewalls
RDS_SECURITY_GROUP_ALLOWS_ALL = "rds-security-group-allows-all"
RDS_SNAPSHOT_PUBLIC = "rds-snapshot-public"
# Service security
RDS_INSTANCE_CA_CERTIFICATE_DEPRECATED = "rds-instance-ca-certificate-deprecated"
RDS_INSTANCE_NO_MINOR_UPGRADE = "rds-instance-no-minor-upgrade"

View File

@ -1,21 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class RedshiftRules(RuleNameEnum):
# Encryption
REDSHIFT_CLUSTER_DATABASE_NOT_ENCRYPTED = "redshift-cluster-database-not-encrypted"
REDSHIFT_PARAMETER_GROUP_SSL_NOT_REQUIRED = "redshift-parameter-group-ssl-not-required"
# Firewalls
REDSHIFT_SECURITY_GROUP_WHITELISTS_ALL = "redshift-security-group-whitelists-all"
# Restrictive Policies
REDSHIFT_CLUSTER_PUBLICLY_ACCESSIBLE = "redshift-cluster-publicly-accessible"
# Logging
REDSHIFT_PARAMETER_GROUP_LOGGING_DISABLED = "redshift-parameter-group-logging-disabled"
# Service security
REDSHIFT_CLUSTER_NO_VERSION_UPGRADE = "redshift-cluster-no-version-upgrade"

View File

@ -1,5 +0,0 @@
from enum import Enum
class RuleNameEnum(Enum):
pass

View File

@ -1,31 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class S3Rules(RuleNameEnum):
# Encryption
S3_BUCKET_ALLOWING_CLEARTEXT = "s3-bucket-allowing-cleartext"
S3_BUCKET_NO_DEFAULT_ENCRYPTION = "s3-bucket-no-default-encryption"
# Data loss prevention
S3_BUCKET_NO_MFA_DELETE = "s3-bucket-no-mfa-delete"
S3_BUCKET_NO_VERSIONING = "s3-bucket-no-versioning"
# Logging
S3_BUCKET_NO_LOGGING = "s3-bucket-no-logging"
# Permissive access rules
S3_BUCKET_AUTHENTICATEDUSERS_WRITE_ACP = "s3-bucket-AuthenticatedUsers-write_acp"
S3_BUCKET_AUTHENTICATEDUSERS_WRITE = "s3-bucket-AuthenticatedUsers-write"
S3_BUCKET_AUTHENTICATEDUSERS_READ_ACP = "s3-bucket-AuthenticatedUsers-read_acp"
S3_BUCKET_AUTHENTICATEDUSERS_READ = "s3-bucket-AuthenticatedUsers-read"
S3_BUCKET_ALLUSERS_WRITE_ACP = "s3-bucket-AllUsers-write_acp"
S3_BUCKET_ALLUSERS_WRITE = "s3-bucket-AllUsers-write"
S3_BUCKET_ALLUSERS_READ_ACP = "s3-bucket-AllUsers-read_acp"
S3_BUCKET_ALLUSERS_READ = "s3-bucket-AllUsers-read"
S3_BUCKET_WORLD_PUT_POLICY = "s3-bucket-world-Put-policy"
S3_BUCKET_WORLD_POLICY_STAR = "s3-bucket-world-policy-star"
S3_BUCKET_WORLD_LIST_POLICY = "s3-bucket-world-List-policy"
S3_BUCKET_WORLD_GET_POLICY = "s3-bucket-world-Get-policy"
S3_BUCKET_WORLD_DELETE_POLICY = "s3-bucket-world-Delete-policy"

View File

@ -1,9 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class SESRules(RuleNameEnum):
# Permissive policies
SES_IDENTITY_WORLD_SENDRAWEMAIL_POLICY = "ses-identity-world-SendRawEmail-policy"
SES_IDENTITY_WORLD_SENDEMAIL_POLICY = "ses-identity-world-SendEmail-policy"

View File

@ -1,14 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class SNSRules(RuleNameEnum):
# Permissive policies
SNS_TOPIC_WORLD_SUBSCRIBE_POLICY = "sns-topic-world-Subscribe-policy"
SNS_TOPIC_WORLD_SETTOPICATTRIBUTES_POLICY = "sns-topic-world-SetTopicAttributes-policy"
SNS_TOPIC_WORLD_REMOVEPERMISSION_POLICY = "sns-topic-world-RemovePermission-policy"
SNS_TOPIC_WORLD_RECEIVE_POLICY = "sns-topic-world-Receive-policy"
SNS_TOPIC_WORLD_PUBLISH_POLICY = "sns-topic-world-Publish-policy"
SNS_TOPIC_WORLD_DELETETOPIC_POLICY = "sns-topic-world-DeleteTopic-policy"
SNS_TOPIC_WORLD_ADDPERMISSION_POLICY = "sns-topic-world-AddPermission-policy"

View File

@ -1,16 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class SQSRules(RuleNameEnum):
# Permissive policies
SQS_QUEUE_WORLD_SENDMESSAGE_POLICY = "sqs-queue-world-SendMessage-policy"
SQS_QUEUE_WORLD_RECEIVEMESSAGE_POLICY = "sqs-queue-world-ReceiveMessage-policy"
SQS_QUEUE_WORLD_PURGEQUEUE_POLICY = "sqs-queue-world-PurgeQueue-policy"
SQS_QUEUE_WORLD_GETQUEUEURL_POLICY = "sqs-queue-world-GetQueueUrl-policy"
SQS_QUEUE_WORLD_GETQUEUEATTRIBUTES_POLICY = "sqs-queue-world-GetQueueAttributes-policy"
SQS_QUEUE_WORLD_DELETEMESSAGE_POLICY = "sqs-queue-world-DeleteMessage-policy"
SQS_QUEUE_WORLD_CHANGEMESSAGEVISIBILITY_POLICY = (
"sqs-queue-world-ChangeMessageVisibility-policy"
)

View File

@ -1,17 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
class VPCRules(RuleNameEnum):
# Logging
SUBNET_WITHOUT_FLOW_LOG = "vpc-subnet-without-flow-log"
# Firewalls
SUBNET_WITH_ALLOW_ALL_INGRESS_ACLS = "vpc-subnet-with-allow-all-ingress-acls"
SUBNET_WITH_ALLOW_ALL_EGRESS_ACLS = "vpc-subnet-with-allow-all-egress-acls"
NETWORK_ACL_NOT_USED = "vpc-network-acl-not-used"
DEFAULT_NETWORK_ACLS_ALLOW_ALL_INGRESS = "vpc-default-network-acls-allow-all-ingress"
DEFAULT_NETWORK_ACLS_ALLOW_ALL_EGRESS = "vpc-default-network-acls-allow-all-egress"
CUSTOM_NETWORK_ACLS_ALLOW_ALL_INGRESS = "vpc-custom-network-acls-allow-all-ingress"
CUSTOM_NETWORK_ACLS_ALLOW_ALL_EGRESS = "vpc-custom-network-acls-allow-all-egress"

View File

@ -1,224 +0,0 @@
from abc import ABC, abstractmethod
from typing import List
from common.common_consts import zero_trust_consts
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudformation_rules import (
CloudformationRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudtrail_rules import (
CloudTrailRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudwatch_rules import (
CloudWatchRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.config_rules import (
ConfigRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ec2_rules import EC2Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elb_rules import ELBRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elbv2_rules import ELBv2Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.iam_rules import IAMRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rds_rules import RDSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.redshift_rules import (
RedshiftRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.s3_rules import S3Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ses_rules import SESRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sns_rules import SNSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sqs_rules import SQSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.vpc_rules import VPCRules
# Class which links ZT tests and rules to ScoutSuite finding
class ScoutSuiteFindingMap(ABC):
@property
@abstractmethod
def rules(self) -> List[RuleNameEnum]:
pass
@property
@abstractmethod
def test(self) -> str:
pass
class PermissiveFirewallRules(ScoutSuiteFindingMap):
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,
EC2Rules.EC2_SECURITY_GROUP_WHITELISTS_AWS,
VPCRules.SUBNET_WITH_ALLOW_ALL_INGRESS_ACLS,
VPCRules.SUBNET_WITH_ALLOW_ALL_EGRESS_ACLS,
VPCRules.NETWORK_ACL_NOT_USED,
VPCRules.DEFAULT_NETWORK_ACLS_ALLOW_ALL_INGRESS,
VPCRules.DEFAULT_NETWORK_ACLS_ALLOW_ALL_EGRESS,
VPCRules.CUSTOM_NETWORK_ACLS_ALLOW_ALL_INGRESS,
VPCRules.CUSTOM_NETWORK_ACLS_ALLOW_ALL_EGRESS,
RDSRules.RDS_SECURITY_GROUP_ALLOWS_ALL,
RedshiftRules.REDSHIFT_SECURITY_GROUP_WHITELISTS_ALL,
]
test = zero_trust_consts.TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES
class UnencryptedData(ScoutSuiteFindingMap):
rules = [
EC2Rules.EBS_SNAPSHOT_NOT_ENCRYPTED,
EC2Rules.EBS_VOLUME_NOT_ENCRYPTED,
EC2Rules.EC2_INSTANCE_WITH_USER_DATA_SECRETS,
ELBv2Rules.ELBV2_LISTENER_ALLOWING_CLEARTEXT,
ELBv2Rules.ELBV2_OLDER_SSL_POLICY,
RDSRules.RDS_INSTANCE_STORAGE_NOT_ENCRYPTED,
RedshiftRules.REDSHIFT_CLUSTER_DATABASE_NOT_ENCRYPTED,
RedshiftRules.REDSHIFT_PARAMETER_GROUP_SSL_NOT_REQUIRED,
S3Rules.S3_BUCKET_ALLOWING_CLEARTEXT,
S3Rules.S3_BUCKET_NO_DEFAULT_ENCRYPTION,
ELBRules.ELB_LISTENER_ALLOWING_CLEARTEXT,
ELBRules.ELB_OLDER_SSL_POLICY,
]
test = zero_trust_consts.TEST_SCOUTSUITE_UNENCRYPTED_DATA
class DataLossPrevention(ScoutSuiteFindingMap):
rules = [
RDSRules.RDS_INSTANCE_BACKUP_DISABLED,
RDSRules.RDS_INSTANCE_SHORT_BACKUP_RETENTION_PERIOD,
RDSRules.RDS_INSTANCE_SINGLE_AZ,
S3Rules.S3_BUCKET_NO_MFA_DELETE,
S3Rules.S3_BUCKET_NO_VERSIONING,
ELBv2Rules.ELBV2_NO_DELETION_PROTECTION,
]
test = zero_trust_consts.TEST_SCOUTSUITE_DATA_LOSS_PREVENTION
class SecureAuthentication(ScoutSuiteFindingMap):
rules = [
IAMRules.IAM_USER_NO_ACTIVE_KEY_ROTATION,
IAMRules.IAM_PASSWORD_POLICY_MINIMUM_LENGTH,
IAMRules.IAM_PASSWORD_POLICY_NO_EXPIRATION,
IAMRules.IAM_PASSWORD_POLICY_REUSE_ENABLED,
IAMRules.IAM_USER_WITH_PASSWORD_AND_KEY,
IAMRules.IAM_ASSUME_ROLE_LACKS_EXTERNAL_ID_AND_MFA,
IAMRules.IAM_USER_WITHOUT_MFA,
IAMRules.IAM_ROOT_ACCOUNT_NO_MFA,
IAMRules.IAM_ROOT_ACCOUNT_WITH_ACTIVE_KEYS,
IAMRules.IAM_USER_NO_INACTIVE_KEY_ROTATION,
IAMRules.IAM_USER_WITH_MULTIPLE_ACCESS_KEYS,
]
test = zero_trust_consts.TEST_SCOUTSUITE_SECURE_AUTHENTICATION
class RestrictivePolicies(ScoutSuiteFindingMap):
rules = [
IAMRules.IAM_ASSUME_ROLE_POLICY_ALLOWS_ALL,
IAMRules.IAM_EC2_ROLE_WITHOUT_INSTANCES,
IAMRules.IAM_GROUP_WITH_INLINE_POLICIES,
IAMRules.IAM_GROUP_WITH_NO_USERS,
IAMRules.IAM_INLINE_GROUP_POLICY_ALLOWS_IAM_PASSROLE,
IAMRules.IAM_INLINE_GROUP_POLICY_ALLOWS_NOTACTIONS,
IAMRules.IAM_INLINE_GROUP_POLICY_ALLOWS_STS_ASSUMEROLE,
IAMRules.IAM_INLINE_ROLE_POLICY_ALLOWS_IAM_PASSROLE,
IAMRules.IAM_INLINE_ROLE_POLICY_ALLOWS_NOTACTIONS,
IAMRules.IAM_INLINE_ROLE_POLICY_ALLOWS_STS_ASSUMEROLE,
IAMRules.IAM_INLINE_USER_POLICY_ALLOWS_IAM_PASSROLE,
IAMRules.IAM_INLINE_USER_POLICY_ALLOWS_NOTACTIONS,
IAMRules.IAM_INLINE_USER_POLICY_ALLOWS_STS_ASSUMEROLE,
IAMRules.IAM_MANAGED_POLICY_ALLOWS_IAM_PASSROLE,
IAMRules.IAM_MANAGED_POLICY_ALLOWS_NOTACTIONS,
IAMRules.IAM_MANAGED_POLICY_ALLOWS_STS_ASSUMEROLE,
IAMRules.IAM_MANAGED_POLICY_NO_ATTACHMENTS,
IAMRules.IAM_ROLE_WITH_INLINE_POLICIES,
IAMRules.IAM_ROOT_ACCOUNT_USED_RECENTLY,
IAMRules.IAM_ROOT_ACCOUNT_WITH_ACTIVE_CERTS,
IAMRules.IAM_USER_WITH_INLINE_POLICIES,
EC2Rules.AMI_PUBLIC,
S3Rules.S3_BUCKET_AUTHENTICATEDUSERS_WRITE_ACP,
S3Rules.S3_BUCKET_AUTHENTICATEDUSERS_WRITE,
S3Rules.S3_BUCKET_AUTHENTICATEDUSERS_READ_ACP,
S3Rules.S3_BUCKET_AUTHENTICATEDUSERS_READ,
S3Rules.S3_BUCKET_ALLUSERS_WRITE_ACP,
S3Rules.S3_BUCKET_ALLUSERS_WRITE,
S3Rules.S3_BUCKET_ALLUSERS_READ_ACP,
S3Rules.S3_BUCKET_ALLUSERS_READ,
S3Rules.S3_BUCKET_WORLD_PUT_POLICY,
S3Rules.S3_BUCKET_WORLD_POLICY_STAR,
S3Rules.S3_BUCKET_WORLD_LIST_POLICY,
S3Rules.S3_BUCKET_WORLD_GET_POLICY,
S3Rules.S3_BUCKET_WORLD_DELETE_POLICY,
EC2Rules.EC2_DEFAULT_SECURITY_GROUP_IN_USE,
EC2Rules.EC2_DEFAULT_SECURITY_GROUP_WITH_RULES,
EC2Rules.EC2_EBS_SNAPSHOT_PUBLIC,
SQSRules.SQS_QUEUE_WORLD_SENDMESSAGE_POLICY,
SQSRules.SQS_QUEUE_WORLD_RECEIVEMESSAGE_POLICY,
SQSRules.SQS_QUEUE_WORLD_PURGEQUEUE_POLICY,
SQSRules.SQS_QUEUE_WORLD_GETQUEUEURL_POLICY,
SQSRules.SQS_QUEUE_WORLD_GETQUEUEATTRIBUTES_POLICY,
SQSRules.SQS_QUEUE_WORLD_DELETEMESSAGE_POLICY,
SQSRules.SQS_QUEUE_WORLD_CHANGEMESSAGEVISIBILITY_POLICY,
SNSRules.SNS_TOPIC_WORLD_SUBSCRIBE_POLICY,
SNSRules.SNS_TOPIC_WORLD_SETTOPICATTRIBUTES_POLICY,
SNSRules.SNS_TOPIC_WORLD_REMOVEPERMISSION_POLICY,
SNSRules.SNS_TOPIC_WORLD_RECEIVE_POLICY,
SNSRules.SNS_TOPIC_WORLD_PUBLISH_POLICY,
SNSRules.SNS_TOPIC_WORLD_DELETETOPIC_POLICY,
SNSRules.SNS_TOPIC_WORLD_ADDPERMISSION_POLICY,
SESRules.SES_IDENTITY_WORLD_SENDRAWEMAIL_POLICY,
SESRules.SES_IDENTITY_WORLD_SENDEMAIL_POLICY,
RedshiftRules.REDSHIFT_CLUSTER_PUBLICLY_ACCESSIBLE,
]
test = zero_trust_consts.TEST_SCOUTSUITE_RESTRICTIVE_POLICIES
class Logging(ScoutSuiteFindingMap):
rules = [
CloudTrailRules.CLOUDTRAIL_DUPLICATED_GLOBAL_SERVICES_LOGGING,
CloudTrailRules.CLOUDTRAIL_NO_DATA_LOGGING,
CloudTrailRules.CLOUDTRAIL_NO_GLOBAL_SERVICES_LOGGING,
CloudTrailRules.CLOUDTRAIL_NO_LOG_FILE_VALIDATION,
CloudTrailRules.CLOUDTRAIL_NO_LOGGING,
CloudTrailRules.CLOUDTRAIL_NOT_CONFIGURED,
CloudWatchRules.CLOUDWATCH_ALARM_WITHOUT_ACTIONS,
ELBRules.ELB_NO_ACCESS_LOGS,
S3Rules.S3_BUCKET_NO_LOGGING,
ELBv2Rules.ELBV2_NO_ACCESS_LOGS,
VPCRules.SUBNET_WITHOUT_FLOW_LOG,
ConfigRules.CONFIG_RECORDER_NOT_CONFIGURED,
RedshiftRules.REDSHIFT_PARAMETER_GROUP_LOGGING_DISABLED,
]
test = zero_trust_consts.TEST_SCOUTSUITE_LOGGING
class ServiceSecurity(ScoutSuiteFindingMap):
rules = [
CloudformationRules.CLOUDFORMATION_STACK_WITH_ROLE,
ELBv2Rules.ELBV2_HTTP_REQUEST_SMUGGLING,
RDSRules.RDS_INSTANCE_CA_CERTIFICATE_DEPRECATED,
RDSRules.RDS_INSTANCE_NO_MINOR_UPGRADE,
RedshiftRules.REDSHIFT_CLUSTER_NO_VERSION_UPGRADE,
]
test = zero_trust_consts.TEST_SCOUTSUITE_SERVICE_SECURITY

View File

@ -1,19 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.scoutsuite_finding_maps import (
DataLossPrevention,
Logging,
PermissiveFirewallRules,
RestrictivePolicies,
SecureAuthentication,
ServiceSecurity,
UnencryptedData,
)
SCOUTSUITE_FINDINGS = [
PermissiveFirewallRules,
UnencryptedData,
DataLossPrevention,
SecureAuthentication,
RestrictivePolicies,
Logging,
ServiceSecurity,
]

View File

@ -1,31 +0,0 @@
from enum import Enum
SERVICES = "services"
FINDINGS = "findings"
class SERVICE_TYPES(Enum):
ACM = "acm"
AWSLAMBDA = "awslambda"
CLOUDFORMATION = "cloudformation"
CLOUDTRAIL = "cloudtrail"
CLOUDWATCH = "cloudwatch"
CONFIG = "config"
DIRECTCONNECT = "directconnect"
EC2 = "ec2"
EFS = "efs"
ELASTICACHE = "elasticache"
ELB = "elb"
ELB_V2 = "elbv2"
EMR = "emr"
IAM = "iam"
KMS = "kms"
RDS = "rds"
REDSHIFT = "redshift"
ROUTE53 = "route53"
S3 = "s3"
SES = "ses"
SNS = "sns"
SQS = "sqs"
VPC = "vpc"
SECRETSMANAGER = "secretsmanager"

View File

@ -1,40 +0,0 @@
from enum import Enum
from common.utils.code_utils import get_value_from_dict
from common.utils.exceptions import RulePathCreatorNotFound
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators_list import ( # noqa: E501
RULE_PATH_CREATORS_LIST,
)
def __build_rule_to_rule_path_creator_hashmap():
hashmap = {}
for rule_path_creator in RULE_PATH_CREATORS_LIST:
for rule_name in rule_path_creator.supported_rules:
hashmap[rule_name] = rule_path_creator
return hashmap
RULE_TO_RULE_PATH_CREATOR_HASHMAP = __build_rule_to_rule_path_creator_hashmap()
class RuleParser:
@staticmethod
def get_rule_data(scoutsuite_data: dict, rule_name: Enum) -> dict:
rule_path = RuleParser._get_rule_path(rule_name)
return get_value_from_dict(scoutsuite_data, rule_path)
@staticmethod
def _get_rule_path(rule_name: Enum):
creator = RuleParser._get_rule_path_creator(rule_name)
return creator.build_rule_path(rule_name)
@staticmethod
def _get_rule_path_creator(rule_name: Enum):
try:
return RULE_TO_RULE_PATH_CREATOR_HASHMAP[rule_name]
except KeyError:
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."
)

View File

@ -1,28 +0,0 @@
from abc import ABC, abstractmethod
from enum import Enum
from typing import List, Type
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name_enum import (
RuleNameEnum,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import (
FINDINGS,
SERVICE_TYPES,
)
class AbstractRulePathCreator(ABC):
@property
@abstractmethod
def service_type(self) -> SERVICE_TYPES:
pass
@property
@abstractmethod
def supported_rules(self) -> Type[RuleNameEnum]:
pass
@classmethod
def build_rule_path(cls, rule_name: Enum) -> List[str]:
assert rule_name in cls.supported_rules
return [cls.service_type.value, FINDINGS, rule_name.value]

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudformation_rules import (
CloudformationRules,
)
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 ( # noqa: E501
AbstractRulePathCreator,
)
class CloudformationRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.CLOUDFORMATION
supported_rules = CloudformationRules

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudtrail_rules import (
CloudTrailRules,
)
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 ( # noqa: E501
AbstractRulePathCreator,
)
class CloudTrailRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.CLOUDTRAIL
supported_rules = CloudTrailRules

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudwatch_rules import (
CloudWatchRules,
)
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 ( # noqa: E501
AbstractRulePathCreator,
)
class CloudWatchRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.CLOUDWATCH
supported_rules = CloudWatchRules

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.config_rules import (
ConfigRules,
)
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 ( # noqa: E501
AbstractRulePathCreator,
)
class ConfigRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.CONFIG
supported_rules = ConfigRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.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 ( # noqa: E501
AbstractRulePathCreator,
)
class EC2RulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.EC2
supported_rules = EC2Rules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elb_rules import ELBRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class ELBRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.ELB
supported_rules = ELBRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elbv2_rules import ELBv2Rules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class ELBv2RulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.ELB_V2
supported_rules = ELBv2Rules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.iam_rules import IAMRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class IAMRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.IAM
supported_rules = IAMRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rds_rules import RDSRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class RDSRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.RDS
supported_rules = RDSRules

View File

@ -1,12 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.redshift_rules import (
RedshiftRules,
)
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 ( # noqa: E501
AbstractRulePathCreator,
)
class RedshiftRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.REDSHIFT
supported_rules = RedshiftRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.s3_rules import S3Rules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class S3RulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.S3
supported_rules = S3Rules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ses_rules import SESRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class SESRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.SES
supported_rules = SESRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sns_rules import SNSRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class SNSRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.SNS
supported_rules = SNSRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sqs_rules import SQSRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class SQSRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.SQS
supported_rules = SQSRules

View File

@ -1,10 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.vpc_rules import VPCRules
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 ( # noqa: E501
AbstractRulePathCreator,
)
class VPCRulePathCreator(AbstractRulePathCreator):
service_type = SERVICE_TYPES.VPC
supported_rules = VPCRules

View File

@ -1,63 +0,0 @@
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudformation_rule_path_creator import ( # noqa: E501
CloudformationRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudtrail_rule_path_creator import ( # noqa: E501
CloudTrailRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudwatch_rule_path_creator import ( # noqa: E501
CloudWatchRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.config_rule_path_creator import ( # noqa: E501
ConfigRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ec2_rule_path_creator import ( # noqa: E501
EC2RulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elb_rule_path_creator import ( # noqa: E501
ELBRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elbv2_rule_path_creator import ( # noqa: E501
ELBv2RulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.iam_rule_path_creator import ( # noqa: E501
IAMRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.rds_rule_path_creator import ( # noqa: E501
RDSRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.redshift_rule_path_creator import ( # noqa: E501
RedshiftRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.s3_rule_path_creator import ( # noqa: E501
S3RulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ses_rule_path_creator import ( # noqa: E501
SESRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sns_rule_path_creator import ( # noqa: E501
SNSRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sqs_rule_path_creator import ( # noqa: E501
SQSRulePathCreator,
)
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.vpc_rule_path_creator import ( # noqa: E501
VPCRulePathCreator,
)
RULE_PATH_CREATORS_LIST = [
EC2RulePathCreator,
ELBv2RulePathCreator,
RDSRulePathCreator,
RedshiftRulePathCreator,
S3RulePathCreator,
IAMRulePathCreator,
CloudTrailRulePathCreator,
ELBRulePathCreator,
VPCRulePathCreator,
CloudWatchRulePathCreator,
SQSRulePathCreator,
SNSRulePathCreator,
SESRulePathCreator,
ConfigRulePathCreator,
CloudformationRulePathCreator,
]

View File

@ -1,58 +0,0 @@
from typing import Tuple
from ScoutSuite.providers.base.authentication_strategy import AuthenticationException
from common.cloud.scoutsuite_consts import CloudProviders
from common.config_value_paths import AWS_KEYS_PATH
from common.utils.exceptions import InvalidAWSKeys
from monkey_island.cc.server_utils.encryption import get_datastore_encryptor
from monkey_island.cc.services.config import ConfigService
def is_cloud_authentication_setup(provider: CloudProviders) -> Tuple[bool, str]:
if provider == CloudProviders.AWS.value:
if is_aws_keys_setup():
return True, "AWS keys already setup."
import ScoutSuite.providers.aws.authentication_strategy as auth_strategy
try:
profile = auth_strategy.AWSAuthenticationStrategy().authenticate()
return True, f' Profile "{profile.session.profile_name}" is already setup. '
except AuthenticationException:
return False, ""
def is_aws_keys_setup():
return ConfigService.get_config_value(
AWS_KEYS_PATH + ["aws_access_key_id"]
) and ConfigService.get_config_value(AWS_KEYS_PATH + ["aws_secret_access_key"])
def set_aws_keys(access_key_id: str, secret_access_key: str, session_token: str):
if not access_key_id or not secret_access_key:
raise InvalidAWSKeys(
"Missing some of the following fields: access key ID, secret access key."
)
_set_aws_key("aws_access_key_id", access_key_id)
_set_aws_key("aws_secret_access_key", secret_access_key)
_set_aws_key("aws_session_token", session_token)
def _set_aws_key(key_type: str, key_value: str):
path_to_keys = AWS_KEYS_PATH
encrypted_key = get_datastore_encryptor().encrypt(key_value)
ConfigService.set_config_value(path_to_keys + [key_type], encrypted_key)
def get_aws_keys():
return {
"access_key_id": _get_aws_key("aws_access_key_id"),
"secret_access_key": _get_aws_key("aws_secret_access_key"),
"session_token": _get_aws_key("aws_session_token"),
}
def _get_aws_key(key_type: str):
path_to_keys = AWS_KEYS_PATH
return ConfigService.get_config_value(config_key_as_arr=path_to_keys + [key_type])

View File

@ -1,29 +0,0 @@
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

View File

@ -1,81 +0,0 @@
from typing import List
from common.common_consts import zero_trust_consts
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
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.consts.scoutsuite_finding_maps import (
ScoutSuiteFindingMap,
)
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import (
ScoutSuiteRuleService,
)
class ScoutSuiteZTFindingService:
@staticmethod
def process_rule(finding: ScoutSuiteFindingMap, rule: ScoutSuiteRule):
existing_findings = ScoutSuiteFinding.objects(test=finding.test)
assert len(existing_findings) < 2, "More than one finding exists for {}".format(
finding.test
)
if len(existing_findings) == 0:
ScoutSuiteZTFindingService._create_new_finding_from_rule(finding, rule)
else:
ScoutSuiteZTFindingService.add_rule(existing_findings[0], rule)
@staticmethod
def _create_new_finding_from_rule(finding: ScoutSuiteFindingMap, rule: ScoutSuiteRule):
details = ScoutSuiteFindingDetails()
details.scoutsuite_rules = [rule]
details.save()
status = ScoutSuiteZTFindingService.get_finding_status_from_rules(details.scoutsuite_rules)
ScoutSuiteFinding.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: ScoutSuiteFinding, rule: ScoutSuiteRule):
ScoutSuiteZTFindingService.change_finding_status_by_rule(finding, rule)
finding.save()
finding.details.fetch().add_rule(rule)
@staticmethod
def change_finding_status_by_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule):
rule_status = ScoutSuiteZTFindingService.get_finding_status_from_rules([rule])
finding_status = finding.status
new_finding_status = ScoutSuiteZTFindingService.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

View File

@ -7,7 +7,6 @@ from common.common_consts import zero_trust_consts
from common.utils.exceptions import UnknownFindingError
from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_details_service import (
MonkeyZTDetailsService,
)
@ -55,7 +54,5 @@ class FindingService:
def _get_finding_details(finding: Finding) -> Union[dict, SON]:
if type(finding) == MonkeyFinding:
return MonkeyZTDetailsService.fetch_details_for_display(finding.details.id)
elif type(finding) == ScoutSuiteFinding:
return finding.details.fetch().to_mongo()
else:
raise UnknownFindingError(f"Unknown finding type {str(type(finding))}")

View File

@ -1,13 +0,0 @@
from monkey_island.cc.models.zero_trust.scoutsuite_data_json import ScoutSuiteRawDataJson
class ScoutSuiteRawDataService:
# Return unparsed json of ScoutSuite results,
# so that UI can pick out values it needs for report
@staticmethod
def get_scoutsuite_data_json() -> str:
try:
return ScoutSuiteRawDataJson.objects.get().scoutsuite_data
except Exception:
return "{}"

View File

@ -71,7 +71,7 @@ class ReportPageComponent extends AuthComponent {
}
getZeroTrustReportFromServer = async () => {
let ztReport = {findings: {}, principles: {}, pillars: {}, scoutsuite_data: {}};
let ztReport = {findings: {}, principles: {}, pillars: {}};
await this.authFetch('/api/report/zero-trust/findings')
.then(res => res.json())
.then(res => {
@ -87,11 +87,6 @@ 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
};

View File

@ -8,7 +8,6 @@ import {cloneDeep} from 'lodash';
import {faCloud, faExpandArrowsAlt} from '@fortawesome/free-solid-svg-icons';
import RunOnIslandButton from './RunOnIslandButton';
import AWSRunButton from './RunOnAWS/AWSRunButton';
import CloudOptions from './scoutsuite-setup/CloudOptions';
const CONFIG_URL = '/api/configuration/island';
@ -56,7 +55,7 @@ function RunOptions(props) {
return InlineSelection(defaultContents, newProps);
}
function shouldShowScoutsuite(islandMode){
function isNotRansomwareMode(islandMode){
return islandMode !== 'ransomware';
}
@ -73,15 +72,7 @@ function RunOptions(props) {
setComponent(LocalManualRunOptions,
{ips: ips, setComponent: setComponent})
}}/>
{shouldShowScoutsuite(props.islandMode) && <AWSRunButton setComponent={setComponent}/> }
{shouldShowScoutsuite(props.islandMode) && <NextSelectionButton title={'Cloud security scan'}
description={'Explains how to enable cloud security scan.'}
icon={faCloud}
onButtonClick={() => {
setComponent(CloudOptions,
{ips: ips, setComponent: setComponent})
}}/>
}
{isNotRansomwareMode(props.islandMode) && <AWSRunButton setComponent={setComponent}/> }
</>
);
}

View File

@ -1,63 +0,0 @@
import {Button} from 'react-bootstrap';
import React from 'react';
import InlineSelection from '../../../../ui-components/inline-selection/InlineSelection';
import {COLUMN_SIZES} from '../../../../ui-components/inline-selection/utils';
import '../../../../../styles/components/scoutsuite/AWSSetup.scss';
import AWSSetupOptions from './AWSSetupOptions';
export default function AWSCLISetup(props) {
return InlineSelection(getContents, {
...props,
collumnSize: COLUMN_SIZES.LARGE,
onBackButtonClick: () => {
props.setComponent(AWSSetupOptions, props);
}
})
}
const getContents = (props) => {
return (
<div className={'aws-scoutsuite-configuration'}>
<h2>AWS CLI configuration for scan</h2>
<p>To assess your AWS infrastructure's security do the following:</p>
<ol>
<li>
1. Configure AWS CLI on Monkey Island Server (if you already have a configured CLI you can skip this step).
<ol className={'nested-ol'}>
<li>
a. Download <Button href={'https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html'}
target={'_blank'} variant={'link'}>AWS CLI</Button> and
install it on the Monkey Island server (machine running this page).
</li>
<li>
b. Run <code>aws configure</code>. It's important to configure credentials as it
allows ScoutSuite to get information about your cloud configuration. The simplest way to do so is to
provide&nbsp;
<Button
href={'https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-creds'}
variant={'link'}
className={'cli-link'}
target={'_blank'}>
Access key ID and secret access key
</Button>.
</li>
</ol>
</li>
<li>
2. If you change the configuration, make sure not to disable AWS system info collector.
</li>
<li>
3. Go <Button onClick={() => props.setComponent()}
variant={'link'}
className={'cli-link'}>back</Button>
&nbsp;and run Monkey on the Island server.
</li>
<li>
4. Assess results in Zero Trust report.
</li>
</ol>
</div>
);
}

View File

@ -1,179 +0,0 @@
import React, {useEffect, useState} from 'react';
import InlineSelection from '../../../../ui-components/inline-selection/InlineSelection';
import {COLUMN_SIZES} from '../../../../ui-components/inline-selection/utils';
import AWSSetupOptions from './AWSSetupOptions';
import {Button, Col, Form, Row} from 'react-bootstrap';
import AuthComponent from '../../../../AuthComponent';
import '../../../../../styles/components/scoutsuite/AWSSetup.scss';
import {PROVIDERS} from '../ProvidersEnum';
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 {faQuestion} from '@fortawesome/free-solid-svg-icons';
import Collapse from '@kunukn/react-collapse/dist/Collapse.umd';
import keySetupForAnyUserImage from '../../../../../images/aws_keys_tutorial-any-user.png';
import keySetupForCurrentUserImage from '../../../../../images/aws_keys_tutorial-current-user.png';
import ImageModal from '../../../../ui-components/ImageModal';
export default function AWSCLISetup(props) {
return InlineSelection(getContents, {
...props,
collumnSize: COLUMN_SIZES.LARGE,
onBackButtonClick: () => {
props.setComponent(AWSSetupOptions, props);
}
})
}
const authComponent = new AuthComponent({})
const getContents = (props) => {
const [accessKeyId, setAccessKeyId] = useState('');
const [secretAccessKey, setSecretAccessKey] = useState('');
const [sessionToken, setSessionToken] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [successMessage, setSuccessMessage] = useState('');
const [docCollapseOpen, setDocCollapseOpen] = useState(false);
function submitKeys(event) {
event.preventDefault();
setSuccessMessage('');
setErrorMessage('');
authComponent.authFetch(
'/api/scoutsuite_auth/' + PROVIDERS.AWS,
{
'method': 'POST',
'body': JSON.stringify({
'accessKeyId': accessKeyId,
'secretAccessKey': secretAccessKey,
'sessionToken': sessionToken
})
})
.then(res => res.json())
.then(res => {
if (res['error_msg'] === '') {
setSuccessMessage('AWS keys saved!');
} else if (res['message'] === 'Internal Server Error') {
setErrorMessage('Something went wrong, double check keys and contact support if problem persists.');
} else {
setErrorMessage(res['error_msg']);
}
});
}
useEffect(() => {
authComponent.authFetch('/api/aws_keys')
.then(res => res.json())
.then(res => {
setAccessKeyId(res['access_key_id']);
setSecretAccessKey(res['secret_access_key']);
setSessionToken(res['session_token']);
});
}, [props]);
// TODO separate into standalone component
function getKeyCreationDocsContent() {
return (
<div className={'key-creation-tutorial'}>
<h5>Tips</h5>
<p>Consider creating a new user account just for this activity. Assign only <b>ReadOnlyAccess</b> and&nbsp;
<b>SecurityAudit</b> policies.</p>
<h5>Keys for custom user</h5>
<p>1. Open the IAM console at <a href={'https://console.aws.amazon.com/iam/'}
target={'_blank'}
rel="noopener noreferrer">https://console.aws.amazon.com/iam/</a>.</p>
<p>2. In the navigation pane, choose Users.</p>
<p>3. Choose the name of the user whose access keys you want to create, and then choose the Security credentials
tab.</p>
<p>4. In the Access keys section, choose Create Access key.</p>
<p>To view the new access key pair, choose Show. Your credentials will look something like this:</p>
<p>Access key ID: AKIAIOSFODNN7EXAMPLE</p>
<p>Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY</p>
<Row>
<Col lg={3} md={3} sm={5} xs={12}>
<ImageModal image={keySetupForAnyUserImage}/>
</Col>
</Row>
<h5>Keys for current user</h5>
<p>1. Click on your username in the upper right corner.</p>
<p>2. Click on "My security credentials".</p>
<p>3. In the Access keys section, choose Create Access key.</p>
<p>To view the new Access key pair, choose Show. Your credentials will look something like this:</p>
<p>Access key ID: AKIAIOSFODNN7EXAMPLE</p>
<p>Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY</p>
<Row>
<Col lg={3} md={3} sm={5} xs={12}>
<ImageModal image={keySetupForCurrentUserImage}/>
</Col>
</Row>
</div>);
}
function getKeyCreationDocs() {
return (
<div className={classNames('collapse-item', {'item--active': docCollapseOpen})}>
<button className={'btn-collapse'}
onClick={() => setDocCollapseOpen(!docCollapseOpen)}>
<span>
<FontAwesomeIcon icon={faQuestion} className={'question-icon'}/>
<p>How to generate keys</p>
</span>
<span>
<FontAwesomeIcon icon={docCollapseOpen ? faChevronDown : faChevronUp}/>
</span>
</button>
<Collapse
className='collapse-comp'
isOpen={docCollapseOpen}
render={getKeyCreationDocsContent}/>
</div>);
}
return (
<div className={'aws-scoutsuite-key-configuration'}>
{getKeyCreationDocs()}
<Form className={'auth-form'} onSubmit={submitKeys}>
<Form.Control onChange={evt => setAccessKeyId(evt.target.value)}
type='text'
placeholder='Access key ID'
value={accessKeyId}/>
<Form.Control onChange={evt => setSecretAccessKey(evt.target.value)}
type='password'
placeholder='Secret access key'
value={secretAccessKey}/>
<Form.Control onChange={evt => setSessionToken(evt.target.value)}
type='text'
placeholder='Session token (optional, only for temp. keys)'
value={sessionToken}/>
{
errorMessage ?
<div className="alert alert-danger" role="alert">{errorMessage}</div>
:
''
}
{
successMessage ?
<div className="alert alert-success" role="alert">{successMessage}&nbsp;
Go back and&nbsp;
<Button variant={'link'} onClick={() => props.setComponent()} className={'link-in-success-message'}>
run Monkey from the Island server </Button> to start AWS scan!</div>
:
''
}
<Row className={'justify-content-center'}>
<Col lg={4} md={6} sm={8} xs={12}>
<Button className={'monkey-submit-button'} type={'submit'}>
Submit
</Button>
</Col>
</Row>
</Form>
</div>
);
}

View File

@ -1,40 +0,0 @@
import React from 'react';
import InlineSelection from '../../../../ui-components/inline-selection/InlineSelection';
import NextSelectionButton from '../../../../ui-components/inline-selection/NextSelectionButton';
import {faKey, faTerminal} from '@fortawesome/free-solid-svg-icons';
import AWSCLISetup from './AWSCLISetup';
import CloudOptions from '../CloudOptions';
import AWSKeySetup from './AWSKeySetup';
const AWSSetupOptions = (props) => {
return InlineSelection(getContents, {
...props,
onBackButtonClick: () => {
props.setComponent(CloudOptions, props);
}
})
}
const getContents = (props) => {
return (
<>
<NextSelectionButton title={'Security keys'}
description={'Provide security keys for monkey to authenticate.'}
icon={faKey}
onButtonClick={() => {
props.setComponent(AWSKeySetup,
{setComponent: props.setComponent})
}}/>
<NextSelectionButton title={'AWS CLI'}
description={'Manually configure AWS CLI yourself.'}
icon={faTerminal}
onButtonClick={() => {
props.setComponent(AWSCLISetup,
{setComponent: props.setComponent})
}}/>
</>
)
}
export default AWSSetupOptions;

View File

@ -1,65 +0,0 @@
import React, {useEffect, useState} from 'react';
import InlineSelection from '../../../ui-components/inline-selection/InlineSelection';
import NextSelectionButton from '../../../ui-components/inline-selection/NextSelectionButton';
import {faCheck, faCloud, faSync} from '@fortawesome/free-solid-svg-icons';
import AWSSetupOptions from './AWSConfiguration/AWSSetupOptions';
import {PROVIDERS} from './ProvidersEnum';
import AuthComponent from '../../../AuthComponent';
const CloudOptions = (props) => {
return InlineSelection(getContents, {
...props,
onBackButtonClick: () => {
props.setComponent()
}
})
}
const authComponent = new AuthComponent({})
const getContents = (props) => {
const [description, setDescription] = useState('Loading...');
const [iconType, setIconType] = useState('spinning-icon');
const [icon, setIcon] = useState(faSync);
useEffect(() => {
authComponent.authFetch('/api/scoutsuite_auth/' + PROVIDERS.AWS)
.then(res => res.json())
.then(res => {
if(res.is_setup){
setDescription(getDescription(res.message));
setIconType('icon-success');
setIcon(faCheck);
} else {
setDescription('Setup Amazon Web Services infrastructure scan.');
setIconType('')
setIcon(faCloud);
}
});
}, [props]);
function getDescription(message){
return (
<>
{message} Run <b>from the Island</b> to start the scan. Click next to change the configuration.
</>
)
}
return (
<>
<NextSelectionButton title={'AWS'}
description={description}
icon={icon}
iconType={iconType}
onButtonClick={() => {
props.setComponent(AWSSetupOptions,
{setComponent: props.setComponent})
}}/>
</>
)
}
export default CloudOptions;

View File

@ -1,9 +0,0 @@
// Should match enum in monkey/common/cloud/scoutsuite_consts.py
export const PROVIDERS = {
AWS : 'aws',
AZURE : 'azure',
GCP : 'gcp',
ALIBABA : 'aliyun',
ORACLE : 'oci'
}

View File

@ -30,8 +30,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
<PrinciplesSection principles={this.state.principles}
pillarsToStatuses={this.state.pillars.pillarsToStatuses}/>
<FindingsSection pillarsToStatuses={this.state.pillars.pillarsToStatuses}
findings={this.state.findings}
scoutsuite_data={this.state.scoutsuite_data}/>
findings={this.state.findings}/>
</div>;
}
@ -59,8 +58,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
stillLoadingDataFromServer() {
return typeof this.state.findings === 'undefined'
|| typeof this.state.pillars === 'undefined'
|| typeof this.state.principles === 'undefined'
|| typeof this.state.scoutsuite_data === 'undefined';
|| typeof this.state.principles === 'undefined';
}

View File

@ -33,13 +33,10 @@ class FindingsSection extends Component {
</p>
<FindingsTable data={findingsByStatus[ZeroTrustStatuses.failed]}
scoutsuite_data={this.props.scoutsuite_data}
status={ZeroTrustStatuses.failed}/>
<FindingsTable data={findingsByStatus[ZeroTrustStatuses.verify]}
scoutsuite_data={this.props.scoutsuite_data}
status={ZeroTrustStatuses.verify}/>
<FindingsTable data={findingsByStatus[ZeroTrustStatuses.passed]}
scoutsuite_data={this.props.scoutsuite_data}
status={ZeroTrustStatuses.passed}/>
</div>
);

View File

@ -4,7 +4,6 @@ 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 = 180;
const PILLARS_COLUMN_MAX_WIDTH = 260;
@ -36,16 +35,11 @@ export class FindingsTable extends Component {
];
getFindingDetails(finding) {
if ('scoutsuite_rules' in finding.details) {
return <ScoutSuiteRuleButton scoutsuite_rules={finding.details.scoutsuite_rules}
scoutsuite_data={this.props.scoutsuite_data}/>;
} else {
return <EventsButton finding_id={finding.finding_id}
latest_events={finding.details.latest_events}
oldest_events={finding.details.oldest_events}
event_count={finding.details.event_count}
exportFilename={'Events_' + finding.test_key}/>;
}
return <EventsButton finding_id={finding.finding_id}
latest_events={finding.details.latest_events}
oldest_events={finding.details.oldest_events}
event_count={finding.details.event_count}
exportFilename={'Events_' + finding.test_key}/>;
}
getFindingPillars(finding) {

View File

@ -1,84 +0,0 @@
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);
let parser = new ScoutSuiteDataParser(props.scoutsuite_data.data.services);
let resource_value = parser.getResourceValue(props.resource_path, props.template_path);
function getResourceDropdown() {
return (
<div key={props.resource_path} className={classNames('collapse-item',
'resource-collapse', {'item--active': isCollapseOpen})}>
<button className={'btn-collapse'}
onClick={() => setIsCollapseOpen(!isCollapseOpen)}>
<span>
{Object.prototype.hasOwnProperty.call(resource_value, 'name') ?
resource_value.name : props.resource_path}
</span>
<span>
<FontAwesomeIcon icon={isCollapseOpen ? faChevronDown : faChevronUp}/>
</span>
</button>
<Collapse
className='collapse-comp'
isOpen={isCollapseOpen}
render={getResourceDropdownContents}/>
</div>
);
}
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(<FontAwesomeIcon icon={faArrowRight} key={'arrow-' + i}/>)
}
}
return display_path;
}
function prettyPrintJson(data) {
return JSON.stringify(data, null, 4);
}
function getResourceValueDisplay() {
return (
<div>
<p className={'resource-value-title'}>Value:</p>
<pre className={'resource-value-json'}>{prettyPrintJson(resource_value)}</pre>
</div>
);
}
function getResourceDropdownContents() {
return (
<div className={'resource-display'}>
<div>
<p className={'resource-path-title'}>Path:</p>
<p className={'resource-path-contents'}>{replacePathDotsWithArrows(props.resource_path)}</p>
</div>
{getResourceValueDisplay()}
</div>
);
}
return getResourceDropdown();
}
ResourceDropdown.propTypes = {
template_path: PropTypes.string,
resource_path: PropTypes.string,
scoutsuite_data: PropTypes.object
};

View File

@ -1,70 +0,0 @@
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 (
<div className={'scoutsuite-rule-display'}>
<div className={'description'}>
<h3>{props.rule.description}({props.rule.service})</h3>
</div>
<div className={'rationale'}>
<p dangerouslySetInnerHTML={{__html: props.rule.rationale}}/>
</div>
<div className={'checked-resources'}>
<p className={'checked-resources-title'}>Resources checked: </p>
<p>{props.rule.checked_items}</p>
</div>
{getReferences()}
{getResources()}
</div>);
function getReferences() {
let references = []
props.rule.references.forEach(reference => {
references.push(<a href={reference}
className={'reference-link'}
target={'_blank'}
rel="noopener noreferrer"
key={reference}>{reference}</a>)
})
if (references.length) {
return (
<div className={'reference-list'}>
<p className={'reference-list-title'}>References:</p>
{references}
</div>)
} else {
return null;
}
}
function getResources() {
let resources = []
for (let i = 0; i < props.rule.items.length; i++) {
let item = props.rule.items[i];
let template_path = Object.prototype.hasOwnProperty.call(props.rule, 'display_path')
? props.rule.display_path : props.rule.path;
resources.push(<ResourceDropdown resource_path={item}
template_path={template_path}
scoutsuite_data={props.scoutsuite_data}
key={template_path + i}/>)
}
if (resources.length) {
return (
<div className={'reference-list'}>
<p className={'reference-list-title'}>Flagged resources (<b>{props.rule.flagged_items}</b>):</p>
{resources}
</div>)
} else {
return null;
}
}
}
RuleDisplay.propTypes = {
rule: PropTypes.object,
scoutsuite_data: PropTypes.object
};

View File

@ -1,118 +0,0 @@
export default class ScoutSuiteDataParser {
constructor(runResults) {
this.runResults = runResults
}
/**
* Gets value of cloud resource based on path of specific checked field and more abstract template path,
* which describes the scope of resource values.
* @param itemPath contains path to a specific value e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled
* @param templatePath contains a template path for resource we would want to display e.g. s3.buckets.id
* @returns {*[]|*} resource value e.g. {'bucket_id': 123, 'bucket_max_size': '123GB'}
*/
getResourceValue(itemPath, templatePath) {
let resourcePath = this.fillTemplatePath(itemPath, templatePath);
return this.getObjectValueByPath(resourcePath, this.runResults);
}
/**
* Replaces id's in template path with id's from item path to form actual path to the object
* @param itemPath e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled
* @param templatePath e.g. s3.buckets.id
* @returns {*} e.g. s3.buckets.da1e7081077ce92
*/
fillTemplatePath(itemPath, templatePath) {
let itemPathArray = itemPath.split('.');
let templatePathArray = templatePath.split('.');
let resourcePathArray = templatePathArray.map((val, i) => {
return val === 'id' ? itemPathArray[i] : val
})
return resourcePathArray.join('.');
}
/**
* Retrieves value from ScoutSuite data object based on path, provided in the rule
* @param path E.g. a.id.c.id.e
* @param source E.g. {a: {b: {c: {d: {e: [{result1: 'result1'}, {result2: 'result2'}]}}}}}
* @returns {*[]|*} E.g. ['result1', 'result2']
*/
getObjectValueByPath(path, source) {
let key;
while (path) {
key = this.getNextKeyInPath(path);
source = this.getValueForKey(key, path, source);
path = this.trimFirstKey(path);
}
return source;
}
/**
* Gets next key from the path
* @param path e.g. s3.buckets.id
* @returns {string|*} s3
*/
getNextKeyInPath(path) {
if (path.indexOf('.') !== -1) {
return path.substr(0, path.indexOf('.'));
} else {
return path;
}
}
/**
* Returns value from object, based on path and current key
* @param key E.g. "a"
* @param path E.g. "a.b.c"
* @param source E.g. {a: {b: {c: 'result'}}}
* @returns {[]|*} E.g. {b: {c: 'result'}}
*/
getValueForKey(key, path, source) {
if (key === 'id') {
return this.getValueByReplacingUnknownKey(path, source);
} else {
return source[key];
}
}
/**
* Gets value from object if first key in path doesn't match source object
* @param path unknown.b.c
* @param source {a: {b: {c: [{result:'result'}]}}}
* @returns {[]} 'result'
*/
getValueByReplacingUnknownKey(path, source) {
let value = [];
for (let key in source) {
value = this.getObjectValueByPath(this.replaceFirstKey(path, key), source);
value = value.concat(Object.values(value));
}
return value;
}
/**
* Replaces first key in path
* @param path E.g. "one.two.three"
* @param replacement E.g. "four"
* @returns string E.g. "four.two.three"
*/
replaceFirstKey(path, replacement) {
return replacement + path.substr(path.indexOf('.'), path.length);
}
/**
* Trims the first key from dot separated path.
* @param path E.g. "one.two.three"
* @returns {string|boolean} E.g. "two.three"
*/
trimFirstKey(path) {
if (path.indexOf('.') !== -1) {
return path.substr(path.indexOf('.') + 1, path.length);
} else {
return false;
}
}
}

View File

@ -1,46 +0,0 @@
import React, {Component} from 'react';
import {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';
import CountBadge from '../../../ui-components/CountBadge';
export default class ScoutSuiteRuleButton extends Component {
constructor(props) {
super(props);
this.state = {
isModalOpen: false
}
}
toggleModal = () => {
this.setState({isModalOpen: !this.state.isModalOpen});
};
render() {
return (
<>
<ScoutSuiteRuleModal scoutsuite_rules={this.props.scoutsuite_rules}
scoutsuite_data={this.props.scoutsuite_data}
isModalOpen={this.state.isModalOpen}
hideCallback={this.toggleModal} />
<div className="text-center" style={{'display': 'grid'}}>
<Button variant={'monkey-info'} size={'lg'} onClick={this.toggleModal}>
<FontAwesomeIcon icon={faList}/> Rules
&nbsp;<CountBadge count={this.props.scoutsuite_rules.length}/>
</Button>
</div>
</>);
}
createRuleCountBadge() {
}
}
ScoutSuiteRuleButton.propTypes = {
scoutsuite_rules: PropTypes.array,
scoutsuite_data: PropTypes.object
};

View File

@ -1,94 +0,0 @@
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';
import STATUSES from '../../common/consts/StatusConsts';
import {getRuleCountByStatus, sortRules} from './rule-parsing/ParsingUtils';
export default function ScoutSuiteRuleModal(props) {
const [openRuleId, setOpenRuleId] = useState(null)
function toggleRuleDropdown(ruleId) {
let ruleIdToSet = (openRuleId === ruleId) ? null : ruleId;
setOpenRuleId(ruleIdToSet);
}
function renderRuleDropdowns() {
let dropdowns = [];
let rules = sortRules(props.scoutsuite_rules);
rules.forEach(rule => {
let dropdown = (<ScoutSuiteSingleRuleDropdown isCollapseOpen={openRuleId === rule.description}
toggleCallback={() => toggleRuleDropdown(rule.description)}
rule={rule}
scoutsuite_data={props.scoutsuite_data}
key={rule.description + rule.path}/>)
dropdowns.push(dropdown)
});
return dropdowns;
}
function getGeneralRuleOverview() {
return <>
There {Pluralize('is', props.scoutsuite_rules.length)}
&nbsp;<span className={'badge badge-primary'}>{props.scoutsuite_rules.length}</span>
&nbsp;ScoutSuite {Pluralize('rule', props.scoutsuite_rules.length)} associated with this finding.
</>
}
function getFailedRuleOverview() {
let failedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_FAILED) +
+ getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_VERIFY);
return <>
&nbsp;<span className={'badge badge-danger'}>{failedRuleCnt}</span>
&nbsp;failed security {Pluralize('rule', failedRuleCnt)}.
</>
}
function getPassedRuleOverview() {
let passedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_PASSED);
return <>
&nbsp;<span className={'badge badge-success'}>{passedRuleCnt}</span>
&nbsp;passed security {Pluralize('rule', passedRuleCnt)}.
</>
}
function getUnexecutedRuleOverview() {
let unexecutedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_UNEXECUTED);
return <>
&nbsp;<span className={'badge badge-default'}>{unexecutedRuleCnt}</span>
&nbsp;{Pluralize('rule', unexecutedRuleCnt)} {Pluralize('was', unexecutedRuleCnt)} not
checked (no relevant resources for the rule).
</>
}
return (
<div>
<Modal show={props.isModalOpen} onHide={() => props.hideCallback()} className={'scoutsuite-rule-modal'}>
<Modal.Body>
<h3>
<div className="text-center">ScoutSuite rules</div>
</h3>
<hr/>
<p>
{getGeneralRuleOverview()}
{getFailedRuleOverview()}
{getPassedRuleOverview()}
{getUnexecutedRuleOverview()}
</p>
{renderRuleDropdowns()}
</Modal.Body>
</Modal>
</div>
);
}
ScoutSuiteRuleModal.propTypes = {
isModalOpen: PropTypes.bool,
scoutsuite_rules: PropTypes.array,
scoutsuite_data: PropTypes.object,
hideCallback: PropTypes.func
};

View File

@ -1,79 +0,0 @@
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 STATUSES from '../../common/consts/StatusConsts';
import {faCheckCircle, faCircle, faExclamationCircle} from '@fortawesome/free-solid-svg-icons';
import RuleDisplay from './RuleDisplay';
import {getRuleStatus} from './rule-parsing/ParsingUtils';
export default function ScoutSuiteSingleRuleDropdown(props) {
function getRuleCollapse() {
return (
<div className={classNames('collapse-item',
'rule-collapse', {'item--active': props.isCollapseOpen})}>
<button className={classNames('btn-collapse', getDropdownClass())}
onClick={props.toggleCallback}>
<span>
<FontAwesomeIcon icon={getRuleIcon()}/>
{props.rule.description}
</span>
<span>
<FontAwesomeIcon icon={props.isCollapseOpen ? faChevronDown : faChevronUp}/>
</span>
</button>
<Collapse
className='collapse-comp'
isOpen={props.isCollapseOpen}
render={renderRule}/>
</div>
);
}
function getRuleIcon() {
let ruleStatus = getRuleStatus(props.rule);
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(props.rule);
switch (ruleStatus) {
case STATUSES.STATUS_PASSED:
return 'collapse-success';
case STATUSES.STATUS_VERIFY:
return 'collapse-danger';
case STATUSES.STATUS_FAILED:
return 'collapse-danger';
case STATUSES.STATUS_UNEXECUTED:
return 'collapse-default';
}
}
function renderRule() {
return <RuleDisplay rule={props.rule} scoutsuite_data={props.scoutsuite_data}/>
}
return getRuleCollapse();
}
ScoutSuiteSingleRuleDropdown.propTypes = {
isCollapseOpen: PropTypes.bool,
rule: PropTypes.object,
scoutsuite_data: PropTypes.object,
toggleCallback: PropTypes.func
};

View File

@ -1,40 +0,0 @@
import STATUSES from '../../../common/consts/StatusConsts';
import RULE_LEVELS from '../../../common/consts/ScoutSuiteConsts/RuleLevels';
export function getRuleStatus(rule) {
if (rule.checked_items === 0) {
return STATUSES.STATUS_UNEXECUTED
} else if (rule.items.length === 0) {
return STATUSES.STATUS_PASSED
} else if (rule.level === RULE_LEVELS.LEVEL_WARNING) {
return STATUSES.STATUS_VERIFY
} else {
return STATUSES.STATUS_FAILED
}
}
export function getRuleCountByStatus(rules, status) {
return rules.filter(rule => getRuleStatus(rule) === status).length;
}
export function sortRules(rules) {
rules.sort(compareRules);
return rules;
}
function compareRules(firstRule, secondRule) {
let firstStatus = getRuleStatus(firstRule);
let secondStatus = getRuleStatus(secondRule);
return compareRuleStatuses(firstStatus, secondStatus);
}
function compareRuleStatuses(ruleStatusOne, ruleStatusTwo) {
const severity_order = {
[STATUSES.STATUS_FAILED]: 1,
[STATUSES.STATUS_VERIFY]: 2,
[STATUSES.STATUS_PASSED]: 3,
[STATUSES.STATUS_UNEXECUTED]: 4
}
return severity_order[ruleStatusOne] - severity_order[ruleStatusTwo]
}

View File

@ -13,7 +13,6 @@
@import 'components/PreviewPane';
@import 'components/AdvancedMultiSelect';
@import 'components/particle-component/ParticleBackground';
@import 'components/scoutsuite/ResourceDropdown';
@import 'components/ImageModal';
@import 'components/Icons';
@import 'components/inline-selection/InlineSelection';

View File

@ -1,86 +0,0 @@
.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: 0;
}
.aws-scoutsuite-configuration h2 {
margin-bottom: 20px;
}
.aws-scoutsuite-configuration p {
margin-bottom: 5px;
}
.aws-scoutsuite-configuration .cli-link {
padding: 0 0 4px 0;
}
.monkey-submit-button {
margin-bottom: 15px;
}
.aws-scoutsuite-key-configuration .collapse-item {
padding: 0;
margin-bottom: 15px;
}
.aws-scoutsuite-key-configuration .collapse-item .btn-collapse .question-icon {
display: inline-block;
margin-right: 7px;
margin-bottom: 1px;
}
.aws-scoutsuite-key-configuration .collapse-item .btn-collapse p {
display: inline-block;
margin-bottom: 0;
font-size: 1.2em;
margin-left: 5px
}
.aws-scoutsuite-key-configuration .key-creation-tutorial {
padding-bottom: 10px;
}
.aws-scoutsuite-key-configuration .key-creation-tutorial p {
margin-bottom: 2px;
font-weight: 400;
}
.aws-scoutsuite-key-configuration .key-creation-tutorial h5 {
margin-top: 15px;
font-weight: 600;
}
.aws-scoutsuite-key-configuration .key-creation-tutorial p:first-child {
margin-top: 15px;
}
.aws-scoutsuite-key-configuration .image-modal {
margin-top: 5px;
}
.aws-scoutsuite-key-configuration .key-creation-tutorial img {
max-width: 100%;
max-height: 100%;
border: 1px solid black;
}
.link-in-success-message {
padding: 0 !important;
vertical-align: initial !important;
}

View File

@ -1,21 +0,0 @@
.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 {
margin-right:5px;
font-weight: 500;
margin-bottom: 0;
}

View File

@ -1,21 +0,0 @@
.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;
}

View File

@ -1,9 +0,0 @@
.scoutsuite-rule-modal .modal-dialog {
max-width: 1000px;
top: 0;
padding: 30px;
}
.collapse-item.rule-collapse button > span:nth-child(2) {
flex: 1
}

View File

@ -1,20 +1,9 @@
from unittest import TestCase
from common.network.network_utils import (
address_to_ip_port,
get_host_from_network_location,
remove_port,
)
from common.network.network_utils import address_to_ip_port, remove_port
class TestNetworkUtils(TestCase):
def test_get_host_from_network_location(self):
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
assert get_host_from_network_location("127.0.0.1") == "127.0.0.1"
assert get_host_from_network_location("www.google.com:8080") == "www.google.com"
assert get_host_from_network_location("user:password@host:8080") == "host"
def test_remove_port_from_url(self):
assert remove_port("https://google.com:80") == "https://google.com"
assert remove_port("https://8.8.8.8:65336") == "https://8.8.8.8"

View File

@ -1,45 +0,0 @@
import pytest
from mongoengine import ValidationError
from tests.unit_tests.monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data import ( # noqa: E501
RULES,
)
import common.common_consts.zero_trust_consts as zero_trust_consts
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.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
MONKEY_FINDING_DETAIL_MOCK = MonkeyFindingDetails()
MONKEY_FINDING_DETAIL_MOCK.events = ["mock1", "mock2"]
SCOUTSUITE_FINDING_DETAIL_MOCK = ScoutSuiteFindingDetails()
SCOUTSUITE_FINDING_DETAIL_MOCK.scoutsuite_rules = []
class TestScoutSuiteFinding:
@pytest.mark.usefixtures("uses_database")
def test_save_finding_validation(self):
with pytest.raises(ValidationError):
_ = ScoutSuiteFinding.save_finding(
test=zero_trust_consts.TEST_SEGMENTATION,
status="bla bla",
detail_ref=SCOUTSUITE_FINDING_DETAIL_MOCK,
)
@pytest.mark.usefixtures("uses_database")
def test_save_finding_sanity(self):
assert len(Finding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 0
rule_example = RULES[0]
scoutsuite_details_example = ScoutSuiteFindingDetails()
scoutsuite_details_example.scoutsuite_rules.append(rule_example)
scoutsuite_details_example.save()
ScoutSuiteFinding.save_finding(
test=zero_trust_consts.TEST_SEGMENTATION,
status=zero_trust_consts.STATUS_FAILED,
detail_ref=scoutsuite_details_example,
)
assert len(ScoutSuiteFinding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 1
assert len(ScoutSuiteFinding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1
assert len(Finding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1

View File

@ -1,169 +0,0 @@
# This is what our codebase receives after running ScoutSuite module.
# Object '...': {'...': '...'} represents continuation of similar objects as above
RAW_SCOUTSUITE_DATA = {
"sg_map": {
"sg-abc": {"region": "ap-northeast-1", "vpc_id": "vpc-abc"},
"sg-abcd": {"region": "ap-northeast-2", "vpc_id": "vpc-abc"},
"...": {"...": "..."},
},
"subnet_map": {
"subnet-abc": {"region": "ap-northeast-1", "vpc_id": "vpc-abc"},
"subnet-abcd": {"region": "ap-northeast-1", "vpc_id": "vpc-abc"},
"...": {"...": "..."},
},
"provider_code": "aws",
"provider_name": "Amazon Web Services",
"environment": None,
"result_format": "json",
"partition": "aws",
"account_id": "125686982355",
"last_run": {
"time": "2021-02-05 16:03:04+0200",
"run_parameters": {
"services": [],
"skipped_services": [],
"regions": [],
"excluded_regions": [],
},
"version": "5.10.0",
"ruleset_name": "default",
"ruleset_about": "This ruleset",
"summary": {
"ec2": {
"checked_items": 3747,
"flagged_items": 262,
"max_level": "warning",
"rules_count": 28,
"resources_count": 176,
},
"s3": {
"checked_items": 88,
"flagged_items": 25,
"max_level": "danger",
"rules_count": 18,
"resources_count": 5,
},
"...": {"...": "..."},
},
},
"metadata": {
"compute": {
"summaries": {
"external attack surface": {
"cols": 1,
"path": "service_groups.compute.summaries.external_attack_surface",
"callbacks": [["merge", {"attribute": "external_attack_surface"}]],
}
},
"...": {"...": "..."},
},
"...": {"...": "..."},
},
# This is the important part, which we parse to get resources
"services": {
"ec2": {
"regions": {
"ap-northeast-1": {
"vpcs": {
"vpc-abc": {
"id": "vpc-abc",
"security_groups": {
"sg-abc": {
"name": "default",
"rules": {
"ingress": {
"protocols": {
"ALL": {
"ports": {
"1-65535": {
"cidrs": [{"CIDR": "0.0.0.0/0"}]
}
}
}
},
"count": 1,
},
"egress": {
"protocols": {
"ALL": {
"ports": {
"1-65535": {
"cidrs": [{"CIDR": "0.0.0.0/0"}]
}
}
}
},
"count": 1,
},
},
}
},
}
},
"...": {"...": "..."},
}
},
# Interesting info, maybe could be used somewhere in the report
"external_attack_surface": {
"52.52.52.52": {
"protocols": {"TCP": {"ports": {"22": {"cidrs": [{"CIDR": "0.0.0.0/0"}]}}}},
"InstanceName": "InstanceName",
"PublicDnsName": "ec2-52-52-52-52.eu-central-1.compute.amazonaws.com",
}
},
# We parse these into ScoutSuite security rules
"findings": {
"ec2-security-group-opens-all-ports-to-all": {
"description": "Security Group Opens All Ports to All",
"path": "ec2.regions.id.vpcs.id.security_groups"
".id.rules.id.protocols.id.ports.id.cidrs.id.CIDR",
"level": "danger",
"display_path": "ec2.regions.id.vpcs.id.security_groups.id",
"items": [
"ec2.regions.ap-northeast-1.vpcs.vpc-abc.security_groups"
".sg-abc.rules.ingress.protocols.ALL.ports.1-65535.cidrs.0.CIDR"
],
"dashboard_name": "Rules",
"checked_items": 179,
"flagged_items": 2,
"service": "EC2",
"rationale": "It was detected that all ports in the security group are "
"open <...>",
"remediation": None,
"compliance": None,
"references": None,
},
"...": {"...": "..."},
},
},
"...": {"...": "..."},
},
"service_list": [
"acm",
"awslambda",
"cloudformation",
"cloudtrail",
"cloudwatch",
"config",
"directconnect",
"dynamodb",
"ec2",
"efs",
"elasticache",
"elb",
"elbv2",
"emr",
"iam",
"kms",
"rds",
"redshift",
"route53",
"s3",
"ses",
"sns",
"sqs",
"vpc",
"secretsmanager",
],
"service_groups": {"...": {"...": "..."}},
}

View File

@ -1,48 +0,0 @@
from enum import Enum
import pytest
from tests.unit_tests.monkey_island.cc.services.zero_trust.raw_scoutsute_data import (
RAW_SCOUTSUITE_DATA,
)
from common.utils.exceptions import RulePathCreatorNotFound
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ec2_rules import EC2Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICES
from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_parser import RuleParser
class ExampleRules(Enum):
NON_EXSISTENT_RULE = "bogus_rule"
ALL_PORTS_OPEN = EC2Rules.SECURITY_GROUP_ALL_PORTS_TO_ALL
EXPECTED_RESULT = {
"description": "Security Group Opens All Ports to All",
"path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id"
".cidrs.id.CIDR",
"level": "danger",
"display_path": "ec2.regions.id.vpcs.id.security_groups.id",
"items": [
"ec2.regions.ap-northeast-1.vpcs.vpc-abc.security_groups."
"sg-abc.rules.ingress.protocols.ALL.ports.1-65535.cidrs.0.CIDR"
],
"dashboard_name": "Rules",
"checked_items": 179,
"flagged_items": 2,
"service": "EC2",
"rationale": "It was detected that all ports in the security group are open <...>",
"remediation": None,
"compliance": None,
"references": None,
}
def test_get_rule_data():
# Test proper parsing of the raw data to rule
results = RuleParser.get_rule_data(RAW_SCOUTSUITE_DATA[SERVICES], ALL_PORTS_OPEN)
assert results == EXPECTED_RESULT
with pytest.raises(RulePathCreatorNotFound):
RuleParser.get_rule_data(RAW_SCOUTSUITE_DATA[SERVICES], ExampleRules.NON_EXSISTENT_RULE)
pass

View File

@ -1,38 +0,0 @@
from unittest.mock import MagicMock
import dpath.util
import pytest
from common.config_value_paths import AWS_KEYS_PATH
from monkey_island.cc.database import mongo
from monkey_island.cc.server_utils.encryption import get_datastore_encryptor
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_auth_service import (
is_aws_keys_setup,
)
class MockObject:
pass
@pytest.mark.slow
@pytest.mark.usefixtures("uses_database", "uses_encryptor")
def test_is_aws_keys_setup(tmp_path):
# Mock default configuration
ConfigService.init_default_config()
mongo.db = MockObject()
mongo.db.config = MockObject()
ConfigService.encrypt_config(ConfigService.default_config)
mongo.db.config.find_one = MagicMock(return_value=ConfigService.default_config)
assert not is_aws_keys_setup()
bogus_key_value = get_datastore_encryptor().encrypt("bogus_aws_key")
dpath.util.set(
ConfigService.default_config, AWS_KEYS_PATH + ["aws_secret_access_key"], bogus_key_value
)
dpath.util.set(
ConfigService.default_config, AWS_KEYS_PATH + ["aws_access_key_id"], bogus_key_value
)
assert is_aws_keys_setup()

View File

@ -1,66 +0,0 @@
from copy import deepcopy
from tests.unit_tests.monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data import ( # noqa: E501
RULES,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_consts import (
RULE_LEVEL_DANGER,
RULE_LEVEL_WARNING,
)
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import (
ScoutSuiteRuleService,
)
example_scoutsuite_data = {
"checked_items": 179,
"compliance": None,
"dashboard_name": "Rules",
"description": "Security Group Opens All Ports to All",
"flagged_items": 2,
"items": [
"ec2.regions.eu-central-1.vpcs.vpc-0ee259b1a13c50229.security_groups.sg-035779fe5c293fc72"
".rules.ingress.protocols.ALL.ports.1-65535.cidrs.2.CIDR",
"ec2.regions.eu-central-1.vpcs.vpc-00015526b6695f9aa.security_groups.sg-019eb67135ec81e65"
".rules.ingress.protocols.ALL.ports.1-65535.cidrs.0.CIDR",
],
"level": "danger",
"path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id"
".cidrs.id.CIDR",
"rationale": "It was detected that all ports in the security group are open, "
"and any source IP address"
" could send traffic to these ports, which creates a wider attack surface "
"for resources "
"assigned to it. Open ports should be reduced to the minimum needed to "
"correctly",
"references": [],
"remediation": None,
"service": "EC2",
}
def test_get_rule_from_rule_data():
assert ScoutSuiteRuleService.get_rule_from_rule_data(example_scoutsuite_data) == RULES[0]
def test_is_rule_dangerous():
test_rule = deepcopy(RULES[0])
assert ScoutSuiteRuleService.is_rule_dangerous(test_rule)
test_rule.level = RULE_LEVEL_WARNING
assert not ScoutSuiteRuleService.is_rule_dangerous(test_rule)
test_rule.level = RULE_LEVEL_DANGER
test_rule.items = []
assert not ScoutSuiteRuleService.is_rule_dangerous(test_rule)
def test_is_rule_warning():
test_rule = deepcopy(RULES[0])
assert not ScoutSuiteRuleService.is_rule_warning(test_rule)
test_rule.level = RULE_LEVEL_WARNING
assert ScoutSuiteRuleService.is_rule_warning(test_rule)
test_rule.items = []
assert not ScoutSuiteRuleService.is_rule_warning(test_rule)

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