zen-ai-pentest 2.0.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.
- agents/__init__.py +28 -0
- agents/agent_base.py +239 -0
- agents/agent_orchestrator.py +346 -0
- agents/analysis_agent.py +225 -0
- agents/cli.py +258 -0
- agents/exploit_agent.py +224 -0
- agents/integration.py +211 -0
- agents/post_scan_agent.py +937 -0
- agents/react_agent.py +384 -0
- agents/react_agent_enhanced.py +616 -0
- agents/react_agent_vm.py +298 -0
- agents/research_agent.py +176 -0
- api/__init__.py +11 -0
- api/auth.py +123 -0
- api/main.py +1027 -0
- api/schemas.py +357 -0
- api/websocket.py +97 -0
- autonomous/__init__.py +122 -0
- autonomous/agent.py +253 -0
- autonomous/agent_loop.py +1370 -0
- autonomous/exploit_validator.py +1537 -0
- autonomous/memory.py +448 -0
- autonomous/react.py +339 -0
- autonomous/tool_executor.py +488 -0
- backends/__init__.py +16 -0
- backends/chatgpt_direct.py +133 -0
- backends/claude_direct.py +130 -0
- backends/duckduckgo.py +138 -0
- backends/openrouter.py +120 -0
- benchmarks/__init__.py +149 -0
- benchmarks/benchmark_engine.py +904 -0
- benchmarks/ci_benchmark.py +785 -0
- benchmarks/comparison.py +729 -0
- benchmarks/metrics.py +553 -0
- benchmarks/run_benchmarks.py +809 -0
- ci_cd/__init__.py +2 -0
- core/__init__.py +17 -0
- core/async_pool.py +282 -0
- core/asyncio_fix.py +222 -0
- core/cache.py +472 -0
- core/container.py +277 -0
- core/database.py +114 -0
- core/input_validator.py +353 -0
- core/models.py +288 -0
- core/orchestrator.py +611 -0
- core/plugin_manager.py +571 -0
- core/rate_limiter.py +405 -0
- core/secure_config.py +328 -0
- core/shield_integration.py +296 -0
- modules/__init__.py +46 -0
- modules/cve_database.py +362 -0
- modules/exploit_assist.py +330 -0
- modules/nuclei_integration.py +480 -0
- modules/osint.py +604 -0
- modules/protonvpn.py +554 -0
- modules/recon.py +165 -0
- modules/sql_injection_db.py +826 -0
- modules/tool_orchestrator.py +498 -0
- modules/vuln_scanner.py +292 -0
- modules/wordlist_generator.py +566 -0
- risk_engine/__init__.py +99 -0
- risk_engine/business_impact.py +267 -0
- risk_engine/business_impact_calculator.py +563 -0
- risk_engine/cvss.py +156 -0
- risk_engine/epss.py +190 -0
- risk_engine/example_usage.py +294 -0
- risk_engine/false_positive_engine.py +1073 -0
- risk_engine/scorer.py +304 -0
- web_ui/backend/main.py +471 -0
- zen_ai_pentest-2.0.0.dist-info/METADATA +795 -0
- zen_ai_pentest-2.0.0.dist-info/RECORD +75 -0
- zen_ai_pentest-2.0.0.dist-info/WHEEL +5 -0
- zen_ai_pentest-2.0.0.dist-info/entry_points.txt +2 -0
- zen_ai_pentest-2.0.0.dist-info/licenses/LICENSE +21 -0
- zen_ai_pentest-2.0.0.dist-info/top_level.txt +10 -0
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Business Impact Calculator für das Zen-AI-Pentest Framework.
|
|
3
|
+
|
|
4
|
+
Berechnet den geschäftlichen Impact von Sicherheitsfindings basierend auf
|
|
5
|
+
Asset-Wertung, Datenklassifizierung, Compliance-Anforderungen und finanziellen Faktoren.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import Dict, List, Optional, Set, Tuple
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
# Logger konfigurieren
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DataClassification(Enum):
|
|
19
|
+
"""Datenklassifizierungsstufen nach sensitivität."""
|
|
20
|
+
PUBLIC = ("public", 0.1, "Öffentlich zugängliche Daten")
|
|
21
|
+
INTERNAL = ("internal", 0.3, "Interne Geschäftsdaten")
|
|
22
|
+
CONFIDENTIAL = ("confidential", 0.6, "Vertrauliche Daten")
|
|
23
|
+
RESTRICTED = ("restricted", 0.9, "Streng vertrauliche Daten")
|
|
24
|
+
|
|
25
|
+
def __init__(self, label: str, weight: float, description: str):
|
|
26
|
+
self.label = label
|
|
27
|
+
self.weight = weight
|
|
28
|
+
self.description = description
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ComplianceFramework(Enum):
|
|
32
|
+
"""Compliance-Frameworks mit ihren jeweiligen Impact-Gewichtungen."""
|
|
33
|
+
PCI_DSS = ("PCI-DSS", 0.95, {"payment_data": 1.0, "cardholder_data": 0.9})
|
|
34
|
+
HIPAA = ("HIPAA", 0.9, {"phi": 1.0, "medical_records": 0.9, "patient_data": 0.85})
|
|
35
|
+
GDPR = ("GDPR", 0.85, {"pii": 0.9, "personal_data": 0.85, "sensitive_data": 0.95})
|
|
36
|
+
SOX = ("SOX", 0.8, {"financial_data": 0.9, "audit_logs": 0.7})
|
|
37
|
+
ISO27001 = ("ISO27001", 0.75, {"isms_data": 0.8, "security_controls": 0.7})
|
|
38
|
+
NIST = ("NIST", 0.7, {"federal_data": 0.9, "critical_infrastructure": 0.85})
|
|
39
|
+
|
|
40
|
+
def __init__(self, name: str, base_weight: float, data_weights: Dict[str, float]):
|
|
41
|
+
self.framework_name = name
|
|
42
|
+
self.base_weight = base_weight
|
|
43
|
+
self.data_weights = data_weights
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class AssetCriticality(Enum):
|
|
47
|
+
"""Kritikalitätsstufen von Assets."""
|
|
48
|
+
CRITICAL = (5, 1.0, "Geschäftskritische Systeme")
|
|
49
|
+
HIGH = (4, 0.8, "Wichtige Geschäftssysteme")
|
|
50
|
+
MEDIUM = (3, 0.5, "Standard-Geschäftssysteme")
|
|
51
|
+
LOW = (2, 0.3, "Nicht-kritische Systeme")
|
|
52
|
+
MINIMAL = (1, 0.1, "Test/Entwicklungssysteme")
|
|
53
|
+
|
|
54
|
+
def __init__(self, level: int, weight: float, description: str):
|
|
55
|
+
self.level = level
|
|
56
|
+
self.weight = weight
|
|
57
|
+
self.description = description
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ReputationImpact(Enum):
|
|
61
|
+
"""Mögliche Auswirkungen auf den Ruf des Unternehmens."""
|
|
62
|
+
SEVERE = (1.0, "Ernsthafter Imageschaden, Medienberichterstattung")
|
|
63
|
+
HIGH = (0.7, "Signifikanter Reputationsschaden")
|
|
64
|
+
MODERATE = (0.4, "Mäßiger Rufschaden")
|
|
65
|
+
LOW = (0.1, "Geringer bis kein Rufschaden")
|
|
66
|
+
|
|
67
|
+
def __init__(self, weight: float, description: str):
|
|
68
|
+
self.weight = weight
|
|
69
|
+
self.description = description
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class FinancialImpact:
|
|
74
|
+
"""Finanzielle Auswirkungen eines Sicherheitsvorfalls."""
|
|
75
|
+
direct_costs: float = 0.0 # Direkte Kosten (Response, Forensik, etc.)
|
|
76
|
+
indirect_costs: float = 0.0 # Indirekte Kosten (Ausfallzeiten, etc.)
|
|
77
|
+
regulatory_fines: float = 0.0 # Regulatorische Strafen
|
|
78
|
+
legal_costs: float = 0.0 # Rechtskosten
|
|
79
|
+
reputation_costs: float = 0.0 # Kosten durch Reputationsschaden
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def total_costs(self) -> float:
|
|
83
|
+
"""Berechnet die gesamten finanziellen Auswirkungen."""
|
|
84
|
+
return (
|
|
85
|
+
self.direct_costs +
|
|
86
|
+
self.indirect_costs +
|
|
87
|
+
self.regulatory_fines +
|
|
88
|
+
self.legal_costs +
|
|
89
|
+
self.reputation_costs
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@dataclass
|
|
94
|
+
class ComplianceImpact:
|
|
95
|
+
"""Compliance-bezogene Auswirkungen."""
|
|
96
|
+
frameworks: Set[ComplianceFramework] = field(default_factory=set)
|
|
97
|
+
violated_controls: List[str] = field(default_factory=list)
|
|
98
|
+
potential_fines: Dict[ComplianceFramework, float] = field(default_factory=dict)
|
|
99
|
+
audit_findings: List[str] = field(default_factory=list)
|
|
100
|
+
|
|
101
|
+
def get_max_fine(self) -> float:
|
|
102
|
+
"""Gibt die maximal mögliche Strafe zurück."""
|
|
103
|
+
return max(self.potential_fines.values()) if self.potential_fines else 0.0
|
|
104
|
+
|
|
105
|
+
def get_compliance_score(self) -> float:
|
|
106
|
+
"""Berechnet einen Compliance-Risiko-Score (0-1)."""
|
|
107
|
+
if not self.frameworks:
|
|
108
|
+
return 0.0
|
|
109
|
+
|
|
110
|
+
base_score = sum(fw.base_weight for fw in self.frameworks) / len(self.frameworks)
|
|
111
|
+
violation_multiplier = min(1.0, len(self.violated_controls) * 0.1)
|
|
112
|
+
return min(1.0, base_score * (1 + violation_multiplier))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass
|
|
116
|
+
class AssetContext:
|
|
117
|
+
"""Kontextinformationen für ein Asset."""
|
|
118
|
+
asset_id: str
|
|
119
|
+
asset_name: str
|
|
120
|
+
asset_type: str
|
|
121
|
+
criticality: AssetCriticality
|
|
122
|
+
data_classification: DataClassification
|
|
123
|
+
compliance_frameworks: Set[ComplianceFramework] = field(default_factory=set)
|
|
124
|
+
internet_exposed: bool = False
|
|
125
|
+
user_count: int = 0
|
|
126
|
+
revenue_dependency: float = 0.0 # Prozentualer Anteil am Umsatz
|
|
127
|
+
|
|
128
|
+
def get_exposure_factor(self) -> float:
|
|
129
|
+
"""Berechnet den Expositionsfaktor basierend auf verschiedenen Parametern."""
|
|
130
|
+
exposure = 0.0
|
|
131
|
+
|
|
132
|
+
if self.internet_exposed:
|
|
133
|
+
exposure += 0.4
|
|
134
|
+
|
|
135
|
+
if self.user_count > 10000:
|
|
136
|
+
exposure += 0.3
|
|
137
|
+
elif self.user_count > 1000:
|
|
138
|
+
exposure += 0.2
|
|
139
|
+
elif self.user_count > 100:
|
|
140
|
+
exposure += 0.1
|
|
141
|
+
|
|
142
|
+
exposure += min(0.3, self.revenue_dependency / 100)
|
|
143
|
+
|
|
144
|
+
return min(1.0, exposure)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class BusinessImpactResult:
|
|
149
|
+
"""Ergebnis der Business-Impact-Berechnung."""
|
|
150
|
+
asset_id: str
|
|
151
|
+
overall_score: float # 0-1 Skala
|
|
152
|
+
financial_impact: FinancialImpact
|
|
153
|
+
compliance_impact: ComplianceImpact
|
|
154
|
+
reputation_impact: ReputationImpact
|
|
155
|
+
asset_criticality_score: float
|
|
156
|
+
data_sensitivity_score: float
|
|
157
|
+
exposure_score: float
|
|
158
|
+
timestamp: datetime = field(default_factory=datetime.now)
|
|
159
|
+
|
|
160
|
+
def get_risk_category(self) -> str:
|
|
161
|
+
"""Kategorisiert das Risiko basierend auf dem Gesamtscore."""
|
|
162
|
+
if self.overall_score >= 0.9:
|
|
163
|
+
return "CRITICAL"
|
|
164
|
+
elif self.overall_score >= 0.7:
|
|
165
|
+
return "HIGH"
|
|
166
|
+
elif self.overall_score >= 0.4:
|
|
167
|
+
return "MEDIUM"
|
|
168
|
+
elif self.overall_score >= 0.2:
|
|
169
|
+
return "LOW"
|
|
170
|
+
return "MINIMAL"
|
|
171
|
+
|
|
172
|
+
def get_prioritized_remediation(self) -> List[str]:
|
|
173
|
+
"""Generiert priorisierte Empfehlungen basierend auf dem Impact."""
|
|
174
|
+
recommendations = []
|
|
175
|
+
|
|
176
|
+
if self.financial_impact.total_costs > 1000000:
|
|
177
|
+
recommendations.append("Sofortige Eskalation an das Management erforderlich")
|
|
178
|
+
|
|
179
|
+
if self.compliance_impact.violated_controls:
|
|
180
|
+
recommendations.append(
|
|
181
|
+
f"Compliance-Verstöße beheben: {', '.join(self.compliance_impact.violated_controls[:3])}"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if self.reputation_impact.weight >= 0.7:
|
|
185
|
+
recommendations.append("PR-Team benachrichtigen für mögliche Krisenkommunikation")
|
|
186
|
+
|
|
187
|
+
if self.exposure_score >= 0.7:
|
|
188
|
+
recommendations.append("Netzwerksegmentierung und Zugangskontrollen überprüfen")
|
|
189
|
+
|
|
190
|
+
return recommendations
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class BusinessImpactCalculator:
|
|
194
|
+
"""
|
|
195
|
+
Berechnet den geschäftlichen Impact von Sicherheitsfindings.
|
|
196
|
+
|
|
197
|
+
Berücksichtigt finanzielle, compliance-bezogene und reputationsbezogene Faktoren.
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __init__(
|
|
201
|
+
self,
|
|
202
|
+
organization_size: str = "medium",
|
|
203
|
+
annual_revenue: float = 0.0,
|
|
204
|
+
industry: str = "technology"
|
|
205
|
+
):
|
|
206
|
+
"""
|
|
207
|
+
Initialisiert den Calculator.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
organization_size: Größe der Organisation (small, medium, large, enterprise)
|
|
211
|
+
annual_revenue: Jährlicher Umsatz in der lokalen Währung
|
|
212
|
+
industry: Branche für branchenspezifische Anpassungen
|
|
213
|
+
"""
|
|
214
|
+
self.organization_size = organization_size
|
|
215
|
+
self.annual_revenue = annual_revenue
|
|
216
|
+
self.industry = industry
|
|
217
|
+
|
|
218
|
+
# Branchenspezifische Multiplikatoren
|
|
219
|
+
self.industry_multipliers = {
|
|
220
|
+
"healthcare": {"compliance": 1.2, "reputation": 1.3, "financial": 1.1},
|
|
221
|
+
"finance": {"compliance": 1.3, "reputation": 1.2, "financial": 1.2},
|
|
222
|
+
"retail": {"compliance": 1.1, "reputation": 1.1, "financial": 1.0},
|
|
223
|
+
"technology": {"compliance": 1.0, "reputation": 1.2, "financial": 1.1},
|
|
224
|
+
"government": {"compliance": 1.4, "reputation": 1.0, "financial": 0.9},
|
|
225
|
+
"manufacturing": {"compliance": 0.9, "reputation": 0.9, "financial": 1.0},
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Organisationsspezifische Basiskosten
|
|
229
|
+
self.base_response_costs = {
|
|
230
|
+
"small": 50000,
|
|
231
|
+
"medium": 150000,
|
|
232
|
+
"large": 500000,
|
|
233
|
+
"enterprise": 2000000,
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
logger.info(f"BusinessImpactCalculator initialisiert für {industry} ({organization_size})")
|
|
237
|
+
|
|
238
|
+
def calculate_financial_impact(
|
|
239
|
+
self,
|
|
240
|
+
asset_context: AssetContext,
|
|
241
|
+
breach_likelihood: float = 0.5,
|
|
242
|
+
data_volume_records: int = 0
|
|
243
|
+
) -> FinancialImpact:
|
|
244
|
+
"""
|
|
245
|
+
Berechnet den finanziellen Impact eines potenziellen Vorfalls.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
asset_context: Kontext des betroffenen Assets
|
|
249
|
+
breach_likelihood: Wahrscheinlichkeit eines Datenlecks (0-1)
|
|
250
|
+
data_volume_records: Anzahl der potenziell betroffenen Datensätze
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
FinancialImpact-Objekt mit allen Kostenkomponenten
|
|
254
|
+
"""
|
|
255
|
+
multipliers = self.industry_multipliers.get(self.industry,
|
|
256
|
+
{"compliance": 1.0, "reputation": 1.0, "financial": 1.0})
|
|
257
|
+
|
|
258
|
+
# Direkte Kosten
|
|
259
|
+
base_response = self.base_response_costs.get(self.organization_size, 150000)
|
|
260
|
+
direct_costs = base_response * breach_likelihood * multipliers["financial"]
|
|
261
|
+
|
|
262
|
+
# Indirekte Kosten (Ausfallzeiten)
|
|
263
|
+
outage_hours = self._estimate_outage_hours(asset_context)
|
|
264
|
+
hourly_cost = (self.annual_revenue / 8760) * asset_context.revenue_dependency / 100
|
|
265
|
+
indirect_costs = outage_hours * hourly_cost * breach_likelihood
|
|
266
|
+
|
|
267
|
+
# Regulatorische Strafen
|
|
268
|
+
regulatory_fines = self._calculate_regulatory_fines(
|
|
269
|
+
asset_context, data_volume_records, breach_likelihood
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Rechtskosten
|
|
273
|
+
legal_costs = self._estimate_legal_costs(data_volume_records, breach_likelihood)
|
|
274
|
+
|
|
275
|
+
# Reputationskosten
|
|
276
|
+
reputation_costs = self._calculate_reputation_costs(
|
|
277
|
+
asset_context, breach_likelihood
|
|
278
|
+
) * multipliers["reputation"]
|
|
279
|
+
|
|
280
|
+
impact = FinancialImpact(
|
|
281
|
+
direct_costs=direct_costs,
|
|
282
|
+
indirect_costs=indirect_costs,
|
|
283
|
+
regulatory_fines=regulatory_fines,
|
|
284
|
+
legal_costs=legal_costs,
|
|
285
|
+
reputation_costs=reputation_costs
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
logger.debug(f"Finanzieller Impact für {asset_context.asset_id}: {impact.total_costs:,.2f}")
|
|
289
|
+
return impact
|
|
290
|
+
|
|
291
|
+
def calculate_compliance_impact(
|
|
292
|
+
self,
|
|
293
|
+
asset_context: AssetContext,
|
|
294
|
+
finding_type: str,
|
|
295
|
+
severity: str
|
|
296
|
+
) -> ComplianceImpact:
|
|
297
|
+
"""
|
|
298
|
+
Berechnet den Compliance-Impact eines Findings.
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
asset_context: Kontext des betroffenen Assets
|
|
302
|
+
finding_type: Typ des Findings
|
|
303
|
+
severity: Schwere des Findings
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
ComplianceImpact-Objekt
|
|
307
|
+
"""
|
|
308
|
+
impact = ComplianceImpact()
|
|
309
|
+
impact.frameworks = asset_context.compliance_frameworks.copy()
|
|
310
|
+
|
|
311
|
+
severity_multiplier = {"critical": 1.0, "high": 0.8, "medium": 0.5, "low": 0.2}.get(severity.lower(), 0.5)
|
|
312
|
+
|
|
313
|
+
for framework in asset_context.compliance_frameworks:
|
|
314
|
+
# Potenzielle Strafen berechnen
|
|
315
|
+
max_fine = self._get_max_regulatory_fine(framework)
|
|
316
|
+
adjusted_fine = max_fine * severity_multiplier
|
|
317
|
+
impact.potential_fines[framework] = adjusted_fine
|
|
318
|
+
|
|
319
|
+
# Verletzte Controls identifizieren
|
|
320
|
+
violated = self._identify_violated_controls(framework, finding_type)
|
|
321
|
+
impact.violated_controls.extend(violated)
|
|
322
|
+
|
|
323
|
+
logger.debug(f"Compliance-Impact für {asset_context.asset_id}: "
|
|
324
|
+
f"{len(impact.violated_controls)} verletzte Controls")
|
|
325
|
+
return impact
|
|
326
|
+
|
|
327
|
+
def assess_reputation_impact(
|
|
328
|
+
self,
|
|
329
|
+
asset_context: AssetContext,
|
|
330
|
+
data_classification: DataClassification,
|
|
331
|
+
public_exposure: bool = False
|
|
332
|
+
) -> ReputationImpact:
|
|
333
|
+
"""
|
|
334
|
+
Bewertet den potenziellen Reputationsschaden.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
asset_context: Kontext des betroffenen Assets
|
|
338
|
+
data_classification: Klassifizierung der betroffenen Daten
|
|
339
|
+
public_exposure: Ob der Vorfall öffentlich bekannt werden könnte
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
ReputationImpact-Enum-Wert
|
|
343
|
+
"""
|
|
344
|
+
score = 0.0
|
|
345
|
+
|
|
346
|
+
# Datenklassifizierung
|
|
347
|
+
score += data_classification.weight * 0.4
|
|
348
|
+
|
|
349
|
+
# Asset-Kritikalität
|
|
350
|
+
score += asset_context.criticality.weight * 0.3
|
|
351
|
+
|
|
352
|
+
# Öffentliche Exposition
|
|
353
|
+
if public_exposure or asset_context.internet_exposed:
|
|
354
|
+
score += 0.3
|
|
355
|
+
|
|
356
|
+
# Benutzeranzahl (Auswirkungsgrad)
|
|
357
|
+
if asset_context.user_count > 1000000:
|
|
358
|
+
score += 0.2
|
|
359
|
+
elif asset_context.user_count > 100000:
|
|
360
|
+
score += 0.15
|
|
361
|
+
elif asset_context.user_count > 10000:
|
|
362
|
+
score += 0.1
|
|
363
|
+
|
|
364
|
+
# Branchenmultiplikator
|
|
365
|
+
multipliers = self.industry_multipliers.get(self.industry, {"reputation": 1.0})
|
|
366
|
+
score = min(1.0, score * multipliers["reputation"])
|
|
367
|
+
|
|
368
|
+
if score >= 0.8:
|
|
369
|
+
return ReputationImpact.SEVERE
|
|
370
|
+
elif score >= 0.6:
|
|
371
|
+
return ReputationImpact.HIGH
|
|
372
|
+
elif score >= 0.3:
|
|
373
|
+
return ReputationImpact.MODERATE
|
|
374
|
+
return ReputationImpact.LOW
|
|
375
|
+
|
|
376
|
+
def calculate_overall_impact(
|
|
377
|
+
self,
|
|
378
|
+
asset_context: AssetContext,
|
|
379
|
+
finding_type: str,
|
|
380
|
+
severity: str,
|
|
381
|
+
breach_likelihood: float = 0.5,
|
|
382
|
+
data_volume_records: int = 0
|
|
383
|
+
) -> BusinessImpactResult:
|
|
384
|
+
"""
|
|
385
|
+
Berechnet den gesamten Business Impact.
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
asset_context: Kontext des betroffenen Assets
|
|
389
|
+
finding_type: Typ des Findings
|
|
390
|
+
severity: Schwere des Findings
|
|
391
|
+
breach_likelihood: Wahrscheinlichkeit eines Vorfalls
|
|
392
|
+
data_volume_records: Anzahl betroffener Datensätze
|
|
393
|
+
|
|
394
|
+
Returns:
|
|
395
|
+
BusinessImpactResult mit allen Impact-Komponenten
|
|
396
|
+
"""
|
|
397
|
+
# Finanzieller Impact
|
|
398
|
+
financial = self.calculate_financial_impact(
|
|
399
|
+
asset_context, breach_likelihood, data_volume_records
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
# Compliance Impact
|
|
403
|
+
compliance = self.calculate_compliance_impact(asset_context, finding_type, severity)
|
|
404
|
+
|
|
405
|
+
# Reputation Impact
|
|
406
|
+
reputation = self.assess_reputation_impact(
|
|
407
|
+
asset_context, asset_context.data_classification,
|
|
408
|
+
public_exposure=asset_context.internet_exposed
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
# Einzelne Scores
|
|
412
|
+
asset_criticality_score = asset_context.criticality.weight
|
|
413
|
+
data_sensitivity_score = asset_context.data_classification.weight
|
|
414
|
+
exposure_score = asset_context.get_exposure_factor()
|
|
415
|
+
|
|
416
|
+
# Gewichtete Berechnung des Gesamtscores
|
|
417
|
+
# Gewichtung: Finanzen 30%, Compliance 25%, Reputation 20%, Asset 15%, Daten 10%
|
|
418
|
+
financial_normalized = (
|
|
419
|
+
min(1.0, financial.total_costs / (self.annual_revenue * 0.1))
|
|
420
|
+
if self.annual_revenue > 0 else 0.5
|
|
421
|
+
)
|
|
422
|
+
compliance_normalized = compliance.get_compliance_score()
|
|
423
|
+
|
|
424
|
+
overall_score = (
|
|
425
|
+
financial_normalized * 0.30 +
|
|
426
|
+
compliance_normalized * 0.25 +
|
|
427
|
+
reputation.weight * 0.20 +
|
|
428
|
+
asset_criticality_score * 0.15 +
|
|
429
|
+
data_sensitivity_score * 0.10
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
# Exposure-Faktor als Multiplikator
|
|
433
|
+
overall_score = min(1.0, overall_score * (1 + exposure_score * 0.2))
|
|
434
|
+
|
|
435
|
+
result = BusinessImpactResult(
|
|
436
|
+
asset_id=asset_context.asset_id,
|
|
437
|
+
overall_score=overall_score,
|
|
438
|
+
financial_impact=financial,
|
|
439
|
+
compliance_impact=compliance,
|
|
440
|
+
reputation_impact=reputation,
|
|
441
|
+
asset_criticality_score=asset_criticality_score,
|
|
442
|
+
data_sensitivity_score=data_sensitivity_score,
|
|
443
|
+
exposure_score=exposure_score
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
logger.info(f"Business Impact für {asset_context.asset_id}: "
|
|
447
|
+
f"Score={overall_score:.2f}, Kategorie={result.get_risk_category()}")
|
|
448
|
+
|
|
449
|
+
return result
|
|
450
|
+
|
|
451
|
+
def _estimate_outage_hours(self, asset_context: AssetContext) -> float:
|
|
452
|
+
"""Schätzt die Ausfallzeit basierend auf der Asset-Kritikalität."""
|
|
453
|
+
base_hours = {
|
|
454
|
+
AssetCriticality.CRITICAL: 72,
|
|
455
|
+
AssetCriticality.HIGH: 48,
|
|
456
|
+
AssetCriticality.MEDIUM: 24,
|
|
457
|
+
AssetCriticality.LOW: 8,
|
|
458
|
+
AssetCriticality.MINIMAL: 2,
|
|
459
|
+
}
|
|
460
|
+
return base_hours.get(asset_context.criticality, 24)
|
|
461
|
+
|
|
462
|
+
def _calculate_regulatory_fines(
|
|
463
|
+
self,
|
|
464
|
+
asset_context: AssetContext,
|
|
465
|
+
data_volume_records: int,
|
|
466
|
+
breach_likelihood: float
|
|
467
|
+
) -> float:
|
|
468
|
+
"""Berechnet potenzielle regulatorische Strafen."""
|
|
469
|
+
max_fine = 0.0
|
|
470
|
+
|
|
471
|
+
for framework in asset_context.compliance_frameworks:
|
|
472
|
+
fine = self._get_max_regulatory_fine(framework)
|
|
473
|
+
# Skalierung basierend auf Datenvolumen
|
|
474
|
+
volume_multiplier = min(2.0, 1 + (data_volume_records / 100000))
|
|
475
|
+
max_fine = max(max_fine, fine * volume_multiplier)
|
|
476
|
+
|
|
477
|
+
return max_fine * breach_likelihood
|
|
478
|
+
|
|
479
|
+
def _get_max_regulatory_fine(self, framework: ComplianceFramework) -> float:
|
|
480
|
+
"""Gibt die maximale Strafe für ein Framework zurück."""
|
|
481
|
+
# Höchststrafen in USD
|
|
482
|
+
max_fines = {
|
|
483
|
+
ComplianceFramework.GDPR: 20000000, # 20M EUR oder 4% des Umsatzes
|
|
484
|
+
ComplianceFramework.HIPAA: 1500000, # pro Verstoß
|
|
485
|
+
ComplianceFramework.PCI_DSS: 100000, # pro Monat
|
|
486
|
+
ComplianceFramework.SOX: 5000000, # + Gefängnisstrafe
|
|
487
|
+
ComplianceFramework.ISO27001: 50000, # Zertifizierungsverlust
|
|
488
|
+
ComplianceFramework.NIST: 1000000, # Vertragsstrafen
|
|
489
|
+
}
|
|
490
|
+
return max_fines.get(framework, 100000)
|
|
491
|
+
|
|
492
|
+
def _estimate_legal_costs(self, data_volume_records: int, breach_likelihood: float) -> float:
|
|
493
|
+
"""Schätzt die Rechtskosten."""
|
|
494
|
+
base_costs = 50000
|
|
495
|
+
per_record_cost = 0.50 # Durchschnittliche Kosten pro Datensatz
|
|
496
|
+
return (base_costs + data_volume_records * per_record_cost) * breach_likelihood
|
|
497
|
+
|
|
498
|
+
def _calculate_reputation_costs(
|
|
499
|
+
self,
|
|
500
|
+
asset_context: AssetContext,
|
|
501
|
+
breach_likelihood: float
|
|
502
|
+
) -> float:
|
|
503
|
+
"""Berechnet die Kosten durch Reputationsschaden."""
|
|
504
|
+
if self.annual_revenue == 0:
|
|
505
|
+
return 50000 * breach_likelihood
|
|
506
|
+
|
|
507
|
+
# Geschätzter Umsatzverlust durch Reputationsschaden (5-15%)
|
|
508
|
+
revenue_loss_percentage = 0.05 + (asset_context.criticality.level * 0.02)
|
|
509
|
+
return self.annual_revenue * revenue_loss_percentage * breach_likelihood
|
|
510
|
+
|
|
511
|
+
def _identify_violated_controls(
|
|
512
|
+
self,
|
|
513
|
+
framework: ComplianceFramework,
|
|
514
|
+
finding_type: str
|
|
515
|
+
) -> List[str]:
|
|
516
|
+
"""Identifiziert verletzte Controls basierend auf dem Finding-Typ."""
|
|
517
|
+
control_mapping = {
|
|
518
|
+
"sql_injection": ["Input Validation", "Secure Coding", "WAF Protection"],
|
|
519
|
+
"xss": ["Output Encoding", "Content Security Policy", "Input Validation"],
|
|
520
|
+
"authentication_bypass": ["Authentication", "Access Control", "Session Management"],
|
|
521
|
+
"sensitive_data_exposure": ["Data Encryption", "Access Control", "Data Classification"],
|
|
522
|
+
"broken_access_control": ["Access Control", "Authorization", "RBAC"],
|
|
523
|
+
"security_misconfiguration": ["Configuration Management", "Hardening", "Patch Management"],
|
|
524
|
+
"insufficient_logging": ["Logging and Monitoring", "Audit Controls", "SIEM"],
|
|
525
|
+
"cryptographic_failure": ["Cryptography", "Key Management", "Data Protection"],
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
finding_lower = finding_type.lower().replace(" ", "_")
|
|
529
|
+
return control_mapping.get(finding_lower, ["General Security Control"])
|
|
530
|
+
|
|
531
|
+
def compare_impacts(
|
|
532
|
+
self,
|
|
533
|
+
results: List[BusinessImpactResult]
|
|
534
|
+
) -> List[Tuple[BusinessImpactResult, int]]:
|
|
535
|
+
"""
|
|
536
|
+
Vergleicht mehrere Impact-Ergebnisse und priorisiert sie.
|
|
537
|
+
|
|
538
|
+
Args:
|
|
539
|
+
results: Liste von BusinessImpactResult-Objekten
|
|
540
|
+
|
|
541
|
+
Returns:
|
|
542
|
+
Liste von Tupeln (Result, Priorität)
|
|
543
|
+
"""
|
|
544
|
+
# Sortieren nach Gesamtscore (absteigend)
|
|
545
|
+
sorted_results = sorted(results, key=lambda x: x.overall_score, reverse=True)
|
|
546
|
+
|
|
547
|
+
return [(result, i + 1) for i, result in enumerate(sorted_results)]
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
# Singleton-Instanz für einfachen Zugriff
|
|
551
|
+
_default_calculator: Optional[BusinessImpactCalculator] = None
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def get_calculator(
|
|
555
|
+
organization_size: str = "medium",
|
|
556
|
+
annual_revenue: float = 0.0,
|
|
557
|
+
industry: str = "technology"
|
|
558
|
+
) -> BusinessImpactCalculator:
|
|
559
|
+
"""Gibt eine Calculator-Instanz zurück (erstellt eine neue bei Bedarf)."""
|
|
560
|
+
global _default_calculator
|
|
561
|
+
if _default_calculator is None:
|
|
562
|
+
_default_calculator = BusinessImpactCalculator(organization_size, annual_revenue, industry)
|
|
563
|
+
return _default_calculator
|