Island: Remove ScoutSuiteRuleService
This commit is contained in:
parent
5423bbbb35
commit
d2947796ff
|
@ -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."
|
|
||||||
)
|
|
|
@ -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
|
|
|
@ -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": {"...": {"...": "..."}},
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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)
|
|
Loading…
Reference in New Issue