souleyez 2.43.26__py3-none-any.whl → 2.43.34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of souleyez might be problematic. Click here for more details.

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 +9526 -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 +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 +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 +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 +854 -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 +173 -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 +223 -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 +23434 -10286
  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.26.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
  353. souleyez-2.43.34.dist-info/RECORD +443 -0
  354. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.26.dist-info/RECORD +0 -379
  356. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
@@ -37,16 +37,16 @@ def _get_job_by_id(job_id: int) -> Optional[Dict[str, Any]]:
37
37
  """Get a single job by ID from the job queue."""
38
38
  jobs = _read_jobs_file()
39
39
  for job in jobs:
40
- if job.get('id') == job_id:
40
+ if job.get("id") == job_id:
41
41
  return job
42
42
  return None
43
43
 
44
44
 
45
45
  def _reconstruct_command(job: Dict[str, Any]) -> str:
46
46
  """Reconstruct the command string from job data."""
47
- tool = job.get('tool', '')
48
- target = job.get('target', '')
49
- args = job.get('args', [])
47
+ tool = job.get("tool", "")
48
+ target = job.get("target", "")
49
+ args = job.get("args", [])
50
50
 
51
51
  # Build command string
52
52
  parts = [tool]
@@ -55,12 +55,13 @@ def _reconstruct_command(job: Dict[str, Any]) -> str:
55
55
  if target and target not in args:
56
56
  parts.append(target)
57
57
 
58
- return ' '.join(parts)
58
+ return " ".join(parts)
59
59
 
60
60
 
61
61
  @dataclass
62
62
  class DetectionResult:
63
63
  """Result of validating detection for a single job."""
64
+
64
65
  job_id: int
65
66
  status: str # 'detected', 'not_detected', 'partial', 'offline', 'unknown'
66
67
  attack_type: str = "" # Tool name (e.g., 'nmap', 'hydra')
@@ -75,6 +76,7 @@ class DetectionResult:
75
76
  @dataclass
76
77
  class EngagementDetectionSummary:
77
78
  """Summary of detection coverage for an engagement."""
79
+
78
80
  engagement_id: int
79
81
  total_attacks: int
80
82
  detected: int
@@ -139,36 +141,36 @@ class DetectionValidator:
139
141
  job = _get_job_by_id(job_id)
140
142
  if not job:
141
143
  return DetectionResult(
142
- job_id=job_id,
143
- status='unknown',
144
- reason="Job not found in queue"
144
+ job_id=job_id, status="unknown", reason="Job not found in queue"
145
145
  )
146
146
 
147
147
  # Verify engagement matches
148
- if job.get('engagement_id') != self.engagement_id:
148
+ if job.get("engagement_id") != self.engagement_id:
149
149
  return DetectionResult(
150
150
  job_id=job_id,
151
- status='unknown',
152
- reason="Job belongs to different engagement"
151
+ status="unknown",
152
+ reason="Job belongs to different engagement",
153
153
  )
154
154
 
155
- job_tool = job.get('tool') or 'unknown'
155
+ job_tool = job.get("tool") or "unknown"
156
156
  job_command = _reconstruct_command(job)
157
157
  # Use started_at or finished_at for execution time
158
- executed_at = job.get('started_at') or job.get('finished_at') or job.get('created_at')
158
+ executed_at = (
159
+ job.get("started_at") or job.get("finished_at") or job.get("created_at")
160
+ )
159
161
  # Job ran successfully if status is done, no_results, or warning
160
162
  # (all of these sent network traffic that should be detectable by SIEM)
161
- job_status = job.get('status', '')
162
- success = job_status in ('done', 'no_results', 'warning')
163
+ job_status = job.get("status", "")
164
+ success = job_status in ("done", "no_results", "warning")
163
165
 
164
166
  # Extract target IP from command (common patterns)
165
167
  target_ip = None
166
- ip_pattern = r'\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b'
168
+ ip_pattern = r"\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
167
169
  ip_matches = re.findall(ip_pattern, job_command)
168
170
  if ip_matches:
169
171
  # Filter out common non-target IPs
170
172
  for ip in ip_matches:
171
- if not ip.startswith('127.') and not ip.startswith('0.'):
173
+ if not ip.startswith("127.") and not ip.startswith("0."):
172
174
  target_ip = ip
173
175
  break
174
176
 
@@ -176,23 +178,23 @@ class DetectionValidator:
176
178
  if not success:
177
179
  return DetectionResult(
178
180
  job_id=job_id,
179
- status='unknown',
181
+ status="unknown",
180
182
  attack_type=job_tool,
181
- target_ip=target_ip or '',
182
- reason=f"Job did not complete successfully"
183
+ target_ip=target_ip or "",
184
+ reason=f"Job did not complete successfully",
183
185
  )
184
186
 
185
187
  # Get attack signature
186
188
  signature = get_signature(job_tool)
187
189
 
188
190
  # Check if offline tool (no network detection expected)
189
- if signature.get('offline'):
191
+ if signature.get("offline"):
190
192
  result = DetectionResult(
191
193
  job_id=job_id,
192
- status='offline',
194
+ status="offline",
193
195
  attack_type=job_tool,
194
- target_ip=target_ip or '',
195
- reason=f"{job_tool} is an offline tool, no network detection expected"
196
+ target_ip=target_ip or "",
197
+ reason=f"{job_tool} is an offline tool, no network detection expected",
196
198
  )
197
199
  self._save_result(result, job_id)
198
200
  return result
@@ -202,28 +204,32 @@ class DetectionValidator:
202
204
  if not client:
203
205
  return DetectionResult(
204
206
  job_id=job_id,
205
- status='unknown',
207
+ status="unknown",
206
208
  attack_type=job_tool,
207
- target_ip=target_ip or '',
208
- reason="SIEM not configured for this engagement"
209
+ target_ip=target_ip or "",
210
+ reason="SIEM not configured for this engagement",
209
211
  )
210
212
 
211
213
  # Parse timestamp
212
214
  try:
213
215
  if isinstance(executed_at, str):
214
- exec_time = datetime.fromisoformat(executed_at.replace('Z', '+00:00').replace(' ', 'T'))
216
+ exec_time = datetime.fromisoformat(
217
+ executed_at.replace("Z", "+00:00").replace(" ", "T")
218
+ )
215
219
  else:
216
220
  exec_time = executed_at or datetime.now()
217
221
  except Exception:
218
222
  exec_time = datetime.now() - timedelta(hours=1)
219
223
 
220
224
  # Query window: 5 minutes before execution to detection_window after
221
- detection_window = signature.get('detection_window_seconds', DEFAULT_DETECTION_WINDOW)
225
+ detection_window = signature.get(
226
+ "detection_window_seconds", DEFAULT_DETECTION_WINDOW
227
+ )
222
228
  query_start = exec_time - timedelta(minutes=5)
223
229
  query_end = exec_time + timedelta(seconds=detection_window)
224
230
 
225
231
  # Get expected rule IDs (convert to strings for compatibility)
226
- expected_rules = signature.get('wazuh_rules', [])
232
+ expected_rules = signature.get("wazuh_rules", [])
227
233
  rule_id_strings = [str(r) for r in expected_rules] if expected_rules else None
228
234
 
229
235
  # Query SIEM for alerts
@@ -233,25 +239,25 @@ class DetectionValidator:
233
239
  end_time=query_end,
234
240
  dest_ip=target_ip, # Target IP is the destination
235
241
  rule_ids=rule_id_strings,
236
- limit=100
242
+ limit=100,
237
243
  )
238
244
  except Exception as e:
239
- siem_type = client.siem_type if client else 'SIEM'
245
+ siem_type = client.siem_type if client else "SIEM"
240
246
  return DetectionResult(
241
247
  job_id=job_id,
242
- status='unknown',
243
- reason=f"Error querying {siem_type}: {str(e)}"
248
+ status="unknown",
249
+ reason=f"Error querying {siem_type}: {str(e)}",
244
250
  )
245
251
 
246
252
  # Also search by patterns if no rule matches
247
- if not alerts and signature.get('search_patterns'):
248
- for pattern in signature['search_patterns'][:3]: # Limit searches
253
+ if not alerts and signature.get("search_patterns"):
254
+ for pattern in signature["search_patterns"][:3]: # Limit searches
249
255
  try:
250
256
  pattern_alerts = client.get_alerts(
251
257
  start_time=query_start,
252
258
  end_time=query_end,
253
259
  search_text=pattern,
254
- limit=50
260
+ limit=50,
255
261
  )
256
262
  alerts.extend(pattern_alerts)
257
263
  except Exception:
@@ -261,51 +267,52 @@ class DetectionValidator:
261
267
  seen_ids = set()
262
268
  unique_alerts = []
263
269
  for alert in alerts:
264
- alert_id = getattr(alert, 'id', None) or str(getattr(alert, 'timestamp', ''))
270
+ alert_id = getattr(alert, "id", None) or str(
271
+ getattr(alert, "timestamp", "")
272
+ )
265
273
  if alert_id not in seen_ids:
266
274
  seen_ids.add(alert_id)
267
275
  unique_alerts.append(alert)
268
276
 
269
277
  # Determine detection status
270
278
  if unique_alerts:
271
- rule_ids = list(set(
272
- getattr(a, 'rule_id', 'unknown')
273
- for a in unique_alerts
274
- ))
279
+ rule_ids = list(
280
+ set(getattr(a, "rule_id", "unknown") for a in unique_alerts)
281
+ )
275
282
  # Convert SIEMAlert dataclass objects to dicts for storage
276
283
  # Include all normalized fields (rule_id, rule_name, severity, etc.)
277
284
  alert_dicts = []
278
285
  for a in unique_alerts[:20]:
279
- if hasattr(a, '__dataclass_fields__'):
286
+ if hasattr(a, "__dataclass_fields__"):
280
287
  # Convert dataclass to dict
281
288
  alert_dict = asdict(a)
282
289
  # Convert datetime to ISO string for JSON serialization
283
- if isinstance(alert_dict.get('timestamp'), datetime):
284
- alert_dict['timestamp'] = alert_dict['timestamp'].isoformat()
290
+ if isinstance(alert_dict.get("timestamp"), datetime):
291
+ alert_dict["timestamp"] = alert_dict["timestamp"].isoformat()
285
292
  alert_dicts.append(alert_dict)
286
293
  elif isinstance(a, dict):
287
294
  alert_dicts.append(a)
288
295
  else:
289
296
  # Fallback: try to extract raw_data or convert to dict
290
- alert_dicts.append(getattr(a, 'raw_data', {}) or {})
297
+ alert_dicts.append(getattr(a, "raw_data", {}) or {})
291
298
  result = DetectionResult(
292
299
  job_id=job_id,
293
- status='detected',
300
+ status="detected",
294
301
  attack_type=job_tool,
295
- target_ip=target_ip or '',
302
+ target_ip=target_ip or "",
296
303
  alerts_count=len(unique_alerts),
297
304
  alerts=alert_dicts,
298
305
  rule_ids=rule_ids,
299
- reason=f"Found {len(unique_alerts)} related alert(s)"
306
+ reason=f"Found {len(unique_alerts)} related alert(s)",
300
307
  )
301
308
  else:
302
309
  result = DetectionResult(
303
310
  job_id=job_id,
304
- status='not_detected',
311
+ status="not_detected",
305
312
  attack_type=job_tool,
306
- target_ip=target_ip or '',
313
+ target_ip=target_ip or "",
307
314
  alerts_count=0,
308
- reason=f"No alerts found for {job_tool} attack on {target_ip}"
315
+ reason=f"No alerts found for {job_tool} attack on {target_ip}",
309
316
  )
310
317
 
311
318
  # Save result to database
@@ -322,21 +329,21 @@ class DetectionValidator:
322
329
  return
323
330
 
324
331
  # Extract target IP from command or use job target
325
- target_ip = job.get('target')
332
+ target_ip = job.get("target")
326
333
  command = _reconstruct_command(job)
327
334
 
328
335
  # Try to extract more specific IP from command
329
- ip_pattern = r'\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b'
336
+ ip_pattern = r"\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
330
337
  ip_matches = re.findall(ip_pattern, command)
331
338
  if ip_matches:
332
339
  for ip in ip_matches:
333
- if not ip.startswith('127.') and not ip.startswith('0.'):
340
+ if not ip.startswith("127.") and not ip.startswith("0."):
334
341
  target_ip = ip
335
342
  break
336
343
 
337
344
  # Get timestamps
338
- attack_start = job.get('started_at') or job.get('created_at')
339
- attack_end = job.get('finished_at') or attack_start
345
+ attack_start = job.get("started_at") or job.get("created_at")
346
+ attack_end = job.get("finished_at") or attack_start
340
347
 
341
348
  db = get_db()
342
349
  conn = db.get_connection()
@@ -346,24 +353,27 @@ class DetectionValidator:
346
353
  cursor.execute("DELETE FROM detection_results WHERE job_id = ?", (job_id,))
347
354
 
348
355
  # Insert new result
349
- cursor.execute("""
356
+ cursor.execute(
357
+ """
350
358
  INSERT INTO detection_results
351
359
  (job_id, engagement_id, attack_type, target_ip, attack_start, attack_end,
352
360
  detection_status, alerts_count, wazuh_alerts_json, rule_ids, checked_at)
353
361
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
354
- """, (
355
- job_id,
356
- self.engagement_id,
357
- job.get('tool'), # attack_type (tool)
358
- target_ip,
359
- attack_start,
360
- attack_end,
361
- result.status,
362
- result.alerts_count,
363
- json.dumps(result.alerts[:20]) if result.alerts else None,
364
- ','.join(result.rule_ids) if result.rule_ids else None,
365
- datetime.now().isoformat()
366
- ))
362
+ """,
363
+ (
364
+ job_id,
365
+ self.engagement_id,
366
+ job.get("tool"), # attack_type (tool)
367
+ target_ip,
368
+ attack_start,
369
+ attack_end,
370
+ result.status,
371
+ result.alerts_count,
372
+ json.dumps(result.alerts[:20]) if result.alerts else None,
373
+ ",".join(result.rule_ids) if result.rule_ids else None,
374
+ datetime.now().isoformat(),
375
+ ),
376
+ )
367
377
  conn.commit()
368
378
 
369
379
  def validate_engagement(self) -> EngagementDetectionSummary:
@@ -378,20 +388,21 @@ class DetectionValidator:
378
388
  # Get all completed jobs for this engagement from job queue
379
389
  all_jobs = _read_jobs_file()
380
390
  completed_jobs = [
381
- job for job in all_jobs
382
- if job.get('engagement_id') == self.engagement_id
383
- and job.get('status') == 'done'
391
+ job
392
+ for job in all_jobs
393
+ if job.get("engagement_id") == self.engagement_id
394
+ and job.get("status") == "done"
384
395
  # Only include known attack tools (filter out echo, cat, etc.)
385
- and job.get('tool', '').lower() in ATTACK_SIGNATURES
396
+ and job.get("tool", "").lower() in ATTACK_SIGNATURES
386
397
  ]
387
398
 
388
399
  # Sort by finished_at descending
389
400
  completed_jobs.sort(
390
- key=lambda j: j.get('finished_at') or j.get('started_at') or '',
391
- reverse=True
401
+ key=lambda j: j.get("finished_at") or j.get("started_at") or "",
402
+ reverse=True,
392
403
  )
393
404
 
394
- job_ids = [job.get('id') for job in completed_jobs if job.get('id') is not None]
405
+ job_ids = [job.get("id") for job in completed_jobs if job.get("id") is not None]
395
406
 
396
407
  if not job_ids:
397
408
  return EngagementDetectionSummary(
@@ -402,7 +413,7 @@ class DetectionValidator:
402
413
  partial=0,
403
414
  offline=0,
404
415
  unknown=0,
405
- coverage_percent=0.0
416
+ coverage_percent=0.0,
406
417
  )
407
418
 
408
419
  # Validate each job
@@ -412,11 +423,11 @@ class DetectionValidator:
412
423
  results.append(result)
413
424
 
414
425
  # Calculate summary
415
- detected = sum(1 for r in results if r.status == 'detected')
416
- not_detected = sum(1 for r in results if r.status == 'not_detected')
417
- partial = sum(1 for r in results if r.status == 'partial')
418
- offline = sum(1 for r in results if r.status == 'offline')
419
- unknown = sum(1 for r in results if r.status == 'unknown')
426
+ detected = sum(1 for r in results if r.status == "detected")
427
+ not_detected = sum(1 for r in results if r.status == "not_detected")
428
+ partial = sum(1 for r in results if r.status == "partial")
429
+ offline = sum(1 for r in results if r.status == "offline")
430
+ unknown = sum(1 for r in results if r.status == "unknown")
420
431
 
421
432
  # Calculate coverage (excluding offline and unknown)
422
433
  countable = detected + not_detected + partial
@@ -431,10 +442,10 @@ class DetectionValidator:
431
442
  offline=offline,
432
443
  unknown=unknown,
433
444
  coverage_percent=round(coverage, 1),
434
- results=results
445
+ results=results,
435
446
  )
436
447
 
437
448
  def get_detection_gaps(self) -> List[DetectionResult]:
438
449
  """Get list of attacks that were NOT detected."""
439
450
  summary = self.validate_engagement()
440
- return [r for r in summary.results if r.status == 'not_detected']
451
+ return [r for r in summary.results if r.status == "not_detected"]
souleyez/devtools.py CHANGED
@@ -16,12 +16,12 @@ import subprocess
16
16
  import shutil
17
17
  from pathlib import Path
18
18
 
19
- CSI = '\033['
20
- RESET = CSI + '0m'
21
- BOLD = CSI + '1m'
22
- GREEN = CSI + '32m'
23
- RED = CSI + '31m'
24
- CYAN = CSI + '36m'
19
+ CSI = "\033["
20
+ RESET = CSI + "0m"
21
+ BOLD = CSI + "1m"
22
+ GREEN = CSI + "32m"
23
+ RED = CSI + "31m"
24
+ CYAN = CSI + "36m"
25
25
 
26
26
 
27
27
  def _ok(msg):
@@ -37,7 +37,9 @@ def _warn(msg):
37
37
 
38
38
 
39
39
  def _run(cmd):
40
- return subprocess.run(cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
40
+ return subprocess.run(
41
+ cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
42
+ )
41
43
 
42
44
 
43
45
  def dev_repair():
@@ -53,13 +55,16 @@ def dev_repair():
53
55
  # 1) Sanity: are we in the repo root (setup.py present)?
54
56
  setup_py = project / "setup.py"
55
57
  if not setup_py.exists():
56
- _warn("setup.py not found in current directory. Run from your project root (e.g., ~/apps/souleyez_app).")
58
+ _warn(
59
+ "setup.py not found in current directory. Run from your project root (e.g., ~/apps/souleyez_app)."
60
+ )
57
61
  return 2
58
62
  _ok("Project root looks good (setup.py found).")
59
63
 
60
64
  # 2) Check import path for souleyez
61
65
  try:
62
66
  import importlib.util
67
+
63
68
  spec = importlib.util.find_spec("souleyez")
64
69
  _info(f"import find_spec: {spec}")
65
70
  except Exception as e:
@@ -76,7 +81,12 @@ def dev_repair():
76
81
 
77
82
  # 5) Clean site-packages leftovers (dist-info + old copies)
78
83
  _info("Cleaning old site-packages metadata...")
79
- site = Path(sys.prefix) / "lib" / f"python{sys.version_info.major}.{sys.version_info.minor}" / "site-packages"
84
+ site = (
85
+ Path(sys.prefix)
86
+ / "lib"
87
+ / f"python{sys.version_info.major}.{sys.version_info.minor}"
88
+ / "site-packages"
89
+ )
80
90
  for pat in ("souleyez-*.dist-info", "souleyez"):
81
91
  for p in site.glob(pat):
82
92
  try:
@@ -107,10 +117,13 @@ def dev_repair():
107
117
  # 9) Verify import location
108
118
  try:
109
119
  import souleyez
120
+
110
121
  _ok(f"'souleyez' imports from: {souleyez.__file__}")
111
122
  except Exception as e:
112
123
  _warn(f"Import failed after reinstall: {e}")
113
124
  return 1
114
125
 
115
- _ok("Dev repair complete. If version still mismatches, ensure no stray pyproject.toml remains and venv is active.")
126
+ _ok(
127
+ "Dev repair complete. If version still mismatches, ensure no stray pyproject.toml remains and venv is active."
128
+ )
116
129
  return 0
souleyez/docs/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # SoulEyez Documentation
2
2
 
3
- **Version:** 2.43.26
4
- **Last Updated:** January 13, 2026
3
+ **Version:** 2.43.34
4
+ **Last Updated:** January 26, 2026
5
5
  **Organization:** CyberSoul Security
6
6
 
7
7
  Welcome to the SoulEyez documentation! This documentation covers architecture, development, user guides, and operational information for the SoulEyez penetration testing platform.
@@ -238,8 +238,8 @@ Legal and compliance documentation.
238
238
 
239
239
  ## 📞 Need Help?
240
240
 
241
- - **Issues**: https://github.com/cybersoul-security/souleyez/issues
242
- - **Discussions**: https://github.com/cybersoul-security/souleyez/discussions
241
+ - **Issues**: https://github.com/cyber-soul-security/SoulEyez/issues
242
+ - **Discussions**: https://github.com/cyber-soul-security/SoulEyez/discussions
243
243
  - **Security**: cysoul.secit@gmail.com
244
244
  - **General**: cysoul.secit@gmail.com
245
245
 
@@ -292,7 +292,7 @@ souleyez jobs enqueue nmap 192.168.1.100 -a "-sS" -l "SYN Scan DC01"
292
292
  souleyez jobs enqueue nikto http://example.com -l "Web Vuln Scan"
293
293
 
294
294
  # Directory enumeration
295
- souleyez jobs enqueue gobuster http://example.com -a "dir -w /usr/share/wordlists/dirb/common.txt"
295
+ souleyez jobs enqueue gobuster http://example.com -a "dir -w data/wordlists/web_dirs_common.txt"
296
296
  ```
297
297
 
298
298
  ---
@@ -801,7 +801,7 @@ souleyez dashboard
801
801
  ### Web Application Testing
802
802
  ```bash
803
803
  souleyez jobs enqueue nikto http://example.com -l "Nikto Scan"
804
- souleyez jobs enqueue gobuster http://example.com -a "dir -w /usr/share/wordlists/dirb/common.txt" -l "Dir Enum"
804
+ souleyez jobs enqueue gobuster http://example.com -a "dir -w data/wordlists/web_dirs_common.txt" -l "Dir Enum"
805
805
  souleyez findings list
806
806
  ```
807
807