souleyez 2.43.26__py3-none-any.whl → 2.43.34__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 souleyez might be problematic. Click here for more details.
- 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 +9526 -2879
- 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 +563 -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 +408 -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 +371 -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 +854 -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 +173 -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 +223 -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 +23434 -10286
- 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.26.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
- souleyez-2.43.34.dist-info/RECORD +443 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
- souleyez-2.43.26.dist-info/RECORD +0 -379
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
souleyez/utils/tool_checker.py
CHANGED
|
@@ -7,6 +7,7 @@ installation instructions for missing tools.
|
|
|
7
7
|
Supports both Kali Linux (apt) and Ubuntu (mixed methods).
|
|
8
8
|
Includes version checking for tools that require specific versions.
|
|
9
9
|
"""
|
|
10
|
+
|
|
10
11
|
import shutil
|
|
11
12
|
import os
|
|
12
13
|
import re
|
|
@@ -26,11 +27,11 @@ def parse_version(version_str: str) -> Tuple[int, ...]:
|
|
|
26
27
|
if not version_str:
|
|
27
28
|
return (0,)
|
|
28
29
|
# Remove leading 'v' if present
|
|
29
|
-
version_str = version_str.lstrip(
|
|
30
|
+
version_str = version_str.lstrip("v")
|
|
30
31
|
# Extract just the numeric version part (before any dash or other suffix)
|
|
31
|
-
match = re.match(r
|
|
32
|
+
match = re.match(r"(\d+(?:\.\d+)*)", version_str)
|
|
32
33
|
if match:
|
|
33
|
-
return tuple(int(x) for x in match.group(1).split(
|
|
34
|
+
return tuple(int(x) for x in match.group(1).split("."))
|
|
34
35
|
return (0,)
|
|
35
36
|
|
|
36
37
|
|
|
@@ -50,7 +51,12 @@ def version_meets_requirement(installed: str, required: str) -> bool:
|
|
|
50
51
|
return installed_tuple >= required_tuple
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def get_tool_version(
|
|
54
|
+
def get_tool_version(
|
|
55
|
+
command: str,
|
|
56
|
+
version_cmd: str = None,
|
|
57
|
+
version_regex: str = None,
|
|
58
|
+
version_fallback: str = None,
|
|
59
|
+
) -> Optional[str]:
|
|
54
60
|
"""
|
|
55
61
|
Get the version of an installed tool.
|
|
56
62
|
|
|
@@ -68,16 +74,13 @@ def get_tool_version(command: str, version_cmd: str = None, version_regex: str =
|
|
|
68
74
|
|
|
69
75
|
# Default version command
|
|
70
76
|
if version_cmd is None:
|
|
71
|
-
version_cmd = f
|
|
77
|
+
version_cmd = f"{command} --version"
|
|
72
78
|
else:
|
|
73
|
-
version_cmd = version_cmd.replace(
|
|
79
|
+
version_cmd = version_cmd.replace("{command}", command)
|
|
74
80
|
|
|
75
81
|
try:
|
|
76
82
|
result = subprocess.run(
|
|
77
|
-
version_cmd.split(),
|
|
78
|
-
capture_output=True,
|
|
79
|
-
text=True,
|
|
80
|
-
timeout=10
|
|
83
|
+
version_cmd.split(), capture_output=True, text=True, timeout=10
|
|
81
84
|
)
|
|
82
85
|
output = result.stdout + result.stderr
|
|
83
86
|
|
|
@@ -89,10 +92,10 @@ def get_tool_version(command: str, version_cmd: str = None, version_regex: str =
|
|
|
89
92
|
|
|
90
93
|
# Try common version patterns
|
|
91
94
|
patterns = [
|
|
92
|
-
r
|
|
93
|
-
r
|
|
94
|
-
r
|
|
95
|
-
r
|
|
95
|
+
r"(\d+\.\d+\.\d+)", # 3.8.2
|
|
96
|
+
r"v(\d+\.\d+\.\d+)", # v3.8.2
|
|
97
|
+
r"version\s+(\d+\.\d+\.\d+)", # version 3.8.2
|
|
98
|
+
r"(\d+\.\d+)", # 3.8
|
|
96
99
|
]
|
|
97
100
|
|
|
98
101
|
for pattern in patterns:
|
|
@@ -112,19 +115,19 @@ def get_tool_version(command: str, version_cmd: str = None, version_regex: str =
|
|
|
112
115
|
def detect_distro() -> str:
|
|
113
116
|
"""Detect the Linux distribution."""
|
|
114
117
|
try:
|
|
115
|
-
with open(
|
|
118
|
+
with open("/etc/os-release", "r") as f:
|
|
116
119
|
content = f.read().lower()
|
|
117
|
-
if
|
|
118
|
-
return
|
|
119
|
-
elif
|
|
120
|
-
return
|
|
121
|
-
elif
|
|
122
|
-
return
|
|
123
|
-
elif
|
|
124
|
-
return
|
|
120
|
+
if "kali" in content:
|
|
121
|
+
return "kali"
|
|
122
|
+
elif "parrot" in content:
|
|
123
|
+
return "parrot"
|
|
124
|
+
elif "ubuntu" in content:
|
|
125
|
+
return "ubuntu"
|
|
126
|
+
elif "debian" in content:
|
|
127
|
+
return "debian"
|
|
125
128
|
except FileNotFoundError:
|
|
126
129
|
pass
|
|
127
|
-
return
|
|
130
|
+
return "unknown"
|
|
128
131
|
|
|
129
132
|
|
|
130
133
|
# Install methods for different distributions
|
|
@@ -132,245 +135,282 @@ def detect_distro() -> str:
|
|
|
132
135
|
# 'kali_only' = apt on Kali, alternative method on Ubuntu
|
|
133
136
|
# 'manual' = requires manual installation on all distros
|
|
134
137
|
EXTERNAL_TOOLS = {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
"prerequisites": {
|
|
139
|
+
"curl": {
|
|
140
|
+
"command": "curl",
|
|
141
|
+
"install_kali": "sudo apt install curl",
|
|
142
|
+
"install_ubuntu": "sudo apt install curl",
|
|
143
|
+
"install_method": "apt",
|
|
144
|
+
"description": "Command-line tool for transferring data with URLs",
|
|
145
|
+
},
|
|
146
|
+
"pip3": {
|
|
147
|
+
"command": "pip3",
|
|
148
|
+
"install_kali": "sudo apt install python3-pip",
|
|
149
|
+
"install_ubuntu": "sudo apt install python3-pip",
|
|
150
|
+
"install_method": "apt",
|
|
151
|
+
"description": "Python package installer (required for many tools)",
|
|
149
152
|
},
|
|
150
153
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
154
|
+
"reconnaissance": {
|
|
155
|
+
"nmap": {
|
|
156
|
+
"command": "nmap",
|
|
157
|
+
"install_kali": "sudo apt install nmap",
|
|
158
|
+
"install_ubuntu": "sudo apt install nmap",
|
|
159
|
+
"install_method": "apt",
|
|
160
|
+
"description": "Network scanner for host/port discovery",
|
|
161
|
+
"needs_sudo": True, # Required for SYN/UDP/OS detection scans
|
|
162
|
+
},
|
|
163
|
+
"theharvester": {
|
|
164
|
+
"command": "theHarvester",
|
|
165
|
+
"install_kali": "sudo apt install theharvester",
|
|
166
|
+
"install_ubuntu": "pipx install git+https://github.com/laramies/theHarvester.git@4.4.4 && pipx inject theharvester netaddr aiomultiprocess aiosqlite pyppeteer uvloop certifi PyYAML censys aiohttp aiodns beautifulsoup4 requests shodan dnspython ujson lxml python-dateutil",
|
|
167
|
+
"install_method": "kali_only",
|
|
168
|
+
"description": "OSINT tool for gathering emails, names, subdomains",
|
|
169
|
+
},
|
|
170
|
+
"whois": {
|
|
171
|
+
"command": "whois",
|
|
172
|
+
"install_kali": "sudo apt install whois",
|
|
173
|
+
"install_ubuntu": "sudo apt install whois",
|
|
174
|
+
"install_method": "apt",
|
|
175
|
+
"description": "Domain registration information lookup",
|
|
176
|
+
},
|
|
177
|
+
"dnsrecon": {
|
|
178
|
+
"command": "dnsrecon",
|
|
179
|
+
"install_kali": "sudo apt install dnsrecon",
|
|
180
|
+
"install_ubuntu": "pipx install dnsrecon",
|
|
181
|
+
"install_method": "kali_only",
|
|
182
|
+
"description": "DNS enumeration and reconnaissance",
|
|
180
183
|
},
|
|
181
184
|
},
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
},
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
185
|
+
"web_scanning": {
|
|
186
|
+
"nuclei": {
|
|
187
|
+
"command": "nuclei",
|
|
188
|
+
"install_kali": "sudo apt install nuclei",
|
|
189
|
+
"install_ubuntu": 'cd /tmp && ARCH=$(uname -m | sed "s/x86_64/amd64/;s/aarch64/arm64/") && curl -sL $(curl -s https://api.github.com/repos/projectdiscovery/nuclei/releases/latest | grep browser_download_url | grep "linux_${ARCH}.zip" | cut -d \\" -f 4) -o nuclei.zip && unzip -o nuclei.zip nuclei && sudo mv nuclei /usr/local/bin/ && rm nuclei.zip',
|
|
190
|
+
"install_method": "kali_only",
|
|
191
|
+
"description": "Fast vulnerability scanner using templates",
|
|
192
|
+
},
|
|
193
|
+
"gobuster": {
|
|
194
|
+
"command": "gobuster",
|
|
195
|
+
"install_kali": "sudo apt install gobuster",
|
|
196
|
+
"install_ubuntu": 'ARCH=$(uname -m | sed "s/aarch64/arm64/") && wget -q https://github.com/OJ/gobuster/releases/download/v3.8.2/gobuster_Linux_${ARCH}.tar.gz -O /tmp/gobuster.tar.gz && tar -xzf /tmp/gobuster.tar.gz -C /tmp && sudo mv /tmp/gobuster /usr/local/bin/ && sudo chmod +x /usr/local/bin/gobuster && rm /tmp/gobuster.tar.gz',
|
|
197
|
+
"install_method": "kali_only",
|
|
198
|
+
"description": "Directory/file & DNS brute-forcing tool (v3.x required)",
|
|
199
|
+
"min_version": "3.0.0",
|
|
200
|
+
"version_cmd": "{command} -v",
|
|
201
|
+
"version_regex": r"version\s+(\d+\.\d+\.\d+)",
|
|
202
|
+
"version_note": "SoulEyez requires gobuster v3+ (uses subcommand syntax)",
|
|
203
|
+
"upgrade_kali": "go install github.com/OJ/gobuster/v3@latest",
|
|
204
|
+
"upgrade_ubuntu": "go install github.com/OJ/gobuster/v3@latest",
|
|
205
|
+
},
|
|
206
|
+
"ffuf": {
|
|
207
|
+
"command": "ffuf",
|
|
208
|
+
"install_kali": "sudo apt install ffuf",
|
|
209
|
+
"install_ubuntu": "sudo apt install ffuf",
|
|
210
|
+
"install_method": "apt",
|
|
211
|
+
"description": "Fast web fuzzer for content discovery",
|
|
212
|
+
},
|
|
213
|
+
"wpscan": {
|
|
214
|
+
"command": "wpscan",
|
|
215
|
+
"install_kali": "sudo apt install wpscan",
|
|
216
|
+
"install_ubuntu": "sudo gem install wpscan",
|
|
217
|
+
"install_method": "kali_only",
|
|
218
|
+
"description": "WordPress vulnerability scanner",
|
|
219
|
+
},
|
|
220
|
+
"nikto": {
|
|
221
|
+
"command": "nikto",
|
|
222
|
+
"install_kali": "sudo apt install nikto",
|
|
223
|
+
"install_ubuntu": "sudo apt install nikto",
|
|
224
|
+
"install_method": "apt",
|
|
225
|
+
"description": "Web server vulnerability scanner",
|
|
226
|
+
},
|
|
227
|
+
"dalfox": {
|
|
228
|
+
"command": "dalfox",
|
|
229
|
+
"install_kali": "go install github.com/hahwul/dalfox/v2@latest",
|
|
230
|
+
"install_ubuntu": "go install github.com/hahwul/dalfox/v2@latest",
|
|
231
|
+
"install_method": "go",
|
|
232
|
+
"description": "XSS vulnerability scanner",
|
|
233
|
+
},
|
|
234
|
+
"katana": {
|
|
235
|
+
"command": "katana",
|
|
236
|
+
"install_kali": "go install github.com/projectdiscovery/katana/cmd/katana@latest",
|
|
237
|
+
"install_ubuntu": "go install github.com/projectdiscovery/katana/cmd/katana@latest",
|
|
238
|
+
"install_method": "go",
|
|
239
|
+
"description": "Web crawling and spidering for parameter discovery",
|
|
240
|
+
"dependencies": ["chromium"],
|
|
230
241
|
},
|
|
231
242
|
},
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
},
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
243
|
+
"exploitation": {
|
|
244
|
+
"sqlmap": {
|
|
245
|
+
"command": "sqlmap",
|
|
246
|
+
"install_kali": "sudo apt install sqlmap",
|
|
247
|
+
"install_ubuntu": "sudo apt install sqlmap",
|
|
248
|
+
"install_method": "apt",
|
|
249
|
+
"description": "Automatic SQL injection exploitation tool",
|
|
250
|
+
},
|
|
251
|
+
"metasploit": {
|
|
252
|
+
"command": "msfconsole",
|
|
253
|
+
"alt_commands": ["/opt/metasploit-framework/bin/msfconsole"],
|
|
254
|
+
"install_kali": "sudo apt install metasploit-framework",
|
|
255
|
+
"install_ubuntu": "sudo apt install -y postgresql postgresql-contrib && sudo systemctl enable postgresql && sudo systemctl start postgresql && curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > /tmp/msfinstall && chmod +x /tmp/msfinstall && sudo /tmp/msfinstall && rm /tmp/msfinstall",
|
|
256
|
+
"install_method": "kali_only",
|
|
257
|
+
"description": "Penetration testing framework",
|
|
258
|
+
"dependencies": ["postgresql"],
|
|
259
|
+
},
|
|
260
|
+
"searchsploit": {
|
|
261
|
+
"command": "searchsploit",
|
|
262
|
+
"install_kali": "sudo apt install exploitdb",
|
|
263
|
+
"install_ubuntu": "sudo git clone https://gitlab.com/exploit-database/exploitdb.git /opt/exploitdb && sudo ln -sf /opt/exploitdb/searchsploit /usr/local/bin/searchsploit",
|
|
264
|
+
"install_method": "kali_only",
|
|
265
|
+
"description": "Exploit database search tool",
|
|
255
266
|
},
|
|
256
267
|
},
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
},
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
268
|
+
"credential_attacks": {
|
|
269
|
+
"hydra": {
|
|
270
|
+
"command": "hydra",
|
|
271
|
+
"install_kali": "sudo apt install hydra",
|
|
272
|
+
"install_ubuntu": "sudo apt install hydra",
|
|
273
|
+
"install_method": "apt",
|
|
274
|
+
"description": "Network login brute-forcing tool",
|
|
275
|
+
},
|
|
276
|
+
"john": {
|
|
277
|
+
"command": "john",
|
|
278
|
+
"install_kali": "sudo apt install john",
|
|
279
|
+
"install_ubuntu": "sudo apt install john",
|
|
280
|
+
"install_method": "apt",
|
|
281
|
+
"description": "John the Ripper password cracker",
|
|
282
|
+
},
|
|
283
|
+
"hashcat": {
|
|
284
|
+
"command": "hashcat",
|
|
285
|
+
"install_kali": "sudo apt install hashcat",
|
|
286
|
+
"install_ubuntu": "sudo apt install hashcat",
|
|
287
|
+
"install_method": "apt",
|
|
288
|
+
"description": "Advanced password recovery tool",
|
|
278
289
|
},
|
|
279
290
|
},
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
},
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
},
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
},
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
291
|
+
"windows_ad": {
|
|
292
|
+
"enum4linux": {
|
|
293
|
+
"command": "enum4linux",
|
|
294
|
+
"alt_commands": ["enum4linux-ng"],
|
|
295
|
+
"install_kali": "sudo apt install enum4linux",
|
|
296
|
+
"install_ubuntu": "sudo apt install -y smbclient && pipx install git+https://github.com/cddmp/enum4linux-ng",
|
|
297
|
+
"install_method": "kali_only",
|
|
298
|
+
"description": "Windows/Samba enumeration tool",
|
|
299
|
+
"system_deps_ubuntu": ["smbclient"],
|
|
300
|
+
},
|
|
301
|
+
"smbmap": {
|
|
302
|
+
"command": "smbmap",
|
|
303
|
+
"install_kali": "sudo apt install smbmap",
|
|
304
|
+
"install_ubuntu": "pipx install --force smbmap && pipx inject smbmap impacket",
|
|
305
|
+
"install_method": "kali_only",
|
|
306
|
+
"description": "SMB share enumeration tool",
|
|
307
|
+
"known_issues": "All versions have pickling bug with impacket. Use netexec instead.",
|
|
308
|
+
"optional": True,
|
|
309
|
+
},
|
|
310
|
+
"netexec": {
|
|
311
|
+
"command": "nxc",
|
|
312
|
+
"install_kali": "sudo apt install netexec",
|
|
313
|
+
"install_ubuntu": "pipx install git+https://github.com/Pennyw0rth/NetExec",
|
|
314
|
+
"install_method": "kali_only",
|
|
315
|
+
"description": "Swiss army knife for pentesting Windows/AD (formerly CrackMapExec)",
|
|
316
|
+
},
|
|
317
|
+
"impacket-scripts": {
|
|
318
|
+
"command": "GetNPUsers.py",
|
|
319
|
+
"alt_commands": ["impacket-GetNPUsers", "GetNPUsers"],
|
|
320
|
+
"install_kali": "sudo apt install python3-impacket",
|
|
321
|
+
"install_ubuntu": "pipx install impacket",
|
|
322
|
+
"install_method": "kali_only",
|
|
323
|
+
"description": "Collection of Python classes for network protocols",
|
|
324
|
+
},
|
|
325
|
+
"bloodhound": {
|
|
326
|
+
"command": "bloodhound-python",
|
|
327
|
+
"install_kali": "sudo apt install bloodhound.py",
|
|
328
|
+
"install_ubuntu": "pipx install bloodhound",
|
|
329
|
+
"install_method": "kali_only",
|
|
330
|
+
"description": "Active Directory relationship mapper",
|
|
331
|
+
},
|
|
332
|
+
"responder": {
|
|
333
|
+
"command": "responder",
|
|
334
|
+
"install_kali": "sudo apt install responder && sudo pip install --break-system-packages --ignore-installed aioquic",
|
|
335
|
+
"install_ubuntu": "sudo git clone https://github.com/lgandx/Responder.git /opt/Responder && sudo pip install --break-system-packages --ignore-installed -r /opt/Responder/requirements.txt aioquic && sudo ln -sf /opt/Responder/Responder.py /usr/local/bin/responder",
|
|
336
|
+
"install_method": "kali_only",
|
|
337
|
+
"description": "LLMNR, NBT-NS and MDNS poisoner",
|
|
338
|
+
"needs_sudo": True, # Required for network poisoning
|
|
339
|
+
},
|
|
340
|
+
"evil-winrm": {
|
|
341
|
+
"command": "evil-winrm",
|
|
342
|
+
"install_kali": "sudo gem install evil-winrm",
|
|
343
|
+
"install_ubuntu": "sudo gem install evil-winrm",
|
|
344
|
+
"install_method": "gem",
|
|
345
|
+
"description": "WinRM shell for pentesting (remote PowerShell access)",
|
|
346
|
+
},
|
|
347
|
+
"certipy": {
|
|
348
|
+
"command": "certipy",
|
|
349
|
+
"alt_commands": ["certipy-ad"],
|
|
350
|
+
"install_kali": "pipx install certipy-ad",
|
|
351
|
+
"install_ubuntu": "pipx install certipy-ad",
|
|
352
|
+
"install_method": "pipx",
|
|
353
|
+
"description": "Active Directory Certificate Services (ADCS) enumeration and exploitation",
|
|
354
|
+
},
|
|
355
|
+
"kerbrute": {
|
|
356
|
+
"command": "kerbrute",
|
|
357
|
+
"install_kali": "go install github.com/ropnop/kerbrute@latest",
|
|
358
|
+
"install_ubuntu": "go install github.com/ropnop/kerbrute@latest",
|
|
359
|
+
"install_method": "go",
|
|
360
|
+
"description": "Kerberos user enumeration and password spraying",
|
|
361
|
+
},
|
|
362
|
+
"rdp-sec-check": {
|
|
363
|
+
"command": "rdp-sec-check",
|
|
364
|
+
"install_kali": "sudo cpan Encoding::BER && sudo git clone https://github.com/CiscoCXSecurity/rdp-sec-check.git /opt/rdp-sec-check && sudo chmod +x /opt/rdp-sec-check/rdp-sec-check.pl && sudo ln -sf /opt/rdp-sec-check/rdp-sec-check.pl /usr/local/bin/rdp-sec-check",
|
|
365
|
+
"install_ubuntu": "sudo cpan Encoding::BER && sudo git clone https://github.com/CiscoCXSecurity/rdp-sec-check.git /opt/rdp-sec-check && sudo chmod +x /opt/rdp-sec-check/rdp-sec-check.pl && sudo ln -sf /opt/rdp-sec-check/rdp-sec-check.pl /usr/local/bin/rdp-sec-check",
|
|
366
|
+
"install_method": "manual",
|
|
367
|
+
"description": "RDP security configuration checker (NLA, encryption)",
|
|
328
368
|
},
|
|
329
369
|
},
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
},
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
},
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
},
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
370
|
+
"router_iot": {
|
|
371
|
+
"routersploit": {
|
|
372
|
+
"command": "rsf.py",
|
|
373
|
+
"install_kali": "pipx install routersploit",
|
|
374
|
+
"install_ubuntu": "pipx install routersploit",
|
|
375
|
+
"install_method": "pipx",
|
|
376
|
+
"description": "Router exploitation framework (like Metasploit for routers)",
|
|
377
|
+
},
|
|
378
|
+
"miniupnpc": {
|
|
379
|
+
"command": "upnpc",
|
|
380
|
+
"install_kali": "sudo apt install miniupnpc",
|
|
381
|
+
"install_ubuntu": "sudo apt install miniupnpc",
|
|
382
|
+
"install_method": "apt",
|
|
383
|
+
"description": "UPnP client for port forwarding manipulation",
|
|
384
|
+
},
|
|
385
|
+
"binwalk": {
|
|
386
|
+
"command": "binwalk",
|
|
387
|
+
"install_kali": "sudo apt install binwalk",
|
|
388
|
+
"install_ubuntu": "sudo apt install binwalk",
|
|
389
|
+
"install_method": "apt",
|
|
390
|
+
"description": "Firmware analysis and extraction tool",
|
|
391
|
+
},
|
|
392
|
+
"dnsutils": {
|
|
393
|
+
"command": "dig",
|
|
394
|
+
"install_kali": "sudo apt install dnsutils",
|
|
395
|
+
"install_ubuntu": "sudo apt install dnsutils",
|
|
396
|
+
"install_method": "apt",
|
|
397
|
+
"description": "DNS lookup utilities (dig, nslookup)",
|
|
358
398
|
},
|
|
359
399
|
},
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
},
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
400
|
+
"remote_access": {
|
|
401
|
+
"tigervnc": {
|
|
402
|
+
"command": "vncviewer",
|
|
403
|
+
"install_kali": "sudo apt install tigervnc-viewer",
|
|
404
|
+
"install_ubuntu": "sudo apt install tigervnc-viewer",
|
|
405
|
+
"install_method": "apt",
|
|
406
|
+
"description": "VNC client for remote desktop access",
|
|
407
|
+
},
|
|
408
|
+
"vncsnapshot": {
|
|
409
|
+
"command": "vncsnapshot",
|
|
410
|
+
"install_kali": "sudo apt install vncsnapshot",
|
|
411
|
+
"install_ubuntu": "sudo apt install vncsnapshot",
|
|
412
|
+
"install_method": "apt",
|
|
413
|
+
"description": "VNC screenshot capture tool",
|
|
374
414
|
},
|
|
375
415
|
},
|
|
376
416
|
}
|
|
@@ -381,20 +421,20 @@ def get_install_command(tool_info: dict, distro: Optional[str] = None) -> str:
|
|
|
381
421
|
if distro is None:
|
|
382
422
|
distro = detect_distro()
|
|
383
423
|
|
|
384
|
-
if distro in (
|
|
385
|
-
return tool_info.get(
|
|
424
|
+
if distro in ("kali", "parrot"):
|
|
425
|
+
return tool_info.get("install_kali", tool_info.get("install", ""))
|
|
386
426
|
else:
|
|
387
|
-
return tool_info.get(
|
|
427
|
+
return tool_info.get("install_ubuntu", tool_info.get("install_kali", ""))
|
|
388
428
|
|
|
389
429
|
|
|
390
430
|
def get_upgrade_command(tool_info: dict, distro: Optional[str] = None) -> Optional[str]:
|
|
391
431
|
"""Get upgrade command if available, else None."""
|
|
392
432
|
if distro is None:
|
|
393
433
|
distro = detect_distro()
|
|
394
|
-
if distro in (
|
|
395
|
-
return tool_info.get(
|
|
434
|
+
if distro in ("kali", "parrot"):
|
|
435
|
+
return tool_info.get("upgrade_kali")
|
|
396
436
|
else:
|
|
397
|
-
return tool_info.get(
|
|
437
|
+
return tool_info.get("upgrade_ubuntu")
|
|
398
438
|
|
|
399
439
|
|
|
400
440
|
def check_tool(command: str, alt_commands: list = None) -> bool:
|
|
@@ -405,7 +445,7 @@ def check_tool(command: str, alt_commands: list = None) -> bool:
|
|
|
405
445
|
if alt_commands:
|
|
406
446
|
for alt in alt_commands:
|
|
407
447
|
# Check if it's an absolute path that exists and is executable
|
|
408
|
-
if alt.startswith(
|
|
448
|
+
if alt.startswith("/") and os.path.isfile(alt) and os.access(alt, os.X_OK):
|
|
409
449
|
return True
|
|
410
450
|
# Otherwise check in PATH
|
|
411
451
|
if shutil.which(alt) is not None:
|
|
@@ -426,7 +466,7 @@ def find_tool_command(command: str, alt_commands: list = None) -> Optional[str]:
|
|
|
426
466
|
if alt_commands:
|
|
427
467
|
for alt in alt_commands:
|
|
428
468
|
# Check if it's an absolute path that exists and is executable
|
|
429
|
-
if alt.startswith(
|
|
469
|
+
if alt.startswith("/") and os.path.isfile(alt) and os.access(alt, os.X_OK):
|
|
430
470
|
return alt
|
|
431
471
|
# Otherwise check in PATH
|
|
432
472
|
if shutil.which(alt) is not None:
|
|
@@ -453,8 +493,10 @@ def check_all_tools() -> Dict[str, Dict[str, bool]]:
|
|
|
453
493
|
for category, tools in EXTERNAL_TOOLS.items():
|
|
454
494
|
results[category] = {}
|
|
455
495
|
for tool_name, tool_info in tools.items():
|
|
456
|
-
alt_commands = tool_info.get(
|
|
457
|
-
results[category][tool_name] = check_tool(
|
|
496
|
+
alt_commands = tool_info.get("alt_commands")
|
|
497
|
+
results[category][tool_name] = check_tool(
|
|
498
|
+
tool_info["command"], alt_commands
|
|
499
|
+
)
|
|
458
500
|
|
|
459
501
|
return results
|
|
460
502
|
|
|
@@ -462,12 +504,17 @@ def check_all_tools() -> Dict[str, Dict[str, bool]]:
|
|
|
462
504
|
def get_tool_stats() -> Tuple[int, int]:
|
|
463
505
|
"""
|
|
464
506
|
Get summary statistics of installed tools.
|
|
465
|
-
|
|
507
|
+
|
|
466
508
|
Returns:
|
|
467
509
|
(installed_count, total_count)
|
|
468
510
|
"""
|
|
469
511
|
status = check_all_tools()
|
|
470
|
-
installed = sum(
|
|
512
|
+
installed = sum(
|
|
513
|
+
1
|
|
514
|
+
for category in status.values()
|
|
515
|
+
for is_installed in category.values()
|
|
516
|
+
if is_installed
|
|
517
|
+
)
|
|
471
518
|
total = sum(len(tools) for tools in EXTERNAL_TOOLS.values())
|
|
472
519
|
return installed, total
|
|
473
520
|
|
|
@@ -500,14 +547,16 @@ def get_missing_tools(distro: Optional[str] = None) -> List[Dict]:
|
|
|
500
547
|
for category, tools in EXTERNAL_TOOLS.items():
|
|
501
548
|
for tool_name, tool_info in tools.items():
|
|
502
549
|
if not status[category][tool_name]:
|
|
503
|
-
missing.append(
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
550
|
+
missing.append(
|
|
551
|
+
{
|
|
552
|
+
"name": tool_name,
|
|
553
|
+
"category": category,
|
|
554
|
+
"command": tool_info["command"],
|
|
555
|
+
"install": get_install_command(tool_info, distro),
|
|
556
|
+
"install_method": tool_info.get("install_method", "apt"),
|
|
557
|
+
"description": tool_info["description"],
|
|
558
|
+
}
|
|
559
|
+
)
|
|
511
560
|
|
|
512
561
|
return missing
|
|
513
562
|
|
|
@@ -530,18 +579,18 @@ def check_tool_version(tool_info: dict) -> Dict[str, any]:
|
|
|
530
579
|
'actual_command': str or None # The command that was found
|
|
531
580
|
}
|
|
532
581
|
"""
|
|
533
|
-
command = tool_info[
|
|
534
|
-
alt_commands = tool_info.get(
|
|
535
|
-
min_version = tool_info.get(
|
|
582
|
+
command = tool_info["command"]
|
|
583
|
+
alt_commands = tool_info.get("alt_commands")
|
|
584
|
+
min_version = tool_info.get("min_version")
|
|
536
585
|
|
|
537
586
|
result = {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
587
|
+
"installed": False,
|
|
588
|
+
"version": None,
|
|
589
|
+
"min_version": min_version,
|
|
590
|
+
"version_ok": True,
|
|
591
|
+
"needs_upgrade": False,
|
|
592
|
+
"version_note": tool_info.get("version_note"),
|
|
593
|
+
"actual_command": None,
|
|
545
594
|
}
|
|
546
595
|
|
|
547
596
|
# Find which command is actually installed (primary or alt)
|
|
@@ -549,31 +598,33 @@ def check_tool_version(tool_info: dict) -> Dict[str, any]:
|
|
|
549
598
|
if not actual_cmd:
|
|
550
599
|
return result
|
|
551
600
|
|
|
552
|
-
result[
|
|
553
|
-
result[
|
|
601
|
+
result["installed"] = True
|
|
602
|
+
result["actual_command"] = actual_cmd
|
|
554
603
|
|
|
555
604
|
# Always try to get version for display purposes
|
|
556
|
-
version_cmd = tool_info.get(
|
|
557
|
-
version_regex = tool_info.get(
|
|
558
|
-
version_fallback = tool_info.get(
|
|
605
|
+
version_cmd = tool_info.get("version_cmd")
|
|
606
|
+
version_regex = tool_info.get("version_regex")
|
|
607
|
+
version_fallback = tool_info.get("version_fallback")
|
|
559
608
|
|
|
560
609
|
# Use actual_cmd for version detection, but version_cmd template uses {command}
|
|
561
610
|
if version_cmd:
|
|
562
611
|
# Replace {command} with the actual found command
|
|
563
|
-
actual_version_cmd = version_cmd.replace(
|
|
612
|
+
actual_version_cmd = version_cmd.replace("{command}", actual_cmd)
|
|
564
613
|
else:
|
|
565
614
|
actual_version_cmd = None
|
|
566
615
|
|
|
567
|
-
installed_version = get_tool_version(
|
|
568
|
-
|
|
616
|
+
installed_version = get_tool_version(
|
|
617
|
+
actual_cmd, actual_version_cmd, version_regex, version_fallback
|
|
618
|
+
)
|
|
619
|
+
result["version"] = installed_version
|
|
569
620
|
|
|
570
621
|
# Check against min_version if there is one
|
|
571
622
|
if min_version and installed_version:
|
|
572
|
-
result[
|
|
573
|
-
result[
|
|
623
|
+
result["version_ok"] = version_meets_requirement(installed_version, min_version)
|
|
624
|
+
result["needs_upgrade"] = not result["version_ok"]
|
|
574
625
|
elif min_version and not installed_version:
|
|
575
626
|
# Couldn't determine version - assume it's OK but flag uncertainty
|
|
576
|
-
result[
|
|
627
|
+
result["version_ok"] = True
|
|
577
628
|
|
|
578
629
|
return result
|
|
579
630
|
|
|
@@ -595,22 +646,24 @@ def get_tools_with_wrong_version(distro: Optional[str] = None) -> List[Dict]:
|
|
|
595
646
|
|
|
596
647
|
for category, tools in EXTERNAL_TOOLS.items():
|
|
597
648
|
for tool_name, tool_info in tools.items():
|
|
598
|
-
if not tool_info.get(
|
|
649
|
+
if not tool_info.get("min_version"):
|
|
599
650
|
continue # No version requirement
|
|
600
651
|
|
|
601
652
|
version_status = check_tool_version(tool_info)
|
|
602
653
|
|
|
603
|
-
if version_status[
|
|
604
|
-
wrong_version.append(
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
654
|
+
if version_status["installed"] and version_status["needs_upgrade"]:
|
|
655
|
+
wrong_version.append(
|
|
656
|
+
{
|
|
657
|
+
"name": tool_name,
|
|
658
|
+
"category": category,
|
|
659
|
+
"command": tool_info["command"],
|
|
660
|
+
"installed_version": version_status["version"],
|
|
661
|
+
"min_version": version_status["min_version"],
|
|
662
|
+
"install": get_install_command(tool_info, distro),
|
|
663
|
+
"description": tool_info["description"],
|
|
664
|
+
"version_note": version_status["version_note"],
|
|
665
|
+
}
|
|
666
|
+
)
|
|
614
667
|
|
|
615
668
|
return wrong_version
|
|
616
669
|
|
|
@@ -678,19 +731,21 @@ def get_tools_by_category(distro: Optional[str] = None) -> Dict[str, List[Dict]]
|
|
|
678
731
|
organized[category] = []
|
|
679
732
|
for tool_name, tool_info in tools.items():
|
|
680
733
|
tool_status = status[category][tool_name]
|
|
681
|
-
organized[category].append(
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
734
|
+
organized[category].append(
|
|
735
|
+
{
|
|
736
|
+
"name": tool_name,
|
|
737
|
+
"installed": tool_status["installed"],
|
|
738
|
+
"version": tool_status.get("version"),
|
|
739
|
+
"version_ok": tool_status.get("version_ok", True),
|
|
740
|
+
"needs_upgrade": tool_status.get("needs_upgrade", False),
|
|
741
|
+
"min_version": tool_status.get("min_version"),
|
|
742
|
+
"command": tool_info["command"],
|
|
743
|
+
"install": get_install_command(tool_info, distro),
|
|
744
|
+
"install_method": tool_info.get("install_method", "apt"),
|
|
745
|
+
"description": tool_info["description"],
|
|
746
|
+
"version_note": tool_info.get("version_note"),
|
|
747
|
+
}
|
|
748
|
+
)
|
|
694
749
|
|
|
695
750
|
return organized
|
|
696
751
|
|
|
@@ -698,16 +753,16 @@ def get_tools_by_category(distro: Optional[str] = None) -> Dict[str, List[Dict]]
|
|
|
698
753
|
def get_category_name(category: str) -> str:
|
|
699
754
|
"""Get human-readable category name."""
|
|
700
755
|
names = {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
756
|
+
"prerequisites": "⚙️ Prerequisites",
|
|
757
|
+
"reconnaissance": "🔍 Reconnaissance",
|
|
758
|
+
"web_scanning": "🌐 Web Scanning",
|
|
759
|
+
"exploitation": "💥 Exploitation",
|
|
760
|
+
"credential_attacks": "🔑 Credential Attacks",
|
|
761
|
+
"windows_ad": "🪟 Windows/Active Directory",
|
|
762
|
+
"router_iot": "📡 Router/IoT Testing",
|
|
763
|
+
"remote_access": "🖥️ Remote Access",
|
|
709
764
|
}
|
|
710
|
-
return names.get(category, category.replace(
|
|
765
|
+
return names.get(category, category.replace("_", " ").title())
|
|
711
766
|
|
|
712
767
|
|
|
713
768
|
def check_msfdb_status() -> Dict[str, any]:
|
|
@@ -724,39 +779,39 @@ def check_msfdb_status() -> Dict[str, any]:
|
|
|
724
779
|
from pathlib import Path
|
|
725
780
|
|
|
726
781
|
result = {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
782
|
+
"initialized": False,
|
|
783
|
+
"running": False,
|
|
784
|
+
"connected": False,
|
|
785
|
+
"message": "Unknown status",
|
|
731
786
|
}
|
|
732
787
|
|
|
733
788
|
# Check if msfdb command exists
|
|
734
|
-
if not shutil.which(
|
|
735
|
-
result[
|
|
789
|
+
if not shutil.which("msfdb"):
|
|
790
|
+
result["message"] = "msfdb command not found - Metasploit may not be installed"
|
|
736
791
|
return result
|
|
737
792
|
|
|
738
793
|
# Helper to check if PostgreSQL is running
|
|
739
794
|
def check_postgresql_running() -> bool:
|
|
740
795
|
try:
|
|
741
796
|
proc = subprocess.run(
|
|
742
|
-
[
|
|
797
|
+
["systemctl", "is-active", "postgresql"],
|
|
743
798
|
capture_output=True,
|
|
744
799
|
text=True,
|
|
745
|
-
timeout=5
|
|
800
|
+
timeout=5,
|
|
746
801
|
)
|
|
747
|
-
return proc.returncode == 0 and
|
|
802
|
+
return proc.returncode == 0 and "active" in proc.stdout.lower()
|
|
748
803
|
except Exception:
|
|
749
804
|
return False
|
|
750
805
|
|
|
751
806
|
# Helper to check system-wide MSF database config (Kali fallback)
|
|
752
807
|
def check_system_config() -> bool:
|
|
753
808
|
"""Check if system-wide database.yml exists with valid PostgreSQL config."""
|
|
754
|
-
config_path = Path(
|
|
809
|
+
config_path = Path("/usr/share/metasploit-framework/config/database.yml")
|
|
755
810
|
if config_path.exists():
|
|
756
811
|
try:
|
|
757
812
|
content = config_path.read_text()
|
|
758
813
|
# Check for PostgreSQL adapter configuration
|
|
759
|
-
return
|
|
814
|
+
return "adapter: postgresql" in content and "database: msf" in content
|
|
760
815
|
except Exception:
|
|
761
816
|
return False
|
|
762
817
|
return False
|
|
@@ -764,61 +819,66 @@ def check_msfdb_status() -> Dict[str, any]:
|
|
|
764
819
|
try:
|
|
765
820
|
# Run msfdb status
|
|
766
821
|
proc = subprocess.run(
|
|
767
|
-
[
|
|
768
|
-
capture_output=True,
|
|
769
|
-
text=True,
|
|
770
|
-
timeout=10
|
|
822
|
+
["msfdb", "status"], capture_output=True, text=True, timeout=10
|
|
771
823
|
)
|
|
772
824
|
output = proc.stdout + proc.stderr
|
|
773
825
|
output_lower = output.lower()
|
|
774
826
|
|
|
775
827
|
# Check if msfdb requires root (common on Kali)
|
|
776
|
-
if
|
|
828
|
+
if "run as root" in output_lower or (
|
|
829
|
+
proc.returncode != 0 and "error" in output_lower
|
|
830
|
+
):
|
|
777
831
|
# Fall back to checking system config file and PostgreSQL status
|
|
778
|
-
result[
|
|
832
|
+
result["running"] = check_postgresql_running()
|
|
779
833
|
if check_system_config():
|
|
780
|
-
result[
|
|
781
|
-
if result[
|
|
782
|
-
result[
|
|
783
|
-
result[
|
|
834
|
+
result["initialized"] = True
|
|
835
|
+
if result["running"]:
|
|
836
|
+
result["connected"] = True
|
|
837
|
+
result["message"] = "Database initialized and running"
|
|
784
838
|
else:
|
|
785
|
-
result[
|
|
839
|
+
result["message"] = (
|
|
840
|
+
"Database initialized but PostgreSQL not running - run: sudo systemctl start postgresql"
|
|
841
|
+
)
|
|
786
842
|
else:
|
|
787
|
-
result[
|
|
843
|
+
result["message"] = "Need sudo to verify - run: sudo msfdb status"
|
|
788
844
|
return result
|
|
789
845
|
|
|
790
846
|
# Check if database is initialized
|
|
791
|
-
if
|
|
792
|
-
result[
|
|
847
|
+
if "no database" in output_lower or "not initialized" in output_lower:
|
|
848
|
+
result["message"] = "Database not initialized - run: msfdb init"
|
|
793
849
|
return result
|
|
794
850
|
|
|
795
851
|
# Check PostgreSQL status
|
|
796
|
-
if
|
|
797
|
-
if
|
|
798
|
-
result[
|
|
852
|
+
if "postgresql" in output_lower:
|
|
853
|
+
if "running" in output_lower or "active" in output_lower:
|
|
854
|
+
result["running"] = True
|
|
799
855
|
|
|
800
856
|
# Check for successful connection indicators
|
|
801
|
-
if
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
857
|
+
if "msf" in output_lower and (
|
|
858
|
+
"database" in output_lower or "connected" in output_lower
|
|
859
|
+
):
|
|
860
|
+
if "no connection" not in output_lower:
|
|
861
|
+
result["initialized"] = True
|
|
862
|
+
result["connected"] = True
|
|
805
863
|
|
|
806
864
|
# If we see the database name, it's initialized
|
|
807
|
-
if
|
|
808
|
-
result[
|
|
865
|
+
if "msf" in output_lower and result["running"]:
|
|
866
|
+
result["initialized"] = True
|
|
809
867
|
|
|
810
868
|
# Build status message
|
|
811
|
-
if result[
|
|
812
|
-
result[
|
|
813
|
-
result[
|
|
814
|
-
elif result[
|
|
815
|
-
result[
|
|
816
|
-
|
|
817
|
-
|
|
869
|
+
if result["initialized"] and result["running"]:
|
|
870
|
+
result["connected"] = True
|
|
871
|
+
result["message"] = "Database initialized and running"
|
|
872
|
+
elif result["initialized"] and not result["running"]:
|
|
873
|
+
result["message"] = (
|
|
874
|
+
"Database initialized but PostgreSQL not running - run: sudo systemctl start postgresql"
|
|
875
|
+
)
|
|
876
|
+
elif not result["initialized"]:
|
|
877
|
+
result["message"] = "Database not initialized - run: msfdb init"
|
|
818
878
|
|
|
819
879
|
except subprocess.TimeoutExpired:
|
|
820
|
-
result[
|
|
880
|
+
result["message"] = "msfdb status timed out"
|
|
821
881
|
except Exception as e:
|
|
822
|
-
result[
|
|
882
|
+
result["message"] = f"Error checking msfdb status: {e}"
|
|
823
883
|
|
|
824
884
|
return result
|