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
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.29
3
+ Version: 3.0.0
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>
@@ -10,7 +10,7 @@ Project-URL: Documentation, https://github.com/cyber-soul-security/SoulEyez#read
10
10
  Project-URL: Repository, https://github.com/cyber-soul-security/SoulEyez.git
11
11
  Project-URL: Issues, https://github.com/cyber-soul-security/SoulEyez/issues
12
12
  Keywords: pentesting,security,hacking,penetration-testing,cybersecurity,nmap,metasploit
13
- Classifier: Development Status :: 4 - Beta
13
+ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Environment :: Console
15
15
  Classifier: Environment :: Console :: Curses
16
16
  Classifier: Intended Audience :: Developers