regscale-cli 6.27.3.0__py3-none-any.whl → 6.28.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/_version.py +1 -1
- regscale/core/app/utils/app_utils.py +11 -2
- regscale/dev/cli.py +26 -0
- regscale/dev/version.py +72 -0
- regscale/integrations/commercial/__init__.py +15 -1
- regscale/integrations/commercial/amazon/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/amazon/common.py +204 -0
- regscale/integrations/commercial/amazon/common.py +48 -58
- regscale/integrations/commercial/aws/audit_manager_compliance.py +2671 -0
- regscale/integrations/commercial/aws/cli.py +3093 -55
- regscale/integrations/commercial/aws/cloudtrail_control_mappings.py +333 -0
- regscale/integrations/commercial/aws/cloudtrail_evidence.py +501 -0
- regscale/integrations/commercial/aws/cloudwatch_control_mappings.py +357 -0
- regscale/integrations/commercial/aws/cloudwatch_evidence.py +490 -0
- regscale/integrations/commercial/aws/config_compliance.py +914 -0
- regscale/integrations/commercial/aws/conformance_pack_mappings.py +198 -0
- regscale/integrations/commercial/aws/evidence_generator.py +283 -0
- regscale/integrations/commercial/aws/guardduty_control_mappings.py +340 -0
- regscale/integrations/commercial/aws/guardduty_evidence.py +1053 -0
- regscale/integrations/commercial/aws/iam_control_mappings.py +368 -0
- regscale/integrations/commercial/aws/iam_evidence.py +574 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +223 -22
- regscale/integrations/commercial/aws/inventory/base.py +107 -5
- regscale/integrations/commercial/aws/inventory/resources/audit_manager.py +513 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudtrail.py +315 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudtrail_logs_metadata.py +476 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudwatch.py +191 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +66 -9
- regscale/integrations/commercial/aws/inventory/resources/config.py +464 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +74 -9
- regscale/integrations/commercial/aws/inventory/resources/database.py +106 -31
- regscale/integrations/commercial/aws/inventory/resources/guardduty.py +286 -0
- regscale/integrations/commercial/aws/inventory/resources/iam.py +470 -0
- regscale/integrations/commercial/aws/inventory/resources/inspector.py +476 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +175 -61
- regscale/integrations/commercial/aws/inventory/resources/kms.py +447 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +103 -67
- regscale/integrations/commercial/aws/inventory/resources/s3.py +394 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +268 -72
- regscale/integrations/commercial/aws/inventory/resources/securityhub.py +473 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +53 -29
- regscale/integrations/commercial/aws/inventory/resources/systems_manager.py +657 -0
- regscale/integrations/commercial/aws/inventory/resources/vpc.py +655 -0
- regscale/integrations/commercial/aws/kms_control_mappings.py +288 -0
- regscale/integrations/commercial/aws/kms_evidence.py +879 -0
- regscale/integrations/commercial/aws/ocsf/__init__.py +7 -0
- regscale/integrations/commercial/aws/ocsf/constants.py +115 -0
- regscale/integrations/commercial/aws/ocsf/mapper.py +435 -0
- regscale/integrations/commercial/aws/org_control_mappings.py +286 -0
- regscale/integrations/commercial/aws/org_evidence.py +666 -0
- regscale/integrations/commercial/aws/s3_control_mappings.py +356 -0
- regscale/integrations/commercial/aws/s3_evidence.py +632 -0
- regscale/integrations/commercial/aws/scanner.py +851 -206
- regscale/integrations/commercial/aws/security_hub.py +319 -0
- regscale/integrations/commercial/aws/session_manager.py +282 -0
- regscale/integrations/commercial/aws/ssm_control_mappings.py +291 -0
- regscale/integrations/commercial/aws/ssm_evidence.py +492 -0
- regscale/integrations/commercial/synqly/ticketing.py +27 -0
- regscale/integrations/compliance_integration.py +308 -38
- regscale/integrations/due_date_handler.py +3 -0
- regscale/integrations/scanner_integration.py +399 -84
- regscale/models/integration_models/cisa_kev_data.json +65 -5
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +17 -9
- regscale/models/regscale_models/assessment.py +2 -1
- regscale/models/regscale_models/control_objective.py +74 -5
- regscale/models/regscale_models/file.py +2 -0
- regscale/models/regscale_models/issue.py +2 -5
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/METADATA +1 -1
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/RECORD +113 -34
- tests/regscale/integrations/commercial/aws/__init__.py +0 -0
- tests/regscale/integrations/commercial/aws/test_audit_manager_compliance.py +1304 -0
- tests/regscale/integrations/commercial/aws/test_audit_manager_evidence_aggregation.py +341 -0
- tests/regscale/integrations/commercial/aws/test_aws_audit_manager_collector.py +1155 -0
- tests/regscale/integrations/commercial/aws/test_aws_cloudtrail_collector.py +534 -0
- tests/regscale/integrations/commercial/aws/test_aws_config_collector.py +400 -0
- tests/regscale/integrations/commercial/aws/test_aws_guardduty_collector.py +315 -0
- tests/regscale/integrations/commercial/aws/test_aws_iam_collector.py +458 -0
- tests/regscale/integrations/commercial/aws/test_aws_inspector_collector.py +353 -0
- tests/regscale/integrations/commercial/aws/test_aws_inventory_integration.py +530 -0
- tests/regscale/integrations/commercial/aws/test_aws_kms_collector.py +919 -0
- tests/regscale/integrations/commercial/aws/test_aws_s3_collector.py +722 -0
- tests/regscale/integrations/commercial/aws/test_aws_scanner_integration.py +722 -0
- tests/regscale/integrations/commercial/aws/test_aws_securityhub_collector.py +792 -0
- tests/regscale/integrations/commercial/aws/test_aws_systems_manager_collector.py +918 -0
- tests/regscale/integrations/commercial/aws/test_aws_vpc_collector.py +996 -0
- tests/regscale/integrations/commercial/aws/test_cli_evidence.py +431 -0
- tests/regscale/integrations/commercial/aws/test_cloudtrail_control_mappings.py +452 -0
- tests/regscale/integrations/commercial/aws/test_cloudtrail_evidence.py +788 -0
- tests/regscale/integrations/commercial/aws/test_config_compliance.py +298 -0
- tests/regscale/integrations/commercial/aws/test_conformance_pack_mappings.py +200 -0
- tests/regscale/integrations/commercial/aws/test_evidence_generator.py +386 -0
- tests/regscale/integrations/commercial/aws/test_guardduty_control_mappings.py +564 -0
- tests/regscale/integrations/commercial/aws/test_guardduty_evidence.py +1041 -0
- tests/regscale/integrations/commercial/aws/test_iam_control_mappings.py +718 -0
- tests/regscale/integrations/commercial/aws/test_iam_evidence.py +1375 -0
- tests/regscale/integrations/commercial/aws/test_kms_control_mappings.py +656 -0
- tests/regscale/integrations/commercial/aws/test_kms_evidence.py +1163 -0
- tests/regscale/integrations/commercial/aws/test_ocsf_mapper.py +370 -0
- tests/regscale/integrations/commercial/aws/test_org_control_mappings.py +546 -0
- tests/regscale/integrations/commercial/aws/test_org_evidence.py +1240 -0
- tests/regscale/integrations/commercial/aws/test_s3_control_mappings.py +672 -0
- tests/regscale/integrations/commercial/aws/test_s3_evidence.py +987 -0
- tests/regscale/integrations/commercial/aws/test_scanner_evidence.py +373 -0
- tests/regscale/integrations/commercial/aws/test_security_hub_config_filtering.py +539 -0
- tests/regscale/integrations/commercial/aws/test_session_manager.py +516 -0
- tests/regscale/integrations/commercial/aws/test_ssm_control_mappings.py +588 -0
- tests/regscale/integrations/commercial/aws/test_ssm_evidence.py +735 -0
- tests/regscale/integrations/commercial/test_aws.py +55 -56
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""AWS GuardDuty Control Mappings for RegScale Compliance Integration."""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger("regscale")
|
|
9
|
+
|
|
10
|
+
# NIST 800-53 R5 Control Mappings for AWS GuardDuty
|
|
11
|
+
GUARDDUTY_CONTROL_MAPPINGS = {
|
|
12
|
+
"SI-4": {
|
|
13
|
+
"name": "System Monitoring",
|
|
14
|
+
"description": "Monitor the system to detect attacks and indicators of potential attacks",
|
|
15
|
+
"checks": {
|
|
16
|
+
"detector_enabled": {
|
|
17
|
+
"weight": 100,
|
|
18
|
+
"pass_criteria": "GuardDuty detector is enabled and actively monitoring",
|
|
19
|
+
"fail_criteria": "GuardDuty detector is disabled or suspended",
|
|
20
|
+
},
|
|
21
|
+
"findings_processed": {
|
|
22
|
+
"weight": 90,
|
|
23
|
+
"pass_criteria": "Active findings are reviewed and remediated",
|
|
24
|
+
"fail_criteria": "High severity findings remain unaddressed",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
"IR-4": {
|
|
29
|
+
"name": "Incident Handling",
|
|
30
|
+
"description": "Implement incident handling capability for security incidents",
|
|
31
|
+
"checks": {
|
|
32
|
+
"high_severity_findings": {
|
|
33
|
+
"weight": 100,
|
|
34
|
+
"pass_criteria": "No unaddressed high severity findings",
|
|
35
|
+
"fail_criteria": "High severity findings detected and not remediated",
|
|
36
|
+
},
|
|
37
|
+
"incident_response": {
|
|
38
|
+
"weight": 90,
|
|
39
|
+
"pass_criteria": "Findings integrated with incident response workflow",
|
|
40
|
+
"fail_criteria": "Findings not tracked in incident management system",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
"IR-5": {
|
|
45
|
+
"name": "Incident Monitoring",
|
|
46
|
+
"description": "Track and document system security incidents",
|
|
47
|
+
"checks": {
|
|
48
|
+
"finding_tracking": {
|
|
49
|
+
"weight": 100,
|
|
50
|
+
"pass_criteria": "All findings tracked and documented",
|
|
51
|
+
"fail_criteria": "Findings not systematically tracked",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
"SI-3": {
|
|
56
|
+
"name": "Malicious Code Protection",
|
|
57
|
+
"description": "Implement malicious code protection mechanisms",
|
|
58
|
+
"checks": {
|
|
59
|
+
"malware_detection": {
|
|
60
|
+
"weight": 100,
|
|
61
|
+
"pass_criteria": "GuardDuty detecting and alerting on malware activities",
|
|
62
|
+
"fail_criteria": "Malware protection findings not enabled or monitored",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
"RA-5": {
|
|
67
|
+
"name": "Vulnerability Monitoring and Scanning",
|
|
68
|
+
"description": "Monitor and scan for vulnerabilities in the system",
|
|
69
|
+
"checks": {
|
|
70
|
+
"threat_intelligence": {
|
|
71
|
+
"weight": 100,
|
|
72
|
+
"pass_criteria": "GuardDuty threat intelligence enabled and current",
|
|
73
|
+
"fail_criteria": "Threat intelligence feeds not enabled or outdated",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Severity mapping (GuardDuty uses 0-10 scale)
|
|
80
|
+
SEVERITY_MAPPING = {
|
|
81
|
+
"LOW": (0.1, 3.9),
|
|
82
|
+
"MEDIUM": (4.0, 6.9),
|
|
83
|
+
"HIGH": (7.0, 8.9),
|
|
84
|
+
"CRITICAL": (9.0, 10.0),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Finding types that may contain CVEs
|
|
88
|
+
CVE_RELATED_FINDING_TYPES = [
|
|
89
|
+
"UnauthorizedAccess:EC2/MaliciousIPCaller",
|
|
90
|
+
"CryptoCurrency:EC2/BitcoinTool",
|
|
91
|
+
"Trojan:EC2/",
|
|
92
|
+
"Backdoor:EC2/",
|
|
93
|
+
"Behavior:EC2/NetworkPortUnusual",
|
|
94
|
+
"Recon:EC2/",
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class GuardDutyControlMapper:
|
|
99
|
+
"""Map AWS GuardDuty findings to compliance control status."""
|
|
100
|
+
|
|
101
|
+
def __init__(self, framework: str = "NIST800-53R5"):
|
|
102
|
+
"""
|
|
103
|
+
Initialize GuardDuty control mapper.
|
|
104
|
+
|
|
105
|
+
:param str framework: Compliance framework
|
|
106
|
+
"""
|
|
107
|
+
self.framework = framework
|
|
108
|
+
self.mappings = GUARDDUTY_CONTROL_MAPPINGS
|
|
109
|
+
|
|
110
|
+
def assess_guardduty_compliance(self, guardduty_data: Dict) -> Dict[str, str]:
|
|
111
|
+
"""
|
|
112
|
+
Assess GuardDuty compliance against all mapped controls.
|
|
113
|
+
|
|
114
|
+
:param Dict guardduty_data: GuardDuty detectors and findings
|
|
115
|
+
:return: Dictionary mapping control IDs to compliance results (PASS/FAIL)
|
|
116
|
+
:rtype: Dict[str, str]
|
|
117
|
+
"""
|
|
118
|
+
results = {}
|
|
119
|
+
|
|
120
|
+
if self.framework == "NIST800-53R5":
|
|
121
|
+
results["SI-4"] = self._assess_si4(guardduty_data)
|
|
122
|
+
results["IR-4"] = self._assess_ir4(guardduty_data)
|
|
123
|
+
results["IR-5"] = self._assess_ir5(guardduty_data)
|
|
124
|
+
results["SI-3"] = self._assess_si3(guardduty_data)
|
|
125
|
+
results["RA-5"] = self._assess_ra5(guardduty_data)
|
|
126
|
+
|
|
127
|
+
return results
|
|
128
|
+
|
|
129
|
+
def _assess_si4(self, guardduty_data: Dict) -> str:
|
|
130
|
+
"""
|
|
131
|
+
Assess SI-4 (System Monitoring) compliance.
|
|
132
|
+
|
|
133
|
+
:param Dict guardduty_data: GuardDuty data
|
|
134
|
+
:return: Compliance result (PASS/FAIL)
|
|
135
|
+
:rtype: str
|
|
136
|
+
"""
|
|
137
|
+
detectors = guardduty_data.get("Detectors", [])
|
|
138
|
+
|
|
139
|
+
if not detectors:
|
|
140
|
+
logger.debug("GuardDuty FAILS SI-4: No detectors configured")
|
|
141
|
+
return "FAIL"
|
|
142
|
+
|
|
143
|
+
# Check if any detector is disabled
|
|
144
|
+
disabled_detectors = [d for d in detectors if d.get("Status") != "ENABLED"]
|
|
145
|
+
if disabled_detectors:
|
|
146
|
+
logger.debug(f"GuardDuty FAILS SI-4: {len(disabled_detectors)} detector(s) disabled")
|
|
147
|
+
return "FAIL"
|
|
148
|
+
|
|
149
|
+
logger.debug(f"GuardDuty PASSES SI-4: {len(detectors)} detector(s) enabled and monitoring")
|
|
150
|
+
return "PASS"
|
|
151
|
+
|
|
152
|
+
def _assess_ir4(self, guardduty_data: Dict) -> str:
|
|
153
|
+
"""
|
|
154
|
+
Assess IR-4 (Incident Handling) compliance.
|
|
155
|
+
|
|
156
|
+
:param Dict guardduty_data: GuardDuty data
|
|
157
|
+
:return: Compliance result (PASS/FAIL)
|
|
158
|
+
:rtype: str
|
|
159
|
+
"""
|
|
160
|
+
findings = guardduty_data.get("Findings", [])
|
|
161
|
+
|
|
162
|
+
# Check for high/critical severity unaddressed findings
|
|
163
|
+
high_severity_findings = [
|
|
164
|
+
f for f in findings if self._get_severity_level(f.get("Severity", 0)) in ["HIGH", "CRITICAL"]
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
if high_severity_findings:
|
|
168
|
+
logger.debug(
|
|
169
|
+
f"GuardDuty FAILS IR-4: {len(high_severity_findings)} high/critical severity "
|
|
170
|
+
"findings requiring incident response"
|
|
171
|
+
)
|
|
172
|
+
return "FAIL"
|
|
173
|
+
|
|
174
|
+
logger.debug("GuardDuty PASSES IR-4: No high severity findings requiring immediate attention")
|
|
175
|
+
return "PASS"
|
|
176
|
+
|
|
177
|
+
def _assess_ir5(self, guardduty_data: Dict) -> str:
|
|
178
|
+
"""
|
|
179
|
+
Assess IR-5 (Incident Monitoring) compliance.
|
|
180
|
+
|
|
181
|
+
GuardDuty's active monitoring satisfies IR-5 requirements by providing continuous
|
|
182
|
+
security monitoring and incident detection capabilities. The presence of GuardDuty
|
|
183
|
+
itself, along with this integration's tracking of findings, fulfills the control.
|
|
184
|
+
|
|
185
|
+
:param Dict guardduty_data: GuardDuty data
|
|
186
|
+
:return: Compliance result (always PASS when GuardDuty is enabled)
|
|
187
|
+
:rtype: str
|
|
188
|
+
"""
|
|
189
|
+
findings = guardduty_data.get("Findings", [])
|
|
190
|
+
|
|
191
|
+
# GuardDuty being active satisfies IR-5 (Incident Monitoring)
|
|
192
|
+
if findings:
|
|
193
|
+
logger.debug(f"GuardDuty PASSES IR-5: {len(findings)} findings tracked for incident monitoring")
|
|
194
|
+
else:
|
|
195
|
+
logger.debug("GuardDuty PASSES IR-5: GuardDuty monitoring active, no incidents detected")
|
|
196
|
+
|
|
197
|
+
return "PASS"
|
|
198
|
+
|
|
199
|
+
def _assess_si3(self, guardduty_data: Dict) -> str:
|
|
200
|
+
"""
|
|
201
|
+
Assess SI-3 (Malicious Code Protection) compliance.
|
|
202
|
+
|
|
203
|
+
:param Dict guardduty_data: GuardDuty data
|
|
204
|
+
:return: Compliance result (PASS/FAIL)
|
|
205
|
+
:rtype: str
|
|
206
|
+
"""
|
|
207
|
+
detectors = guardduty_data.get("Detectors", [])
|
|
208
|
+
findings = guardduty_data.get("Findings", [])
|
|
209
|
+
|
|
210
|
+
# Check if GuardDuty is enabled (provides malware detection)
|
|
211
|
+
if not detectors or all(d.get("Status") != "ENABLED" for d in detectors):
|
|
212
|
+
logger.debug("GuardDuty FAILS SI-3: No enabled detectors for malware protection")
|
|
213
|
+
return "FAIL"
|
|
214
|
+
|
|
215
|
+
# Check for malware-related findings
|
|
216
|
+
malware_findings = [f for f in findings if self._is_malware_finding(f)]
|
|
217
|
+
|
|
218
|
+
if malware_findings:
|
|
219
|
+
logger.warning(
|
|
220
|
+
f"GuardDuty malware findings detected: {len(malware_findings)} "
|
|
221
|
+
"potential malware activities (requires remediation)"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
logger.debug("GuardDuty PASSES SI-3: Malware protection monitoring enabled")
|
|
225
|
+
return "PASS"
|
|
226
|
+
|
|
227
|
+
def _assess_ra5(self, guardduty_data: Dict) -> str:
|
|
228
|
+
"""
|
|
229
|
+
Assess RA-5 (Vulnerability Monitoring) compliance.
|
|
230
|
+
|
|
231
|
+
:param Dict guardduty_data: GuardDuty data
|
|
232
|
+
:return: Compliance result (PASS/FAIL)
|
|
233
|
+
:rtype: str
|
|
234
|
+
"""
|
|
235
|
+
detectors = guardduty_data.get("Detectors", [])
|
|
236
|
+
|
|
237
|
+
# Check if threat intelligence is enabled
|
|
238
|
+
threat_intel_enabled = any(
|
|
239
|
+
d.get("DataSources", {}).get("S3Logs", {}).get("Status") == "ENABLED" for d in detectors
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
if not threat_intel_enabled:
|
|
243
|
+
logger.debug("GuardDuty FAILS RA-5: Threat intelligence data sources not fully enabled")
|
|
244
|
+
return "FAIL"
|
|
245
|
+
|
|
246
|
+
logger.debug("GuardDuty PASSES RA-5: Threat intelligence and vulnerability monitoring active")
|
|
247
|
+
return "PASS"
|
|
248
|
+
|
|
249
|
+
def _get_severity_level(self, severity_score: float) -> str:
|
|
250
|
+
"""
|
|
251
|
+
Map GuardDuty severity score to severity level.
|
|
252
|
+
|
|
253
|
+
:param float severity_score: Severity score (0-10)
|
|
254
|
+
:return: Severity level (LOW, MEDIUM, HIGH, CRITICAL)
|
|
255
|
+
:rtype: str
|
|
256
|
+
"""
|
|
257
|
+
for level, (min_score, max_score) in SEVERITY_MAPPING.items():
|
|
258
|
+
if min_score <= severity_score <= max_score:
|
|
259
|
+
return level
|
|
260
|
+
return "LOW"
|
|
261
|
+
|
|
262
|
+
def _is_malware_finding(self, finding: Dict) -> bool:
|
|
263
|
+
"""
|
|
264
|
+
Check if finding is related to malware.
|
|
265
|
+
|
|
266
|
+
:param Dict finding: GuardDuty finding
|
|
267
|
+
:return: True if malware-related
|
|
268
|
+
:rtype: bool
|
|
269
|
+
"""
|
|
270
|
+
finding_type = finding.get("Type", "")
|
|
271
|
+
malware_indicators = [
|
|
272
|
+
"Trojan",
|
|
273
|
+
"Backdoor",
|
|
274
|
+
"CryptoCurrency",
|
|
275
|
+
"Malware",
|
|
276
|
+
"Bitcoin",
|
|
277
|
+
"CryptoCoin",
|
|
278
|
+
]
|
|
279
|
+
return any(indicator in finding_type for indicator in malware_indicators)
|
|
280
|
+
|
|
281
|
+
def has_cve_reference(self, finding: Dict) -> bool:
|
|
282
|
+
"""
|
|
283
|
+
Check if GuardDuty finding references a CVE.
|
|
284
|
+
|
|
285
|
+
:param Dict finding: GuardDuty finding
|
|
286
|
+
:return: True if CVE referenced
|
|
287
|
+
:rtype: bool
|
|
288
|
+
"""
|
|
289
|
+
# Check finding description and title for CVE patterns
|
|
290
|
+
description = finding.get("Description", "")
|
|
291
|
+
title = finding.get("Title", "")
|
|
292
|
+
service = finding.get("Service", {})
|
|
293
|
+
additional_info = service.get("AdditionalInfo", {})
|
|
294
|
+
|
|
295
|
+
# CVE pattern: CVE-YYYY-NNNNN
|
|
296
|
+
text_to_search = f"{description} {title} {str(additional_info)}"
|
|
297
|
+
return "CVE-" in text_to_search.upper()
|
|
298
|
+
|
|
299
|
+
def extract_cves_from_finding(self, finding: Dict) -> List[str]:
|
|
300
|
+
"""
|
|
301
|
+
Extract CVE IDs from GuardDuty finding.
|
|
302
|
+
|
|
303
|
+
:param Dict finding: GuardDuty finding
|
|
304
|
+
:return: List of CVE IDs
|
|
305
|
+
:rtype: List[str]
|
|
306
|
+
"""
|
|
307
|
+
import re
|
|
308
|
+
|
|
309
|
+
cves = []
|
|
310
|
+
description = finding.get("Description", "")
|
|
311
|
+
title = finding.get("Title", "")
|
|
312
|
+
service = finding.get("Service", {})
|
|
313
|
+
additional_info = str(service.get("AdditionalInfo", {}))
|
|
314
|
+
|
|
315
|
+
text_to_search = f"{description} {title} {additional_info}"
|
|
316
|
+
|
|
317
|
+
# CVE pattern: CVE-YYYY-NNNNN
|
|
318
|
+
cve_pattern = r"CVE-\d{4}-\d{4,7}"
|
|
319
|
+
matches = re.findall(cve_pattern, text_to_search, re.IGNORECASE)
|
|
320
|
+
|
|
321
|
+
cves = list({match.upper() for match in matches})
|
|
322
|
+
return cves
|
|
323
|
+
|
|
324
|
+
def get_control_description(self, control_id: str) -> Optional[str]:
|
|
325
|
+
"""Get human-readable description for a control."""
|
|
326
|
+
control_data = self.mappings.get(control_id)
|
|
327
|
+
if control_data:
|
|
328
|
+
return f"{control_data.get('name')}: {control_data.get('description', '')}"
|
|
329
|
+
return None
|
|
330
|
+
|
|
331
|
+
def get_mapped_controls(self) -> List[str]:
|
|
332
|
+
"""Get list of all control IDs mapped for this framework."""
|
|
333
|
+
return list(self.mappings.keys())
|
|
334
|
+
|
|
335
|
+
def get_check_details(self, control_id: str) -> Optional[Dict]:
|
|
336
|
+
"""Get detailed check criteria for a control."""
|
|
337
|
+
control_data = self.mappings.get(control_id)
|
|
338
|
+
if control_data:
|
|
339
|
+
return control_data.get("checks", {})
|
|
340
|
+
return None
|