souleyez 2.43.28__py3-none-any.whl → 2.43.32__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 (356) 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 +9592 -2879
  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 +1238 -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 +2198 -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 +563 -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 +408 -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 +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +288 -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/whois_handler.py +277 -0
  126. souleyez/handlers/wpscan_handler.py +554 -0
  127. souleyez/history.py +32 -16
  128. souleyez/importers/msf_importer.py +106 -75
  129. souleyez/importers/smart_importer.py +208 -147
  130. souleyez/integrations/siem/__init__.py +10 -10
  131. souleyez/integrations/siem/base.py +17 -18
  132. souleyez/integrations/siem/elastic.py +108 -122
  133. souleyez/integrations/siem/factory.py +207 -80
  134. souleyez/integrations/siem/googlesecops.py +146 -154
  135. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  136. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  137. souleyez/integrations/siem/sentinel.py +107 -109
  138. souleyez/integrations/siem/splunk.py +246 -212
  139. souleyez/integrations/siem/wazuh.py +65 -71
  140. souleyez/integrations/wazuh/__init__.py +5 -5
  141. souleyez/integrations/wazuh/client.py +70 -93
  142. souleyez/integrations/wazuh/config.py +85 -57
  143. souleyez/integrations/wazuh/host_mapper.py +28 -36
  144. souleyez/integrations/wazuh/sync.py +78 -68
  145. souleyez/intelligence/__init__.py +4 -5
  146. souleyez/intelligence/correlation_analyzer.py +309 -295
  147. souleyez/intelligence/exploit_knowledge.py +661 -623
  148. souleyez/intelligence/exploit_suggestions.py +159 -139
  149. souleyez/intelligence/gap_analyzer.py +132 -97
  150. souleyez/intelligence/gap_detector.py +251 -214
  151. souleyez/intelligence/sensitive_tables.py +266 -129
  152. souleyez/intelligence/service_parser.py +137 -123
  153. souleyez/intelligence/surface_analyzer.py +407 -268
  154. souleyez/intelligence/target_parser.py +159 -162
  155. souleyez/licensing/__init__.py +6 -6
  156. souleyez/licensing/validator.py +17 -19
  157. souleyez/log_config.py +79 -54
  158. souleyez/main.py +1505 -687
  159. souleyez/migrations/fix_job_counter.py +16 -14
  160. souleyez/parsers/bloodhound_parser.py +41 -39
  161. souleyez/parsers/crackmapexec_parser.py +178 -111
  162. souleyez/parsers/dalfox_parser.py +72 -77
  163. souleyez/parsers/dnsrecon_parser.py +103 -91
  164. souleyez/parsers/enum4linux_parser.py +183 -153
  165. souleyez/parsers/ffuf_parser.py +29 -25
  166. souleyez/parsers/gobuster_parser.py +301 -41
  167. souleyez/parsers/hashcat_parser.py +324 -79
  168. souleyez/parsers/http_fingerprint_parser.py +350 -103
  169. souleyez/parsers/hydra_parser.py +131 -111
  170. souleyez/parsers/impacket_parser.py +231 -178
  171. souleyez/parsers/john_parser.py +98 -86
  172. souleyez/parsers/katana_parser.py +316 -0
  173. souleyez/parsers/msf_parser.py +943 -498
  174. souleyez/parsers/nikto_parser.py +346 -65
  175. souleyez/parsers/nmap_parser.py +262 -174
  176. souleyez/parsers/nuclei_parser.py +40 -44
  177. souleyez/parsers/responder_parser.py +26 -26
  178. souleyez/parsers/searchsploit_parser.py +74 -74
  179. souleyez/parsers/service_explorer_parser.py +279 -0
  180. souleyez/parsers/smbmap_parser.py +180 -124
  181. souleyez/parsers/sqlmap_parser.py +434 -308
  182. souleyez/parsers/theharvester_parser.py +75 -57
  183. souleyez/parsers/whois_parser.py +135 -94
  184. souleyez/parsers/wpscan_parser.py +278 -190
  185. souleyez/plugins/afp.py +44 -36
  186. souleyez/plugins/afp_brute.py +114 -46
  187. souleyez/plugins/ard.py +48 -37
  188. souleyez/plugins/bloodhound.py +95 -61
  189. souleyez/plugins/certipy.py +303 -0
  190. souleyez/plugins/crackmapexec.py +186 -85
  191. souleyez/plugins/dalfox.py +120 -59
  192. souleyez/plugins/dns_hijack.py +146 -41
  193. souleyez/plugins/dnsrecon.py +97 -61
  194. souleyez/plugins/enum4linux.py +91 -66
  195. souleyez/plugins/evil_winrm.py +291 -0
  196. souleyez/plugins/ffuf.py +166 -90
  197. souleyez/plugins/firmware_extract.py +133 -29
  198. souleyez/plugins/gobuster.py +387 -190
  199. souleyez/plugins/gpp_extract.py +393 -0
  200. souleyez/plugins/hashcat.py +100 -73
  201. souleyez/plugins/http_fingerprint.py +854 -267
  202. souleyez/plugins/hydra.py +566 -200
  203. souleyez/plugins/impacket_getnpusers.py +117 -69
  204. souleyez/plugins/impacket_psexec.py +84 -64
  205. souleyez/plugins/impacket_secretsdump.py +103 -69
  206. souleyez/plugins/impacket_smbclient.py +89 -75
  207. souleyez/plugins/john.py +86 -69
  208. souleyez/plugins/katana.py +313 -0
  209. souleyez/plugins/kerbrute.py +237 -0
  210. souleyez/plugins/lfi_extract.py +541 -0
  211. souleyez/plugins/macos_ssh.py +117 -48
  212. souleyez/plugins/mdns.py +35 -30
  213. souleyez/plugins/msf_auxiliary.py +253 -130
  214. souleyez/plugins/msf_exploit.py +239 -161
  215. souleyez/plugins/nikto.py +134 -78
  216. souleyez/plugins/nmap.py +275 -91
  217. souleyez/plugins/nuclei.py +180 -89
  218. souleyez/plugins/nxc.py +285 -0
  219. souleyez/plugins/plugin_base.py +35 -36
  220. souleyez/plugins/plugin_template.py +13 -5
  221. souleyez/plugins/rdp_sec_check.py +130 -0
  222. souleyez/plugins/responder.py +112 -71
  223. souleyez/plugins/router_http_brute.py +76 -65
  224. souleyez/plugins/router_ssh_brute.py +118 -41
  225. souleyez/plugins/router_telnet_brute.py +124 -42
  226. souleyez/plugins/routersploit.py +91 -59
  227. souleyez/plugins/routersploit_exploit.py +77 -55
  228. souleyez/plugins/searchsploit.py +91 -77
  229. souleyez/plugins/service_explorer.py +1160 -0
  230. souleyez/plugins/smbmap.py +122 -72
  231. souleyez/plugins/smbpasswd.py +215 -0
  232. souleyez/plugins/sqlmap.py +301 -113
  233. souleyez/plugins/theharvester.py +127 -75
  234. souleyez/plugins/tr069.py +79 -57
  235. souleyez/plugins/upnp.py +65 -47
  236. souleyez/plugins/upnp_abuse.py +73 -55
  237. souleyez/plugins/vnc_access.py +129 -42
  238. souleyez/plugins/vnc_brute.py +109 -38
  239. souleyez/plugins/whois.py +77 -58
  240. souleyez/plugins/wpscan.py +173 -69
  241. souleyez/reporting/__init__.py +2 -1
  242. souleyez/reporting/attack_chain.py +411 -346
  243. souleyez/reporting/charts.py +436 -501
  244. souleyez/reporting/compliance_mappings.py +334 -201
  245. souleyez/reporting/detection_report.py +126 -125
  246. souleyez/reporting/formatters.py +828 -591
  247. souleyez/reporting/generator.py +386 -302
  248. souleyez/reporting/metrics.py +72 -75
  249. souleyez/scanner.py +35 -29
  250. souleyez/security/__init__.py +37 -11
  251. souleyez/security/scope_validator.py +175 -106
  252. souleyez/security/validation.py +223 -149
  253. souleyez/security.py +22 -6
  254. souleyez/storage/credentials.py +247 -186
  255. souleyez/storage/crypto.py +296 -129
  256. souleyez/storage/database.py +73 -50
  257. souleyez/storage/db.py +58 -36
  258. souleyez/storage/deliverable_evidence.py +177 -128
  259. souleyez/storage/deliverable_exporter.py +282 -246
  260. souleyez/storage/deliverable_templates.py +134 -116
  261. souleyez/storage/deliverables.py +135 -130
  262. souleyez/storage/engagements.py +109 -56
  263. souleyez/storage/evidence.py +181 -152
  264. souleyez/storage/execution_log.py +31 -17
  265. souleyez/storage/exploit_attempts.py +93 -57
  266. souleyez/storage/exploits.py +67 -36
  267. souleyez/storage/findings.py +48 -61
  268. souleyez/storage/hosts.py +176 -144
  269. souleyez/storage/migrate_to_engagements.py +43 -19
  270. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  271. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  272. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  273. souleyez/storage/migrations/_005_screenshots.py +13 -5
  274. souleyez/storage/migrations/_006_deliverables.py +13 -5
  275. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  276. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  277. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  278. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  279. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  280. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  281. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  282. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  283. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  284. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  285. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  286. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  287. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  288. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  289. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  290. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  291. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  292. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  293. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  294. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  295. souleyez/storage/migrations/__init__.py +26 -26
  296. souleyez/storage/migrations/migration_manager.py +19 -19
  297. souleyez/storage/msf_sessions.py +100 -65
  298. souleyez/storage/osint.py +17 -24
  299. souleyez/storage/recommendation_engine.py +269 -235
  300. souleyez/storage/screenshots.py +33 -32
  301. souleyez/storage/smb_shares.py +136 -92
  302. souleyez/storage/sqlmap_data.py +183 -128
  303. souleyez/storage/team_collaboration.py +135 -141
  304. souleyez/storage/timeline_tracker.py +122 -94
  305. souleyez/storage/wazuh_vulns.py +64 -66
  306. souleyez/storage/web_paths.py +33 -37
  307. souleyez/testing/credential_tester.py +221 -205
  308. souleyez/ui/__init__.py +1 -1
  309. souleyez/ui/ai_quotes.py +12 -12
  310. souleyez/ui/attack_surface.py +2439 -1516
  311. souleyez/ui/chain_rules_view.py +914 -382
  312. souleyez/ui/correlation_view.py +312 -230
  313. souleyez/ui/dashboard.py +2382 -1130
  314. souleyez/ui/deliverables_view.py +148 -62
  315. souleyez/ui/design_system.py +13 -13
  316. souleyez/ui/errors.py +49 -49
  317. souleyez/ui/evidence_linking_view.py +284 -179
  318. souleyez/ui/evidence_vault.py +393 -285
  319. souleyez/ui/exploit_suggestions_view.py +555 -349
  320. souleyez/ui/export_view.py +100 -66
  321. souleyez/ui/gap_analysis_view.py +315 -171
  322. souleyez/ui/help_system.py +105 -97
  323. souleyez/ui/intelligence_view.py +436 -293
  324. souleyez/ui/interactive.py +23142 -10430
  325. souleyez/ui/interactive_selector.py +75 -68
  326. souleyez/ui/log_formatter.py +47 -39
  327. souleyez/ui/menu_components.py +22 -13
  328. souleyez/ui/msf_auxiliary_menu.py +184 -133
  329. souleyez/ui/pending_chains_view.py +336 -172
  330. souleyez/ui/progress_indicators.py +5 -3
  331. souleyez/ui/recommendations_view.py +195 -137
  332. souleyez/ui/rule_builder.py +343 -225
  333. souleyez/ui/setup_wizard.py +678 -284
  334. souleyez/ui/shortcuts.py +217 -165
  335. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  336. souleyez/ui/splunk_vulns_view.py +139 -86
  337. souleyez/ui/team_dashboard.py +498 -335
  338. souleyez/ui/template_selector.py +196 -105
  339. souleyez/ui/terminal.py +6 -6
  340. souleyez/ui/timeline_view.py +198 -127
  341. souleyez/ui/tool_setup.py +264 -164
  342. souleyez/ui/tutorial.py +202 -72
  343. souleyez/ui/tutorial_state.py +40 -40
  344. souleyez/ui/wazuh_vulns_view.py +235 -141
  345. souleyez/ui/wordlist_browser.py +260 -107
  346. souleyez/ui.py +464 -312
  347. souleyez/utils/tool_checker.py +427 -367
  348. souleyez/utils.py +33 -29
  349. souleyez/wordlists.py +134 -167
  350. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/METADATA +1 -1
  351. souleyez-2.43.32.dist-info/RECORD +441 -0
  352. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/WHEEL +1 -1
  353. souleyez-2.43.28.dist-info/RECORD +0 -379
  354. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/entry_points.txt +0 -0
  355. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/licenses/LICENSE +0 -0
  356. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/top_level.txt +0 -0
souleyez/utils.py CHANGED
@@ -7,9 +7,9 @@ import re
7
7
  import platform
8
8
  import ipaddress
9
9
 
10
- APP_DIR = Path.home() / '.souleyez'
11
- SCANS_DIR = APP_DIR / 'scans'
12
- HISTORY_FILE = APP_DIR / 'recon_history.json'
10
+ APP_DIR = Path.home() / ".souleyez"
11
+ SCANS_DIR = APP_DIR / "scans"
12
+ HISTORY_FILE = APP_DIR / "recon_history.json"
13
13
 
14
14
 
15
15
  def ensure_dirs():
@@ -18,46 +18,50 @@ def ensure_dirs():
18
18
 
19
19
 
20
20
  def nmap_installed():
21
- return shutil.which('nmap') is not None
21
+ return shutil.which("nmap") is not None
22
22
 
23
23
 
24
24
  def timestamp_str():
25
25
  from datetime import datetime
26
- return datetime.now().strftime('%Y%m%d-%H%M%S')
26
+
27
+ return datetime.now().strftime("%Y%m%d-%H%M%S")
27
28
 
28
29
 
29
30
  def join_cmd(args):
30
31
  import shlex
31
- return ' '.join(shlex.quote(a) for a in args)
32
+
33
+ return " ".join(shlex.quote(a) for a in args)
32
34
 
33
35
 
34
36
  def read_json(path):
35
37
  try:
36
- with open(path, 'r') as f:
38
+ with open(path, "r") as f:
37
39
  return json.load(f)
38
40
  except Exception:
39
41
  return []
40
42
 
41
43
 
42
44
  def write_json(path, data):
43
- with open(path, 'w') as f:
45
+ with open(path, "w") as f:
44
46
  json.dump(data, f, indent=2)
45
47
 
46
48
 
47
49
  def _run(cmd):
48
50
  try:
49
- return subprocess.run(cmd, capture_output=True, text=True, check=False).stdout.strip()
51
+ return subprocess.run(
52
+ cmd, capture_output=True, text=True, check=False
53
+ ).stdout.strip()
50
54
  except Exception:
51
- return ''
55
+ return ""
52
56
 
53
57
 
54
58
  def _hexmask_to_prefix(hexmask):
55
59
  try:
56
- if hexmask.startswith('0x'):
60
+ if hexmask.startswith("0x"):
57
61
  val = int(hexmask, 16)
58
62
  mask_bytes = [(val >> (i * 8)) & 0xFF for i in (3, 2, 1, 0)]
59
- bits = ''.join(f'{b:08b}' for b in mask_bytes)
60
- return bits.count('1')
63
+ bits = "".join(f"{b:08b}" for b in mask_bytes)
64
+ return bits.count("1")
61
65
  except Exception:
62
66
  pass
63
67
  return None
@@ -66,38 +70,38 @@ def _hexmask_to_prefix(hexmask):
66
70
  def detect_local_subnet():
67
71
  system = platform.system().lower()
68
72
  cidr = None
69
- if system == 'linux':
70
- out = _run(['ip', 'route', 'get', '8.8.8.8'])
71
- m = re.search(r'src (\S+)', out)
73
+ if system == "linux":
74
+ out = _run(["ip", "route", "get", "8.8.8.8"])
75
+ m = re.search(r"src (\S+)", out)
72
76
  if m:
73
77
  ip_src = m.group(1)
74
- out2 = _run(['ip', '-o', '-4', 'addr', 'show'])
75
- m2 = re.search(rf'{re.escape(ip_src)}/(\d+)', out2)
78
+ out2 = _run(["ip", "-o", "-4", "addr", "show"])
79
+ m2 = re.search(rf"{re.escape(ip_src)}/(\d+)", out2)
76
80
  if m2:
77
- cidr = f'{ip_src}/{m2.group(1)}'
81
+ cidr = f"{ip_src}/{m2.group(1)}"
78
82
  else:
79
- out = _run(['route', '-n', 'get', '8.8.8.8'])
80
- m = re.search(r'source address: (\S+)', out)
83
+ out = _run(["route", "-n", "get", "8.8.8.8"])
84
+ m = re.search(r"source address: (\S+)", out)
81
85
  if m:
82
86
  ip_src = m.group(1)
83
- ic = _run(['ifconfig'])
84
- m3 = re.search(rf'{re.escape(ip_src)} netmask (0x[0-9a-fA-F]+)', ic)
87
+ ic = _run(["ifconfig"])
88
+ m3 = re.search(rf"{re.escape(ip_src)} netmask (0x[0-9a-fA-F]+)", ic)
85
89
  if m3:
86
90
  prefix = _hexmask_to_prefix(m3.group(1))
87
91
  if prefix:
88
- cidr = f'{ip_src}/{prefix}'
92
+ cidr = f"{ip_src}/{prefix}"
89
93
  if not cidr:
90
- out3 = _run(['ip', '-o', '-4', 'addr', 'show'])
91
- m4 = re.search(r'inet (\d+\.\d+\.\d+\.\d+)/(\d+)', out3)
94
+ out3 = _run(["ip", "-o", "-4", "addr", "show"])
95
+ m4 = re.search(r"inet (\d+\.\d+\.\d+\.\d+)/(\d+)", out3)
92
96
  if m4:
93
- cidr = f'{m4.group(1)}/{m4.group(2)}'
97
+ cidr = f"{m4.group(1)}/{m4.group(2)}"
94
98
  if not cidr:
95
99
  return None
96
100
  try:
97
101
  return str(ipaddress.ip_interface(cidr).network)
98
102
  except Exception:
99
103
  try:
100
- ip = cidr.split('/')[0]
101
- return str(ipaddress.ip_network(ip + '/24', strict=False))
104
+ ip = cidr.split("/")[0]
105
+ return str(ipaddress.ip_network(ip + "/24", strict=False))
102
106
  except Exception:
103
107
  return None
souleyez/wordlists.py CHANGED
@@ -22,14 +22,14 @@ def resolve_wordlist_path(relative_path: str) -> str:
22
22
  Absolute path to the wordlist file, or original path if not found
23
23
  """
24
24
  # If it's already an absolute path, return as-is
25
- if relative_path.startswith('/'):
25
+ if relative_path.startswith("/"):
26
26
  return relative_path
27
27
 
28
28
  # Extract just the filename if it's a data/wordlists/ path
29
- if 'data/wordlists/' in relative_path:
30
- filename = relative_path.split('data/wordlists/')[-1]
31
- elif relative_path.startswith('wordlists/'):
32
- filename = relative_path.replace('wordlists/', '', 1)
29
+ if "data/wordlists/" in relative_path:
30
+ filename = relative_path.split("data/wordlists/")[-1]
31
+ elif relative_path.startswith("wordlists/"):
32
+ filename = relative_path.replace("wordlists/", "", 1)
33
33
  else:
34
34
  filename = relative_path
35
35
 
@@ -62,10 +62,10 @@ def resolve_args_wordlists(args: list) -> list:
62
62
  """
63
63
  resolved = []
64
64
  for arg in args:
65
- if isinstance(arg, str) and 'data/wordlists/' in arg:
65
+ if isinstance(arg, str) and "data/wordlists/" in arg:
66
66
  # Check if this is a KEY=value format (e.g., USER_FILE=data/wordlists/foo.txt)
67
- if '=' in arg:
68
- key, value = arg.split('=', 1)
67
+ if "=" in arg:
68
+ key, value = arg.split("=", 1)
69
69
  resolved_path = resolve_wordlist_path(value)
70
70
  resolved.append(f"{key}={resolved_path}")
71
71
  else:
@@ -84,7 +84,7 @@ def ensure_user_wordlists():
84
84
  user_wordlist_dir = Path.home() / ".souleyez" / "data" / "wordlists"
85
85
 
86
86
  # Only do this once
87
- if user_wordlist_dir.exists() and any(user_wordlist_dir.glob('*.txt')):
87
+ if user_wordlist_dir.exists() and any(user_wordlist_dir.glob("*.txt")):
88
88
  return
89
89
 
90
90
  # Try to find source wordlists
@@ -95,7 +95,7 @@ def ensure_user_wordlists():
95
95
 
96
96
  source_dir = None
97
97
  for d in source_dirs:
98
- if d.exists() and any(d.glob('*.txt')):
98
+ if d.exists() and any(d.glob("*.txt")):
99
99
  source_dir = d
100
100
  break
101
101
 
@@ -106,7 +106,8 @@ def ensure_user_wordlists():
106
106
  user_wordlist_dir.mkdir(parents=True, exist_ok=True)
107
107
 
108
108
  import shutil
109
- for src_file in source_dir.glob('*.txt'):
109
+
110
+ for src_file in source_dir.glob("*.txt"):
110
111
  dst_file = user_wordlist_dir / src_file.name
111
112
  if not dst_file.exists():
112
113
  try:
@@ -116,92 +117,103 @@ def ensure_user_wordlists():
116
117
 
117
118
 
118
119
  wordlist_map = {
120
+ # All wordlists are now self-contained in the project
121
+ # No external dependencies on /usr/share/* paths
119
122
  "hydra": {
120
123
  "users": [
124
+ "data/wordlists/usernames_common.txt",
121
125
  "data/wordlists/all_users.txt",
122
- "data/wordlists/linux_users.txt",
123
- "/usr/share/metasploit-framework/data/wordlists/unix_users.txt",
124
- "/usr/share/seclists/Usernames/top-usernames-shortlist.txt"
126
+ "data/wordlists/ad_users.txt",
125
127
  ],
126
128
  "passwords": [
127
- "data/wordlists/top20_quick.txt",
129
+ "data/wordlists/passwords_brute.txt",
128
130
  "data/wordlists/top100.txt",
129
- "/usr/share/wordlists/rockyou.txt",
130
- "/usr/share/wordlists/fasttrack.txt"
131
- ]
131
+ "data/wordlists/top20_quick.txt",
132
+ ],
132
133
  },
133
-
134
134
  "medusa": {
135
135
  "users": [
136
+ "data/wordlists/usernames_common.txt",
136
137
  "data/wordlists/all_users.txt",
137
- "data/wordlists/linux_users.txt",
138
- "/usr/share/metasploit-framework/data/wordlists/unix_users.txt"
139
138
  ],
140
139
  "passwords": [
141
- "data/wordlists/top20_quick.txt",
140
+ "data/wordlists/passwords_brute.txt",
142
141
  "data/wordlists/top100.txt",
143
- "/usr/share/wordlists/rockyou.txt"
144
- ]
142
+ ],
145
143
  },
146
-
147
144
  "gobuster": {
148
145
  "dirs": [
146
+ "data/wordlists/web_dirs_large.txt",
149
147
  "data/wordlists/web_dirs_common.txt",
150
- "/usr/share/wordlists/dirb/common.txt",
151
- "/usr/share/seclists/Discovery/Web-Content/common.txt",
152
- "/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt"
153
148
  ],
154
149
  "files": [
155
150
  "data/wordlists/web_files_common.txt",
156
- "/usr/share/seclists/Discovery/Web-Content/raft-small-files.txt"
157
151
  ],
158
152
  "dns": [
153
+ "data/wordlists/subdomains_large.txt",
159
154
  "data/wordlists/subdomains_common.txt",
160
- "/usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt"
161
155
  ],
162
156
  "extensions": [
163
- "data/wordlists/web_extensions.txt"
164
- ]
157
+ "data/wordlists/web_extensions.txt",
158
+ ],
165
159
  },
166
-
167
160
  "dirb": {
168
161
  "wordlist": [
162
+ "data/wordlists/web_dirs_large.txt",
169
163
  "data/wordlists/web_dirs_common.txt",
170
- "/usr/share/wordlists/dirb/common.txt",
171
- "/usr/share/wordlists/dirb/big.txt"
172
164
  ]
173
165
  },
174
-
175
166
  "wfuzz": {
176
167
  "wordlist": [
168
+ "data/wordlists/web_dirs_large.txt",
177
169
  "data/wordlists/web_dirs_common.txt",
178
- "/usr/share/wfuzz/wordlist/general/common.txt"
179
170
  ]
180
171
  },
181
-
172
+ "ffuf": {
173
+ "dirs": [
174
+ "data/wordlists/web_dirs_large.txt",
175
+ "data/wordlists/web_dirs_common.txt",
176
+ ],
177
+ "api": [
178
+ "data/wordlists/api_endpoints_large.txt",
179
+ "data/wordlists/api_endpoints.txt",
180
+ ],
181
+ "params": [
182
+ "data/wordlists/web_files_common.txt",
183
+ ],
184
+ },
182
185
  "msf_auxiliary": {
183
186
  "users": [
184
- "data/wordlists/all_users.txt",
185
- "data/wordlists/linux_users.txt",
186
- "/usr/share/metasploit-framework/data/wordlists/unix_users.txt"
187
+ "data/wordlists/usernames_common.txt",
188
+ "data/wordlists/soul_users.txt",
187
189
  ],
188
190
  "passwords": [
189
- "data/wordlists/msf_passwords.txt",
191
+ "data/wordlists/passwords_brute.txt",
190
192
  "data/wordlists/top20_quick.txt",
191
- "/usr/share/metasploit-framework/data/wordlists/unix_passwords.txt"
192
- ]
193
+ ],
193
194
  },
194
-
195
195
  "ncrack": {
196
196
  "users": [
197
+ "data/wordlists/usernames_common.txt",
197
198
  "data/wordlists/all_users.txt",
198
- "data/wordlists/linux_users.txt"
199
199
  ],
200
200
  "passwords": [
201
- "data/wordlists/top20_quick.txt",
202
- "data/wordlists/top100.txt"
201
+ "data/wordlists/passwords_brute.txt",
202
+ "data/wordlists/top100.txt",
203
+ ],
204
+ },
205
+ "hashcat": {
206
+ "passwords": [
207
+ "data/wordlists/passwords_crack.txt",
208
+ "data/wordlists/passwords_brute.txt",
203
209
  ]
204
- }
210
+ },
211
+ "john": {
212
+ "passwords": [
213
+ "data/wordlists/passwords_crack.txt",
214
+ "data/wordlists/passwords_brute.txt",
215
+ ]
216
+ },
205
217
  }
206
218
 
207
219
 
@@ -260,20 +272,20 @@ def _discover_wordlists_by_category(wordlist_dir, category):
260
272
  import os
261
273
 
262
274
  # Special handling for categories that should show all wordlists
263
- show_all_categories = {'users', 'passwords'}
275
+ show_all_categories = {"users", "passwords"}
264
276
 
265
277
  # Category-specific patterns (only for non-show-all categories)
266
278
  category_patterns = {
267
- 'dirs': ['_dirs', 'directories'],
268
- 'files': ['_files'],
269
- 'dns': ['subdomains', 'dns'],
270
- 'wordlist': [] # Generic - include all
279
+ "dirs": ["_dirs", "directories"],
280
+ "files": ["_files"],
281
+ "dns": ["subdomains", "dns"],
282
+ "wordlist": [], # Generic - include all
271
283
  }
272
284
 
273
285
  matches = []
274
286
 
275
287
  try:
276
- for file in sorted(wordlist_dir.glob('*.txt')):
288
+ for file in sorted(wordlist_dir.glob("*.txt")):
277
289
  filename = file.name.lower()
278
290
 
279
291
  # For users/passwords, show ALL wordlists
@@ -310,7 +322,9 @@ def get_wordlist_info(wordlist_path):
310
322
 
311
323
  try:
312
324
  with open(wordlist_path) as f:
313
- line_count = sum(1 for line in f if line.strip() and not line.startswith('#'))
325
+ line_count = sum(
326
+ 1 for line in f if line.strip() and not line.startswith("#")
327
+ )
314
328
  size_mb = os.path.getsize(wordlist_path) / (1024 * 1024)
315
329
  # Check if it's a built-in wordlist (from any souleyez location)
316
330
  builtin_dirs = [
@@ -321,135 +335,86 @@ def get_wordlist_info(wordlist_path):
321
335
  is_builtin = any(bd in wordlist_path for bd in builtin_dirs)
322
336
 
323
337
  return {
324
- 'path': wordlist_path,
325
- 'line_count': line_count,
326
- 'size_mb': size_mb,
327
- 'is_builtin': is_builtin
338
+ "path": wordlist_path,
339
+ "line_count": line_count,
340
+ "size_mb": size_mb,
341
+ "is_builtin": is_builtin,
328
342
  }
329
343
  except Exception:
330
344
  return None
331
345
 
332
346
 
333
- def display_wordlist_menu(tool_name, category, title="Wordlist Selection"):
347
+ def display_wordlist_menu(
348
+ tool_name, category, title="Wordlist Selection", allow_single_value=None
349
+ ):
334
350
  """
335
- Display an interactive wordlist selection menu.
336
-
351
+ Display an interactive wordlist selection browser.
352
+
353
+ Goes directly to the full wordlist browser with recommended wordlists highlighted.
354
+
337
355
  Args:
338
356
  tool_name: Name of the tool
339
357
  category: Category of wordlist
340
358
  title: Menu title
341
-
359
+ allow_single_value: If True, enable single value entry. If None (default),
360
+ auto-detect based on category (True for users/passwords)
361
+
342
362
  Returns:
343
- Selected wordlist path or None if cancelled
363
+ Selected wordlist path, ('single', value) tuple, or None if cancelled
344
364
  """
345
365
  import click
346
-
366
+ from souleyez.ui.wordlist_browser import browse_wordlists
367
+
368
+ # Get recommended wordlists for this tool/category
347
369
  wordlists = get_wordlists(tool_name, category)
348
-
349
- if not wordlists:
350
- click.echo(click.style(f"No wordlists found for {tool_name} {category}", fg='red'))
351
- return None
352
-
353
- click.echo()
354
- click.echo(click.style(f"📝 {title}", bold=True, fg='yellow'))
355
- click.echo()
356
- click.echo("Available wordlists:")
357
-
358
- # Separate built-in and system wordlists
359
- # Built-in = under souleyez wordlist directories (user, package, or dev)
370
+
371
+ # Separate built-in wordlists (these are recommended)
360
372
  builtin_dirs = [
361
373
  str(Path.home() / ".souleyez" / "data" / "wordlists"),
362
374
  "/usr/share/souleyez/wordlists",
363
375
  str(Path(__file__).parent / "data" / "wordlists"), # Package bundled
364
376
  ]
365
- builtin = [w for w in wordlists if any(bd in w for bd in builtin_dirs)]
366
- system = [w for w in wordlists if w not in builtin]
367
-
368
- choice_map = {}
369
- idx = 1
370
-
371
- if builtin:
372
- click.echo(click.style(" SoulEyez Built-in (Recommended):", fg='cyan', bold=True))
373
- for wl in builtin:
374
- info = get_wordlist_info(wl)
375
- if info:
376
- click.echo(f" {idx}. {wl} ({info['line_count']} entries)")
377
- choice_map[idx] = wl
378
- idx += 1
379
- click.echo()
380
-
381
- if system:
382
- click.echo(click.style(" System Wordlists:", fg='yellow'))
383
- for wl in system:
384
- info = get_wordlist_info(wl)
385
- if info:
386
- if info['size_mb'] > 0.1:
387
- click.echo(f" {idx}. {wl} ({info['size_mb']:.1f} MB)")
388
- else:
389
- click.echo(f" {idx}. {wl} ({info['line_count']} entries)")
390
- choice_map[idx] = wl
391
- idx += 1
392
- click.echo()
393
-
394
- # Browse all wordlists option
395
- click.echo(f" {idx}. Browse all wordlists...")
396
- browse_idx = idx
397
- idx += 1
398
-
399
- # Dynamic label based on category
400
- single_label = "Enter single username" if category == 'users' else "Enter single password" if category == 'passwords' else "Enter single value"
401
-
402
- click.echo(f" {idx}. {single_label}")
403
- single_idx = idx
404
- idx += 1
405
- click.echo(f" {idx}. Enter custom path")
406
- custom_idx = idx
407
- click.echo(f" 0. Cancel")
408
- click.echo()
409
-
410
- try:
411
- choice = click.prompt("Select wordlist", type=int, default=1)
412
-
413
- if choice == 0:
414
- return None
415
- elif choice in choice_map:
416
- selected = choice_map[choice]
417
- click.echo(click.style(f"✓ Selected: {selected}", fg='green'))
418
- return selected
419
- elif choice == browse_idx:
420
- # Launch interactive wordlist browser
421
- from souleyez.ui.wordlist_browser import browse_wordlists
422
- selected = browse_wordlists(category_filter=category, title=f'SELECT {category.upper()} WORDLIST')
423
- if selected:
424
- click.echo(click.style(f"✓ Selected: {selected}", fg='green'))
425
- return selected
426
- elif choice == single_idx:
427
- # Single value entry - return tuple to indicate it's not a file
428
- value_prompt = "Enter username" if category == 'users' else "Enter password" if category == 'passwords' else "Enter value"
429
- value = click.prompt(value_prompt, type=str)
430
- if value.strip():
431
- click.echo(click.style(f"✓ Single value: {value.strip()}", fg='green'))
432
- return ('single', value.strip())
433
- else:
434
- click.echo(click.style("✗ Empty value", fg='red'))
435
- return None
436
- elif choice == custom_idx:
437
- custom = click.prompt("Enter custom wordlist path", type=str)
438
- import os
439
- if os.path.exists(custom):
440
- click.echo(click.style(f"✓ Custom wordlist: {custom}", fg='green'))
441
- return custom
442
- else:
443
- click.echo(click.style("✗ File not found", fg='red'))
444
- return None
377
+ recommended = [w for w in wordlists if any(bd in w for bd in builtin_dirs)]
378
+
379
+ # Determine single value label based on category
380
+ single_label = (
381
+ "username"
382
+ if category == "users"
383
+ else "password" if category == "passwords" else "value"
384
+ )
385
+
386
+ # Auto-detect allow_single_value based on category if not specified
387
+ # Single values make sense for users/passwords but not for dirs/dns wordlists
388
+ if allow_single_value is None:
389
+ allow_single_value = category in ("users", "passwords")
390
+
391
+ # Launch browser directly with recommended paths highlighted
392
+ selected = browse_wordlists(
393
+ category_filter=category,
394
+ title=(
395
+ f"SELECT {category.upper()} WORDLIST"
396
+ if title == "Wordlist Selection"
397
+ else title.upper()
398
+ ),
399
+ recommended_paths=recommended,
400
+ allow_single_value=allow_single_value,
401
+ allow_custom_path=True,
402
+ single_value_label=single_label,
403
+ )
404
+
405
+ # Show confirmation message
406
+ if selected:
407
+ if isinstance(selected, tuple) and selected[0] == "single":
408
+ click.echo(
409
+ click.style(f"✓ Single {single_label}: {selected[1]}", fg="green")
410
+ )
445
411
  else:
446
- click.echo(click.style("Invalid selection", fg='red'))
447
- return None
448
- except (KeyboardInterrupt, click.Abort):
449
- return None
412
+ click.echo(click.style(f" Selected: {selected}", fg="green"))
413
+
414
+ return selected
450
415
 
451
416
 
452
- def get_available_wordlists(category='users'):
417
+ def get_available_wordlists(category="users"):
453
418
  """
454
419
  Get available wordlists for a category.
455
420
 
@@ -461,20 +426,20 @@ def get_available_wordlists(category='users'):
461
426
  """
462
427
  result = {}
463
428
 
464
- if category == 'users':
429
+ if category == "users":
465
430
  files = [
466
431
  ("All Users", "all_users.txt"),
467
432
  ("Linux Users", "linux_users.txt"),
468
433
  ("Soul Users", "soul_users.txt"),
469
434
  ]
470
- elif category == 'passwords':
435
+ elif category == "passwords":
471
436
  files = [
472
437
  ("Top 20 Quick", "top20_quick.txt"),
473
438
  ("Top 100", "top100.txt"),
474
439
  ("Soul Passwords", "soul_pass.txt"),
475
440
  ("Default Credentials", "default_credentials.txt"),
476
441
  ]
477
- elif category == 'credentials':
442
+ elif category == "credentials":
478
443
  files = [
479
444
  ("Default Credentials (user:pass)", "default_credentials.txt"),
480
445
  ]
@@ -488,7 +453,9 @@ def get_available_wordlists(category='users'):
488
453
  # Dynamically calculate entry count (excluding comments and blank lines)
489
454
  try:
490
455
  with open(resolved) as f:
491
- count = sum(1 for line in f if line.strip() and not line.startswith('#'))
456
+ count = sum(
457
+ 1 for line in f if line.strip() and not line.startswith("#")
458
+ )
492
459
  name_with_count = f"{name} ({count})"
493
460
  except Exception:
494
461
  name_with_count = name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: souleyez
3
- Version: 2.43.28
3
+ Version: 2.43.32
4
4
  Summary: AI-Powered Penetration Testing Platform with 40+ integrated tools
5
5
  Author-email: CyberSoul Security <contact@cybersoulsecurity.com>
6
6
  Maintainer-email: CyberSoul Security <contact@cybersoulsecurity.com>