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,8 +4,9 @@ souleyez.parsers.sqlmap_parser
4
4
 
5
5
  Parses SQLMap SQL injection detection output into structured findings.
6
6
  """
7
+
7
8
  import re
8
- from typing import Dict, Any
9
+ from typing import Any, Dict
9
10
 
10
11
 
11
12
  def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
@@ -181,6 +182,29 @@ def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
181
182
  elif method == "POST" and effective_post_data:
182
183
  result["injectable_post_data"] = effective_post_data
183
184
 
185
+ # Look ahead for Type: lines to extract techniques
186
+ techniques = []
187
+ technique_str = None
188
+ for m in range(j + 1, min(j + 20, len(lines))):
189
+ type_line = lines[m].strip()
190
+ if type_line.startswith("Type:"):
191
+ tech_type = type_line.replace("Type:", "").strip()
192
+ techniques.append(tech_type)
193
+ if not technique_str:
194
+ technique_str = tech_type
195
+ elif type_line.startswith("---") and techniques:
196
+ break # End of technique block
197
+ elif type_line.startswith("[") and techniques:
198
+ break # Hit next section
199
+
200
+ # Determine technique string
201
+ if len(techniques) > 1:
202
+ technique_str = "multiple"
203
+ elif techniques:
204
+ technique_str = techniques[0]
205
+ else:
206
+ technique_str = "sqli"
207
+
184
208
  # Add vulnerability entry
185
209
  result["vulnerabilities"].append(
186
210
  {
@@ -190,6 +214,8 @@ def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
190
214
  "injectable": True,
191
215
  "severity": "critical",
192
216
  "description": f"Parameter '{param}' is vulnerable to SQL injection (resumed from session)",
217
+ "technique": technique_str,
218
+ "dbms": "Unknown", # Will be updated later if found
193
219
  }
194
220
  )
195
221
 
@@ -199,7 +225,7 @@ def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
199
225
  "parameter": param,
200
226
  "method": method,
201
227
  "post_data": effective_post_data,
202
- "techniques": [],
228
+ "techniques": techniques,
203
229
  }
204
230
  if not any(
205
231
  ip["url"] == injection_point["url"]
@@ -498,6 +524,8 @@ def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
498
524
  "injectable": True,
499
525
  "severity": "critical",
500
526
  "description": f"Parameter '{param}' is vulnerable to SQL injection",
527
+ "technique": "sqli",
528
+ "dbms": result.get("dbms", "Unknown"),
501
529
  }
502
530
  )
503
531
 
@@ -829,6 +857,12 @@ def parse_sqlmap_output(output: str, target: str = "") -> Dict[str, Any]:
829
857
  if best["post_data"]:
830
858
  result["injectable_post_data"] = best["post_data"]
831
859
 
860
+ # POST-PROCESSING: Update vulnerabilities with actual DBMS if it was parsed later
861
+ if result.get("dbms"):
862
+ for vuln in result["vulnerabilities"]:
863
+ if vuln.get("dbms") == "Unknown" or vuln.get("dbms") is None:
864
+ vuln["dbms"] = result["dbms"]
865
+
832
866
  return result
833
867
 
834
868
 
@@ -4,8 +4,9 @@ souleyez.parsers.theharvester_parser
4
4
 
5
5
  Parses theHarvester OSINT output into structured data.
6
6
  """
7
+
7
8
  import re
8
- from typing import Dict, Any
9
+ from typing import Any, Dict
9
10
 
10
11
 
11
12
  def parse_theharvester_output(output: str, target: str = "") -> Dict[str, Any]:
@@ -4,8 +4,9 @@ souleyez.parsers.whois_parser
4
4
 
5
5
  Parses WHOIS domain information output into structured OSINT data.
6
6
  """
7
+
7
8
  import re
8
- from typing import Dict, List, Any
9
+ from typing import Any, Dict, List
9
10
 
10
11
 
11
12
  def parse_whois_output(output: str, target: str = "") -> Dict[str, Any]:
@@ -4,9 +4,10 @@ souleyez.parsers.wpscan_parser
4
4
 
5
5
  Parses WPScan WordPress vulnerability scan output into structured findings.
6
6
  """
7
- import re
7
+
8
8
  import json
9
- from typing import Dict, List, Any, Optional
9
+ import re
10
+ from typing import Any, Dict, List, Optional
10
11
 
11
12
 
12
13
  def parse_wpscan_output(output: str, target: str = "") -> Dict[str, Any]:
souleyez/plugins/afp.py CHANGED
@@ -5,12 +5,14 @@ souleyez.plugins.afp
5
5
  AFP (Apple Filing Protocol) enumeration plugin.
6
6
  Discovers AFP shares on macOS systems.
7
7
  """
8
+
8
9
  import subprocess
9
10
  import time
10
11
  from typing import List
11
12
 
13
+ from souleyez.security.validation import ValidationError, validate_target
14
+
12
15
  from .plugin_base import PluginBase
13
- from souleyez.security.validation import validate_target, ValidationError
14
16
 
15
17
  HELP = {
16
18
  "name": "AFP — Apple File Sharing Enumeration",
@@ -5,12 +5,14 @@ souleyez.plugins.afp_brute
5
5
  AFP brute force plugin using Hydra.
6
6
  Attacks AFP file sharing on macOS systems.
7
7
  """
8
+
8
9
  import subprocess
9
10
  import time
10
11
  from typing import List
11
12
 
13
+ from souleyez.security.validation import ValidationError, validate_target
14
+
12
15
  from .plugin_base import PluginBase
13
- from souleyez.security.validation import validate_target, ValidationError
14
16
 
15
17
  HELP = {
16
18
  "name": "AFP Brute — Apple File Sharing Attack",
souleyez/plugins/ard.py CHANGED
@@ -5,12 +5,14 @@ souleyez.plugins.ard
5
5
  ARD/VNC (Apple Remote Desktop) enumeration plugin.
6
6
  Discovers VNC/ARD services on macOS systems.
7
7
  """
8
+
8
9
  import subprocess
9
10
  import time
10
11
  from typing import List
11
12
 
13
+ from souleyez.security.validation import ValidationError, validate_target
14
+
12
15
  from .plugin_base import PluginBase
13
- from souleyez.security.validation import validate_target, ValidationError
14
16
 
15
17
  HELP = {
16
18
  "name": "ARD — Apple Remote Desktop/VNC Enumeration",
@@ -2,10 +2,11 @@
2
2
  """
3
3
  Bloodhound plugin - Active Directory attack path mapping.
4
4
  """
5
- import subprocess
5
+
6
6
  import json
7
- from pathlib import Path
7
+ import subprocess
8
8
  from datetime import datetime
9
+ from pathlib import Path
9
10
 
10
11
  HELP = {
11
12
  "name": "Bloodhound - Active Directory Attack Path Mapping",
@@ -2,6 +2,7 @@
2
2
  """
3
3
  souleyez.plugins.certipy - Active Directory Certificate Services (ADCS) enumeration
4
4
  """
5
+
5
6
  import subprocess
6
7
  import time
7
8
  from typing import List
@@ -4,12 +4,14 @@ souleyez.plugins.crackmapexec - Swiss army knife for Windows/AD pentesting
4
4
 
5
5
  Note: Uses NetExec (netexec/nxc), the successor to CrackMapExec
6
6
  """
7
+
7
8
  import subprocess
8
9
  import time
9
10
  from typing import List
10
11
 
12
+ from souleyez.security.validation import ValidationError, validate_target
13
+
11
14
  from .plugin_base import PluginBase
12
- from souleyez.security.validation import validate_target, ValidationError
13
15
 
14
16
  HELP = {
15
17
  "name": "CrackMapExec (CME) - Windows/AD Pentesting Tool",
@@ -248,6 +250,8 @@ class CrackMapExecPlugin(PluginBase):
248
250
  elif protocol not in args:
249
251
  cmd.extend(["--shares"])
250
252
 
253
+ # For anonymous enumeration, use null session with empty domain
254
+ # netexec 1.5.0 requires -d '' for proper null session (1.4.0 didn't need it)
251
255
  has_creds = any(arg in cmd for arg in ["-u", "--username", "-p", "--password"])
252
256
  has_enum = any(
253
257
  arg in cmd
@@ -267,6 +271,8 @@ class CrackMapExecPlugin(PluginBase):
267
271
  cmd.insert(insert_pos + 1, "")
268
272
  cmd.insert(insert_pos + 2, "-p")
269
273
  cmd.insert(insert_pos + 3, "")
274
+ cmd.insert(insert_pos + 4, "-d")
275
+ cmd.insert(insert_pos + 5, "")
270
276
 
271
277
  return {"cmd": cmd, "timeout": 1800}
272
278
 
@@ -341,8 +347,8 @@ class CrackMapExecPlugin(PluginBase):
341
347
  # No protocol specified in args, add default behavior
342
348
  cmd.extend(["--shares"])
343
349
 
344
- # Auto-add null credentials for unauthenticated enumeration if no creds specified
345
- # Check if -u or --username already in command
350
+ # For anonymous enumeration, use null session with empty domain
351
+ # netexec 1.5.0 requires -d '' for proper null session (1.4.0 didn't need it)
346
352
  has_creds = any(arg in cmd for arg in ["-u", "--username", "-p", "--password"])
347
353
  has_enum = any(
348
354
  arg in cmd
@@ -357,15 +363,13 @@ class CrackMapExecPlugin(PluginBase):
357
363
  )
358
364
 
359
365
  if has_enum and not has_creds:
360
- # Add null session credentials after ALL targets but before flags
361
- # Position: 1 (netexec) + 1 (protocol) + len(target_list)
362
- # Example: ['netexec', 'smb', '10.0.0.14', '10.0.0.82', '--shares']
363
- # Insert at position 4: ['netexec', 'smb', '10.0.0.14', '10.0.0.82', '-u', '', '-p', '', '--shares']
364
366
  insert_pos = 2 + len(target_list)
365
367
  cmd.insert(insert_pos, "-u")
366
368
  cmd.insert(insert_pos + 1, "")
367
369
  cmd.insert(insert_pos + 2, "-p")
368
370
  cmd.insert(insert_pos + 3, "")
371
+ cmd.insert(insert_pos + 4, "-d")
372
+ cmd.insert(insert_pos + 5, "")
369
373
 
370
374
  if not log_path:
371
375
  try:
@@ -2,14 +2,17 @@
2
2
  """
3
3
  souleyez.plugins.dalfox - XSS vulnerability scanner
4
4
  """
5
+
5
6
  from __future__ import annotations
7
+
8
+ import json
6
9
  import subprocess
7
10
  import time
8
- import json
9
11
  from typing import List
10
12
 
13
+ from souleyez.security.validation import ValidationError, validate_url
14
+
11
15
  from .plugin_base import PluginBase
12
- from souleyez.security.validation import validate_url, ValidationError
13
16
 
14
17
  HELP = {
15
18
  "name": "Dalfox - XSS Vulnerability Scanner",
@@ -5,12 +5,14 @@ souleyez.plugins.dns_hijack
5
5
  DNS hijacking detection plugin.
6
6
  Checks if a router is performing DNS hijacking/redirection.
7
7
  """
8
+
8
9
  import subprocess
9
10
  import time
10
11
  from typing import List
11
12
 
13
+ from souleyez.security.validation import ValidationError, validate_target
14
+
12
15
  from .plugin_base import PluginBase
13
- from souleyez.security.validation import validate_target, ValidationError
14
16
 
15
17
  HELP = {
16
18
  "name": "DNS Hijack — DNS Manipulation Detection",
@@ -4,12 +4,14 @@ souleyez.plugins.dnsrecon
4
4
 
5
5
  DNSRecon DNS enumeration and reconnaissance plugin.
6
6
  """
7
+
7
8
  import subprocess
8
9
  import time
9
10
  from typing import List
10
11
 
12
+ from souleyez.security.validation import ValidationError, validate_target
13
+
11
14
  from .plugin_base import PluginBase
12
- from souleyez.security.validation import validate_target, ValidationError
13
15
 
14
16
  HELP = {
15
17
  "name": "DNSRecon — DNS Enumeration Tool",
@@ -4,12 +4,14 @@ souleyez.plugins.enum4linux
4
4
 
5
5
  Enum4linux SMB enumeration plugin with unified interface.
6
6
  """
7
+
7
8
  import subprocess
8
9
  import time
9
10
  from typing import List
10
11
 
12
+ from souleyez.security.validation import ValidationError, validate_target
13
+
11
14
  from .plugin_base import PluginBase
12
- from souleyez.security.validation import validate_target, ValidationError
13
15
 
14
16
  HELP = {
15
17
  "name": "enum4linux (SMB Enumeration)",
@@ -4,6 +4,7 @@ souleyez.plugins.evil_winrm
4
4
 
5
5
  Evil-WinRM - Windows Remote Management Shell plugin.
6
6
  """
7
+
7
8
  import subprocess
8
9
  import time
9
10
  from typing import List
souleyez/plugins/ffuf.py CHANGED
@@ -2,11 +2,13 @@
2
2
  """
3
3
  souleyez.plugins.ffuf - Fast web fuzzer
4
4
  """
5
+
5
6
  import subprocess
6
7
  from typing import List
7
8
 
9
+ from souleyez.security.validation import ValidationError, validate_url
10
+
8
11
  from .plugin_base import PluginBase
9
- from souleyez.security.validation import validate_url, ValidationError
10
12
 
11
13
  HELP = {
12
14
  "name": "ffuf - Fast Web Fuzzer",
@@ -5,10 +5,11 @@ souleyez.plugins.firmware_extract
5
5
  Firmware extraction and analysis plugin using binwalk.
6
6
  Extracts and analyzes router firmware images.
7
7
  """
8
- import subprocess
8
+
9
+ import os
9
10
  import shutil
11
+ import subprocess
10
12
  import time
11
- import os
12
13
  from typing import List
13
14
 
14
15
  from .plugin_base import PluginBase
@@ -2,18 +2,21 @@
2
2
  """
3
3
  souleyez.plugins.gobuster
4
4
  """
5
+
5
6
  from __future__ import annotations
7
+
8
+ import re
6
9
  import subprocess
7
10
  import time
8
- import re
9
11
  import uuid
10
- from typing import List, Dict, Optional
12
+ from typing import Dict, List, Optional
11
13
  from urllib.parse import urlparse
12
14
 
13
15
  import requests
14
16
 
17
+ from souleyez.security.validation import ValidationError, validate_url
18
+
15
19
  from .plugin_base import PluginBase
16
- from souleyez.security.validation import validate_url, ValidationError
17
20
 
18
21
  HELP = {
19
22
  "name": "Gobuster — Directory, File & DNS/VHost Brute-Force Tool",
@@ -4,6 +4,7 @@ GPP (Group Policy Preferences) credential extraction plugin.
4
4
 
5
5
  Downloads GPP XML files from SMB shares and extracts/decrypts cPassword values.
6
6
  """
7
+
7
8
  import os
8
9
  import re
9
10
  import subprocess
@@ -4,9 +4,10 @@ souleyez.plugins.hashcat
4
4
 
5
5
  Hashcat password cracking plugin.
6
6
  """
7
+
8
+ import os
7
9
  import subprocess
8
10
  import time
9
- import os
10
11
  from typing import List
11
12
 
12
13
  from .plugin_base import PluginBase
@@ -337,50 +337,79 @@ class HttpFingerprintPlugin(PluginBase):
337
337
  target = f"http://{target}"
338
338
 
339
339
  try:
340
- # Smart dual-probe: try both HTTP and HTTPS, use the better one
341
- result, effective_url = self._smart_probe(target, timeout)
340
+ # Use thread-based hard timeout to prevent indefinite hangs
341
+ # urllib timeouts don't always work if server accepts connection but stalls
342
+ from concurrent.futures import ThreadPoolExecutor
343
+ from concurrent.futures import TimeoutError as FuturesTimeout
344
+
345
+ hard_timeout = timeout * 3 # 30 seconds max for entire probe operation
346
+
347
+ with ThreadPoolExecutor(max_workers=1) as executor:
348
+ future = executor.submit(self._smart_probe, target, timeout)
349
+ try:
350
+ result, effective_url = future.result(timeout=hard_timeout)
351
+ except FuturesTimeout:
352
+ # Hard timeout hit - server is unresponsive
353
+ result = {
354
+ "error": f"Timeout: server did not respond within {hard_timeout}s",
355
+ "status_code": None,
356
+ "server": None,
357
+ "waf": [],
358
+ "cdn": [],
359
+ "managed_hosting": None,
360
+ "technologies": [],
361
+ "headers": {},
362
+ "cookies": [],
363
+ "tls": None,
364
+ "redirect_url": None,
365
+ }
366
+ effective_url = target
367
+
342
368
  output = self._format_output(effective_url, result, label)
343
369
 
344
370
  if log_path:
345
371
  with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
346
372
  fh.write(output)
347
- # Fetch robots.txt and sitemap.xml for path discovery
348
- robots_paths, sitemap_paths = self._fetch_robots_sitemap(
349
- effective_url, timeout
350
- )
351
- result["robots_paths"] = robots_paths
352
- result["sitemap_paths"] = sitemap_paths
353
-
354
- # Quick path probing for CMS, admin panels, API endpoints
355
- quick_probe = self._quick_path_probe(effective_url, timeout)
356
- result["cms_detected"] = quick_probe.get("cms")
357
- result["admin_panels"] = quick_probe.get("admin_panels", [])
358
- result["api_endpoints"] = quick_probe.get("api_endpoints", [])
359
-
360
- # Write additional detections to log
361
- if quick_probe.get("cms"):
362
- cms = quick_probe["cms"]
363
- fh.write(f"\n{'=' * 40}\n")
364
- fh.write(
365
- f"CMS DETECTED: {cms['name']} ({cms['confidence']} confidence)\n"
366
- )
367
- for p in cms["paths"]:
368
- fh.write(f" - {p['path']} (HTTP {p['status']})\n")
369
- fh.write(f"{'=' * 40}\n")
370
373
 
371
- if quick_probe.get("admin_panels"):
372
- fh.write(f"\nADMIN PANELS FOUND:\n")
373
- for panel in quick_probe["admin_panels"]:
374
+ # Skip additional probing if initial fingerprint failed
375
+ if not result.get("error"):
376
+ # Fetch robots.txt and sitemap.xml for path discovery
377
+ robots_paths, sitemap_paths = self._fetch_robots_sitemap(
378
+ effective_url, timeout
379
+ )
380
+ result["robots_paths"] = robots_paths
381
+ result["sitemap_paths"] = sitemap_paths
382
+
383
+ # Quick path probing for CMS, admin panels, API endpoints
384
+ quick_probe = self._quick_path_probe(effective_url, timeout)
385
+ result["cms_detected"] = quick_probe.get("cms")
386
+ result["admin_panels"] = quick_probe.get("admin_panels", [])
387
+ result["api_endpoints"] = quick_probe.get("api_endpoints", [])
388
+
389
+ # Write additional detections to log
390
+ if quick_probe.get("cms"):
391
+ cms = quick_probe["cms"]
392
+ fh.write(f"\n{'=' * 40}\n")
374
393
  fh.write(
375
- f" - {panel['name']}: {panel['url']} (HTTP {panel['status']})\n"
394
+ f"CMS DETECTED: {cms['name']} ({cms['confidence']} confidence)\n"
376
395
  )
396
+ for p in cms["paths"]:
397
+ fh.write(f" - {p['path']} (HTTP {p['status']})\n")
398
+ fh.write(f"{'=' * 40}\n")
399
+
400
+ if quick_probe.get("admin_panels"):
401
+ fh.write(f"\nADMIN PANELS FOUND:\n")
402
+ for panel in quick_probe["admin_panels"]:
403
+ fh.write(
404
+ f" - {panel['name']}: {panel['url']} (HTTP {panel['status']})\n"
405
+ )
377
406
 
378
- if quick_probe.get("api_endpoints"):
379
- fh.write(f"\nAPI ENDPOINTS FOUND:\n")
380
- for api in quick_probe["api_endpoints"]:
381
- fh.write(
382
- f" - {api['type']}: {api['url']} (HTTP {api['status']})\n"
383
- )
407
+ if quick_probe.get("api_endpoints"):
408
+ fh.write(f"\nAPI ENDPOINTS FOUND:\n")
409
+ for api in quick_probe["api_endpoints"]:
410
+ fh.write(
411
+ f" - {api['type']}: {api['url']} (HTTP {api['status']})\n"
412
+ )
384
413
 
385
414
  # Write JSON result for parsing
386
415
  fh.write("\n\n=== JSON_RESULT ===\n")
@@ -413,8 +442,32 @@ class HttpFingerprintPlugin(PluginBase):
413
442
  tuple: (result_dict, effective_url)
414
443
  """
415
444
  parsed = urlparse(target)
445
+
446
+ # Quick connectivity check - fail fast if port isn't responding
416
447
  host = parsed.hostname
417
448
  port = parsed.port or (443 if parsed.scheme == "https" else 80)
449
+ try:
450
+ with socket.create_connection(
451
+ (host, port), timeout=min(timeout, 5)
452
+ ) as sock:
453
+ pass # Just checking if we can connect
454
+ except (socket.timeout, socket.error, OSError) as e:
455
+ # Port not responding - return error result immediately
456
+ return {
457
+ "error": f"Connection failed: {e}",
458
+ "status_code": None,
459
+ "server": None,
460
+ "waf": [],
461
+ "cdn": [],
462
+ "managed_hosting": None,
463
+ "technologies": [],
464
+ "headers": {},
465
+ "cookies": [],
466
+ "tls": None,
467
+ "redirect_url": None,
468
+ "protocol_detection": "failed",
469
+ "effective_url": target,
470
+ }, target
418
471
 
419
472
  # Build both URL variants
420
473
  http_url = (
@@ -564,6 +617,11 @@ class HttpFingerprintPlugin(PluginBase):
564
617
  import urllib.error
565
618
  import urllib.request
566
619
 
620
+ # Set global socket timeout to prevent hanging on slow/unresponsive servers
621
+ # This is a safety net - individual requests also have timeouts
622
+ old_timeout = socket.getdefaulttimeout()
623
+ socket.setdefaulttimeout(timeout + 5) # Slightly longer than request timeout
624
+
567
625
  result = {
568
626
  "server": None,
569
627
  "server_version": None,
@@ -700,6 +758,10 @@ class HttpFingerprintPlugin(PluginBase):
700
758
  except Exception as e:
701
759
  result["error"] = f"{type(e).__name__}: {e}"
702
760
 
761
+ finally:
762
+ # Restore original socket timeout
763
+ socket.setdefaulttimeout(old_timeout)
764
+
703
765
  return result
704
766
 
705
767
  def _detect_waf(self, headers: Dict[str, str], cookies: List[str]) -> List[str]:
@@ -1021,9 +1083,60 @@ class HttpFingerprintPlugin(PluginBase):
1021
1083
  # Track CMS detections to avoid duplicates
1022
1084
  cms_detected = {}
1023
1085
 
1086
+ # CMS-specific content markers to verify detection (prevents SPA false positives)
1087
+ cms_content_markers = {
1088
+ "WordPress": [
1089
+ b"wp-login",
1090
+ b"wp-includes",
1091
+ b"wp-content",
1092
+ b"wordpress",
1093
+ b"wlwmanifest",
1094
+ b"xmlrpc.php",
1095
+ ],
1096
+ "Joomla": [b"joomla", b"com_content", b"/administrator/"],
1097
+ "Drupal": [b"drupal", b"sites/default", b"sites/all"],
1098
+ "TYPO3": [b"typo3", b"typo3conf"],
1099
+ "Sitecore": [b"sitecore"],
1100
+ }
1101
+
1024
1102
  for path, category, subtype in paths_to_check:
1025
1103
  try:
1026
1104
  url = base.rstrip("/") + path
1105
+
1106
+ # For CMS detection, use GET to verify content (prevents SPA false positives)
1107
+ # SPAs return 200 for all routes but with same content
1108
+ if category == "cms":
1109
+ req = urllib.request.Request(
1110
+ url,
1111
+ method="GET",
1112
+ headers={
1113
+ "User-Agent": "Mozilla/5.0 (compatible; SoulEyez/1.0)"
1114
+ },
1115
+ )
1116
+ try:
1117
+ with urllib.request.urlopen(
1118
+ req, timeout=timeout, context=ctx
1119
+ ) as response:
1120
+ status = response.getcode()
1121
+ # Read first 4KB to check for CMS markers
1122
+ content = response.read(4096).lower()
1123
+ except urllib.error.HTTPError as e:
1124
+ status = e.code
1125
+ content = b""
1126
+
1127
+ # Verify response contains CMS-specific content
1128
+ if status in (200, 301, 302, 401, 403):
1129
+ markers = cms_content_markers.get(subtype, [])
1130
+ has_cms_content = any(marker in content for marker in markers)
1131
+ if has_cms_content:
1132
+ if subtype not in cms_detected:
1133
+ cms_detected[subtype] = []
1134
+ cms_detected[subtype].append(
1135
+ {"path": path, "status": status}
1136
+ )
1137
+ continue
1138
+
1139
+ # For admin/API detection, HEAD is fine (just checking existence)
1027
1140
  req = urllib.request.Request(
1028
1141
  url,
1029
1142
  method="HEAD",
@@ -1040,11 +1153,7 @@ class HttpFingerprintPlugin(PluginBase):
1040
1153
 
1041
1154
  # Consider 2xx, 3xx, 401, 403 as "exists"
1042
1155
  if status in (200, 201, 204, 301, 302, 303, 307, 308, 401, 403):
1043
- if category == "cms":
1044
- if subtype not in cms_detected:
1045
- cms_detected[subtype] = []
1046
- cms_detected[subtype].append({"path": path, "status": status})
1047
- elif category == "admin":
1156
+ if category == "admin":
1048
1157
  result["admin_panels"].append(
1049
1158
  {
1050
1159
  "path": path,