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.
Files changed (358) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9564 -2881
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1239 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2200 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +564 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +409 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +417 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +292 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/web_login_test_handler.py +327 -0
  126. souleyez/handlers/whois_handler.py +277 -0
  127. souleyez/handlers/wpscan_handler.py +554 -0
  128. souleyez/history.py +32 -16
  129. souleyez/importers/msf_importer.py +106 -75
  130. souleyez/importers/smart_importer.py +208 -147
  131. souleyez/integrations/siem/__init__.py +10 -10
  132. souleyez/integrations/siem/base.py +17 -18
  133. souleyez/integrations/siem/elastic.py +108 -122
  134. souleyez/integrations/siem/factory.py +207 -80
  135. souleyez/integrations/siem/googlesecops.py +146 -154
  136. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  137. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  138. souleyez/integrations/siem/sentinel.py +107 -109
  139. souleyez/integrations/siem/splunk.py +246 -212
  140. souleyez/integrations/siem/wazuh.py +65 -71
  141. souleyez/integrations/wazuh/__init__.py +5 -5
  142. souleyez/integrations/wazuh/client.py +70 -93
  143. souleyez/integrations/wazuh/config.py +85 -57
  144. souleyez/integrations/wazuh/host_mapper.py +28 -36
  145. souleyez/integrations/wazuh/sync.py +78 -68
  146. souleyez/intelligence/__init__.py +4 -5
  147. souleyez/intelligence/correlation_analyzer.py +309 -295
  148. souleyez/intelligence/exploit_knowledge.py +661 -623
  149. souleyez/intelligence/exploit_suggestions.py +159 -139
  150. souleyez/intelligence/gap_analyzer.py +132 -97
  151. souleyez/intelligence/gap_detector.py +251 -214
  152. souleyez/intelligence/sensitive_tables.py +266 -129
  153. souleyez/intelligence/service_parser.py +137 -123
  154. souleyez/intelligence/surface_analyzer.py +407 -268
  155. souleyez/intelligence/target_parser.py +159 -162
  156. souleyez/licensing/__init__.py +6 -6
  157. souleyez/licensing/validator.py +17 -19
  158. souleyez/log_config.py +79 -54
  159. souleyez/main.py +1505 -687
  160. souleyez/migrations/fix_job_counter.py +16 -14
  161. souleyez/parsers/bloodhound_parser.py +41 -39
  162. souleyez/parsers/crackmapexec_parser.py +178 -111
  163. souleyez/parsers/dalfox_parser.py +72 -77
  164. souleyez/parsers/dnsrecon_parser.py +103 -91
  165. souleyez/parsers/enum4linux_parser.py +183 -153
  166. souleyez/parsers/ffuf_parser.py +29 -25
  167. souleyez/parsers/gobuster_parser.py +301 -41
  168. souleyez/parsers/hashcat_parser.py +324 -79
  169. souleyez/parsers/http_fingerprint_parser.py +350 -103
  170. souleyez/parsers/hydra_parser.py +131 -111
  171. souleyez/parsers/impacket_parser.py +231 -178
  172. souleyez/parsers/john_parser.py +98 -86
  173. souleyez/parsers/katana_parser.py +316 -0
  174. souleyez/parsers/msf_parser.py +943 -498
  175. souleyez/parsers/nikto_parser.py +346 -65
  176. souleyez/parsers/nmap_parser.py +262 -174
  177. souleyez/parsers/nuclei_parser.py +40 -44
  178. souleyez/parsers/responder_parser.py +26 -26
  179. souleyez/parsers/searchsploit_parser.py +74 -74
  180. souleyez/parsers/service_explorer_parser.py +279 -0
  181. souleyez/parsers/smbmap_parser.py +180 -124
  182. souleyez/parsers/sqlmap_parser.py +434 -308
  183. souleyez/parsers/theharvester_parser.py +75 -57
  184. souleyez/parsers/whois_parser.py +135 -94
  185. souleyez/parsers/wpscan_parser.py +278 -190
  186. souleyez/plugins/afp.py +44 -36
  187. souleyez/plugins/afp_brute.py +114 -46
  188. souleyez/plugins/ard.py +48 -37
  189. souleyez/plugins/bloodhound.py +95 -61
  190. souleyez/plugins/certipy.py +303 -0
  191. souleyez/plugins/crackmapexec.py +186 -85
  192. souleyez/plugins/dalfox.py +120 -59
  193. souleyez/plugins/dns_hijack.py +146 -41
  194. souleyez/plugins/dnsrecon.py +97 -61
  195. souleyez/plugins/enum4linux.py +91 -66
  196. souleyez/plugins/evil_winrm.py +291 -0
  197. souleyez/plugins/ffuf.py +166 -90
  198. souleyez/plugins/firmware_extract.py +133 -29
  199. souleyez/plugins/gobuster.py +387 -190
  200. souleyez/plugins/gpp_extract.py +393 -0
  201. souleyez/plugins/hashcat.py +100 -73
  202. souleyez/plugins/http_fingerprint.py +913 -267
  203. souleyez/plugins/hydra.py +566 -200
  204. souleyez/plugins/impacket_getnpusers.py +117 -69
  205. souleyez/plugins/impacket_psexec.py +84 -64
  206. souleyez/plugins/impacket_secretsdump.py +103 -69
  207. souleyez/plugins/impacket_smbclient.py +89 -75
  208. souleyez/plugins/john.py +86 -69
  209. souleyez/plugins/katana.py +313 -0
  210. souleyez/plugins/kerbrute.py +237 -0
  211. souleyez/plugins/lfi_extract.py +541 -0
  212. souleyez/plugins/macos_ssh.py +117 -48
  213. souleyez/plugins/mdns.py +35 -30
  214. souleyez/plugins/msf_auxiliary.py +253 -130
  215. souleyez/plugins/msf_exploit.py +239 -161
  216. souleyez/plugins/nikto.py +134 -78
  217. souleyez/plugins/nmap.py +275 -91
  218. souleyez/plugins/nuclei.py +180 -89
  219. souleyez/plugins/nxc.py +285 -0
  220. souleyez/plugins/plugin_base.py +35 -36
  221. souleyez/plugins/plugin_template.py +13 -5
  222. souleyez/plugins/rdp_sec_check.py +130 -0
  223. souleyez/plugins/responder.py +112 -71
  224. souleyez/plugins/router_http_brute.py +76 -65
  225. souleyez/plugins/router_ssh_brute.py +118 -41
  226. souleyez/plugins/router_telnet_brute.py +124 -42
  227. souleyez/plugins/routersploit.py +91 -59
  228. souleyez/plugins/routersploit_exploit.py +77 -55
  229. souleyez/plugins/searchsploit.py +91 -77
  230. souleyez/plugins/service_explorer.py +1160 -0
  231. souleyez/plugins/smbmap.py +122 -72
  232. souleyez/plugins/smbpasswd.py +215 -0
  233. souleyez/plugins/sqlmap.py +301 -113
  234. souleyez/plugins/theharvester.py +127 -75
  235. souleyez/plugins/tr069.py +79 -57
  236. souleyez/plugins/upnp.py +65 -47
  237. souleyez/plugins/upnp_abuse.py +73 -55
  238. souleyez/plugins/vnc_access.py +129 -42
  239. souleyez/plugins/vnc_brute.py +109 -38
  240. souleyez/plugins/web_login_test.py +417 -0
  241. souleyez/plugins/whois.py +77 -58
  242. souleyez/plugins/wpscan.py +219 -69
  243. souleyez/reporting/__init__.py +2 -1
  244. souleyez/reporting/attack_chain.py +411 -346
  245. souleyez/reporting/charts.py +436 -501
  246. souleyez/reporting/compliance_mappings.py +334 -201
  247. souleyez/reporting/detection_report.py +126 -125
  248. souleyez/reporting/formatters.py +828 -591
  249. souleyez/reporting/generator.py +386 -302
  250. souleyez/reporting/metrics.py +72 -75
  251. souleyez/scanner.py +35 -29
  252. souleyez/security/__init__.py +37 -11
  253. souleyez/security/scope_validator.py +175 -106
  254. souleyez/security/validation.py +237 -149
  255. souleyez/security.py +22 -6
  256. souleyez/storage/credentials.py +247 -186
  257. souleyez/storage/crypto.py +296 -129
  258. souleyez/storage/database.py +73 -50
  259. souleyez/storage/db.py +58 -36
  260. souleyez/storage/deliverable_evidence.py +177 -128
  261. souleyez/storage/deliverable_exporter.py +282 -246
  262. souleyez/storage/deliverable_templates.py +134 -116
  263. souleyez/storage/deliverables.py +135 -130
  264. souleyez/storage/engagements.py +109 -56
  265. souleyez/storage/evidence.py +181 -152
  266. souleyez/storage/execution_log.py +31 -17
  267. souleyez/storage/exploit_attempts.py +93 -57
  268. souleyez/storage/exploits.py +67 -36
  269. souleyez/storage/findings.py +48 -61
  270. souleyez/storage/hosts.py +176 -144
  271. souleyez/storage/migrate_to_engagements.py +43 -19
  272. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  273. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  274. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  275. souleyez/storage/migrations/_005_screenshots.py +13 -5
  276. souleyez/storage/migrations/_006_deliverables.py +13 -5
  277. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  278. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  279. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  280. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  281. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  282. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  283. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  284. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  285. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  286. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  287. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  288. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  289. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  290. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  291. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  292. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  293. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  294. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  295. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  296. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  297. souleyez/storage/migrations/__init__.py +26 -26
  298. souleyez/storage/migrations/migration_manager.py +19 -19
  299. souleyez/storage/msf_sessions.py +100 -65
  300. souleyez/storage/osint.py +17 -24
  301. souleyez/storage/recommendation_engine.py +269 -235
  302. souleyez/storage/screenshots.py +33 -32
  303. souleyez/storage/smb_shares.py +136 -92
  304. souleyez/storage/sqlmap_data.py +183 -128
  305. souleyez/storage/team_collaboration.py +135 -141
  306. souleyez/storage/timeline_tracker.py +122 -94
  307. souleyez/storage/wazuh_vulns.py +64 -66
  308. souleyez/storage/web_paths.py +33 -37
  309. souleyez/testing/credential_tester.py +221 -205
  310. souleyez/ui/__init__.py +1 -1
  311. souleyez/ui/ai_quotes.py +12 -12
  312. souleyez/ui/attack_surface.py +2439 -1516
  313. souleyez/ui/chain_rules_view.py +914 -382
  314. souleyez/ui/correlation_view.py +312 -230
  315. souleyez/ui/dashboard.py +2382 -1130
  316. souleyez/ui/deliverables_view.py +148 -62
  317. souleyez/ui/design_system.py +13 -13
  318. souleyez/ui/errors.py +49 -49
  319. souleyez/ui/evidence_linking_view.py +284 -179
  320. souleyez/ui/evidence_vault.py +393 -285
  321. souleyez/ui/exploit_suggestions_view.py +555 -349
  322. souleyez/ui/export_view.py +100 -66
  323. souleyez/ui/gap_analysis_view.py +315 -171
  324. souleyez/ui/help_system.py +105 -97
  325. souleyez/ui/intelligence_view.py +436 -293
  326. souleyez/ui/interactive.py +23034 -10679
  327. souleyez/ui/interactive_selector.py +75 -68
  328. souleyez/ui/log_formatter.py +47 -39
  329. souleyez/ui/menu_components.py +22 -13
  330. souleyez/ui/msf_auxiliary_menu.py +184 -133
  331. souleyez/ui/pending_chains_view.py +336 -172
  332. souleyez/ui/progress_indicators.py +5 -3
  333. souleyez/ui/recommendations_view.py +195 -137
  334. souleyez/ui/rule_builder.py +343 -225
  335. souleyez/ui/setup_wizard.py +678 -284
  336. souleyez/ui/shortcuts.py +217 -165
  337. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  338. souleyez/ui/splunk_vulns_view.py +139 -86
  339. souleyez/ui/team_dashboard.py +498 -335
  340. souleyez/ui/template_selector.py +196 -105
  341. souleyez/ui/terminal.py +6 -6
  342. souleyez/ui/timeline_view.py +198 -127
  343. souleyez/ui/tool_setup.py +264 -164
  344. souleyez/ui/tutorial.py +202 -72
  345. souleyez/ui/tutorial_state.py +40 -40
  346. souleyez/ui/wazuh_vulns_view.py +235 -141
  347. souleyez/ui/wordlist_browser.py +260 -107
  348. souleyez/ui.py +464 -312
  349. souleyez/utils/tool_checker.py +427 -367
  350. souleyez/utils.py +33 -29
  351. souleyez/wordlists.py +134 -167
  352. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/METADATA +2 -2
  353. souleyez-3.0.0.dist-info/RECORD +443 -0
  354. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.29.dist-info/RECORD +0 -379
  356. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/top_level.txt +0 -0
@@ -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('v')
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'(\d+(?:\.\d+)*)', version_str)
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(command: str, version_cmd: str = None, version_regex: str = None, version_fallback: str = None) -> Optional[str]:
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'{command} --version'
77
+ version_cmd = f"{command} --version"
72
78
  else:
73
- version_cmd = version_cmd.replace('{command}', command)
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'(\d+\.\d+\.\d+)', # 3.8.2
93
- r'v(\d+\.\d+\.\d+)', # v3.8.2
94
- r'version\s+(\d+\.\d+\.\d+)', # version 3.8.2
95
- r'(\d+\.\d+)', # 3.8
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('/etc/os-release', 'r') as f:
118
+ with open("/etc/os-release", "r") as f:
116
119
  content = f.read().lower()
117
- if 'kali' in content:
118
- return 'kali'
119
- elif 'parrot' in content:
120
- return 'parrot'
121
- elif 'ubuntu' in content:
122
- return 'ubuntu'
123
- elif 'debian' in content:
124
- return 'debian'
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 'unknown'
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
- 'prerequisites': {
136
- 'curl': {
137
- 'command': 'curl',
138
- 'install_kali': 'sudo apt install curl',
139
- 'install_ubuntu': 'sudo apt install curl',
140
- 'install_method': 'apt',
141
- 'description': 'Command-line tool for transferring data with URLs'
142
- },
143
- 'pip3': {
144
- 'command': 'pip3',
145
- 'install_kali': 'sudo apt install python3-pip',
146
- 'install_ubuntu': 'sudo apt install python3-pip',
147
- 'install_method': 'apt',
148
- 'description': 'Python package installer (required for many tools)'
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
- 'reconnaissance': {
152
- 'nmap': {
153
- 'command': 'nmap',
154
- 'install_kali': 'sudo apt install nmap',
155
- 'install_ubuntu': 'sudo apt install nmap',
156
- 'install_method': 'apt',
157
- 'description': 'Network scanner for host/port discovery',
158
- 'needs_sudo': True # Required for SYN/UDP/OS detection scans
159
- },
160
- 'theharvester': {
161
- 'command': 'theHarvester',
162
- 'install_kali': 'sudo apt install theharvester',
163
- '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',
164
- 'install_method': 'kali_only',
165
- 'description': 'OSINT tool for gathering emails, names, subdomains'
166
- },
167
- 'whois': {
168
- 'command': 'whois',
169
- 'install_kali': 'sudo apt install whois',
170
- 'install_ubuntu': 'sudo apt install whois',
171
- 'install_method': 'apt',
172
- 'description': 'Domain registration information lookup'
173
- },
174
- 'dnsrecon': {
175
- 'command': 'dnsrecon',
176
- 'install_kali': 'sudo apt install dnsrecon',
177
- 'install_ubuntu': 'pipx install dnsrecon',
178
- 'install_method': 'kali_only',
179
- 'description': 'DNS enumeration and reconnaissance'
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
- 'web_scanning': {
183
- 'nuclei': {
184
- 'command': 'nuclei',
185
- 'install_kali': 'sudo apt install nuclei',
186
- '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',
187
- 'install_method': 'kali_only',
188
- 'description': 'Fast vulnerability scanner using templates'
189
- },
190
- 'gobuster': {
191
- 'command': 'gobuster',
192
- 'install_kali': 'sudo apt install gobuster',
193
- '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',
194
- 'install_method': 'kali_only',
195
- 'description': 'Directory/file & DNS brute-forcing tool (v3.x required)',
196
- 'min_version': '3.0.0',
197
- 'version_cmd': '{command} -v',
198
- 'version_regex': r'version\s+(\d+\.\d+\.\d+)',
199
- 'version_note': 'SoulEyez requires gobuster v3+ (uses subcommand syntax)',
200
- 'upgrade_kali': 'go install github.com/OJ/gobuster/v3@latest',
201
- 'upgrade_ubuntu': 'go install github.com/OJ/gobuster/v3@latest'
202
- },
203
- 'ffuf': {
204
- 'command': 'ffuf',
205
- 'install_kali': 'sudo apt install ffuf',
206
- 'install_ubuntu': 'sudo apt install ffuf',
207
- 'install_method': 'apt',
208
- 'description': 'Fast web fuzzer for content discovery'
209
- },
210
- 'wpscan': {
211
- 'command': 'wpscan',
212
- 'install_kali': 'sudo apt install wpscan',
213
- 'install_ubuntu': 'sudo gem install wpscan',
214
- 'install_method': 'kali_only',
215
- 'description': 'WordPress vulnerability scanner'
216
- },
217
- 'nikto': {
218
- 'command': 'nikto',
219
- 'install_kali': 'sudo apt install nikto',
220
- 'install_ubuntu': 'sudo apt install nikto',
221
- 'install_method': 'apt',
222
- 'description': 'Web server vulnerability scanner'
223
- },
224
- 'dalfox': {
225
- 'command': 'dalfox',
226
- 'install_kali': 'go install github.com/hahwul/dalfox/v2@latest',
227
- 'install_ubuntu': 'go install github.com/hahwul/dalfox/v2@latest',
228
- 'install_method': 'go',
229
- 'description': 'XSS vulnerability scanner'
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
- 'exploitation': {
233
- 'sqlmap': {
234
- 'command': 'sqlmap',
235
- 'install_kali': 'sudo apt install sqlmap',
236
- 'install_ubuntu': 'sudo apt install sqlmap',
237
- 'install_method': 'apt',
238
- 'description': 'Automatic SQL injection exploitation tool'
239
- },
240
- 'metasploit': {
241
- 'command': 'msfconsole',
242
- 'alt_commands': ['/opt/metasploit-framework/bin/msfconsole'],
243
- 'install_kali': 'sudo apt install metasploit-framework',
244
- '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',
245
- 'install_method': 'kali_only',
246
- 'description': 'Penetration testing framework',
247
- 'dependencies': ['postgresql']
248
- },
249
- 'searchsploit': {
250
- 'command': 'searchsploit',
251
- 'install_kali': 'sudo apt install exploitdb',
252
- 'install_ubuntu': 'sudo git clone https://gitlab.com/exploit-database/exploitdb.git /opt/exploitdb && sudo ln -sf /opt/exploitdb/searchsploit /usr/local/bin/searchsploit',
253
- 'install_method': 'kali_only',
254
- 'description': 'Exploit database search tool'
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
- 'credential_attacks': {
258
- 'hydra': {
259
- 'command': 'hydra',
260
- 'install_kali': 'sudo apt install hydra',
261
- 'install_ubuntu': 'sudo apt install hydra',
262
- 'install_method': 'apt',
263
- 'description': 'Network login brute-forcing tool'
264
- },
265
- 'john': {
266
- 'command': 'john',
267
- 'install_kali': 'sudo apt install john',
268
- 'install_ubuntu': 'sudo apt install john',
269
- 'install_method': 'apt',
270
- 'description': 'John the Ripper password cracker'
271
- },
272
- 'hashcat': {
273
- 'command': 'hashcat',
274
- 'install_kali': 'sudo apt install hashcat',
275
- 'install_ubuntu': 'sudo apt install hashcat',
276
- 'install_method': 'apt',
277
- 'description': 'Advanced password recovery tool'
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
- 'windows_ad': {
281
- 'enum4linux': {
282
- 'command': 'enum4linux',
283
- 'alt_commands': ['enum4linux-ng'],
284
- 'install_kali': 'sudo apt install enum4linux',
285
- 'install_ubuntu': 'sudo apt install -y smbclient && pipx install git+https://github.com/cddmp/enum4linux-ng',
286
- 'install_method': 'kali_only',
287
- 'description': 'Windows/Samba enumeration tool',
288
- 'system_deps_ubuntu': ['smbclient']
289
- },
290
- 'smbmap': {
291
- 'command': 'smbmap',
292
- 'install_kali': 'sudo apt install smbmap',
293
- 'install_ubuntu': 'pipx install --force smbmap && pipx inject smbmap impacket',
294
- 'install_method': 'kali_only',
295
- 'description': 'SMB share enumeration tool',
296
- 'known_issues': 'All versions have pickling bug with impacket. Use netexec instead.',
297
- 'optional': True
298
- },
299
- 'netexec': {
300
- 'command': 'nxc',
301
- 'install_kali': 'sudo apt install netexec',
302
- 'install_ubuntu': 'pipx install git+https://github.com/Pennyw0rth/NetExec',
303
- 'install_method': 'kali_only',
304
- 'description': 'Swiss army knife for pentesting Windows/AD (formerly CrackMapExec)'
305
- },
306
- 'impacket-scripts': {
307
- 'command': 'GetNPUsers.py',
308
- 'alt_commands': ['impacket-GetNPUsers', 'GetNPUsers'],
309
- 'install_kali': 'sudo apt install python3-impacket',
310
- 'install_ubuntu': 'pipx install impacket',
311
- 'install_method': 'kali_only',
312
- 'description': 'Collection of Python classes for network protocols'
313
- },
314
- 'bloodhound': {
315
- 'command': 'bloodhound-python',
316
- 'install_kali': 'sudo apt install bloodhound.py',
317
- 'install_ubuntu': 'pipx install bloodhound',
318
- 'install_method': 'kali_only',
319
- 'description': 'Active Directory relationship mapper'
320
- },
321
- 'responder': {
322
- 'command': 'responder',
323
- 'install_kali': 'sudo apt install responder && sudo pip install --break-system-packages --ignore-installed aioquic',
324
- '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',
325
- 'install_method': 'kali_only',
326
- 'description': 'LLMNR, NBT-NS and MDNS poisoner',
327
- 'needs_sudo': True # Required for network poisoning
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
- 'router_iot': {
331
- 'routersploit': {
332
- 'command': 'rsf.py',
333
- 'install_kali': 'pipx install routersploit',
334
- 'install_ubuntu': 'pipx install routersploit',
335
- 'install_method': 'pipx',
336
- 'description': 'Router exploitation framework (like Metasploit for routers)'
337
- },
338
- 'miniupnpc': {
339
- 'command': 'upnpc',
340
- 'install_kali': 'sudo apt install miniupnpc',
341
- 'install_ubuntu': 'sudo apt install miniupnpc',
342
- 'install_method': 'apt',
343
- 'description': 'UPnP client for port forwarding manipulation'
344
- },
345
- 'binwalk': {
346
- 'command': 'binwalk',
347
- 'install_kali': 'sudo apt install binwalk',
348
- 'install_ubuntu': 'sudo apt install binwalk',
349
- 'install_method': 'apt',
350
- 'description': 'Firmware analysis and extraction tool'
351
- },
352
- 'dnsutils': {
353
- 'command': 'dig',
354
- 'install_kali': 'sudo apt install dnsutils',
355
- 'install_ubuntu': 'sudo apt install dnsutils',
356
- 'install_method': 'apt',
357
- 'description': 'DNS lookup utilities (dig, nslookup)'
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
- 'remote_access': {
361
- 'tigervnc': {
362
- 'command': 'vncviewer',
363
- 'install_kali': 'sudo apt install tigervnc-viewer',
364
- 'install_ubuntu': 'sudo apt install tigervnc-viewer',
365
- 'install_method': 'apt',
366
- 'description': 'VNC client for remote desktop access'
367
- },
368
- 'vncsnapshot': {
369
- 'command': 'vncsnapshot',
370
- 'install_kali': 'sudo apt install vncsnapshot',
371
- 'install_ubuntu': 'sudo apt install vncsnapshot',
372
- 'install_method': 'apt',
373
- 'description': 'VNC screenshot capture tool'
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 ('kali', 'parrot'):
385
- return tool_info.get('install_kali', tool_info.get('install', ''))
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('install_ubuntu', tool_info.get('install_kali', ''))
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 ('kali', 'parrot'):
395
- return tool_info.get('upgrade_kali')
434
+ if distro in ("kali", "parrot"):
435
+ return tool_info.get("upgrade_kali")
396
436
  else:
397
- return tool_info.get('upgrade_ubuntu')
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('/') and os.path.isfile(alt) and os.access(alt, os.X_OK):
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('/') and os.path.isfile(alt) and os.access(alt, os.X_OK):
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('alt_commands')
457
- results[category][tool_name] = check_tool(tool_info['command'], alt_commands)
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(1 for category in status.values() for is_installed in category.values() if is_installed)
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
- 'name': tool_name,
505
- 'category': category,
506
- 'command': tool_info['command'],
507
- 'install': get_install_command(tool_info, distro),
508
- 'install_method': tool_info.get('install_method', 'apt'),
509
- 'description': tool_info['description']
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['command']
534
- alt_commands = tool_info.get('alt_commands')
535
- min_version = tool_info.get('min_version')
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
- 'installed': False,
539
- 'version': None,
540
- 'min_version': min_version,
541
- 'version_ok': True,
542
- 'needs_upgrade': False,
543
- 'version_note': tool_info.get('version_note'),
544
- 'actual_command': None
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['installed'] = True
553
- result['actual_command'] = actual_cmd
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('version_cmd')
557
- version_regex = tool_info.get('version_regex')
558
- version_fallback = tool_info.get('version_fallback')
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('{command}', actual_cmd)
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(actual_cmd, actual_version_cmd, version_regex, version_fallback)
568
- result['version'] = installed_version
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['version_ok'] = version_meets_requirement(installed_version, min_version)
573
- result['needs_upgrade'] = not result['version_ok']
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['version_ok'] = True
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('min_version'):
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['installed'] and version_status['needs_upgrade']:
604
- wrong_version.append({
605
- 'name': tool_name,
606
- 'category': category,
607
- 'command': tool_info['command'],
608
- 'installed_version': version_status['version'],
609
- 'min_version': version_status['min_version'],
610
- 'install': get_install_command(tool_info, distro),
611
- 'description': tool_info['description'],
612
- 'version_note': version_status['version_note']
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
- 'name': tool_name,
683
- 'installed': tool_status['installed'],
684
- 'version': tool_status.get('version'),
685
- 'version_ok': tool_status.get('version_ok', True),
686
- 'needs_upgrade': tool_status.get('needs_upgrade', False),
687
- 'min_version': tool_status.get('min_version'),
688
- 'command': tool_info['command'],
689
- 'install': get_install_command(tool_info, distro),
690
- 'install_method': tool_info.get('install_method', 'apt'),
691
- 'description': tool_info['description'],
692
- 'version_note': tool_info.get('version_note')
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
- 'prerequisites': '⚙️ Prerequisites',
702
- 'reconnaissance': '🔍 Reconnaissance',
703
- 'web_scanning': '🌐 Web Scanning',
704
- 'exploitation': '💥 Exploitation',
705
- 'credential_attacks': '🔑 Credential Attacks',
706
- 'windows_ad': '🪟 Windows/Active Directory',
707
- 'router_iot': '📡 Router/IoT Testing',
708
- 'remote_access': '🖥️ Remote Access'
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('_', ' ').title())
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
- 'initialized': False,
728
- 'running': False,
729
- 'connected': False,
730
- 'message': 'Unknown status'
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('msfdb'):
735
- result['message'] = 'msfdb command not found - Metasploit may not be installed'
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
- ['systemctl', 'is-active', 'postgresql'],
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 'active' in proc.stdout.lower()
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('/usr/share/metasploit-framework/config/database.yml')
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 'adapter: postgresql' in content and 'database: msf' in content
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
- ['msfdb', 'status'],
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 'run as root' in output_lower or (proc.returncode != 0 and 'error' in output_lower):
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['running'] = check_postgresql_running()
832
+ result["running"] = check_postgresql_running()
779
833
  if check_system_config():
780
- result['initialized'] = True
781
- if result['running']:
782
- result['connected'] = True
783
- result['message'] = 'Database initialized and running'
834
+ result["initialized"] = True
835
+ if result["running"]:
836
+ result["connected"] = True
837
+ result["message"] = "Database initialized and running"
784
838
  else:
785
- result['message'] = 'Database initialized but PostgreSQL not running - run: sudo systemctl start postgresql'
839
+ result["message"] = (
840
+ "Database initialized but PostgreSQL not running - run: sudo systemctl start postgresql"
841
+ )
786
842
  else:
787
- result['message'] = 'Need sudo to verify - run: sudo msfdb status'
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 'no database' in output_lower or 'not initialized' in output_lower:
792
- result['message'] = 'Database not initialized - run: msfdb init'
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 'postgresql' in output_lower:
797
- if 'running' in output_lower or 'active' in output_lower:
798
- result['running'] = True
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 'msf' in output_lower and ('database' in output_lower or 'connected' in output_lower):
802
- if 'no connection' not in output_lower:
803
- result['initialized'] = True
804
- result['connected'] = True
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 'msf' in output_lower and result['running']:
808
- result['initialized'] = True
865
+ if "msf" in output_lower and result["running"]:
866
+ result["initialized"] = True
809
867
 
810
868
  # Build status message
811
- if result['initialized'] and result['running']:
812
- result['connected'] = True
813
- result['message'] = 'Database initialized and running'
814
- elif result['initialized'] and not result['running']:
815
- result['message'] = 'Database initialized but PostgreSQL not running - run: sudo systemctl start postgresql'
816
- elif not result['initialized']:
817
- result['message'] = 'Database not initialized - run: msfdb init'
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['message'] = 'msfdb status timed out'
880
+ result["message"] = "msfdb status timed out"
821
881
  except Exception as e:
822
- result['message'] = f'Error checking msfdb status: {e}'
882
+ result["message"] = f"Error checking msfdb status: {e}"
823
883
 
824
884
  return result