Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve output of risk severity field. #191

Merged
merged 4 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions contentctl/objects/detection_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@
from contentctl.objects.mitre_attack_enrichment import MitreAttackEnrichment
from contentctl.objects.constants import ATTACK_TACTICS_KILLCHAIN_MAPPING
from contentctl.objects.observable import Observable
from contentctl.objects.enums import Cis18Value, AssetType, SecurityDomain, RiskSeverity, KillChainPhase, NistCategory, SecurityContentProductName
from contentctl.objects.enums import (
Cis18Value,
AssetType,
SecurityDomain,
RiskSeverity,
KillChainPhase,
NistCategory,
RiskLevel,
SecurityContentProductName
)

from contentctl.objects.atomic import AtomicTest
from contentctl.objects.annotated_types import MITRE_ATTACK_ID_TYPE, CVE_TYPE

Expand All @@ -50,6 +51,23 @@ class DetectionTags(BaseModel):
@property
def risk_score(self) -> int:
return round((self.confidence * self.impact)/100)

@computed_field
@property
def severity(self)->RiskSeverity:
if 0 <= self.risk_score <= 20:
return RiskSeverity.INFO
elif 20 < self.risk_score <= 40:
return RiskSeverity.LOW
elif 40 < self.risk_score <= 60:
return RiskSeverity.MEDIUM
elif 60 < self.risk_score <= 80:
return RiskSeverity.HIGH
elif 80 < self.risk_score <= 100:
return RiskSeverity.CRITICAL
else:
raise Exception(f"Error getting severity - risk_score must be between 0-100, but was actually {self.risk_score}")


mitre_attack_id: List[MITRE_ATTACK_ID_TYPE] = []
nist: list[NistCategory] = []
Expand All @@ -59,17 +77,6 @@ def risk_score(self) -> int:
required_fields: list[str] = Field(min_length=1)
throttling: Optional[Throttling] = None
security_domain: SecurityDomain = Field(...)

@computed_field
@property
def risk_severity(self) -> RiskSeverity:
if self.risk_score >= 80:
return RiskSeverity('high')
elif (self.risk_score >= 50 and self.risk_score <= 79):
return RiskSeverity('medium')
else:
return RiskSeverity('low')

cve: List[CVE_TYPE] = []
atomic_guid: List[AtomicTest] = []
drilldown_search: Optional[str] = None
Expand All @@ -78,10 +85,6 @@ def risk_severity(self) -> RiskSeverity:
mitre_attack_enrichments: List[MitreAttackEnrichment] = Field([], validate_default=True)
confidence_id: Optional[PositiveInt] = Field(None, ge=1, le=3)
impact_id: Optional[PositiveInt] = Field(None, ge=1, le=5)
# context_ids: list = None
risk_level_id: Optional[NonNegativeInt] = Field(None, le=4)
risk_level: Optional[RiskLevel] = None
# observable_str: str = None
evidence_str: Optional[str] = None

@computed_field
Expand Down Expand Up @@ -157,7 +160,7 @@ def serialize_model(self):
"message": self.message,
"risk_score": self.risk_score,
"security_domain": self.security_domain,
"risk_severity": self.risk_severity,
"risk_severity": self.severity,
"mitre_attack_id": self.mitre_attack_id,
"mitre_attack_enrichments": self.mitre_attack_enrichments
}
Expand Down
14 changes: 8 additions & 6 deletions contentctl/objects/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,14 +409,16 @@ class NistCategory(str, enum.Enum):
RC_IM = "RC.IM"
RC_CO = "RC.CO"

class RiskLevel(str,enum.Enum):
class RiskSeverity(str,enum.Enum):
# Levels taken from the following documentation link
# https://docs.splunk.com/Documentation/ES/7.3.2/User/RiskScoring
# 20 - Info (0-20 for us)
# 40 - Low (21-40 for us)
# 60 - Medium (41-60 for us)
# 80 - High (61-80 for us)
# 100 - Critical (81 - 100 for us)
INFO = "Info"
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
CRITICAL = "Critical"

class RiskSeverity(str,enum.Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
2 changes: 1 addition & 1 deletion contentctl/output/templates/savedsearches_detections.j2
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ action.notable.param.nes_fields = {{ detection.nes_fields }}
action.notable.param.rule_description = {{ detection.deployment.alert_action.notable.rule_description | custom_jinja2_enrichment_filter(detection) | escapeNewlines()}}
action.notable.param.rule_title = {% if detection.type | lower == "correlation" %}RBA: {{ detection.deployment.alert_action.notable.rule_title | custom_jinja2_enrichment_filter(detection) }}{% else %}{{ detection.deployment.alert_action.notable.rule_title | custom_jinja2_enrichment_filter(detection) }}{% endif +%}
action.notable.param.security_domain = {{ detection.tags.security_domain.value }}
action.notable.param.severity = high
action.notable.param.severity = {{ detection.tags.severity.value }}
{% endif %}
{% if detection.deployment.alert_action.email %}
action.email.subject.alert = {{ detection.deployment.alert_action.email.subject | custom_jinja2_enrichment_filter(detection) | escapeNewlines() }}
Expand Down
Loading