souleyez 2.43.29__py3-none-any.whl → 3.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.
- souleyez/__init__.py +1 -2
- souleyez/ai/__init__.py +21 -15
- souleyez/ai/action_mapper.py +249 -150
- souleyez/ai/chain_advisor.py +116 -100
- souleyez/ai/claude_provider.py +29 -28
- souleyez/ai/context_builder.py +80 -62
- souleyez/ai/executor.py +158 -117
- souleyez/ai/feedback_handler.py +136 -121
- souleyez/ai/llm_factory.py +27 -20
- souleyez/ai/llm_provider.py +4 -2
- souleyez/ai/ollama_provider.py +6 -9
- souleyez/ai/ollama_service.py +44 -37
- souleyez/ai/path_scorer.py +91 -76
- souleyez/ai/recommender.py +176 -144
- souleyez/ai/report_context.py +74 -73
- souleyez/ai/report_service.py +84 -66
- souleyez/ai/result_parser.py +222 -229
- souleyez/ai/safety.py +67 -44
- souleyez/auth/__init__.py +23 -22
- souleyez/auth/audit.py +36 -26
- souleyez/auth/engagement_access.py +65 -48
- souleyez/auth/permissions.py +14 -3
- souleyez/auth/session_manager.py +54 -37
- souleyez/auth/user_manager.py +109 -64
- souleyez/commands/audit.py +40 -43
- souleyez/commands/auth.py +35 -15
- souleyez/commands/deliverables.py +55 -50
- souleyez/commands/engagement.py +47 -28
- souleyez/commands/license.py +32 -23
- souleyez/commands/screenshots.py +36 -32
- souleyez/commands/user.py +82 -36
- souleyez/config.py +52 -44
- souleyez/core/credential_tester.py +87 -81
- souleyez/core/cve_mappings.py +179 -192
- souleyez/core/cve_matcher.py +162 -148
- souleyez/core/msf_auto_mapper.py +100 -83
- souleyez/core/msf_chain_engine.py +294 -256
- souleyez/core/msf_database.py +153 -70
- souleyez/core/msf_integration.py +679 -673
- souleyez/core/msf_rpc_client.py +40 -42
- souleyez/core/msf_rpc_manager.py +77 -79
- souleyez/core/msf_sync_manager.py +241 -181
- souleyez/core/network_utils.py +22 -15
- souleyez/core/parser_handler.py +34 -25
- souleyez/core/pending_chains.py +114 -63
- souleyez/core/templates.py +158 -107
- souleyez/core/tool_chaining.py +9564 -2881
- souleyez/core/version_utils.py +79 -94
- souleyez/core/vuln_correlation.py +136 -89
- souleyez/core/web_utils.py +33 -32
- souleyez/data/wordlists/ad_users.txt +378 -0
- souleyez/data/wordlists/api_endpoints_large.txt +769 -0
- souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
- souleyez/data/wordlists/lfi_payloads.txt +82 -0
- souleyez/data/wordlists/passwords_brute.txt +1548 -0
- souleyez/data/wordlists/passwords_crack.txt +2479 -0
- souleyez/data/wordlists/passwords_spray.txt +386 -0
- souleyez/data/wordlists/subdomains_large.txt +5057 -0
- souleyez/data/wordlists/usernames_common.txt +694 -0
- souleyez/data/wordlists/web_dirs_large.txt +4769 -0
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +12 -17
- souleyez/detection/mitre_mappings.py +61 -55
- souleyez/detection/validator.py +97 -86
- souleyez/devtools.py +23 -10
- souleyez/docs/README.md +4 -4
- souleyez/docs/api-reference/cli-commands.md +2 -2
- souleyez/docs/developer-guide/adding-new-tools.md +562 -0
- souleyez/docs/user-guide/auto-chaining.md +30 -8
- souleyez/docs/user-guide/getting-started.md +1 -1
- souleyez/docs/user-guide/installation.md +26 -3
- souleyez/docs/user-guide/metasploit-integration.md +2 -2
- souleyez/docs/user-guide/rbac.md +1 -1
- souleyez/docs/user-guide/scope-management.md +1 -1
- souleyez/docs/user-guide/siem-integration.md +1 -1
- souleyez/docs/user-guide/tools-reference.md +1 -8
- souleyez/docs/user-guide/worker-management.md +1 -1
- souleyez/engine/background.py +1239 -535
- souleyez/engine/base.py +4 -1
- souleyez/engine/job_status.py +17 -49
- souleyez/engine/log_sanitizer.py +103 -77
- souleyez/engine/manager.py +38 -7
- souleyez/engine/result_handler.py +2200 -1550
- souleyez/engine/worker_manager.py +50 -41
- souleyez/export/evidence_bundle.py +72 -62
- souleyez/feature_flags/features.py +16 -20
- souleyez/feature_flags.py +5 -9
- souleyez/handlers/__init__.py +11 -0
- souleyez/handlers/base.py +188 -0
- souleyez/handlers/bash_handler.py +277 -0
- souleyez/handlers/bloodhound_handler.py +243 -0
- souleyez/handlers/certipy_handler.py +311 -0
- souleyez/handlers/crackmapexec_handler.py +486 -0
- souleyez/handlers/dnsrecon_handler.py +344 -0
- souleyez/handlers/enum4linux_handler.py +400 -0
- souleyez/handlers/evil_winrm_handler.py +493 -0
- souleyez/handlers/ffuf_handler.py +815 -0
- souleyez/handlers/gobuster_handler.py +1114 -0
- souleyez/handlers/gpp_extract_handler.py +334 -0
- souleyez/handlers/hashcat_handler.py +444 -0
- souleyez/handlers/hydra_handler.py +564 -0
- souleyez/handlers/impacket_getuserspns_handler.py +343 -0
- souleyez/handlers/impacket_psexec_handler.py +222 -0
- souleyez/handlers/impacket_secretsdump_handler.py +426 -0
- souleyez/handlers/john_handler.py +286 -0
- souleyez/handlers/katana_handler.py +425 -0
- souleyez/handlers/kerbrute_handler.py +298 -0
- souleyez/handlers/ldapsearch_handler.py +636 -0
- souleyez/handlers/lfi_extract_handler.py +464 -0
- souleyez/handlers/msf_auxiliary_handler.py +409 -0
- souleyez/handlers/msf_exploit_handler.py +380 -0
- souleyez/handlers/nikto_handler.py +413 -0
- souleyez/handlers/nmap_handler.py +821 -0
- souleyez/handlers/nuclei_handler.py +359 -0
- souleyez/handlers/nxc_handler.py +417 -0
- souleyez/handlers/rdp_sec_check_handler.py +353 -0
- souleyez/handlers/registry.py +292 -0
- souleyez/handlers/responder_handler.py +232 -0
- souleyez/handlers/service_explorer_handler.py +434 -0
- souleyez/handlers/smbclient_handler.py +344 -0
- souleyez/handlers/smbmap_handler.py +510 -0
- souleyez/handlers/smbpasswd_handler.py +296 -0
- souleyez/handlers/sqlmap_handler.py +1116 -0
- souleyez/handlers/theharvester_handler.py +601 -0
- souleyez/handlers/web_login_test_handler.py +327 -0
- souleyez/handlers/whois_handler.py +277 -0
- souleyez/handlers/wpscan_handler.py +554 -0
- souleyez/history.py +32 -16
- souleyez/importers/msf_importer.py +106 -75
- souleyez/importers/smart_importer.py +208 -147
- souleyez/integrations/siem/__init__.py +10 -10
- souleyez/integrations/siem/base.py +17 -18
- souleyez/integrations/siem/elastic.py +108 -122
- souleyez/integrations/siem/factory.py +207 -80
- souleyez/integrations/siem/googlesecops.py +146 -154
- souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
- souleyez/integrations/siem/sentinel.py +107 -109
- souleyez/integrations/siem/splunk.py +246 -212
- souleyez/integrations/siem/wazuh.py +65 -71
- souleyez/integrations/wazuh/__init__.py +5 -5
- souleyez/integrations/wazuh/client.py +70 -93
- souleyez/integrations/wazuh/config.py +85 -57
- souleyez/integrations/wazuh/host_mapper.py +28 -36
- souleyez/integrations/wazuh/sync.py +78 -68
- souleyez/intelligence/__init__.py +4 -5
- souleyez/intelligence/correlation_analyzer.py +309 -295
- souleyez/intelligence/exploit_knowledge.py +661 -623
- souleyez/intelligence/exploit_suggestions.py +159 -139
- souleyez/intelligence/gap_analyzer.py +132 -97
- souleyez/intelligence/gap_detector.py +251 -214
- souleyez/intelligence/sensitive_tables.py +266 -129
- souleyez/intelligence/service_parser.py +137 -123
- souleyez/intelligence/surface_analyzer.py +407 -268
- souleyez/intelligence/target_parser.py +159 -162
- souleyez/licensing/__init__.py +6 -6
- souleyez/licensing/validator.py +17 -19
- souleyez/log_config.py +79 -54
- souleyez/main.py +1505 -687
- souleyez/migrations/fix_job_counter.py +16 -14
- souleyez/parsers/bloodhound_parser.py +41 -39
- souleyez/parsers/crackmapexec_parser.py +178 -111
- souleyez/parsers/dalfox_parser.py +72 -77
- souleyez/parsers/dnsrecon_parser.py +103 -91
- souleyez/parsers/enum4linux_parser.py +183 -153
- souleyez/parsers/ffuf_parser.py +29 -25
- souleyez/parsers/gobuster_parser.py +301 -41
- souleyez/parsers/hashcat_parser.py +324 -79
- souleyez/parsers/http_fingerprint_parser.py +350 -103
- souleyez/parsers/hydra_parser.py +131 -111
- souleyez/parsers/impacket_parser.py +231 -178
- souleyez/parsers/john_parser.py +98 -86
- souleyez/parsers/katana_parser.py +316 -0
- souleyez/parsers/msf_parser.py +943 -498
- souleyez/parsers/nikto_parser.py +346 -65
- souleyez/parsers/nmap_parser.py +262 -174
- souleyez/parsers/nuclei_parser.py +40 -44
- souleyez/parsers/responder_parser.py +26 -26
- souleyez/parsers/searchsploit_parser.py +74 -74
- souleyez/parsers/service_explorer_parser.py +279 -0
- souleyez/parsers/smbmap_parser.py +180 -124
- souleyez/parsers/sqlmap_parser.py +434 -308
- souleyez/parsers/theharvester_parser.py +75 -57
- souleyez/parsers/whois_parser.py +135 -94
- souleyez/parsers/wpscan_parser.py +278 -190
- souleyez/plugins/afp.py +44 -36
- souleyez/plugins/afp_brute.py +114 -46
- souleyez/plugins/ard.py +48 -37
- souleyez/plugins/bloodhound.py +95 -61
- souleyez/plugins/certipy.py +303 -0
- souleyez/plugins/crackmapexec.py +186 -85
- souleyez/plugins/dalfox.py +120 -59
- souleyez/plugins/dns_hijack.py +146 -41
- souleyez/plugins/dnsrecon.py +97 -61
- souleyez/plugins/enum4linux.py +91 -66
- souleyez/plugins/evil_winrm.py +291 -0
- souleyez/plugins/ffuf.py +166 -90
- souleyez/plugins/firmware_extract.py +133 -29
- souleyez/plugins/gobuster.py +387 -190
- souleyez/plugins/gpp_extract.py +393 -0
- souleyez/plugins/hashcat.py +100 -73
- souleyez/plugins/http_fingerprint.py +913 -267
- souleyez/plugins/hydra.py +566 -200
- souleyez/plugins/impacket_getnpusers.py +117 -69
- souleyez/plugins/impacket_psexec.py +84 -64
- souleyez/plugins/impacket_secretsdump.py +103 -69
- souleyez/plugins/impacket_smbclient.py +89 -75
- souleyez/plugins/john.py +86 -69
- souleyez/plugins/katana.py +313 -0
- souleyez/plugins/kerbrute.py +237 -0
- souleyez/plugins/lfi_extract.py +541 -0
- souleyez/plugins/macos_ssh.py +117 -48
- souleyez/plugins/mdns.py +35 -30
- souleyez/plugins/msf_auxiliary.py +253 -130
- souleyez/plugins/msf_exploit.py +239 -161
- souleyez/plugins/nikto.py +134 -78
- souleyez/plugins/nmap.py +275 -91
- souleyez/plugins/nuclei.py +180 -89
- souleyez/plugins/nxc.py +285 -0
- souleyez/plugins/plugin_base.py +35 -36
- souleyez/plugins/plugin_template.py +13 -5
- souleyez/plugins/rdp_sec_check.py +130 -0
- souleyez/plugins/responder.py +112 -71
- souleyez/plugins/router_http_brute.py +76 -65
- souleyez/plugins/router_ssh_brute.py +118 -41
- souleyez/plugins/router_telnet_brute.py +124 -42
- souleyez/plugins/routersploit.py +91 -59
- souleyez/plugins/routersploit_exploit.py +77 -55
- souleyez/plugins/searchsploit.py +91 -77
- souleyez/plugins/service_explorer.py +1160 -0
- souleyez/plugins/smbmap.py +122 -72
- souleyez/plugins/smbpasswd.py +215 -0
- souleyez/plugins/sqlmap.py +301 -113
- souleyez/plugins/theharvester.py +127 -75
- souleyez/plugins/tr069.py +79 -57
- souleyez/plugins/upnp.py +65 -47
- souleyez/plugins/upnp_abuse.py +73 -55
- souleyez/plugins/vnc_access.py +129 -42
- souleyez/plugins/vnc_brute.py +109 -38
- souleyez/plugins/web_login_test.py +417 -0
- souleyez/plugins/whois.py +77 -58
- souleyez/plugins/wpscan.py +219 -69
- souleyez/reporting/__init__.py +2 -1
- souleyez/reporting/attack_chain.py +411 -346
- souleyez/reporting/charts.py +436 -501
- souleyez/reporting/compliance_mappings.py +334 -201
- souleyez/reporting/detection_report.py +126 -125
- souleyez/reporting/formatters.py +828 -591
- souleyez/reporting/generator.py +386 -302
- souleyez/reporting/metrics.py +72 -75
- souleyez/scanner.py +35 -29
- souleyez/security/__init__.py +37 -11
- souleyez/security/scope_validator.py +175 -106
- souleyez/security/validation.py +237 -149
- souleyez/security.py +22 -6
- souleyez/storage/credentials.py +247 -186
- souleyez/storage/crypto.py +296 -129
- souleyez/storage/database.py +73 -50
- souleyez/storage/db.py +58 -36
- souleyez/storage/deliverable_evidence.py +177 -128
- souleyez/storage/deliverable_exporter.py +282 -246
- souleyez/storage/deliverable_templates.py +134 -116
- souleyez/storage/deliverables.py +135 -130
- souleyez/storage/engagements.py +109 -56
- souleyez/storage/evidence.py +181 -152
- souleyez/storage/execution_log.py +31 -17
- souleyez/storage/exploit_attempts.py +93 -57
- souleyez/storage/exploits.py +67 -36
- souleyez/storage/findings.py +48 -61
- souleyez/storage/hosts.py +176 -144
- souleyez/storage/migrate_to_engagements.py +43 -19
- souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
- souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
- souleyez/storage/migrations/_003_add_execution_log.py +14 -8
- souleyez/storage/migrations/_005_screenshots.py +13 -5
- souleyez/storage/migrations/_006_deliverables.py +13 -5
- souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
- souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
- souleyez/storage/migrations/_010_evidence_linking.py +17 -10
- souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
- souleyez/storage/migrations/_012_team_collaboration.py +34 -21
- souleyez/storage/migrations/_013_add_host_tags.py +12 -6
- souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
- souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
- souleyez/storage/migrations/_016_add_domain_field.py +10 -4
- souleyez/storage/migrations/_017_msf_sessions.py +16 -8
- souleyez/storage/migrations/_018_add_osint_target.py +10 -6
- souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
- souleyez/storage/migrations/_020_add_rbac.py +36 -15
- souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
- souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
- souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
- souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
- souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
- souleyez/storage/migrations/__init__.py +26 -26
- souleyez/storage/migrations/migration_manager.py +19 -19
- souleyez/storage/msf_sessions.py +100 -65
- souleyez/storage/osint.py +17 -24
- souleyez/storage/recommendation_engine.py +269 -235
- souleyez/storage/screenshots.py +33 -32
- souleyez/storage/smb_shares.py +136 -92
- souleyez/storage/sqlmap_data.py +183 -128
- souleyez/storage/team_collaboration.py +135 -141
- souleyez/storage/timeline_tracker.py +122 -94
- souleyez/storage/wazuh_vulns.py +64 -66
- souleyez/storage/web_paths.py +33 -37
- souleyez/testing/credential_tester.py +221 -205
- souleyez/ui/__init__.py +1 -1
- souleyez/ui/ai_quotes.py +12 -12
- souleyez/ui/attack_surface.py +2439 -1516
- souleyez/ui/chain_rules_view.py +914 -382
- souleyez/ui/correlation_view.py +312 -230
- souleyez/ui/dashboard.py +2382 -1130
- souleyez/ui/deliverables_view.py +148 -62
- souleyez/ui/design_system.py +13 -13
- souleyez/ui/errors.py +49 -49
- souleyez/ui/evidence_linking_view.py +284 -179
- souleyez/ui/evidence_vault.py +393 -285
- souleyez/ui/exploit_suggestions_view.py +555 -349
- souleyez/ui/export_view.py +100 -66
- souleyez/ui/gap_analysis_view.py +315 -171
- souleyez/ui/help_system.py +105 -97
- souleyez/ui/intelligence_view.py +436 -293
- souleyez/ui/interactive.py +23034 -10679
- souleyez/ui/interactive_selector.py +75 -68
- souleyez/ui/log_formatter.py +47 -39
- souleyez/ui/menu_components.py +22 -13
- souleyez/ui/msf_auxiliary_menu.py +184 -133
- souleyez/ui/pending_chains_view.py +336 -172
- souleyez/ui/progress_indicators.py +5 -3
- souleyez/ui/recommendations_view.py +195 -137
- souleyez/ui/rule_builder.py +343 -225
- souleyez/ui/setup_wizard.py +678 -284
- souleyez/ui/shortcuts.py +217 -165
- souleyez/ui/splunk_gap_analysis_view.py +452 -270
- souleyez/ui/splunk_vulns_view.py +139 -86
- souleyez/ui/team_dashboard.py +498 -335
- souleyez/ui/template_selector.py +196 -105
- souleyez/ui/terminal.py +6 -6
- souleyez/ui/timeline_view.py +198 -127
- souleyez/ui/tool_setup.py +264 -164
- souleyez/ui/tutorial.py +202 -72
- souleyez/ui/tutorial_state.py +40 -40
- souleyez/ui/wazuh_vulns_view.py +235 -141
- souleyez/ui/wordlist_browser.py +260 -107
- souleyez/ui.py +464 -312
- souleyez/utils/tool_checker.py +427 -367
- souleyez/utils.py +33 -29
- souleyez/wordlists.py +134 -167
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/METADATA +2 -2
- souleyez-3.0.0.dist-info/RECORD +443 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
- souleyez-2.43.29.dist-info/RECORD +0 -379
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/top_level.txt +0 -0
souleyez/storage/deliverables.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Deliverable tracking and acceptance criteria management.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from typing import List, Dict, Optional
|
|
5
6
|
from .database import get_db
|
|
6
7
|
|
|
@@ -17,11 +18,11 @@ class DeliverableManager:
|
|
|
17
18
|
category: str,
|
|
18
19
|
title: str,
|
|
19
20
|
description: str = None,
|
|
20
|
-
target_type: str =
|
|
21
|
+
target_type: str = "manual",
|
|
21
22
|
target_value: int = None,
|
|
22
23
|
auto_validate: bool = False,
|
|
23
24
|
validation_query: str = None,
|
|
24
|
-
priority: str =
|
|
25
|
+
priority: str = "medium",
|
|
25
26
|
) -> int:
|
|
26
27
|
"""
|
|
27
28
|
Add a deliverable to an engagement.
|
|
@@ -40,25 +41,25 @@ class DeliverableManager:
|
|
|
40
41
|
Returns:
|
|
41
42
|
Deliverable ID
|
|
42
43
|
"""
|
|
43
|
-
deliverable_id = self.db.insert(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
deliverable_id = self.db.insert(
|
|
45
|
+
"deliverables",
|
|
46
|
+
{
|
|
47
|
+
"engagement_id": engagement_id,
|
|
48
|
+
"category": category,
|
|
49
|
+
"title": title,
|
|
50
|
+
"description": description,
|
|
51
|
+
"target_type": target_type,
|
|
52
|
+
"target_value": target_value,
|
|
53
|
+
"auto_validate": auto_validate,
|
|
54
|
+
"validation_query": validation_query,
|
|
55
|
+
"priority": priority,
|
|
56
|
+
},
|
|
57
|
+
)
|
|
54
58
|
|
|
55
59
|
return deliverable_id
|
|
56
60
|
|
|
57
61
|
def list_deliverables(
|
|
58
|
-
self,
|
|
59
|
-
engagement_id: int,
|
|
60
|
-
category: str = None,
|
|
61
|
-
status: str = None
|
|
62
|
+
self, engagement_id: int, category: str = None, status: str = None
|
|
62
63
|
) -> List[Dict]:
|
|
63
64
|
"""
|
|
64
65
|
List deliverables for engagement.
|
|
@@ -89,8 +90,7 @@ class DeliverableManager:
|
|
|
89
90
|
def get_deliverable(self, deliverable_id: int) -> Optional[Dict]:
|
|
90
91
|
"""Get deliverable by ID."""
|
|
91
92
|
return self.db.execute_one(
|
|
92
|
-
"SELECT * FROM deliverables WHERE id = ?",
|
|
93
|
-
(deliverable_id,)
|
|
93
|
+
"SELECT * FROM deliverables WHERE id = ?", (deliverable_id,)
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
def update_deliverable(
|
|
@@ -98,29 +98,28 @@ class DeliverableManager:
|
|
|
98
98
|
deliverable_id: int,
|
|
99
99
|
current_value: int = None,
|
|
100
100
|
status: str = None,
|
|
101
|
-
completed_at: str = None
|
|
101
|
+
completed_at: str = None,
|
|
102
102
|
) -> bool:
|
|
103
103
|
"""Update deliverable progress."""
|
|
104
104
|
updates = {}
|
|
105
105
|
|
|
106
106
|
if current_value is not None:
|
|
107
|
-
updates[
|
|
107
|
+
updates["current_value"] = current_value
|
|
108
108
|
|
|
109
109
|
if status:
|
|
110
|
-
updates[
|
|
110
|
+
updates["status"] = status
|
|
111
111
|
|
|
112
112
|
if completed_at:
|
|
113
|
-
updates[
|
|
113
|
+
updates["completed_at"] = completed_at
|
|
114
114
|
|
|
115
115
|
if not updates:
|
|
116
116
|
return False
|
|
117
117
|
|
|
118
|
-
set_clause =
|
|
118
|
+
set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
|
|
119
119
|
values = list(updates.values()) + [deliverable_id]
|
|
120
120
|
|
|
121
121
|
self.db.execute(
|
|
122
|
-
f"UPDATE deliverables SET {set_clause} WHERE id = ?",
|
|
123
|
-
tuple(values)
|
|
122
|
+
f"UPDATE deliverables SET {set_clause} WHERE id = ?", tuple(values)
|
|
124
123
|
)
|
|
125
124
|
|
|
126
125
|
return True
|
|
@@ -128,15 +127,14 @@ class DeliverableManager:
|
|
|
128
127
|
def mark_complete(self, deliverable_id: int) -> bool:
|
|
129
128
|
"""Mark deliverable as completed."""
|
|
130
129
|
from datetime import datetime
|
|
130
|
+
|
|
131
131
|
return self.update_deliverable(
|
|
132
|
-
deliverable_id,
|
|
133
|
-
status='completed',
|
|
134
|
-
completed_at=datetime.now().isoformat()
|
|
132
|
+
deliverable_id, status="completed", completed_at=datetime.now().isoformat()
|
|
135
133
|
)
|
|
136
134
|
|
|
137
135
|
def mark_failed(self, deliverable_id: int) -> bool:
|
|
138
136
|
"""Mark deliverable as failed."""
|
|
139
|
-
return self.update_deliverable(deliverable_id, status=
|
|
137
|
+
return self.update_deliverable(deliverable_id, status="failed")
|
|
140
138
|
|
|
141
139
|
def validate_all(self, engagement_id: int) -> Dict:
|
|
142
140
|
"""
|
|
@@ -151,17 +149,23 @@ class DeliverableManager:
|
|
|
151
149
|
}
|
|
152
150
|
"""
|
|
153
151
|
deliverables = self.list_deliverables(engagement_id)
|
|
154
|
-
stats = {
|
|
152
|
+
stats = {
|
|
153
|
+
"updated": 0,
|
|
154
|
+
"completed": 0,
|
|
155
|
+
"in_progress": 0,
|
|
156
|
+
"pending": 0,
|
|
157
|
+
"failed": 0,
|
|
158
|
+
}
|
|
155
159
|
|
|
156
160
|
for d in deliverables:
|
|
157
|
-
if not d[
|
|
161
|
+
if not d["auto_validate"]:
|
|
158
162
|
continue
|
|
159
163
|
|
|
160
164
|
result = self._validate_deliverable(d)
|
|
161
165
|
|
|
162
|
-
if result[
|
|
163
|
-
stats[
|
|
164
|
-
stats[result[
|
|
166
|
+
if result["updated"]:
|
|
167
|
+
stats["updated"] += 1
|
|
168
|
+
stats[result["status"]] += 1
|
|
165
169
|
|
|
166
170
|
return stats
|
|
167
171
|
|
|
@@ -177,54 +181,55 @@ class DeliverableManager:
|
|
|
177
181
|
'status': 'in_progress'
|
|
178
182
|
}
|
|
179
183
|
"""
|
|
180
|
-
if not deliverable[
|
|
181
|
-
return {
|
|
184
|
+
if not deliverable["validation_query"]:
|
|
185
|
+
return {"updated": False}
|
|
182
186
|
|
|
183
187
|
try:
|
|
184
|
-
result = self.db.execute_one(deliverable[
|
|
188
|
+
result = self.db.execute_one(deliverable["validation_query"])
|
|
185
189
|
|
|
186
190
|
if not result:
|
|
187
|
-
return {
|
|
191
|
+
return {"updated": False}
|
|
188
192
|
|
|
189
|
-
current_value = result.get(
|
|
193
|
+
current_value = result.get("count") or result.get("value") or 0
|
|
190
194
|
|
|
191
|
-
target_type = deliverable[
|
|
192
|
-
target_value = deliverable[
|
|
195
|
+
target_type = deliverable["target_type"]
|
|
196
|
+
target_value = deliverable["target_value"]
|
|
193
197
|
|
|
194
|
-
if target_type ==
|
|
198
|
+
if target_type == "count":
|
|
195
199
|
if current_value >= target_value:
|
|
196
|
-
status =
|
|
200
|
+
status = "completed"
|
|
197
201
|
elif current_value > 0:
|
|
198
|
-
status =
|
|
202
|
+
status = "in_progress"
|
|
199
203
|
else:
|
|
200
|
-
status =
|
|
201
|
-
elif target_type ==
|
|
202
|
-
status =
|
|
204
|
+
status = "pending"
|
|
205
|
+
elif target_type == "boolean":
|
|
206
|
+
status = "completed" if current_value > 0 else "pending"
|
|
203
207
|
else:
|
|
204
|
-
status =
|
|
208
|
+
status = "pending"
|
|
205
209
|
|
|
206
210
|
completed_at = None
|
|
207
|
-
if status ==
|
|
211
|
+
if status == "completed" and deliverable["status"] != "completed":
|
|
208
212
|
from datetime import datetime
|
|
213
|
+
|
|
209
214
|
completed_at = datetime.now().isoformat()
|
|
210
215
|
|
|
211
216
|
self.update_deliverable(
|
|
212
|
-
deliverable[
|
|
217
|
+
deliverable["id"],
|
|
213
218
|
current_value=current_value,
|
|
214
219
|
status=status,
|
|
215
|
-
completed_at=completed_at
|
|
220
|
+
completed_at=completed_at,
|
|
216
221
|
)
|
|
217
222
|
|
|
218
223
|
return {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
"updated": True,
|
|
225
|
+
"current_value": current_value,
|
|
226
|
+
"target_value": target_value,
|
|
227
|
+
"status": status,
|
|
223
228
|
}
|
|
224
229
|
|
|
225
230
|
except Exception as e:
|
|
226
231
|
print(f"Validation error for deliverable {deliverable['id']}: {e}")
|
|
227
|
-
return {
|
|
232
|
+
return {"updated": False}
|
|
228
233
|
|
|
229
234
|
def get_summary(self, engagement_id: int) -> Dict:
|
|
230
235
|
"""
|
|
@@ -244,34 +249,34 @@ class DeliverableManager:
|
|
|
244
249
|
deliverables = self.list_deliverables(engagement_id)
|
|
245
250
|
|
|
246
251
|
summary = {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
"total": len(deliverables),
|
|
253
|
+
"completed": 0,
|
|
254
|
+
"in_progress": 0,
|
|
255
|
+
"pending": 0,
|
|
256
|
+
"failed": 0,
|
|
257
|
+
"by_category": {},
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
for d in deliverables:
|
|
256
|
-
status = d[
|
|
261
|
+
status = d["status"]
|
|
257
262
|
summary[status] += 1
|
|
258
263
|
|
|
259
|
-
category = d[
|
|
260
|
-
if category not in summary[
|
|
261
|
-
summary[
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
category = d["category"]
|
|
265
|
+
if category not in summary["by_category"]:
|
|
266
|
+
summary["by_category"][category] = {
|
|
267
|
+
"total": 0,
|
|
268
|
+
"completed": 0,
|
|
269
|
+
"in_progress": 0,
|
|
270
|
+
"pending": 0,
|
|
266
271
|
}
|
|
267
272
|
|
|
268
|
-
summary[
|
|
269
|
-
summary[
|
|
273
|
+
summary["by_category"][category]["total"] += 1
|
|
274
|
+
summary["by_category"][category][status] += 1
|
|
270
275
|
|
|
271
|
-
if summary[
|
|
272
|
-
summary[
|
|
276
|
+
if summary["total"] > 0:
|
|
277
|
+
summary["completion_rate"] = summary["completed"] / summary["total"]
|
|
273
278
|
else:
|
|
274
|
-
summary[
|
|
279
|
+
summary["completion_rate"] = 0.0
|
|
275
280
|
|
|
276
281
|
return summary
|
|
277
282
|
|
|
@@ -284,74 +289,74 @@ class DeliverableManager:
|
|
|
284
289
|
"""
|
|
285
290
|
defaults = [
|
|
286
291
|
{
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
"category": "reconnaissance",
|
|
293
|
+
"title": "Identify 5+ live hosts",
|
|
294
|
+
"target_type": "count",
|
|
295
|
+
"target_value": 5,
|
|
296
|
+
"auto_validate": True,
|
|
297
|
+
"validation_query": f"SELECT COUNT(*) as count FROM hosts WHERE engagement_id = {engagement_id} AND status = 'up'",
|
|
298
|
+
"priority": "high",
|
|
294
299
|
},
|
|
295
300
|
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
"category": "reconnaissance",
|
|
302
|
+
"title": "Enumerate 10+ services",
|
|
303
|
+
"target_type": "count",
|
|
304
|
+
"target_value": 10,
|
|
305
|
+
"auto_validate": True,
|
|
306
|
+
"validation_query": f"SELECT COUNT(*) as count FROM services s JOIN hosts h ON s.host_id = h.id WHERE h.engagement_id = {engagement_id}",
|
|
307
|
+
"priority": "medium",
|
|
303
308
|
},
|
|
304
309
|
{
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
310
|
+
"category": "enumeration",
|
|
311
|
+
"title": "Enumerate 5+ user accounts",
|
|
312
|
+
"target_type": "count",
|
|
313
|
+
"target_value": 5,
|
|
314
|
+
"auto_validate": True,
|
|
315
|
+
"validation_query": f"SELECT COUNT(DISTINCT username) as count FROM credentials WHERE engagement_id = {engagement_id} AND username IS NOT NULL",
|
|
316
|
+
"priority": "high",
|
|
312
317
|
},
|
|
313
318
|
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
319
|
+
"category": "exploitation",
|
|
320
|
+
"title": "Obtain 3+ valid credentials",
|
|
321
|
+
"target_type": "count",
|
|
322
|
+
"target_value": 3,
|
|
323
|
+
"auto_validate": True,
|
|
324
|
+
"validation_query": f"SELECT COUNT(*) as count FROM credentials WHERE engagement_id = {engagement_id} AND status = 'valid'",
|
|
325
|
+
"priority": "critical",
|
|
321
326
|
},
|
|
322
327
|
{
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
"category": "exploitation",
|
|
329
|
+
"title": "Compromise 2+ hosts",
|
|
330
|
+
"target_type": "count",
|
|
331
|
+
"target_value": 2,
|
|
332
|
+
"auto_validate": True,
|
|
333
|
+
"validation_query": f"SELECT COUNT(*) as count FROM hosts WHERE engagement_id = {engagement_id} AND access_level != 'none'",
|
|
334
|
+
"priority": "critical",
|
|
330
335
|
},
|
|
331
336
|
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
337
|
+
"category": "post_exploitation",
|
|
338
|
+
"title": "Extract database contents",
|
|
339
|
+
"target_type": "count",
|
|
340
|
+
"target_value": 1,
|
|
341
|
+
"auto_validate": True,
|
|
342
|
+
"validation_query": f"SELECT COUNT(*) as count FROM sqli_databases WHERE engagement_id = {engagement_id}",
|
|
343
|
+
"priority": "high",
|
|
339
344
|
},
|
|
340
345
|
{
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
346
|
+
"category": "techniques",
|
|
347
|
+
"title": "Demonstrate privilege escalation",
|
|
348
|
+
"target_type": "manual",
|
|
349
|
+
"auto_validate": False,
|
|
350
|
+
"priority": "high",
|
|
351
|
+
"description": "Escalate from user to root/admin on at least one system",
|
|
347
352
|
},
|
|
348
353
|
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
"category": "techniques",
|
|
355
|
+
"title": "Perform lateral movement",
|
|
356
|
+
"target_type": "manual",
|
|
357
|
+
"auto_validate": False,
|
|
358
|
+
"priority": "medium",
|
|
359
|
+
"description": "Move from one compromised host to another",
|
|
355
360
|
},
|
|
356
361
|
]
|
|
357
362
|
|