Skip to content

Commit

Permalink
Merge pull request #1635 from nccgroup/develop
Browse files Browse the repository at this point in the history
Release 5.14.0
  • Loading branch information
fernando-gallego authored May 10, 2024
2 parents 7feb470 + 4194142 commit 7909f2f
Show file tree
Hide file tree
Showing 122 changed files with 2,752 additions and 210 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The following cloud providers are currently supported:
- Alibaba Cloud (alpha)
- Oracle Cloud Infrastructure (alpha)
- Kubernetes clusters on a cloud provider (alpha)
- DigitalOcean Cloud (alpha)

## Installation

Expand Down
2 changes: 1 addition & 1 deletion ScoutSuite/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = 'NCC Group'
__version__ = '5.13.0'
__version__ = '5.14.0'

ERRORS_LIST = []

Expand Down
17 changes: 17 additions & 0 deletions ScoutSuite/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ def run_from_cli():
kubernetes_context=args.get('kubernetes_context'),
kubernetes_persist_config=args.get('kubernetes_persist_config'),
kubernetes_azure_subscription_id=args.get('kubernetes_azure_subscription_id'),
#DigitalOcean
token=args.get('token'),
access_key=args.get('access_key'),
access_secret=args.get('access_secret'),
# General
report_name=args.get('report_name'), report_dir=args.get('report_dir'),
timestamp=args.get('timestamp'),
Expand Down Expand Up @@ -113,6 +117,10 @@ def run(provider,
kubernetes_context=None,
kubernetes_persist_config=True,
kubernetes_azure_subscription_id=None,
#DigitalOcean
token=None,
access_key=None,
access_secret=None,
# General
report_name=None, report_dir=None,
timestamp=False,
Expand Down Expand Up @@ -171,6 +179,10 @@ async def _run(provider,
kubernetes_context,
kubernetes_persist_config,
kubernetes_azure_subscription_id,
#DigitalOcean
token,
access_key,
access_secret,
# General
report_name, report_dir,
timestamp,
Expand Down Expand Up @@ -221,6 +233,11 @@ async def _run(provider,
access_key_id=access_key_id,
access_key_secret=access_key_secret,

#DigitalOcean
token=token,
access_key=access_key,
access_secret=access_secret,

# Kubernetes
kubernetes_cluster_provider=kubernetes_cluster_provider,
kubernetes_config_file=kubernetes_config_file,
Expand Down
32 changes: 32 additions & 0 deletions ScoutSuite/core/cli_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self):
self._init_aliyun_parser()
self._init_oci_parser()
self._init_kubernetes_parser()
self._init_do_parser()

def _init_aws_parser(self):
parser = self.subparsers.add_parser("aws",
Expand Down Expand Up @@ -254,6 +255,32 @@ def _init_oci_parser(self):
dest='profile',
default=None,
help='Name of the profile')

def _init_do_parser(self):
do_parser = self.subparsers.add_parser("do",
parents=[self.common_providers_args_parser],
help="Run Scout against an DigitalOcean account")

parser = do_parser.add_argument_group('Authentication parameters')

parser.add_argument('-t',
'--token',
action='store',
default=None,
dest='token',
help='DO Token')

parser.add_argument('--access_key',
action='store',
default=None,
dest='access_key',
help='Spaces Access Key ID')
parser.add_argument('--access_secret',
action='store',
default=None,
dest='access_secret',
help='Spaces Secret Access Key')


def _init_kubernetes_parser(self):
kubernetes_parser = self.subparsers.add_parser("kubernetes",
Expand Down Expand Up @@ -436,6 +463,11 @@ def parse_args(self, args=None):
if v.get('subscription_ids') and v.get('all_subscriptions'):
self.parser.error('--subscription-ids and --all-subscriptions are mutually exclusive options')

# DigitalOcean
if v.get('provider') == 'do':
if (v.get('access_key') or v.get('access_secret')) and not (v.get('access_key') and v.get('access_secret')):
self.parser.error('For DO Spaces service please provide both --access_key and --access_secret')

# Kubernetes
elif v.get('provider') == 'kubernetes':
cluster_provider = v.get('kubernetes_cluster_provider')
Expand Down
6 changes: 5 additions & 1 deletion ScoutSuite/core/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,13 @@ def pass_condition(b, test, a):

# Dictionary keys tests
elif test == 'withKey':
result = (a in b)
result = a in b
elif test == 'withoutKey':
result = a not in b
elif test == 'withKeyCaseInsensitive':
result = a.lower() in map(str.lower, b)
elif test == 'withoutKeyCaseInsensitive':
result = a.lower() not in map(str.lower, b)

# String test
elif test == 'containString':
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- EC2 regional settings partial -->
<script id="services.ec2.regions.id.regional_settings.partial" type="text/x-handlebars-template">
<div id="resource-name" class="list-group-item active">
<h4 class="list-group-item-heading">{{region}}</h4>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">Regional settings</h4>
<ul>
<li class="list-group-item-text">Encryption enabled for EBS Volumes by default: <span id="ec2.regions.{{region}}.regional_settings.{{@key}}.NoDefaultEBSEncryption"><samp>{{ebs_encryption_default}}</samp></span></li>
<li class="list-group-item-text">Default encryption key: <span id="ec2.regions.{{region}}.regional_settings.{{@key}}.ebs_default_encryption_key"><samp>{{ebs_default_encryption_key_id}}</samp></span></li>
</ul>
</div>
</script>

<script>
Handlebars.registerPartial("services.ec2.regions.id.regional_settings", $("#services\\.ec2\\.regions\\.id\\.regional_settings\\.partial").html());
</script>

<!-- Single region template -->
<!-- **UNTESTED** Intended for details popups. Not used at this time. -->
<script id="single_ec2_region-template" type="text/x-handlebars-template">
{{> modal-template template='services.ec2.regions.id.regional_settings'}}
</script>
<script>
var single_ec2_region_template = Handlebars.compile($("#single_ec2_region-template").html());
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
<h4 class="list-group-item-heading">{{name}}</h4>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">Attributes</h4>
{{> generic_object this}}
<h4 class="list-group-item-heading">Information</h4>
<div class="list-group-item-text item-margin">ID: <span id="ec2.regions.{{region}}.volumes.{{@key}}.id"><samp>{{value_or_none id}}</samp></span></div>
<div class="list-group-item-text item-margin">ARN: <span id="ec2.regions.{{region}}.volumes.{{@key}}.arn"><samp>{{value_or_none arn}}</samp></span></div>
<div class="list-group-item-text item-margin">Name: <span id="ec2.regions.{{region}}.volumes.{{@key}}.name"><samp>{{value_or_none name}}</samp></span></div>
<div class="list-group-item-text item-margin">State: <span id="ec2.regions.{{region}}.volumes.{{@key}}.state"><samp>{{value_or_none State}}</samp></span></div>
<div class="list-group-item-text item-margin">Size: <span id="ec2.regions.{{region}}.volumes.{{@key}}.size"><samp>{{value_or_none Size}} GiB</samp></span></div>
<div class="list-group-item-text item-margin">Volume Type: <span id="ec2.regions.{{region}}.volumes.{{@key}}.volume_type"><samp>{{value_or_none VolumeType}}</samp></span></div>
<div class="list-group-item-text item-margin">Create Time: <span id="ec2.regions.{{region}}.volumes.{{@key}}.create_time"><samp>{{value_or_none CreateTime}}</samp></span></div>
<div class="list-group-item-text item-margin">Encryption: <span id="ec2.regions.{{region}}.volumes.{{@key}}.encrypted">{{convert_bool_to_enabled Encrypted}}</span></div>
</div>
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ <h4 class="list-group-item-heading">{{name}}</h4>
<h4 class="list-group-item-heading">Credentials Report</h4>
<div class="list-group-item-text item-margin">Creation Date: {{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'user_creation_time')}}</div>
<div class="list-group-item-text item-margin">Last Used Date: <span id="iam.credential_reports.{{@key}}.inactive_user">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'last_used')}}</span></div>
<div class="list-group-item-text item-margin">Password Enabled: <span class="iam.credential_reports.{{@key}}.unused_credentials"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'password_enabled'}}</samp></span></div>
<div class="list-group-item-text item-margin">Password Last Used: <span class="iam.credential_reports.{{@key}}.unused_credentials" id="iam.credential_reports.{{@key}}.password_last_used">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'password_last_used')}}</span></div>
<div class="list-group-item-text item-margin">Password Enabled: <span {{#ifEqual password_enabled 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}}><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'password_enabled'}}</samp></span></div>
<div class="list-group-item-text item-margin">Password Last Used: <span {{#ifEqual password_enabled 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}} id="iam.credential_reports.{{@key}}.password_last_used">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'password_last_used')}}</span></div>
<div class="list-group-item-text item-margin">Password Last Changed: <span>{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'password_last_changed')}}</span></div>
<div class="list-group-item-text item-margin">MFA Active: <span id="iam.credential_reports.{{@key}}.mfa_active"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'mfa_active'}}</samp></span></div>
<div class="list-group-item-text item-margin">Hardware MFA Active: <span id="iam.credential_reports.{{@key}}.mfa_active_hardware"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'mfa_active_hardware'}}</samp></span></div>
<div class="list-group-item-text item-margin">Access Key 1 Active: <span class="iam.credential_reports.{{@key}}.unused_credentials" id="iam.credential_reports.{{@key}}.access_key_1_active"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_1_active'}}</samp></span></div>
<div class="list-group-item-text item-margin">Access Key 1 Last Used: <span class="iam.credential_reports.{{@key}}.unused_credentials" class="iam.credential_reports.{{@key}}.unused_access_key">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_1_last_used_date')}}</span></div>
<div class="list-group-item-text item-margin">Access Key 1 Active: <span {{#ifEqual access_key_1_active 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}} id="iam.credential_reports.{{@key}}.access_key_1_active"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_1_active'}}</samp></span></div>
<div class="list-group-item-text item-margin">Access Key 1 Last Used: <span {{#ifEqual access_key_1_active 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}} class="iam.credential_reports.{{@key}}.unused_access_key">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_1_last_used_date')}}</span></div>
<div class="list-group-item-text item-margin">Access Key 1 Last Rotated: <span>{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_1_last_rotated')}}</span></div>
<div class="list-group-item-text item-margin">Access Key 2 Active: <span class="iam.credential_reports.{{@key}}.unused_credentials" id="iam.credential_reports.{{@key}}.access_key_2_active"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_2_active'}}</samp></span></div>
<div class="list-group-item-text item-margin">Access Key 2 Last Used: <span class="iam.credential_reports.{{@key}}.unused_credentials" class="iam.credential_reports.{{@key}}.unused_access_key">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_2_last_used_date')}}</span></div>
<div class="list-group-item-text item-margin">Access Key 2 Active: <span {{#ifEqual access_key_2_active 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}} id="iam.credential_reports.{{@key}}.access_key_2_active"><samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_2_active'}}</samp></span></div>
<div class="list-group-item-text item-margin">Access Key 2 Last Used: <span {{#ifEqual access_key_2_active 'true'}}class="iam.credential_reports.{{@key}}.unused_credentials"{{/ifEqual}} class="iam.credential_reports.{{@key}}.unused_access_key">{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_2_last_used_date')}}</span></div>
<div class="list-group-item-text item-margin">Access Key 2 Last Rotated: <span>{{ format_date (getValueAt 'services' 'iam' 'credential_reports' @key 'access_key_2_last_rotated')}}</span></div>
<div class="list-group-item-text item-margin">Signing Cert 1 Active: <samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'cert_1_active'}}</samp></div>
<div class="list-group-item-text item-margin">Signing Cert 2 Active: <samp>{{getValueAt 'services' 'iam' 'credential_reports' @key 'cert_2_active'}}</samp></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ <h4 class="list-group-item-heading">Information</h4>
<div class="list-group-item-text item-margin">Public Traffic: <span id="storageaccounts.subscriptions.{{@../key}}.storage_accounts.{{@key}}.public_traffic_allowed">{{convert_bool_to_enabled public_traffic_allowed }}</span></div>
<div class="list-group-item-text item-margin">HTTPS Required: <span id="storageaccounts.subscriptions.{{@../key}}.storage_accounts.{{@key}}.https_traffic_enabled">{{convert_bool_to_enabled https_traffic_enabled}}</span></div>
<div class="list-group-item-text item-margin">Microsoft Trusted Services: <span id="storageaccounts.subscriptions.{{@../key}}.storage_accounts.{{@key}}.trusted_microsoft_services_enabled">{{convert_bool_to_enabled trusted_microsoft_services_enabled }}</span></div>
<div class="list-group-item-text item-margin">Access Key Usage: <span id="storageaccounts.subscriptions.{{@../key}}.storage_accounts.{{@key}}.shared_key_access_allowed">{{convert_bool_to_enabled shared_key_access_allowed}}</span></div>
<div class="list-group-item-text item-margin">Last Access Key Rotation:
<span id="storageaccounts.subscriptions.{{@../key}}.storage_accounts.{{@key}}.access_keys_rotated">
{{#if access_keys_last_rotation_date }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!-- database databases -->
<script id="services.database.databases.partial" type="text/x-handlebars-template">
<div id="resource-name" class="list-group-item active">
<h4 class="list-group-item-heading">{{name}}</h4>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">Information</h4>
<div class="list-group-item-text item-margin">Id: <span id="database.databases.{{@key}}.id"><samp>{{value_or_none id}}</samp></span></div>
<div class="list-group-item-text item-margin">Name: <span id="database.databases.{{@key}}.name"><samp>{{value_or_none name}}</samp></span></div>
<div class="list-group-item-text item-margin">Engine: <span id="database.databases.{{@key}}.engine"><samp>{{value_or_none engine}}</samp></span></div>
<div class="list-group-item-text item-margin">Version: <span id="database.databases.{{@key}}.version"><samp>{{value_or_none version}}</samp></span></div>
<div class="list-group-item-text item-margin">Semantic Version: <span id="database.databases.{{@key}}.semantic_version">
<samp>{{value_or_none semantic_version}}</samp></span></div>
<div class="list-group-item-text item-margin">Connection Pools: <span id="database.databases.{{@key}}.connection_pools"><samp>{{value_or_none connection_pools}}</samp></span></div>
<div class="list-group-item-text item-margin">Eviciton Policy: <span id="database.databases.{{@key}}.eviction_policy"><samp>{{value_or_none eviction_policy}}</samp></span></div>
<div class="list-group-item-text item-margin">Legacy Password encryption: <span id="database.databases.{{@key}}.legacy_encryption_users"><samp>{{value_or_none legacy_encryption_users}}</samp></span></div>
<div class="list-group-item-text item-margin">Tags: <span id="database.databases.{{@key}}.tags"><samp>{{value_or_none tags}}</samp></span></div>
<div class="list-group-item-text item-margin">Databases: <span id="database.databases.{{@key}}.databases"><samp>{{value_or_none databases}}</samp></span></div>
<div class="list-group-item-text item-margin">Trusted Sources: <span id="database.databases.{{@key}}.trusted_sources"><samp>{{value_or_none trusted_resources}}</samp></span></div>
</div>
</script>

<script>
Handlebars.registerPartial("services.database.databases", $("#services\\.database\\.databases\\.partial").html());
</script>

<!-- Single database database template -->
<script id="single_database_database-template" type="text/x-handlebars-template">
{{> modal-template template='services.database.databases'}}
</script>
<script>
var single_database_database_template = Handlebars.compile($("#single_database_database-template").html());
</script>
Loading

0 comments on commit 7909f2f

Please sign in to comment.