diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py index 7a6b924c8..4b3093545 100644 --- a/monkey/monkey_island/cc/models/zero_trust/finding.py +++ b/monkey/monkey_island/cc/models/zero_trust/finding.py @@ -2,6 +2,8 @@ """ Define a Document Schema for Zero Trust findings. """ + +from __future__ import annotations from typing import Union from mongoengine import Document, GenericLazyReferenceField, StringField @@ -50,13 +52,13 @@ class Finding(Document): @staticmethod def save_finding(test: str, status: str, - detail_ref: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]): - temp_finding = Finding(test=test, - status=status, - details=detail_ref, - finding_type=Finding._get_finding_type_by_details(detail_ref)) - temp_finding.save() - return temp_finding + detail_ref: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]) -> Finding: + finding = Finding(test=test, + status=status, + details=detail_ref, + finding_type=Finding._get_finding_type_by_details(detail_ref)) + finding.save() + return finding @staticmethod def _get_finding_type_by_details(details: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]) -> str: diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py index 2ec8f6182..7fa96544b 100644 --- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py +++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings.py @@ -1,3 +1,5 @@ +from abc import ABC, abstractmethod + 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 @@ -16,7 +18,19 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sqs_rules from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.vpc_rules import VPCRules -class PERMISSIVE_FIREWALL_RULES: +class ScoutSuiteFinding(ABC): + @property + @abstractmethod + def rules(self): + pass + + @property + @abstractmethod + def test(self): + pass + + +class PermissiveFirewallRules(ScoutSuiteFinding): 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, @@ -41,7 +55,7 @@ class PERMISSIVE_FIREWALL_RULES: test = zero_trust_consts.TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES -class UNENCRYPTED_DATA: +class UnencryptedData(ScoutSuiteFinding): 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, @@ -54,7 +68,7 @@ class UNENCRYPTED_DATA: test = zero_trust_consts.TEST_SCOUTSUITE_UNENCRYPTED_DATA -class DATA_LOSS_PREVENTION: +class DataLossPrevention(ScoutSuiteFinding): 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] @@ -62,7 +76,7 @@ class DATA_LOSS_PREVENTION: test = zero_trust_consts.TEST_SCOUTSUITE_DATA_LOSS_PREVENTION -class SECURE_AUTHENTICATION: +class SecureAuthentication(ScoutSuiteFinding): rules = [ IAMRules.IAM_USER_NO_ACTIVE_KEY_ROTATION, IAMRules.IAM_PASSWORD_POLICY_MINIMUM_LENGTH, @@ -80,7 +94,7 @@ class SECURE_AUTHENTICATION: test = zero_trust_consts.TEST_SCOUTSUITE_SECURE_AUTHENTICATION -class RESTRICTIVE_POLICIES: +class RestrictivePolicies(ScoutSuiteFinding): rules = [ IAMRules.IAM_ASSUME_ROLE_POLICY_ALLOWS_ALL, IAMRules.IAM_EC2_ROLE_WITHOUT_INSTANCES, @@ -142,7 +156,7 @@ class RESTRICTIVE_POLICIES: test = zero_trust_consts.TEST_SCOUTSUITE_RESTRICTIVE_POLICIES -class LOGGING: +class Logging(ScoutSuiteFinding): rules = [ CloudTrailRules.CLOUDTRAIL_DUPLICATED_GLOBAL_SERVICES_LOGGING, CloudTrailRules.CLOUDTRAIL_NO_DATA_LOGGING, @@ -162,7 +176,7 @@ class LOGGING: test = zero_trust_consts.TEST_SCOUTSUITE_LOGGING -class SERVICE_SECURITY: +class ServiceSecurity(ScoutSuiteFinding): rules = [ CloudformationRules.CLOUDFORMATION_STACK_WITH_ROLE, ELBv2Rules.ELBV2_HTTP_REQUEST_SMUGGLING, diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py index 7f7a42c5e..72a4cb47a 100644 --- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py +++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/findings_list.py @@ -1,8 +1,8 @@ -from monkey_island.cc.services.zero_trust.scoutsuite.consts.findings import (DATA_LOSS_PREVENTION, LOGGING, - PERMISSIVE_FIREWALL_RULES, - RESTRICTIVE_POLICIES, - SECURE_AUTHENTICATION, SERVICE_SECURITY, - UNENCRYPTED_DATA) +from monkey_island.cc.services.zero_trust.scoutsuite.consts.findings import (DataLossPrevention, Logging, + PermissiveFirewallRules, + RestrictivePolicies, + SecureAuthentication, ServiceSecurity, + UnencryptedData) -SCOUTSUITE_FINDINGS = [PERMISSIVE_FIREWALL_RULES, UNENCRYPTED_DATA, DATA_LOSS_PREVENTION, SECURE_AUTHENTICATION, - RESTRICTIVE_POLICIES, LOGGING, SERVICE_SECURITY] +SCOUTSUITE_FINDINGS = [PermissiveFirewallRules, UnencryptedData, DataLossPrevention, SecureAuthentication, + RestrictivePolicies, Logging, ServiceSecurity] diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py index 8424e61c9..eff9e64b0 100644 --- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py +++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_finding_service.py @@ -4,14 +4,14 @@ from common.common_consts import zero_trust_consts from monkey_island.cc.models.zero_trust.finding import Finding from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule +from monkey_island.cc.services.zero_trust.scoutsuite.consts.findings import ScoutSuiteFinding from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import ScoutSuiteRuleService class ScoutSuiteFindingService: @staticmethod - # TODO add type hinting like finding: Union[SCOUTSUITE_FINDINGS]? - def process_rule(finding, rule: ScoutSuiteRule): + def process_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule): existing_findings = Finding.objects(test=finding.test, finding_type=zero_trust_consts.SCOUTSUITE_FINDING) assert (len(existing_findings) < 2), "More than one finding exists for {}".format(finding.test) @@ -21,7 +21,7 @@ class ScoutSuiteFindingService: ScoutSuiteFindingService.add_rule(existing_findings[0], rule) @staticmethod - def create_new_finding_from_rule(finding, rule: ScoutSuiteRule): + def create_new_finding_from_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule): details = ScoutSuiteFindingDetails() details.scoutsuite_rules = [rule] details.save()