souleyez 2.43.34__py3-none-any.whl → 3.0.7__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 (326) hide show
  1. souleyez/__init__.py +1 -1
  2. souleyez/ai/__init__.py +7 -7
  3. souleyez/ai/action_mapper.py +3 -2
  4. souleyez/ai/chain_advisor.py +2 -1
  5. souleyez/ai/claude_provider.py +2 -2
  6. souleyez/ai/context_builder.py +4 -2
  7. souleyez/ai/executor.py +9 -6
  8. souleyez/ai/feedback_handler.py +4 -2
  9. souleyez/ai/llm_provider.py +2 -2
  10. souleyez/ai/ollama_provider.py +2 -2
  11. souleyez/ai/ollama_service.py +10 -26
  12. souleyez/ai/path_scorer.py +2 -1
  13. souleyez/ai/recommender.py +6 -4
  14. souleyez/ai/report_context.py +2 -2
  15. souleyez/ai/report_service.py +5 -5
  16. souleyez/ai/result_parser.py +3 -2
  17. souleyez/ai/safety.py +5 -2
  18. souleyez/auth/__init__.py +6 -6
  19. souleyez/auth/audit.py +2 -2
  20. souleyez/auth/engagement_access.py +5 -7
  21. souleyez/auth/permissions.py +1 -1
  22. souleyez/auth/session_manager.py +5 -5
  23. souleyez/auth/user_manager.py +4 -5
  24. souleyez/commands/audit.py +6 -5
  25. souleyez/commands/auth.py +6 -5
  26. souleyez/commands/deliverables.py +2 -3
  27. souleyez/commands/engagement.py +3 -3
  28. souleyez/commands/license.py +3 -2
  29. souleyez/commands/screenshots.py +5 -4
  30. souleyez/commands/user.py +10 -8
  31. souleyez/config.py +4 -2
  32. souleyez/core/credential_tester.py +4 -2
  33. souleyez/core/cve_mappings.py +2 -1
  34. souleyez/core/cve_matcher.py +2 -1
  35. souleyez/core/msf_auto_mapper.py +2 -0
  36. souleyez/core/msf_chain_engine.py +3 -1
  37. souleyez/core/msf_database.py +7 -13
  38. souleyez/core/msf_integration.py +2 -2
  39. souleyez/core/msf_rpc_client.py +3 -2
  40. souleyez/core/msf_rpc_manager.py +4 -4
  41. souleyez/core/msf_sync_manager.py +7 -7
  42. souleyez/core/network_utils.py +1 -1
  43. souleyez/core/parser_handler.py +2 -1
  44. souleyez/core/pending_chains.py +4 -3
  45. souleyez/core/templates.py +5 -2
  46. souleyez/core/tool_chaining.py +297 -230
  47. souleyez/core/version_utils.py +1 -0
  48. souleyez/core/vuln_correlation.py +3 -2
  49. souleyez/core/web_utils.py +2 -1
  50. souleyez/detection/__init__.py +1 -1
  51. souleyez/detection/attack_signatures.py +1 -1
  52. souleyez/detection/mitre_mappings.py +1 -2
  53. souleyez/detection/validator.py +5 -4
  54. souleyez/devtools.py +4 -2
  55. souleyez/docs/README.md +2 -2
  56. souleyez/engine/background.py +168 -7
  57. souleyez/engine/base.py +2 -1
  58. souleyez/engine/loader.py +4 -2
  59. souleyez/engine/log_sanitizer.py +1 -0
  60. souleyez/engine/manager.py +3 -1
  61. souleyez/engine/result_handler.py +50 -67
  62. souleyez/engine/worker_manager.py +6 -4
  63. souleyez/export/evidence_bundle.py +1 -0
  64. souleyez/handlers/base.py +1 -0
  65. souleyez/handlers/bash_handler.py +1 -0
  66. souleyez/handlers/bloodhound_handler.py +1 -0
  67. souleyez/handlers/certipy_handler.py +1 -0
  68. souleyez/handlers/crackmapexec_handler.py +2 -20
  69. souleyez/handlers/dnsrecon_handler.py +2 -1
  70. souleyez/handlers/enum4linux_handler.py +65 -37
  71. souleyez/handlers/evil_winrm_handler.py +1 -0
  72. souleyez/handlers/ffuf_handler.py +3 -1
  73. souleyez/handlers/gobuster_handler.py +7 -6
  74. souleyez/handlers/gpp_extract_handler.py +1 -0
  75. souleyez/handlers/hashcat_handler.py +1 -0
  76. souleyez/handlers/hydra_handler.py +5 -1
  77. souleyez/handlers/impacket_getuserspns_handler.py +1 -0
  78. souleyez/handlers/impacket_psexec_handler.py +1 -0
  79. souleyez/handlers/impacket_secretsdump_handler.py +1 -0
  80. souleyez/handlers/john_handler.py +1 -0
  81. souleyez/handlers/katana_handler.py +39 -2
  82. souleyez/handlers/kerbrute_handler.py +1 -0
  83. souleyez/handlers/ldapsearch_handler.py +90 -17
  84. souleyez/handlers/lfi_extract_handler.py +1 -0
  85. souleyez/handlers/msf_auxiliary_handler.py +2 -0
  86. souleyez/handlers/msf_exploit_handler.py +1 -0
  87. souleyez/handlers/nikto_handler.py +2 -1
  88. souleyez/handlers/nmap_handler.py +2 -1
  89. souleyez/handlers/nuclei_handler.py +2 -1
  90. souleyez/handlers/nxc_handler.py +50 -19
  91. souleyez/handlers/rdp_sec_check_handler.py +1 -0
  92. souleyez/handlers/registry.py +1 -0
  93. souleyez/handlers/responder_handler.py +1 -0
  94. souleyez/handlers/service_explorer_handler.py +2 -1
  95. souleyez/handlers/smbclient_handler.py +1 -0
  96. souleyez/handlers/smbmap_handler.py +3 -2
  97. souleyez/handlers/sqlmap_handler.py +6 -4
  98. souleyez/handlers/theharvester_handler.py +2 -1
  99. souleyez/handlers/web_login_test_handler.py +1 -0
  100. souleyez/handlers/whois_handler.py +3 -2
  101. souleyez/handlers/wpscan_handler.py +2 -1
  102. souleyez/history.py +4 -3
  103. souleyez/importers/msf_importer.py +5 -3
  104. souleyez/importers/smart_importer.py +6 -4
  105. souleyez/integrations/siem/__init__.py +6 -6
  106. souleyez/integrations/siem/base.py +1 -1
  107. souleyez/integrations/siem/elastic.py +3 -3
  108. souleyez/integrations/siem/factory.py +1 -2
  109. souleyez/integrations/siem/googlesecops.py +4 -4
  110. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +1 -1
  111. souleyez/integrations/siem/sentinel.py +3 -3
  112. souleyez/integrations/siem/splunk.py +3 -3
  113. souleyez/integrations/siem/wazuh.py +4 -4
  114. souleyez/integrations/wazuh/__init__.py +1 -1
  115. souleyez/integrations/wazuh/client.py +3 -2
  116. souleyez/integrations/wazuh/config.py +3 -2
  117. souleyez/integrations/wazuh/host_mapper.py +3 -1
  118. souleyez/integrations/wazuh/sync.py +4 -1
  119. souleyez/intelligence/__init__.py +1 -1
  120. souleyez/intelligence/correlation_analyzer.py +6 -5
  121. souleyez/intelligence/exploit_knowledge.py +4 -4
  122. souleyez/intelligence/exploit_suggestions.py +4 -3
  123. souleyez/intelligence/gap_analyzer.py +5 -3
  124. souleyez/intelligence/gap_detector.py +2 -0
  125. souleyez/intelligence/sensitive_tables.py +1 -1
  126. souleyez/intelligence/service_parser.py +1 -0
  127. souleyez/intelligence/surface_analyzer.py +9 -9
  128. souleyez/intelligence/target_parser.py +1 -0
  129. souleyez/licensing/__init__.py +3 -3
  130. souleyez/main.py +25 -18
  131. souleyez/migrations/fix_job_counter.py +2 -1
  132. souleyez/parsers/bloodhound_parser.py +1 -0
  133. souleyez/parsers/crackmapexec_parser.py +2 -1
  134. souleyez/parsers/dalfox_parser.py +3 -2
  135. souleyez/parsers/dnsrecon_parser.py +2 -1
  136. souleyez/parsers/enum4linux_parser.py +2 -1
  137. souleyez/parsers/ffuf_parser.py +2 -1
  138. souleyez/parsers/gobuster_parser.py +2 -1
  139. souleyez/parsers/hashcat_parser.py +3 -2
  140. souleyez/parsers/http_fingerprint_parser.py +2 -1
  141. souleyez/parsers/hydra_parser.py +2 -1
  142. souleyez/parsers/impacket_parser.py +2 -1
  143. souleyez/parsers/john_parser.py +4 -3
  144. souleyez/parsers/katana_parser.py +134 -2
  145. souleyez/parsers/msf_parser.py +2 -1
  146. souleyez/parsers/nikto_parser.py +2 -1
  147. souleyez/parsers/nmap_parser.py +14 -3
  148. souleyez/parsers/nuclei_parser.py +3 -2
  149. souleyez/parsers/responder_parser.py +1 -0
  150. souleyez/parsers/searchsploit_parser.py +3 -2
  151. souleyez/parsers/service_explorer_parser.py +1 -0
  152. souleyez/parsers/smbmap_parser.py +2 -1
  153. souleyez/parsers/sqlmap_parser.py +36 -2
  154. souleyez/parsers/theharvester_parser.py +2 -1
  155. souleyez/parsers/whois_parser.py +2 -1
  156. souleyez/parsers/wpscan_parser.py +3 -2
  157. souleyez/plugins/afp.py +3 -1
  158. souleyez/plugins/afp_brute.py +3 -1
  159. souleyez/plugins/ard.py +3 -1
  160. souleyez/plugins/bloodhound.py +3 -2
  161. souleyez/plugins/certipy.py +1 -0
  162. souleyez/plugins/crackmapexec.py +11 -7
  163. souleyez/plugins/dalfox.py +5 -2
  164. souleyez/plugins/dns_hijack.py +3 -1
  165. souleyez/plugins/dnsrecon.py +3 -1
  166. souleyez/plugins/enum4linux.py +3 -1
  167. souleyez/plugins/evil_winrm.py +1 -0
  168. souleyez/plugins/ffuf.py +3 -1
  169. souleyez/plugins/firmware_extract.py +3 -2
  170. souleyez/plugins/gobuster.py +6 -3
  171. souleyez/plugins/gpp_extract.py +1 -0
  172. souleyez/plugins/hashcat.py +2 -1
  173. souleyez/plugins/http_fingerprint.py +149 -40
  174. souleyez/plugins/hydra.py +5 -3
  175. souleyez/plugins/impacket_common.py +40 -0
  176. souleyez/plugins/impacket_getnpusers.py +19 -2
  177. souleyez/plugins/impacket_getuserspns.py +158 -0
  178. souleyez/plugins/impacket_psexec.py +19 -2
  179. souleyez/plugins/impacket_secretsdump.py +19 -2
  180. souleyez/plugins/impacket_smbclient.py +19 -2
  181. souleyez/plugins/john.py +2 -1
  182. souleyez/plugins/katana.py +48 -6
  183. souleyez/plugins/kerbrute.py +1 -0
  184. souleyez/plugins/lfi_extract.py +1 -0
  185. souleyez/plugins/macos_ssh.py +3 -1
  186. souleyez/plugins/mdns.py +3 -1
  187. souleyez/plugins/msf_auxiliary.py +3 -2
  188. souleyez/plugins/msf_exploit.py +6 -5
  189. souleyez/plugins/nikto.py +5 -2
  190. souleyez/plugins/nmap.py +6 -4
  191. souleyez/plugins/nuclei.py +3 -1
  192. souleyez/plugins/nxc.py +1 -0
  193. souleyez/plugins/plugin_base.py +3 -2
  194. souleyez/plugins/plugin_template.py +3 -2
  195. souleyez/plugins/rdp_sec_check.py +1 -0
  196. souleyez/plugins/responder.py +2 -1
  197. souleyez/plugins/router_http_brute.py +3 -1
  198. souleyez/plugins/router_ssh_brute.py +3 -1
  199. souleyez/plugins/router_telnet_brute.py +3 -1
  200. souleyez/plugins/routersploit.py +5 -3
  201. souleyez/plugins/routersploit_exploit.py +5 -3
  202. souleyez/plugins/searchsploit.py +1 -0
  203. souleyez/plugins/service_explorer.py +2 -1
  204. souleyez/plugins/smbmap.py +3 -1
  205. souleyez/plugins/smbpasswd.py +1 -0
  206. souleyez/plugins/sqlmap.py +3 -1
  207. souleyez/plugins/theharvester.py +3 -1
  208. souleyez/plugins/tr069.py +3 -1
  209. souleyez/plugins/upnp.py +3 -1
  210. souleyez/plugins/upnp_abuse.py +4 -2
  211. souleyez/plugins/vnc_access.py +4 -2
  212. souleyez/plugins/vnc_brute.py +3 -1
  213. souleyez/plugins/web_login_test.py +1 -0
  214. souleyez/plugins/whois.py +3 -1
  215. souleyez/plugins/wpscan.py +49 -1
  216. souleyez/reporting/attack_chain.py +2 -1
  217. souleyez/reporting/charts.py +1 -0
  218. souleyez/reporting/compliance_mappings.py +1 -0
  219. souleyez/reporting/detection_report.py +10 -10
  220. souleyez/reporting/formatters.py +7 -12
  221. souleyez/reporting/generator.py +34 -46
  222. souleyez/reporting/metrics.py +2 -1
  223. souleyez/scanner.py +6 -3
  224. souleyez/security/__init__.py +7 -5
  225. souleyez/security/scope_validator.py +5 -4
  226. souleyez/security/validation.py +14 -0
  227. souleyez/security.py +5 -2
  228. souleyez/storage/credentials.py +14 -19
  229. souleyez/storage/crypto.py +7 -4
  230. souleyez/storage/database.py +6 -6
  231. souleyez/storage/db.py +8 -8
  232. souleyez/storage/deliverable_evidence.py +2 -1
  233. souleyez/storage/deliverable_exporter.py +3 -2
  234. souleyez/storage/deliverable_templates.py +2 -1
  235. souleyez/storage/deliverables.py +2 -1
  236. souleyez/storage/engagements.py +6 -4
  237. souleyez/storage/evidence.py +5 -4
  238. souleyez/storage/execution_log.py +4 -2
  239. souleyez/storage/exploit_attempts.py +3 -2
  240. souleyez/storage/exploits.py +3 -1
  241. souleyez/storage/findings.py +3 -1
  242. souleyez/storage/hosts.py +5 -2
  243. souleyez/storage/migrate_to_engagements.py +14 -24
  244. souleyez/storage/migrations/_001_add_credential_enhancements.py +12 -21
  245. souleyez/storage/migrations/_003_add_execution_log.py +8 -13
  246. souleyez/storage/migrations/_005_screenshots.py +2 -4
  247. souleyez/storage/migrations/_006_deliverables.py +2 -4
  248. souleyez/storage/migrations/_007_deliverable_templates.py +4 -8
  249. souleyez/storage/migrations/_008_add_nuclei_table.py +2 -4
  250. souleyez/storage/migrations/_010_evidence_linking.py +6 -12
  251. souleyez/storage/migrations/_012_team_collaboration.py +12 -24
  252. souleyez/storage/migrations/_013_add_host_tags.py +2 -4
  253. souleyez/storage/migrations/_014_exploit_attempts.py +10 -20
  254. souleyez/storage/migrations/_015_add_mac_os_fields.py +4 -8
  255. souleyez/storage/migrations/_016_add_domain_field.py +2 -4
  256. souleyez/storage/migrations/_017_msf_sessions.py +8 -16
  257. souleyez/storage/migrations/_018_add_osint_target.py +4 -8
  258. souleyez/storage/migrations/_019_add_engagement_type.py +4 -8
  259. souleyez/storage/migrations/_020_add_rbac.py +9 -17
  260. souleyez/storage/migrations/_021_wazuh_integration.py +4 -8
  261. souleyez/storage/migrations/_023_fix_detection_results_fk.py +2 -4
  262. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +4 -8
  263. souleyez/storage/migrations/_026_add_engagement_scope.py +4 -8
  264. souleyez/storage/migrations/_027_multi_siem_persistence.py +8 -16
  265. souleyez/storage/migrations/__init__.py +1 -4
  266. souleyez/storage/migrations/migration_manager.py +6 -9
  267. souleyez/storage/msf_sessions.py +1 -1
  268. souleyez/storage/osint.py +3 -1
  269. souleyez/storage/recommendation_engine.py +3 -2
  270. souleyez/storage/screenshots.py +2 -1
  271. souleyez/storage/smb_shares.py +3 -1
  272. souleyez/storage/sqlmap_data.py +6 -4
  273. souleyez/storage/team_collaboration.py +3 -2
  274. souleyez/storage/timeline_tracker.py +2 -1
  275. souleyez/storage/wazuh_vulns.py +3 -1
  276. souleyez/storage/web_paths.py +3 -1
  277. souleyez/testing/credential_tester.py +2 -0
  278. souleyez/ui/__init__.py +2 -1
  279. souleyez/ui/ai_quotes.py +1 -1
  280. souleyez/ui/attack_surface.py +50 -28
  281. souleyez/ui/chain_rules_view.py +6 -3
  282. souleyez/ui/correlation_view.py +3 -2
  283. souleyez/ui/dashboard.py +85 -139
  284. souleyez/ui/deliverables_view.py +1 -1
  285. souleyez/ui/design_system.py +5 -3
  286. souleyez/ui/errors.py +3 -1
  287. souleyez/ui/evidence_linking_view.py +2 -1
  288. souleyez/ui/evidence_vault.py +11 -6
  289. souleyez/ui/exploit_suggestions_view.py +11 -7
  290. souleyez/ui/export_view.py +3 -1
  291. souleyez/ui/gap_analysis_view.py +6 -3
  292. souleyez/ui/help_system.py +4 -1
  293. souleyez/ui/intelligence_view.py +7 -3
  294. souleyez/ui/interactive.py +1512 -584
  295. souleyez/ui/interactive_selector.py +3 -2
  296. souleyez/ui/log_formatter.py +1 -0
  297. souleyez/ui/menu_components.py +3 -1
  298. souleyez/ui/msf_auxiliary_menu.py +4 -1
  299. souleyez/ui/pending_chains_view.py +15 -12
  300. souleyez/ui/progress_indicators.py +5 -2
  301. souleyez/ui/recommendations_view.py +4 -2
  302. souleyez/ui/rule_builder.py +4 -1
  303. souleyez/ui/setup_wizard.py +10 -8
  304. souleyez/ui/shortcuts.py +1 -1
  305. souleyez/ui/splunk_gap_analysis_view.py +7 -4
  306. souleyez/ui/splunk_vulns_view.py +4 -1
  307. souleyez/ui/team_dashboard.py +7 -5
  308. souleyez/ui/template_selector.py +2 -1
  309. souleyez/ui/terminal.py +3 -2
  310. souleyez/ui/timeline_view.py +2 -1
  311. souleyez/ui/tool_setup.py +92 -31
  312. souleyez/ui/tutorial.py +7 -4
  313. souleyez/ui/tutorial_state.py +3 -2
  314. souleyez/ui/wazuh_vulns_view.py +5 -2
  315. souleyez/ui/wordlist_browser.py +4 -3
  316. souleyez/ui.py +13 -7
  317. souleyez/utils/tool_checker.py +61 -12
  318. souleyez/utils.py +4 -4
  319. souleyez/wordlists.py +1 -0
  320. {souleyez-2.43.34.dist-info → souleyez-3.0.7.dist-info}/METADATA +2 -2
  321. souleyez-3.0.7.dist-info/RECORD +445 -0
  322. souleyez-2.43.34.dist-info/RECORD +0 -443
  323. {souleyez-2.43.34.dist-info → souleyez-3.0.7.dist-info}/WHEEL +0 -0
  324. {souleyez-2.43.34.dist-info → souleyez-3.0.7.dist-info}/entry_points.txt +0 -0
  325. {souleyez-2.43.34.dist-info → souleyez-3.0.7.dist-info}/licenses/LICENSE +0 -0
  326. {souleyez-2.43.34.dist-info → souleyez-3.0.7.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ souleyez.core.version_utils
5
5
  Semantic version parsing and comparison for version-aware tool chaining.
6
6
  Supports conditions like: version:nginx:<1.19, version:apache:>=2.4.49,<=2.4.50
7
7
  """
8
+
8
9
  import re
9
10
  from dataclasses import dataclass
10
11
  from enum import Enum
@@ -8,9 +8,10 @@ Analyzes findings from multiple tools to:
8
8
  3. Prioritize findings based on correlation
9
9
  4. Suggest exploit paths
10
10
  """
11
- from typing import List, Dict, Any, Optional
12
- from dataclasses import dataclass, field
11
+
13
12
  import re
13
+ from dataclasses import dataclass, field
14
+ from typing import Any, Dict, List, Optional
14
15
 
15
16
 
16
17
  @dataclass
@@ -4,10 +4,11 @@ Web utility functions for SoulEyez.
4
4
  Includes HTTP redirect detection and other web-related helpers.
5
5
  """
6
6
 
7
- import requests
8
7
  from typing import Dict, Optional
9
8
  from urllib.parse import urlparse
10
9
 
10
+ import requests
11
+
11
12
 
12
13
  def check_http_redirect(ip: str, port: int = 80, timeout: int = 3) -> Dict[str, any]:
13
14
  """
@@ -1,7 +1,7 @@
1
1
  # SoulEyez Detection Validation
2
2
  # Correlates attacks with SIEM detections
3
3
 
4
- from .validator import DetectionValidator
5
4
  from .attack_signatures import ATTACK_SIGNATURES
5
+ from .validator import DetectionValidator
6
6
 
7
7
  __all__ = ["DetectionValidator", "ATTACK_SIGNATURES"]
@@ -5,7 +5,7 @@ Maps SoulEyez tool names to expected Wazuh detection rules and search patterns.
5
5
  Used for correlating attacks with SIEM alerts.
6
6
  """
7
7
 
8
- from typing import Dict, Any, List
8
+ from typing import Any, Dict, List
9
9
 
10
10
  # Detection window in seconds after attack completes
11
11
  DEFAULT_DETECTION_WINDOW = 300 # 5 minutes
@@ -5,9 +5,8 @@ Maps SoulEyez attack tools to MITRE ATT&CK techniques and tactics.
5
5
  Used for generating detection coverage reports with ATT&CK heatmaps.
6
6
  """
7
7
 
8
- from typing import Dict, List, Any, Optional
9
8
  from dataclasses import dataclass, field
10
-
9
+ from typing import Any, Dict, List, Optional
11
10
 
12
11
  # MITRE ATT&CK Tactics (Enterprise Matrix)
13
12
  # Reference: https://attack.mitre.org/tactics/enterprise/
@@ -9,13 +9,14 @@ Supports multiple SIEM platforms: Wazuh, Splunk, Elastic, Sentinel.
9
9
 
10
10
  import json
11
11
  import os
12
+ from dataclasses import asdict, dataclass, field
12
13
  from datetime import datetime, timedelta
13
- from dataclasses import dataclass, field, asdict
14
- from typing import List, Dict, Any, Optional
14
+ from typing import Any, Dict, List, Optional
15
15
 
16
+ from souleyez.integrations.siem import SIEMClient, SIEMFactory
16
17
  from souleyez.storage.database import get_db
17
- from souleyez.integrations.siem import SIEMFactory, SIEMClient
18
- from .attack_signatures import get_signature, DEFAULT_DETECTION_WINDOW
18
+
19
+ from .attack_signatures import DEFAULT_DETECTION_WINDOW, get_signature
19
20
 
20
21
  # Job queue file location (same as background.py)
21
22
  DATA_DIR = os.path.join(os.path.expanduser("~"), ".souleyez", "data")
souleyez/devtools.py CHANGED
@@ -9,11 +9,13 @@ Command: souleyez dev repair
9
9
  - Verifies installed version and import path
10
10
  - Prints helpful guidance (no destructive data ops)
11
11
  """
12
+
12
13
  from __future__ import annotations
14
+
13
15
  import os
14
- import sys
15
- import subprocess
16
16
  import shutil
17
+ import subprocess
18
+ import sys
17
19
  from pathlib import Path
18
20
 
19
21
  CSI = "\033["
souleyez/docs/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # SoulEyez Documentation
2
2
 
3
- **Version:** 2.43.34
4
- **Last Updated:** January 26, 2026
3
+ **Version:** 3.0.7
4
+ **Last Updated:** January 31, 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.
@@ -73,6 +73,10 @@ TRANSIENT_ERROR_PATTERNS = [
73
73
  "Resource temporarily unavailable",
74
74
  "SMBTimeout",
75
75
  "timed out while waiting",
76
+ # Impacket-specific timeout patterns
77
+ "] timed out", # Matches: [Errno Connection error (IP:port)] timed out
78
+ "RemoteOperations failed", # Impacket remote operation failures
79
+ "Errno Connection error", # Generic Impacket connection errors
76
80
  ]
77
81
 
78
82
  _lock = threading.RLock() # Reentrant lock allows nested acquisition by same thread
@@ -88,6 +92,40 @@ def _is_transient_error(log_content: str) -> bool:
88
92
  return False
89
93
 
90
94
 
95
+ def _is_netexec_flaky_empty(log_content: str, job: dict) -> bool:
96
+ """
97
+ Check if netexec/crackmapexec produced no output (flaky ARM behavior).
98
+
99
+ On ARM, netexec is ~20% flaky - it exits 0 but sometimes produces
100
+ zero output. This detects ONLY that case.
101
+
102
+ DOES NOT retry when:
103
+ - Access denied (has "[-]" error output)
104
+ - Connected but no shares (legitimate result)
105
+ - Any netexec output exists
106
+ """
107
+ tool = job.get("tool", "").lower()
108
+ args = job.get("args", [])
109
+
110
+ if tool not in ("crackmapexec", "nxc", "netexec"):
111
+ return False
112
+
113
+ args_str = " ".join(args).lower() if args else ""
114
+ if "--shares" not in args_str and "smb" not in args_str:
115
+ return False
116
+
117
+ lower = log_content.lower()
118
+
119
+ # If we got ANY netexec output, it's a real response - don't retry
120
+ # This includes error output like "[-]" which indicates access denied
121
+ has_any_output = any(
122
+ x in lower for x in ["smb", "[*]", "[+]", "[-]", "445", "signing"]
123
+ )
124
+
125
+ # Only retry if truly zero output (ARM flakiness)
126
+ return not has_any_output
127
+
128
+
91
129
  class _CrossProcessLock:
92
130
  """
93
131
  Cross-process file lock using fcntl.flock().
@@ -1516,6 +1554,78 @@ def _is_stdbuf_available() -> bool:
1516
1554
  return _stdbuf_available
1517
1555
 
1518
1556
 
1557
+ def _is_python_tool(cmd: List[str]) -> bool:
1558
+ """
1559
+ Check if a command is a Python-based tool.
1560
+
1561
+ stdbuf doesn't work well with Python scripts because Python manages its own
1562
+ buffering internally. On some systems (especially ARM), stdbuf can prevent
1563
+ Python tools from producing any output at all.
1564
+
1565
+ Args:
1566
+ cmd: Command array to check
1567
+
1568
+ Returns:
1569
+ True if the command is a Python tool that should skip stdbuf
1570
+ """
1571
+ if not cmd:
1572
+ return False
1573
+
1574
+ executable = cmd[0]
1575
+
1576
+ # Direct Python invocation
1577
+ if executable in ("python", "python3") or executable.startswith("python"):
1578
+ return True
1579
+
1580
+ # .py extension
1581
+ if executable.endswith(".py"):
1582
+ return True
1583
+
1584
+ # Known Python tools that don't work with stdbuf
1585
+ # These are tools installed via pip/pipx that are Python scripts
1586
+ python_tools = {
1587
+ "netexec",
1588
+ "nxc",
1589
+ "crackmapexec",
1590
+ "cme",
1591
+ "smbmap",
1592
+ "impacket-GetNPUsers",
1593
+ "impacket-GetUserSPNs",
1594
+ "impacket-secretsdump",
1595
+ "impacket-psexec",
1596
+ "impacket-smbclient",
1597
+ "impacket-wmiexec",
1598
+ "impacket-dcomexec",
1599
+ "impacket-atexec",
1600
+ "GetNPUsers.py",
1601
+ "GetUserSPNs.py",
1602
+ "secretsdump.py",
1603
+ "psexec.py",
1604
+ "smbclient.py",
1605
+ "certipy",
1606
+ "bloodhound-python",
1607
+ "ldapdomaindump",
1608
+ }
1609
+
1610
+ # Check base name (handle full paths)
1611
+ base_name = os.path.basename(executable)
1612
+ if base_name in python_tools:
1613
+ return True
1614
+
1615
+ # Check shebang for Python interpreter
1616
+ exe_path = shutil.which(executable)
1617
+ if exe_path:
1618
+ try:
1619
+ with open(exe_path, "rb") as f:
1620
+ first_bytes = f.read(100)
1621
+ if first_bytes.startswith(b"#!") and b"python" in first_bytes:
1622
+ return True
1623
+ except (IOError, OSError):
1624
+ pass
1625
+
1626
+ return False
1627
+
1628
+
1519
1629
  def _wrap_cmd_for_line_buffering(cmd: List[str]) -> List[str]:
1520
1630
  """
1521
1631
  Wrap a command with stdbuf for line-buffered output when available.
@@ -1524,6 +1634,9 @@ def _wrap_cmd_for_line_buffering(cmd: List[str]) -> List[str]:
1524
1634
  improving real-time log monitoring and ensuring output is captured
1525
1635
  before process termination.
1526
1636
 
1637
+ Note: Python tools are excluded because stdbuf interferes with Python's
1638
+ internal buffering and can cause zero output on some systems (Ubuntu ARM).
1639
+
1527
1640
  Args:
1528
1641
  cmd: Command to wrap
1529
1642
 
@@ -1533,6 +1646,10 @@ def _wrap_cmd_for_line_buffering(cmd: List[str]) -> List[str]:
1533
1646
  if not cmd:
1534
1647
  return cmd
1535
1648
 
1649
+ # Skip stdbuf for Python tools - causes output capture failures on ARM
1650
+ if _is_python_tool(cmd):
1651
+ return cmd
1652
+
1536
1653
  if _is_stdbuf_available():
1537
1654
  # stdbuf -oL = line-buffered stdout, -eL = line-buffered stderr
1538
1655
  return ["stdbuf", "-oL", "-eL"] + cmd
@@ -2064,21 +2181,30 @@ def run_job(jid: int) -> None:
2064
2181
  job = get_job(jid)
2065
2182
  retry_count = job.get("metadata", {}).get("retry_count", 0)
2066
2183
  if retry_count < MAX_RETRIES:
2067
- # Read log to check for transient errors
2068
- # Note: Check even when rc==0 because tools like nxc may exit 0 but log errors
2184
+ # Read log to check for transient errors or flaky netexec
2069
2185
  log_path = job.get("log", "")
2070
2186
  if log_path and os.path.exists(log_path):
2071
2187
  try:
2072
2188
  with open(log_path, "r", encoding="utf-8", errors="replace") as f:
2073
2189
  log_content = f.read()
2074
- if _is_transient_error(log_content):
2075
- # Transient error detected - auto-retry
2190
+
2191
+ # Check for transient errors OR flaky netexec (connected but no shares)
2192
+ is_transient = _is_transient_error(log_content)
2193
+ is_netexec_flaky = _is_netexec_flaky_empty(log_content, job)
2194
+ retry_reason = None
2195
+
2196
+ if is_transient:
2197
+ retry_reason = "transient error"
2198
+ elif is_netexec_flaky:
2199
+ retry_reason = "netexec connected but no shares"
2200
+
2201
+ if retry_reason:
2076
2202
  logger.info(
2077
- "Transient error detected, auto-retrying job",
2203
+ f"Auto-retrying job: {retry_reason}",
2078
2204
  extra={"job_id": jid, "retry_count": retry_count + 1},
2079
2205
  )
2080
2206
  _append_worker_log(
2081
- f"job {jid}: transient error detected, auto-retry {retry_count + 1}/{MAX_RETRIES}"
2207
+ f"job {jid}: {retry_reason}, auto-retry {retry_count + 1}/{MAX_RETRIES}"
2082
2208
  )
2083
2209
 
2084
2210
  # Build new job metadata with incremented retry count
@@ -2095,7 +2221,7 @@ def run_job(jid: int) -> None:
2095
2221
  engagement_id=job.get("engagement_id"),
2096
2222
  metadata=new_metadata,
2097
2223
  parent_id=job.get("metadata", {}).get("parent_id"),
2098
- reason=f"Auto-retry {retry_count + 1}/{MAX_RETRIES} (transient error)",
2224
+ reason=f"Auto-retry {retry_count + 1}/{MAX_RETRIES} ({retry_reason})",
2099
2225
  rule_id=job.get("metadata", {}).get("rule_id"),
2100
2226
  skip_scope_check=True, # Already validated on first run
2101
2227
  )
@@ -2120,6 +2246,41 @@ def run_job(jid: int) -> None:
2120
2246
 
2121
2247
  # Re-fetch job to get updated data
2122
2248
  job = get_job(jid)
2249
+
2250
+ # Ensure log file is fully flushed to disk before parsing
2251
+ # Some tools (especially Python-based like impacket) may have buffered output
2252
+ log_path = job.get("log", "")
2253
+ if log_path and os.path.exists(log_path):
2254
+ # Wait for completion marker with retries
2255
+ # Log files end with "Exit Code:" or "=== Completed"
2256
+ max_retries = 5
2257
+ retry_delay = 0.2 # 200ms between retries
2258
+ log_complete = False
2259
+
2260
+ for attempt in range(max_retries):
2261
+ try:
2262
+ with open(
2263
+ log_path, "r", encoding="utf-8", errors="replace"
2264
+ ) as f:
2265
+ content = f.read()
2266
+ # Check for completion markers
2267
+ if "Exit Code:" in content or "=== Completed" in content:
2268
+ log_complete = True
2269
+ break
2270
+ except Exception:
2271
+ pass
2272
+
2273
+ if attempt < max_retries - 1:
2274
+ time.sleep(retry_delay)
2275
+
2276
+ if not log_complete:
2277
+ # Last resort: force filesystem sync and proceed anyway
2278
+ try:
2279
+ with open(log_path, "a") as f:
2280
+ os.fsync(f.fileno())
2281
+ except Exception:
2282
+ pass
2283
+
2123
2284
  parse_result = handle_job_result(job)
2124
2285
 
2125
2286
  # Handle parse failure cases
souleyez/engine/base.py CHANGED
@@ -3,7 +3,8 @@
3
3
  Simple plugin base classes and type hints for souleyez.
4
4
  Plugins should implement ScannerPlugin.run(prepared) -> dict (ScanResult).
5
5
  """
6
- from typing import Dict, Any, Optional
6
+
7
+ from typing import Any, Dict, Optional
7
8
 
8
9
  ScanResult = Dict[str, Any]
9
10
 
souleyez/engine/loader.py CHANGED
@@ -2,10 +2,12 @@
2
2
  """
3
3
  Simple plugin loader for souleyez (L1).
4
4
  """
5
+
5
6
  from __future__ import annotations
6
- import pkgutil
7
+
7
8
  import importlib
8
- from typing import Dict, Any
9
+ import pkgutil
10
+ from typing import Any, Dict
9
11
 
10
12
 
11
13
  def _safe_import_module(fullname: str):
@@ -5,6 +5,7 @@ souleyez.engine.log_sanitizer - Sanitize sensitive data from logs
5
5
  Redacts credentials and sensitive information from job logs to prevent
6
6
  plaintext password exposure, while maintaining log readability.
7
7
  """
8
+
8
9
  import re
9
10
  from typing import Optional
10
11
 
@@ -6,11 +6,13 @@ This manager contains a small built-in adapter for "nmap" that uses your existin
6
6
  souleyez.scanner.run_nmap function. Later plugins can be added by implementing
7
7
  ScannerPlugin in their own modules and registering them here.
8
8
  """
9
+
10
+ import importlib
9
11
  import threading
10
12
  from typing import Optional
13
+
11
14
  from ..storage.db import init_db, insert_scan, update_scan
12
15
  from ..utils import timestamp_str
13
- import importlib
14
16
 
15
17
  # lazy import existing run_nmap (your project has souleyez/scanner.py)
16
18