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
@@ -4,6 +4,7 @@ Hashcat handler.
4
4
 
5
5
  Consolidates parsing and display logic for Hashcat password cracking jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  from typing import Any, Dict, Optional
@@ -4,6 +4,7 @@ Hydra handler.
4
4
 
5
5
  Consolidates parsing and display logic for Hydra brute-force jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -58,8 +59,8 @@ class HydraHandler(BaseToolHandler):
58
59
  Extracts credentials and usernames from the output.
59
60
  """
60
61
  try:
61
- from souleyez.parsers.hydra_parser import parse_hydra_output
62
62
  from souleyez.engine.result_handler import detect_tool_error
63
+ from souleyez.parsers.hydra_parser import parse_hydra_output
63
64
 
64
65
  # Import managers if not provided
65
66
  if host_manager is None:
@@ -261,6 +262,9 @@ class HydraHandler(BaseToolHandler):
261
262
  "port": parsed.get("port"),
262
263
  "credentials_found": len(parsed.get("credentials", [])),
263
264
  "credentials_added": creds_added,
265
+ "credentials": parsed.get(
266
+ "credentials", []
267
+ ), # Include actual creds for smart chains
264
268
  "usernames_found": len(parsed.get("usernames", [])),
265
269
  "usernames": parsed.get("usernames", []),
266
270
  "usernames_added": usernames_added,
@@ -4,6 +4,7 @@ Impacket GetUserSPNs handler.
4
4
 
5
5
  Handles parsing and display for Kerberoasting results.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -4,6 +4,7 @@ Impacket psexec handler.
4
4
 
5
5
  Consolidates parsing and display logic for Impacket psexec remote execution jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -4,6 +4,7 @@ Impacket secretsdump handler.
4
4
 
5
5
  Consolidates parsing and display logic for Impacket secretsdump credential extraction jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -4,6 +4,7 @@ John the Ripper handler.
4
4
 
5
5
  Consolidates parsing and display logic for John the Ripper password cracking jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  from typing import Any, Dict, Optional
@@ -4,6 +4,7 @@ Katana handler.
4
4
 
5
5
  Consolidates parsing and display logic for katana web crawling jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  from typing import Any, Dict, List, Optional
@@ -49,11 +50,11 @@ class KatanaHandler(BaseToolHandler):
49
50
  Extracts discovered URLs, parameters, forms, and JS endpoints.
50
51
  """
51
52
  try:
53
+ from souleyez.engine.result_handler import detect_tool_error
52
54
  from souleyez.parsers.katana_parser import (
53
- parse_katana_output,
54
55
  extract_injectable_urls,
56
+ parse_katana_output,
55
57
  )
56
- from souleyez.engine.result_handler import detect_tool_error
57
58
 
58
59
  # Import managers if not provided
59
60
  if host_manager is None:
@@ -134,6 +135,42 @@ class KatanaHandler(BaseToolHandler):
134
135
 
135
136
  lfi_urls = extract_lfi_urls(parsed)
136
137
 
138
+ # ARM64/headless workaround: If we have JS files but few parameterized URLs,
139
+ # extract endpoints directly from JavaScript source code
140
+ js_files = [u for u in parsed.get("urls", []) if u.endswith(".js")]
141
+ urls_with_params_list = parsed.get("urls_with_params", [])
142
+ sqli_candidates = parsed.get("sqli_candidate_urls", [])
143
+
144
+ if js_files and len(urls_with_params_list) < 10:
145
+ try:
146
+ from souleyez.parsers.katana_parser import (
147
+ fetch_and_extract_js_endpoints,
148
+ )
149
+
150
+ logger.info(
151
+ f"Extracting endpoints from {len(js_files)} JavaScript files..."
152
+ )
153
+ js_endpoints = fetch_and_extract_js_endpoints(target, js_files)
154
+
155
+ if js_endpoints:
156
+ logger.info(
157
+ f"Found {len(js_endpoints)} additional endpoints from JavaScript"
158
+ )
159
+ # Add to parsed results
160
+ for ep in js_endpoints:
161
+ if ep not in urls_with_params_list:
162
+ urls_with_params_list.append(ep)
163
+ if ep not in sqli_candidates:
164
+ sqli_candidates.append(ep)
165
+ if ep not in injectable_urls:
166
+ injectable_urls.append(ep)
167
+
168
+ # Update parsed dict for display
169
+ parsed["urls_with_params"] = urls_with_params_list
170
+ parsed["sqli_candidate_urls"] = sqli_candidates
171
+ except Exception as e:
172
+ logger.warning(f"JavaScript endpoint extraction failed: {e}")
173
+
137
174
  # Determine status
138
175
  urls_list = parsed.get("urls", [])
139
176
  urls_with_params_list = parsed.get("urls_with_params", [])
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Handler for kerbrute Kerberos enumeration tool.
4
4
  """
5
+
5
6
  import logging
6
7
  import os
7
8
  import re
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Handler for ldapsearch LDAP enumeration tool.
4
4
  """
5
+
5
6
  import logging
6
7
  import os
7
8
  import re
@@ -177,8 +178,8 @@ class LdapsearchHandler(BaseToolHandler):
177
178
  f"{user.get('sAMAccountName')} - check description field"
178
179
  )
179
180
 
180
- # Store credentials if found
181
- if credentials_found and credentials_manager:
181
+ # Store credentials if found AND store enumerated users
182
+ if (credentials_found or usernames) and credentials_manager:
182
183
  if host_manager is None:
183
184
  from souleyez.storage.hosts import HostManager
184
185
 
@@ -186,6 +187,7 @@ class LdapsearchHandler(BaseToolHandler):
186
187
 
187
188
  host = host_manager.get_host_by_ip(engagement_id, target)
188
189
  if host:
190
+ # Store passwords found in descriptions
189
191
  for cred in credentials_found:
190
192
  credentials_manager.add_credential(
191
193
  engagement_id=engagement_id,
@@ -199,6 +201,31 @@ class LdapsearchHandler(BaseToolHandler):
199
201
  notes="Found in LDAP user description field",
200
202
  )
201
203
 
204
+ # Store enumerated usernames (without passwords)
205
+ usernames_stored = 0
206
+ for username in usernames:
207
+ # Skip if already stored with a password
208
+ already_has_cred = any(
209
+ c["username"] == username for c in credentials_found
210
+ )
211
+ if not already_has_cred:
212
+ credentials_manager.add_credential(
213
+ engagement_id=engagement_id,
214
+ host_id=host["id"],
215
+ username=username,
216
+ password="",
217
+ service="ldap",
218
+ credential_type="ldap_user",
219
+ tool="ldapsearch",
220
+ status="enumerated",
221
+ notes="Enumerated via LDAP",
222
+ )
223
+ usernames_stored += 1
224
+ if usernames_stored > 0:
225
+ logger.info(
226
+ f"Stored {usernames_stored} enumerated LDAP usernames"
227
+ )
228
+
202
229
  logger.info(
203
230
  f"ldapsearch parse complete: {len(naming_contexts)} naming contexts, "
204
231
  f"{len(domains)} domains, {len(users)} users, {len(credentials_found)} creds, base_dn={base_dn}"
@@ -420,8 +447,11 @@ class LdapsearchHandler(BaseToolHandler):
420
447
 
421
448
  # New entry starts with "dn:"
422
449
  if line.startswith("dn:"):
450
+ # Save previous entry if it's not explicitly a group
451
+ # Default to including (is_group=False) if no objectClass info
423
452
  if current_user and current_user.get("sAMAccountName"):
424
- users.append(current_user)
453
+ if not current_user.get("is_group", False):
454
+ users.append(current_user)
425
455
  current_user = {}
426
456
  # Extract OU from DN
427
457
  ou_match = re.search(r"OU=([^,]+)", line, re.IGNORECASE)
@@ -448,12 +478,43 @@ class LdapsearchHandler(BaseToolHandler):
448
478
  "key ",
449
479
  "dns",
450
480
  "ras ",
481
+ "cloneable ",
451
482
  )
452
483
  ):
453
484
  current_user["cn_username"] = cn_name.replace(" ", ".")
454
485
 
486
+ elif line.startswith("objectClass:"):
487
+ obj_class = line.split(":", 1)[1].strip().lower()
488
+ # Mark as group if objectClass is group (blacklist approach)
489
+ if obj_class == "group":
490
+ current_user["is_group"] = True
491
+
455
492
  elif line.startswith("sAMAccountName:"):
456
- current_user["sAMAccountName"] = line.split(":", 1)[1].strip()
493
+ sam = line.split(":", 1)[1].strip()
494
+ current_user["sAMAccountName"] = sam
495
+ # Filter out obvious group names by sAMAccountName pattern
496
+ sam_lower = sam.lower()
497
+ if sam_lower in (
498
+ "guest",
499
+ "domain users",
500
+ "domain computers",
501
+ "domain guests",
502
+ "domain admins",
503
+ "enterprise admins",
504
+ "schema admins",
505
+ "cert publishers",
506
+ "group policy creator owners",
507
+ "ras and ias servers",
508
+ "allowed rodc password replication group",
509
+ "denied rodc password replication group",
510
+ "read-only domain controllers",
511
+ "enterprise read-only domain controllers",
512
+ "cloneable domain controllers",
513
+ "protected users",
514
+ "dnsadmins",
515
+ "dnsupdateproxy",
516
+ ):
517
+ current_user["is_group"] = True
457
518
 
458
519
  elif line.startswith("description:"):
459
520
  current_user["description"] = line.split(":", 1)[1].strip()
@@ -466,9 +527,10 @@ class LdapsearchHandler(BaseToolHandler):
466
527
  if cn_match:
467
528
  current_user["memberOf"].append(cn_match.group(1))
468
529
 
469
- # Don't forget last user
530
+ # Don't forget last user - only if it's not a group
470
531
  if current_user and current_user.get("sAMAccountName"):
471
- users.append(current_user)
532
+ if not current_user.get("is_group", False):
533
+ users.append(current_user)
472
534
 
473
535
  # Second pass: add users found only via CN (no sAMAccountName returned)
474
536
  # This catches users from broader queries like (objectClass=*)
@@ -476,9 +538,11 @@ class LdapsearchHandler(BaseToolHandler):
476
538
  for line in log_content.split("\n"):
477
539
  line = line.strip()
478
540
  if line.startswith("dn:"):
479
- if current_user.get("cn_username") and not current_user.get(
480
- "sAMAccountName"
481
- ):
541
+ if (
542
+ current_user.get("cn_username")
543
+ and not current_user.get("sAMAccountName")
544
+ and not current_user.get("is_group", False)
545
+ ): # Default to user if no objectClass
482
546
  # Check if we already have this user
483
547
  existing = [
484
548
  u
@@ -507,24 +571,33 @@ class LdapsearchHandler(BaseToolHandler):
507
571
  "key ",
508
572
  "dns",
509
573
  "ras ",
574
+ "cloneable ",
510
575
  )
511
576
  ):
512
577
  current_user["cn_username"] = cn_name.replace(" ", ".")
513
578
  if ou_match:
514
579
  current_user["ou"] = ou_match.group(1)
580
+ elif line.startswith("objectClass:"):
581
+ obj_class = line.split(":", 1)[1].strip().lower()
582
+ # Blacklist groups - mark as group if objectClass is group
583
+ if obj_class == "group":
584
+ current_user["is_group"] = True
515
585
  elif line.startswith("sAMAccountName:"):
516
586
  current_user["sAMAccountName"] = line.split(":", 1)[1].strip()
517
587
 
518
588
  # Last entry from second pass
519
589
  if current_user.get("cn_username") and not current_user.get("sAMAccountName"):
520
- existing = [
521
- u
522
- for u in users
523
- if u.get("sAMAccountName") == current_user.get("cn_username")
524
- ]
525
- if not existing:
526
- current_user["sAMAccountName"] = current_user["cn_username"]
527
- users.append(current_user)
590
+ if not current_user.get(
591
+ "is_group", False
592
+ ): # Default to user if no objectClass
593
+ existing = [
594
+ u
595
+ for u in users
596
+ if u.get("sAMAccountName") == current_user.get("cn_username")
597
+ ]
598
+ if not existing:
599
+ current_user["sAMAccountName"] = current_user["cn_username"]
600
+ users.append(current_user)
528
601
 
529
602
  return users
530
603
 
@@ -4,6 +4,7 @@ souleyez.handlers.lfi_extract_handler - Handler for LFI credential extraction
4
4
 
5
5
  Parses LFI extract results and stores discovered credentials in the database.
6
6
  """
7
+
7
8
  import json
8
9
  import logging
9
10
  import os
@@ -4,6 +4,7 @@ Metasploit auxiliary handler.
4
4
 
5
5
  Consolidates parsing and display logic for msf_auxiliary jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -165,6 +166,7 @@ class MsfAuxiliaryHandler(BaseToolHandler):
165
166
  credential_summaries.append(
166
167
  {
167
168
  "username": cred.get("username", ""),
169
+ "password": cred.get("password", ""),
168
170
  "service": cred.get("service", "unknown"),
169
171
  "port": cred.get("port"),
170
172
  }
@@ -4,6 +4,7 @@ Metasploit exploit handler.
4
4
 
5
5
  Consolidates parsing and display logic for msf_exploit jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -4,6 +4,7 @@ Nikto handler.
4
4
 
5
5
  Consolidates parsing and display logic for nikto web scanner jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -45,8 +46,8 @@ class NiktoHandler(BaseToolHandler):
45
46
  Extracts web server issues and stores them as findings.
46
47
  """
47
48
  try:
48
- from souleyez.parsers.nikto_parser import parse_nikto_output
49
49
  from souleyez.engine.result_handler import detect_tool_error
50
+ from souleyez.parsers.nikto_parser import parse_nikto_output
50
51
 
51
52
  # Import managers if not provided
52
53
  if host_manager is None:
@@ -4,6 +4,7 @@ Nmap handler.
4
4
 
5
5
  Consolidates parsing and display logic for nmap and ARD (which uses nmap) jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -70,9 +71,9 @@ class NmapHandler(BaseToolHandler):
70
71
  Imports hosts/services into database and creates findings for CVEs.
71
72
  """
72
73
  try:
73
- from souleyez.parsers.nmap_parser import parse_nmap_log
74
74
  from souleyez.core.cve_matcher import CVEMatcher
75
75
  from souleyez.engine.result_handler import detect_tool_error
76
+ from souleyez.parsers.nmap_parser import parse_nmap_log
76
77
 
77
78
  # Import managers if not provided
78
79
  if host_manager is None:
@@ -4,6 +4,7 @@ Nuclei handler.
4
4
 
5
5
  Consolidates parsing and display logic for nuclei vulnerability scanning jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -48,8 +49,8 @@ class NucleiHandler(BaseToolHandler):
48
49
  Extracts vulnerabilities and stores them as findings.
49
50
  """
50
51
  try:
51
- from souleyez.parsers.nuclei_parser import parse_nuclei
52
52
  from souleyez.engine.result_handler import detect_tool_error
53
+ from souleyez.parsers.nuclei_parser import parse_nuclei
53
54
 
54
55
  # Import managers if not provided
55
56
  if host_manager is None:
@@ -3,6 +3,7 @@
3
3
  Handler for NetExec (nxc) - successor to CrackMapExec.
4
4
  Parses shares, credentials, and authentication results.
5
5
  """
6
+
6
7
  import logging
7
8
  import os
8
9
  import re
@@ -77,10 +78,51 @@ class NxcHandler(BaseToolHandler):
77
78
  hostname = banner_match.group(1)
78
79
  domain = banner_match.group(2)
79
80
 
80
- # Check for Pwn3d
81
+ # Check for Pwn3d (SMB admin access)
81
82
  if re.search(self.PWNED_PATTERN, log_content):
82
83
  is_pwned = True
83
84
 
85
+ # Check for SSH Shell access (Linux)
86
+ # Format: [+] leia_organa:help_me_obiwan Linux - Shell access!
87
+ has_shell_access = False
88
+ if "Shell access!" in log_content:
89
+ has_shell_access = True
90
+ # Parse SSH credentials
91
+ ssh_cred_pattern = r"\[\+\]\s+([^:\s]+):(\S+)\s+.*Shell access!"
92
+ for match in re.finditer(ssh_cred_pattern, log_content):
93
+ username = match.group(1)
94
+ password = match.group(2)
95
+ cred = {
96
+ "username": username,
97
+ "password": password,
98
+ "domain": "",
99
+ "service": "ssh",
100
+ "status": "valid",
101
+ }
102
+ credentials.append(cred)
103
+
104
+ # Store in database
105
+ if credentials_manager and host_manager:
106
+ try:
107
+ host = host_manager.get_host_by_ip(engagement_id, target)
108
+ if host:
109
+ credentials_manager.add_credential(
110
+ engagement_id=engagement_id,
111
+ host_id=host["id"],
112
+ username=username,
113
+ password=password,
114
+ service="ssh",
115
+ port=22,
116
+ credential_type="password",
117
+ tool="nxc",
118
+ status="valid",
119
+ )
120
+ logger.warning(
121
+ f"SSH SHELL ACCESS: {username}:{password} on {target}"
122
+ )
123
+ except Exception as e:
124
+ logger.debug(f"Could not store SSH credential: {e}")
125
+
84
126
  # Parse valid credentials
85
127
  # Format: [+] baby2.vl\Carl.Moore:Carl.Moore
86
128
  for match in re.finditer(self.VALID_CRED_PATTERN, log_content):
@@ -218,30 +260,16 @@ class NxcHandler(BaseToolHandler):
218
260
  if "WRITE" in perms:
219
261
  writable_shares.append(share)
220
262
 
221
- # Determine status
222
- # Check for transient errors first (should trigger retry)
223
- transient_errors = [
224
- "NetBIOSTimeout",
225
- "connection timed out",
226
- "Connection reset",
227
- ]
228
- has_transient_error = any(
229
- err.lower() in log_content.lower() for err in transient_errors
230
- )
231
-
263
+ # Determine status based on results found
264
+ # Retry logic is handled by background.py before parsing
232
265
  if credentials:
233
266
  status = STATUS_DONE
267
+ elif has_shell_access:
268
+ status = STATUS_DONE # SSH shell access without parsed creds
234
269
  elif expired_credentials:
235
270
  status = STATUS_WARNING # Expired creds need attention
236
271
  elif shares:
237
272
  status = STATUS_DONE
238
- elif has_transient_error:
239
- status = STATUS_WARNING # Transient error - may be retried
240
- elif (
241
- "STATUS_LOGON_FAILURE" in log_content
242
- or "STATUS_ACCESS_DENIED" in log_content
243
- ):
244
- status = STATUS_NO_RESULTS
245
273
  else:
246
274
  status = STATUS_NO_RESULTS
247
275
 
@@ -255,6 +283,8 @@ class NxcHandler(BaseToolHandler):
255
283
  )
256
284
  if is_pwned:
257
285
  summary_parts.append("PWNED!")
286
+ if has_shell_access:
287
+ summary_parts.append("SHELL ACCESS!")
258
288
  if shares:
259
289
  summary_parts.append(
260
290
  f"{len(shares)} shares ({len(readable_shares)} readable, {len(writable_shares)} writable)"
@@ -273,6 +303,7 @@ class NxcHandler(BaseToolHandler):
273
303
  "credentials": credentials,
274
304
  "expired_credentials": expired_credentials,
275
305
  "is_pwned": is_pwned,
306
+ "has_shell_access": has_shell_access,
276
307
  "summary": summary,
277
308
  }
278
309
 
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Handler for rdp-sec-check RDP security scanner.
4
4
  """
5
+
5
6
  import logging
6
7
  import os
7
8
  import re
@@ -7,6 +7,7 @@ Provides a central registry for tool handlers that:
7
7
  - Provides capability queries (has_warning_handler, etc.)
8
8
  - Returns None for unmigrated tools (fallback to legacy code)
9
9
  """
10
+
10
11
  import logging
11
12
  from typing import Dict, List, Optional
12
13
 
@@ -4,6 +4,7 @@ Responder handler.
4
4
 
5
5
  Consolidates parsing and display logic for Responder credential capture jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  from typing import Any, Dict, Optional
@@ -4,6 +4,7 @@ Service Explorer handler.
4
4
 
5
5
  Consolidates parsing and display logic for Service Explorer jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -45,8 +46,8 @@ class ServiceExplorerHandler(BaseToolHandler):
45
46
  """
46
47
  try:
47
48
  from souleyez.parsers.service_explorer_parser import (
48
- parse_service_explorer_output,
49
49
  extract_findings,
50
+ parse_service_explorer_output,
50
51
  )
51
52
 
52
53
  # Import managers if not provided
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Handler for smbclient share browsing and file listing.
4
4
  """
5
+
5
6
  import logging
6
7
  import os
7
8
  import re
@@ -4,6 +4,7 @@ SMBMap handler.
4
4
 
5
5
  Consolidates parsing and display logic for SMBMap SMB share enumeration jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -44,12 +45,12 @@ class SMBMapHandler(BaseToolHandler):
44
45
  Extracts SMB shares and stores them along with findings.
45
46
  """
46
47
  try:
48
+ from souleyez.engine.result_handler import detect_tool_error
47
49
  from souleyez.parsers.smbmap_parser import (
48
- parse_smbmap_output,
49
50
  extract_findings,
51
+ parse_smbmap_output,
50
52
  )
51
53
  from souleyez.storage.smb_shares import SMBSharesManager
52
- from souleyez.engine.result_handler import detect_tool_error
53
54
 
54
55
  # Import managers if not provided
55
56
  if host_manager is None:
@@ -4,6 +4,7 @@ SQLMap handler.
4
4
 
5
5
  Consolidates parsing and display logic for SQLMap SQL injection scanner jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -45,13 +46,14 @@ class SQLMapHandler(BaseToolHandler):
45
46
  Extracts SQL injection vulnerabilities, databases, tables, and dumped data.
46
47
  """
47
48
  try:
49
+ import socket
50
+
51
+ from souleyez.engine.result_handler import detect_tool_error
48
52
  from souleyez.parsers.sqlmap_parser import (
49
- parse_sqlmap_output,
50
53
  get_sqli_stats,
54
+ parse_sqlmap_output,
51
55
  )
52
56
  from souleyez.storage.sqlmap_data import SQLMapDataManager
53
- from souleyez.engine.result_handler import detect_tool_error
54
- import socket
55
57
 
56
58
  # Import managers if not provided
57
59
  if host_manager is None:
@@ -833,8 +835,8 @@ class SQLMapHandler(BaseToolHandler):
833
835
  """Display successful SQLMap results."""
834
836
  try:
835
837
  from souleyez.parsers.sqlmap_parser import (
836
- parse_sqlmap_output,
837
838
  get_sqli_stats,
839
+ parse_sqlmap_output,
838
840
  )
839
841
 
840
842
  if not log_path or not os.path.exists(log_path):
@@ -4,6 +4,7 @@ TheHarvester handler.
4
4
 
5
5
  Consolidates parsing and display logic for theHarvester OSINT jobs.
6
6
  """
7
+
7
8
  import logging
8
9
  import os
9
10
  import re
@@ -194,8 +195,8 @@ class TheHarvesterHandler(BaseToolHandler):
194
195
  """
195
196
  try:
196
197
  from souleyez.parsers.theharvester_parser import (
197
- parse_theharvester_output,
198
198
  get_osint_stats,
199
+ parse_theharvester_output,
199
200
  )
200
201
 
201
202
  # Import managers if not provided