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

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

Potentially problematic release.


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

Files changed (358) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9526 -2879
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1239 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2200 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +563 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +408 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +292 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/web_login_test_handler.py +327 -0
  126. souleyez/handlers/whois_handler.py +277 -0
  127. souleyez/handlers/wpscan_handler.py +554 -0
  128. souleyez/history.py +32 -16
  129. souleyez/importers/msf_importer.py +106 -75
  130. souleyez/importers/smart_importer.py +208 -147
  131. souleyez/integrations/siem/__init__.py +10 -10
  132. souleyez/integrations/siem/base.py +17 -18
  133. souleyez/integrations/siem/elastic.py +108 -122
  134. souleyez/integrations/siem/factory.py +207 -80
  135. souleyez/integrations/siem/googlesecops.py +146 -154
  136. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  137. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  138. souleyez/integrations/siem/sentinel.py +107 -109
  139. souleyez/integrations/siem/splunk.py +246 -212
  140. souleyez/integrations/siem/wazuh.py +65 -71
  141. souleyez/integrations/wazuh/__init__.py +5 -5
  142. souleyez/integrations/wazuh/client.py +70 -93
  143. souleyez/integrations/wazuh/config.py +85 -57
  144. souleyez/integrations/wazuh/host_mapper.py +28 -36
  145. souleyez/integrations/wazuh/sync.py +78 -68
  146. souleyez/intelligence/__init__.py +4 -5
  147. souleyez/intelligence/correlation_analyzer.py +309 -295
  148. souleyez/intelligence/exploit_knowledge.py +661 -623
  149. souleyez/intelligence/exploit_suggestions.py +159 -139
  150. souleyez/intelligence/gap_analyzer.py +132 -97
  151. souleyez/intelligence/gap_detector.py +251 -214
  152. souleyez/intelligence/sensitive_tables.py +266 -129
  153. souleyez/intelligence/service_parser.py +137 -123
  154. souleyez/intelligence/surface_analyzer.py +407 -268
  155. souleyez/intelligence/target_parser.py +159 -162
  156. souleyez/licensing/__init__.py +6 -6
  157. souleyez/licensing/validator.py +17 -19
  158. souleyez/log_config.py +79 -54
  159. souleyez/main.py +1505 -687
  160. souleyez/migrations/fix_job_counter.py +16 -14
  161. souleyez/parsers/bloodhound_parser.py +41 -39
  162. souleyez/parsers/crackmapexec_parser.py +178 -111
  163. souleyez/parsers/dalfox_parser.py +72 -77
  164. souleyez/parsers/dnsrecon_parser.py +103 -91
  165. souleyez/parsers/enum4linux_parser.py +183 -153
  166. souleyez/parsers/ffuf_parser.py +29 -25
  167. souleyez/parsers/gobuster_parser.py +301 -41
  168. souleyez/parsers/hashcat_parser.py +324 -79
  169. souleyez/parsers/http_fingerprint_parser.py +350 -103
  170. souleyez/parsers/hydra_parser.py +131 -111
  171. souleyez/parsers/impacket_parser.py +231 -178
  172. souleyez/parsers/john_parser.py +98 -86
  173. souleyez/parsers/katana_parser.py +316 -0
  174. souleyez/parsers/msf_parser.py +943 -498
  175. souleyez/parsers/nikto_parser.py +346 -65
  176. souleyez/parsers/nmap_parser.py +262 -174
  177. souleyez/parsers/nuclei_parser.py +40 -44
  178. souleyez/parsers/responder_parser.py +26 -26
  179. souleyez/parsers/searchsploit_parser.py +74 -74
  180. souleyez/parsers/service_explorer_parser.py +279 -0
  181. souleyez/parsers/smbmap_parser.py +180 -124
  182. souleyez/parsers/sqlmap_parser.py +434 -308
  183. souleyez/parsers/theharvester_parser.py +75 -57
  184. souleyez/parsers/whois_parser.py +135 -94
  185. souleyez/parsers/wpscan_parser.py +278 -190
  186. souleyez/plugins/afp.py +44 -36
  187. souleyez/plugins/afp_brute.py +114 -46
  188. souleyez/plugins/ard.py +48 -37
  189. souleyez/plugins/bloodhound.py +95 -61
  190. souleyez/plugins/certipy.py +303 -0
  191. souleyez/plugins/crackmapexec.py +186 -85
  192. souleyez/plugins/dalfox.py +120 -59
  193. souleyez/plugins/dns_hijack.py +146 -41
  194. souleyez/plugins/dnsrecon.py +97 -61
  195. souleyez/plugins/enum4linux.py +91 -66
  196. souleyez/plugins/evil_winrm.py +291 -0
  197. souleyez/plugins/ffuf.py +166 -90
  198. souleyez/plugins/firmware_extract.py +133 -29
  199. souleyez/plugins/gobuster.py +387 -190
  200. souleyez/plugins/gpp_extract.py +393 -0
  201. souleyez/plugins/hashcat.py +100 -73
  202. souleyez/plugins/http_fingerprint.py +854 -267
  203. souleyez/plugins/hydra.py +566 -200
  204. souleyez/plugins/impacket_getnpusers.py +117 -69
  205. souleyez/plugins/impacket_psexec.py +84 -64
  206. souleyez/plugins/impacket_secretsdump.py +103 -69
  207. souleyez/plugins/impacket_smbclient.py +89 -75
  208. souleyez/plugins/john.py +86 -69
  209. souleyez/plugins/katana.py +313 -0
  210. souleyez/plugins/kerbrute.py +237 -0
  211. souleyez/plugins/lfi_extract.py +541 -0
  212. souleyez/plugins/macos_ssh.py +117 -48
  213. souleyez/plugins/mdns.py +35 -30
  214. souleyez/plugins/msf_auxiliary.py +253 -130
  215. souleyez/plugins/msf_exploit.py +239 -161
  216. souleyez/plugins/nikto.py +134 -78
  217. souleyez/plugins/nmap.py +275 -91
  218. souleyez/plugins/nuclei.py +180 -89
  219. souleyez/plugins/nxc.py +285 -0
  220. souleyez/plugins/plugin_base.py +35 -36
  221. souleyez/plugins/plugin_template.py +13 -5
  222. souleyez/plugins/rdp_sec_check.py +130 -0
  223. souleyez/plugins/responder.py +112 -71
  224. souleyez/plugins/router_http_brute.py +76 -65
  225. souleyez/plugins/router_ssh_brute.py +118 -41
  226. souleyez/plugins/router_telnet_brute.py +124 -42
  227. souleyez/plugins/routersploit.py +91 -59
  228. souleyez/plugins/routersploit_exploit.py +77 -55
  229. souleyez/plugins/searchsploit.py +91 -77
  230. souleyez/plugins/service_explorer.py +1160 -0
  231. souleyez/plugins/smbmap.py +122 -72
  232. souleyez/plugins/smbpasswd.py +215 -0
  233. souleyez/plugins/sqlmap.py +301 -113
  234. souleyez/plugins/theharvester.py +127 -75
  235. souleyez/plugins/tr069.py +79 -57
  236. souleyez/plugins/upnp.py +65 -47
  237. souleyez/plugins/upnp_abuse.py +73 -55
  238. souleyez/plugins/vnc_access.py +129 -42
  239. souleyez/plugins/vnc_brute.py +109 -38
  240. souleyez/plugins/web_login_test.py +417 -0
  241. souleyez/plugins/whois.py +77 -58
  242. souleyez/plugins/wpscan.py +173 -69
  243. souleyez/reporting/__init__.py +2 -1
  244. souleyez/reporting/attack_chain.py +411 -346
  245. souleyez/reporting/charts.py +436 -501
  246. souleyez/reporting/compliance_mappings.py +334 -201
  247. souleyez/reporting/detection_report.py +126 -125
  248. souleyez/reporting/formatters.py +828 -591
  249. souleyez/reporting/generator.py +386 -302
  250. souleyez/reporting/metrics.py +72 -75
  251. souleyez/scanner.py +35 -29
  252. souleyez/security/__init__.py +37 -11
  253. souleyez/security/scope_validator.py +175 -106
  254. souleyez/security/validation.py +223 -149
  255. souleyez/security.py +22 -6
  256. souleyez/storage/credentials.py +247 -186
  257. souleyez/storage/crypto.py +296 -129
  258. souleyez/storage/database.py +73 -50
  259. souleyez/storage/db.py +58 -36
  260. souleyez/storage/deliverable_evidence.py +177 -128
  261. souleyez/storage/deliverable_exporter.py +282 -246
  262. souleyez/storage/deliverable_templates.py +134 -116
  263. souleyez/storage/deliverables.py +135 -130
  264. souleyez/storage/engagements.py +109 -56
  265. souleyez/storage/evidence.py +181 -152
  266. souleyez/storage/execution_log.py +31 -17
  267. souleyez/storage/exploit_attempts.py +93 -57
  268. souleyez/storage/exploits.py +67 -36
  269. souleyez/storage/findings.py +48 -61
  270. souleyez/storage/hosts.py +176 -144
  271. souleyez/storage/migrate_to_engagements.py +43 -19
  272. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  273. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  274. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  275. souleyez/storage/migrations/_005_screenshots.py +13 -5
  276. souleyez/storage/migrations/_006_deliverables.py +13 -5
  277. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  278. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  279. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  280. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  281. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  282. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  283. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  284. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  285. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  286. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  287. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  288. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  289. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  290. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  291. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  292. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  293. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  294. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  295. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  296. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  297. souleyez/storage/migrations/__init__.py +26 -26
  298. souleyez/storage/migrations/migration_manager.py +19 -19
  299. souleyez/storage/msf_sessions.py +100 -65
  300. souleyez/storage/osint.py +17 -24
  301. souleyez/storage/recommendation_engine.py +269 -235
  302. souleyez/storage/screenshots.py +33 -32
  303. souleyez/storage/smb_shares.py +136 -92
  304. souleyez/storage/sqlmap_data.py +183 -128
  305. souleyez/storage/team_collaboration.py +135 -141
  306. souleyez/storage/timeline_tracker.py +122 -94
  307. souleyez/storage/wazuh_vulns.py +64 -66
  308. souleyez/storage/web_paths.py +33 -37
  309. souleyez/testing/credential_tester.py +221 -205
  310. souleyez/ui/__init__.py +1 -1
  311. souleyez/ui/ai_quotes.py +12 -12
  312. souleyez/ui/attack_surface.py +2439 -1516
  313. souleyez/ui/chain_rules_view.py +914 -382
  314. souleyez/ui/correlation_view.py +312 -230
  315. souleyez/ui/dashboard.py +2382 -1130
  316. souleyez/ui/deliverables_view.py +148 -62
  317. souleyez/ui/design_system.py +13 -13
  318. souleyez/ui/errors.py +49 -49
  319. souleyez/ui/evidence_linking_view.py +284 -179
  320. souleyez/ui/evidence_vault.py +393 -285
  321. souleyez/ui/exploit_suggestions_view.py +555 -349
  322. souleyez/ui/export_view.py +100 -66
  323. souleyez/ui/gap_analysis_view.py +315 -171
  324. souleyez/ui/help_system.py +105 -97
  325. souleyez/ui/intelligence_view.py +436 -293
  326. souleyez/ui/interactive.py +23434 -10286
  327. souleyez/ui/interactive_selector.py +75 -68
  328. souleyez/ui/log_formatter.py +47 -39
  329. souleyez/ui/menu_components.py +22 -13
  330. souleyez/ui/msf_auxiliary_menu.py +184 -133
  331. souleyez/ui/pending_chains_view.py +336 -172
  332. souleyez/ui/progress_indicators.py +5 -3
  333. souleyez/ui/recommendations_view.py +195 -137
  334. souleyez/ui/rule_builder.py +343 -225
  335. souleyez/ui/setup_wizard.py +678 -284
  336. souleyez/ui/shortcuts.py +217 -165
  337. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  338. souleyez/ui/splunk_vulns_view.py +139 -86
  339. souleyez/ui/team_dashboard.py +498 -335
  340. souleyez/ui/template_selector.py +196 -105
  341. souleyez/ui/terminal.py +6 -6
  342. souleyez/ui/timeline_view.py +198 -127
  343. souleyez/ui/tool_setup.py +264 -164
  344. souleyez/ui/tutorial.py +202 -72
  345. souleyez/ui/tutorial_state.py +40 -40
  346. souleyez/ui/wazuh_vulns_view.py +235 -141
  347. souleyez/ui/wordlist_browser.py +260 -107
  348. souleyez/ui.py +464 -312
  349. souleyez/utils/tool_checker.py +427 -367
  350. souleyez/utils.py +33 -29
  351. souleyez/wordlists.py +134 -167
  352. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
  353. souleyez-2.43.34.dist-info/RECORD +443 -0
  354. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.26.dist-info/RECORD +0 -379
  356. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ souleyez.plugins.evil_winrm
4
+
5
+ Evil-WinRM - Windows Remote Management Shell plugin.
6
+ """
7
+ import subprocess
8
+ import time
9
+ from typing import List
10
+
11
+ from .plugin_base import PluginBase
12
+
13
+ HELP = {
14
+ "name": "Evil-WinRM - Windows Remote Shell",
15
+ "description": (
16
+ "Got Windows creds and need a shell?\n\n"
17
+ "Evil-WinRM is the ultimate WinRM shell for hacking. It provides a fully "
18
+ "interactive PowerShell session on Windows targets over WinRM (port 5985/5986).\n\n"
19
+ "Perfect for post-exploitation after discovering valid credentials through "
20
+ "Hydra, secretsdump, or other credential attacks.\n\n"
21
+ "Quick tips:\n"
22
+ "- Supports password, NTLM hash (pass-the-hash), and Kerberos authentication\n"
23
+ "- Built-in file upload/download functionality\n"
24
+ "- Execute commands non-interactively with -c flag\n"
25
+ "- Works when SMB is blocked but WinRM is open\n"
26
+ "- Default ports: 5985 (HTTP) and 5986 (HTTPS/SSL)\n"
27
+ ),
28
+ "usage": 'souleyez jobs enqueue evil_winrm <target> --args "-u <user> -p <pass>"',
29
+ "examples": [
30
+ 'souleyez jobs enqueue evil_winrm 192.168.1.10 --args "-u administrator -p Password123!"',
31
+ 'souleyez jobs enqueue evil_winrm 192.168.1.10 --args "-u admin -H aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0"',
32
+ "souleyez jobs enqueue evil_winrm 192.168.1.10 --args \"-u admin -p Password123! -c 'whoami /all'\"",
33
+ "souleyez jobs enqueue evil_winrm 192.168.1.10 --args \"-u admin@DOMAIN -p Password123! -c 'hostname'\"",
34
+ ],
35
+ "flags": [
36
+ ["-i, --ip <IP>", "Remote host IP or hostname"],
37
+ ["-u, --user <USER>", "Username for authentication"],
38
+ ["-p, --password <PASS>", "Password for authentication"],
39
+ ["-H, --hash <HASH>", "NTLM hash for pass-the-hash (LM:NT or just NT)"],
40
+ ["-P, --port <PORT>", "WinRM port (default: 5985)"],
41
+ ["-s, --ssl", "Enable SSL (port 5986)"],
42
+ ["-c, --command <CMD>", "Execute command and exit (non-interactive)"],
43
+ ["-S, --scripts <PATH>", "PowerShell scripts local path"],
44
+ ["-e, --executables <PATH>", "C# executables local path"],
45
+ ["-r, --realm <DOMAIN>", "Kerberos realm (domain)"],
46
+ ],
47
+ "preset_categories": {
48
+ "authentication": [
49
+ {
50
+ "name": "Password Auth",
51
+ "args": ["-u", "administrator", "-p", "PASSWORD"],
52
+ "desc": "Authenticate with username and password",
53
+ },
54
+ {
55
+ "name": "Pass-the-Hash",
56
+ "args": ["-u", "administrator", "-H", "HASH"],
57
+ "desc": "Authenticate with NTLM hash",
58
+ },
59
+ {
60
+ "name": "SSL Connection",
61
+ "args": ["-u", "administrator", "-p", "PASSWORD", "-s", "-P", "5986"],
62
+ "desc": "Connect over SSL (HTTPS)",
63
+ },
64
+ ],
65
+ "command_execution": [
66
+ {
67
+ "name": "Whoami",
68
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "whoami /all"],
69
+ "desc": "Check current user and privileges",
70
+ },
71
+ {
72
+ "name": "System Info",
73
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "systeminfo"],
74
+ "desc": "Get system information",
75
+ },
76
+ {
77
+ "name": "Network Info",
78
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "ipconfig /all"],
79
+ "desc": "Get network configuration",
80
+ },
81
+ {
82
+ "name": "List Users",
83
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "net user"],
84
+ "desc": "List local users",
85
+ },
86
+ {
87
+ "name": "List Domain Users",
88
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "net user /domain"],
89
+ "desc": "List domain users",
90
+ },
91
+ ],
92
+ "enumeration": [
93
+ {
94
+ "name": "Enum Shares",
95
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "net share"],
96
+ "desc": "List network shares",
97
+ },
98
+ {
99
+ "name": "Enum Services",
100
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "sc query"],
101
+ "desc": "List running services",
102
+ },
103
+ {
104
+ "name": "Enum Processes",
105
+ "args": ["-u", "USER", "-p", "PASSWORD", "-c", "tasklist"],
106
+ "desc": "List running processes",
107
+ },
108
+ ],
109
+ },
110
+ "presets": [],
111
+ "common_options": {
112
+ "-i": "Target IP address (can also be positional)",
113
+ "-u": "Username (user@domain for domain accounts)",
114
+ "-p": "Password",
115
+ "-H": "NTLM hash (format: LM:NT or just NT)",
116
+ "-P": "Port number (default 5985, use 5986 for SSL)",
117
+ "-s": "Enable SSL connection",
118
+ "-c": "Command to execute (non-interactive mode)",
119
+ },
120
+ "notes": [
121
+ "Requires evil-winrm gem installed (gem install evil-winrm)",
122
+ "Target must have WinRM enabled (port 5985 or 5986)",
123
+ "For domain accounts, use user@domain or domain\\\\user format",
124
+ "Pass-the-hash only works with local admin accounts (not domain accounts)",
125
+ "Use -c for non-interactive command execution in automated chains",
126
+ ],
127
+ "help_sections": [
128
+ {
129
+ "title": "What is Evil-WinRM?",
130
+ "color": "cyan",
131
+ "content": [
132
+ {
133
+ "title": "Overview",
134
+ "desc": "Evil-WinRM is a WinRM shell for pentesting that provides a fully interactive PowerShell session over Windows Remote Management.",
135
+ },
136
+ {
137
+ "title": "Use Cases",
138
+ "desc": "Post-exploitation access to Windows systems",
139
+ "tips": [
140
+ "Shell access after credential discovery",
141
+ "Pass-the-hash attacks with NTLM hashes",
142
+ "File upload/download for data exfil",
143
+ "Command execution for enumeration",
144
+ ],
145
+ },
146
+ ],
147
+ },
148
+ {
149
+ "title": "How to Use",
150
+ "color": "green",
151
+ "content": [
152
+ {
153
+ "title": "Basic Workflow",
154
+ "desc": "1. Find valid credentials (Hydra, secretsdump, etc.)\n 2. Check if WinRM is open (port 5985/5986)\n 3. Connect with evil-winrm using creds\n 4. Run commands or drop into interactive shell",
155
+ },
156
+ {
157
+ "title": "Authentication Methods",
158
+ "desc": "Different ways to authenticate",
159
+ "tips": [
160
+ "Password: -u user -p password",
161
+ "NTLM Hash: -u user -H hash (pass-the-hash)",
162
+ "Kerberos: -u user@domain -r REALM",
163
+ "SSL: Add -s flag for port 5986",
164
+ ],
165
+ },
166
+ ],
167
+ },
168
+ {
169
+ "title": "Tips & Best Practices",
170
+ "color": "yellow",
171
+ "content": [
172
+ (
173
+ "Best Practices:",
174
+ [
175
+ "Use -c flag for automated command execution",
176
+ "Check 'whoami /priv' for privilege escalation vectors",
177
+ "Use domain\\\\user or user@domain format for AD",
178
+ "Try both port 5985 and 5986 if one fails",
179
+ ],
180
+ ),
181
+ (
182
+ "Common Issues:",
183
+ [
184
+ "Access denied: Check credentials and permissions",
185
+ "Connection refused: WinRM may be disabled",
186
+ "Timeout: Target may be filtering WinRM ports",
187
+ "Kerberos errors: Check realm and DNS settings",
188
+ ],
189
+ ),
190
+ ],
191
+ },
192
+ ],
193
+ }
194
+
195
+ # Flatten presets from categories
196
+ for category_presets in HELP["preset_categories"].values():
197
+ HELP["presets"].extend(category_presets)
198
+
199
+
200
+ class EvilWinRMPlugin(PluginBase):
201
+ name = "Evil-WinRM"
202
+ tool = "evil_winrm"
203
+ category = "lateral_movement"
204
+ HELP = HELP
205
+
206
+ def build_command(
207
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
208
+ ):
209
+ """Build command for background execution with PID tracking."""
210
+ args = args or []
211
+
212
+ # Build evil-winrm command
213
+ cmd = ["evil-winrm", "-i", target]
214
+
215
+ # Add any extra arguments
216
+ cmd.extend(args)
217
+
218
+ return {"cmd": cmd, "timeout": 300} # 5 minute timeout for commands
219
+
220
+ def run(
221
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
222
+ ) -> int:
223
+ """Execute Evil-WinRM."""
224
+ args = args or []
225
+
226
+ if log_path:
227
+ return self._run_with_logpath(target, args, log_path)
228
+
229
+ return self._run_legacy(target, args)
230
+
231
+ def _run_with_logpath(self, target: str, args: List[str], log_path: str) -> int:
232
+ """Run Evil-WinRM and write output to log_path."""
233
+ try:
234
+ cmd = ["evil-winrm", "-i", target]
235
+ cmd.extend(args)
236
+
237
+ with open(log_path, "w", encoding="utf-8", errors="replace") as fh:
238
+ fh.write("=== Evil-WinRM Session ===\n")
239
+ fh.write(f"Target: {target}\n")
240
+ fh.write(f"Args: {' '.join(args)}\n")
241
+ fh.write(
242
+ f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n\n"
243
+ )
244
+ fh.write(f"Command: {' '.join(cmd)}\n\n")
245
+ fh.flush()
246
+
247
+ # Run evil-winrm
248
+ proc = subprocess.run(
249
+ cmd,
250
+ stdout=fh,
251
+ stderr=subprocess.STDOUT,
252
+ timeout=300, # 5 minutes
253
+ check=False,
254
+ )
255
+
256
+ fh.write(
257
+ f"\n\nCompleted: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n"
258
+ )
259
+ fh.write(f"Exit Code: {proc.returncode}\n")
260
+
261
+ return proc.returncode
262
+
263
+ except subprocess.TimeoutExpired:
264
+ with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
265
+ fh.write("\nERROR: Evil-WinRM command timed out after 300 seconds\n")
266
+ return 124
267
+
268
+ except FileNotFoundError:
269
+ with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
270
+ fh.write("\nERROR: evil-winrm not found in PATH\n")
271
+ fh.write("Install with: gem install evil-winrm\n")
272
+ return 127
273
+
274
+ except Exception as e:
275
+ with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
276
+ fh.write(f"\nERROR: {type(e).__name__}: {e}\n")
277
+ return 1
278
+
279
+ def _run_legacy(self, target: str, args: List[str]) -> int:
280
+ """Legacy execution without log_path."""
281
+ cmd = ["evil-winrm", "-i", target]
282
+ cmd.extend(args)
283
+
284
+ try:
285
+ proc = subprocess.run(cmd, capture_output=True, timeout=300, check=False)
286
+ return proc.returncode
287
+ except Exception:
288
+ return 1
289
+
290
+
291
+ plugin = EvilWinRMPlugin()
souleyez/plugins/ffuf.py CHANGED
@@ -26,11 +26,11 @@ HELP = {
26
26
  "- Use -e flag to append extensions automatically\n"
27
27
  "- Results are JSON-formatted for easy parsing\n"
28
28
  ),
29
- "usage": "souleyez jobs enqueue ffuf <target> --args \"-w wordlist.txt\"",
29
+ "usage": 'souleyez jobs enqueue ffuf <target> --args "-w wordlist.txt"',
30
30
  "examples": [
31
- "souleyez jobs enqueue ffuf http://example.com/FUZZ --args \"-w /usr/share/wordlists/dirb/common.txt\"",
32
- "souleyez jobs enqueue ffuf http://example.com/FUZZ --args \"-w wordlist.txt -e .php,.html,.txt\"",
33
- "souleyez jobs enqueue ffuf http://example.com/?id=FUZZ --args \"-w numbers.txt\"",
31
+ 'souleyez jobs enqueue ffuf http://example.com/FUZZ --args "-w data/wordlists/web_dirs_common.txt"',
32
+ 'souleyez jobs enqueue ffuf http://example.com/FUZZ --args "-w wordlist.txt -e .php,.html,.txt"',
33
+ 'souleyez jobs enqueue ffuf http://example.com/?id=FUZZ --args "-w numbers.txt"',
34
34
  ],
35
35
  "flags": [
36
36
  ["-w <wordlist>", "Wordlist file path"],
@@ -46,100 +46,178 @@ HELP = {
46
46
  {
47
47
  "name": "Directory Fuzzing",
48
48
  "args": ["-w", "data/wordlists/web_dirs_common.txt"],
49
- "desc": "Basic directory discovery"
49
+ "desc": "Basic directory discovery",
50
50
  },
51
51
  {
52
52
  "name": "File Fuzzing (PHP)",
53
- "args": ["-w", "data/wordlists/web_files_common.txt", "-e", ".php,.phps,.php3,.php4,.php5"],
54
- "desc": "Fuzz for PHP files"
55
- }
53
+ "args": [
54
+ "-w",
55
+ "data/wordlists/web_files_common.txt",
56
+ "-e",
57
+ ".php,.phps,.php3,.php4,.php5",
58
+ ],
59
+ "desc": "Fuzz for PHP files",
60
+ },
56
61
  ],
57
62
  "parameter_fuzzing": [
58
63
  {
59
64
  "name": "GET Parameters",
60
65
  "args": ["-w", "data/wordlists/web_files_common.txt"],
61
- "desc": "Discover GET parameters (add ?FUZZ=test to URL)"
66
+ "desc": "Discover GET parameters (add ?FUZZ=test to URL)",
62
67
  },
63
68
  {
64
69
  "name": "POST Parameters",
65
- "args": ["-w", "data/wordlists/web_files_common.txt", "-X", "POST", "-d", "FUZZ=test"],
66
- "desc": "Discover POST parameters"
70
+ "args": [
71
+ "-w",
72
+ "data/wordlists/web_files_common.txt",
73
+ "-X",
74
+ "POST",
75
+ "-d",
76
+ "FUZZ=test",
77
+ ],
78
+ "desc": "Discover POST parameters",
67
79
  },
68
80
  {
69
81
  "name": "Header Fuzzing",
70
- "args": ["-w", "data/wordlists/web_files_common.txt", "-H", "FUZZ: test"],
71
- "desc": "Find header-based vulnerabilities"
82
+ "args": [
83
+ "-w",
84
+ "data/wordlists/web_files_common.txt",
85
+ "-H",
86
+ "FUZZ: test",
87
+ ],
88
+ "desc": "Find header-based vulnerabilities",
72
89
  },
73
90
  {
74
91
  "name": "Value Fuzzing",
75
92
  "args": ["-w", "data/wordlists/web_files_common.txt"],
76
- "desc": "Test parameter values (use ?param=FUZZ)"
77
- }
93
+ "desc": "Test parameter values (use ?param=FUZZ)",
94
+ },
78
95
  ],
79
96
  "vhost_fuzzing": [
80
97
  {
81
98
  "name": "Virtual Hosts",
82
- "args": ["-w", "data/wordlists/subdomains_common.txt", "-H", "Host: FUZZ.target.com"],
83
- "desc": "Discover virtual hosts"
99
+ "args": [
100
+ "-w",
101
+ "data/wordlists/subdomains_common.txt",
102
+ "-H",
103
+ "Host: FUZZ.target.com",
104
+ ],
105
+ "desc": "Discover virtual hosts",
84
106
  }
85
- ]
107
+ ],
86
108
  },
87
109
  "presets": [
88
- {"name": "Directory Fuzzing", "args": ["-w", "data/wordlists/web_dirs_common.txt"], "desc": "Basic directory discovery"},
89
- {"name": "File Fuzzing (PHP)", "args": ["-w", "data/wordlists/web_files_common.txt", "-e", ".php,.phps,.php3,.php4,.php5"], "desc": "Fuzz for PHP files"},
90
- {"name": "GET Parameters", "args": ["-w", "data/wordlists/web_files_common.txt"], "desc": "Discover GET parameters (add ?FUZZ=test to URL)"},
91
- {"name": "POST Parameters", "args": ["-w", "data/wordlists/web_files_common.txt", "-X", "POST", "-d", "FUZZ=test"], "desc": "Discover POST parameters"},
92
- {"name": "Header Fuzzing", "args": ["-w", "data/wordlists/web_files_common.txt", "-H", "FUZZ: test"], "desc": "Find header-based vulnerabilities"},
93
- {"name": "Value Fuzzing", "args": ["-w", "data/wordlists/web_files_common.txt"], "desc": "Test parameter values (use ?param=FUZZ)"},
110
+ {
111
+ "name": "Directory Fuzzing",
112
+ "args": ["-w", "data/wordlists/web_dirs_common.txt"],
113
+ "desc": "Basic directory discovery",
114
+ },
115
+ {
116
+ "name": "File Fuzzing (PHP)",
117
+ "args": [
118
+ "-w",
119
+ "data/wordlists/web_files_common.txt",
120
+ "-e",
121
+ ".php,.phps,.php3,.php4,.php5",
122
+ ],
123
+ "desc": "Fuzz for PHP files",
124
+ },
125
+ {
126
+ "name": "GET Parameters",
127
+ "args": ["-w", "data/wordlists/web_files_common.txt"],
128
+ "desc": "Discover GET parameters (add ?FUZZ=test to URL)",
129
+ },
130
+ {
131
+ "name": "POST Parameters",
132
+ "args": [
133
+ "-w",
134
+ "data/wordlists/web_files_common.txt",
135
+ "-X",
136
+ "POST",
137
+ "-d",
138
+ "FUZZ=test",
139
+ ],
140
+ "desc": "Discover POST parameters",
141
+ },
142
+ {
143
+ "name": "Header Fuzzing",
144
+ "args": ["-w", "data/wordlists/web_files_common.txt", "-H", "FUZZ: test"],
145
+ "desc": "Find header-based vulnerabilities",
146
+ },
147
+ {
148
+ "name": "Value Fuzzing",
149
+ "args": ["-w", "data/wordlists/web_files_common.txt"],
150
+ "desc": "Test parameter values (use ?param=FUZZ)",
151
+ },
94
152
  ],
95
153
  "help_sections": [
96
154
  {
97
155
  "title": "What is ffuf?",
98
156
  "color": "cyan",
99
157
  "content": [
100
- {"title": "Overview", "desc": "ffuf (Fuzz Faster U Fool) is a modern, fast web fuzzer that can fuzz any part of an HTTP request - URLs, headers, POST data, and more."},
101
- {"title": "Use Cases", "desc": "Advanced web fuzzing beyond simple directory scans", "tips": [
102
- "Fuzz for hidden files with specific extensions",
103
- "Discover GET/POST parameters",
104
- "Find virtual hosts",
105
- "Test for IDOR vulnerabilities",
106
- "Fuzz headers and cookies"
107
- ]}
108
- ]
158
+ {
159
+ "title": "Overview",
160
+ "desc": "ffuf (Fuzz Faster U Fool) is a modern, fast web fuzzer that can fuzz any part of an HTTP request - URLs, headers, POST data, and more.",
161
+ },
162
+ {
163
+ "title": "Use Cases",
164
+ "desc": "Advanced web fuzzing beyond simple directory scans",
165
+ "tips": [
166
+ "Fuzz for hidden files with specific extensions",
167
+ "Discover GET/POST parameters",
168
+ "Find virtual hosts",
169
+ "Test for IDOR vulnerabilities",
170
+ "Fuzz headers and cookies",
171
+ ],
172
+ },
173
+ ],
109
174
  },
110
175
  {
111
176
  "title": "How to Use",
112
177
  "color": "green",
113
178
  "content": [
114
- {"title": "Basic Workflow", "desc": "1. Use FUZZ keyword to mark position to fuzz\n 2. Apply filters (-fc, -fs, -fw) to reduce noise\n 3. Use -e flag to append extensions automatically\n 4. Review JSON output for results"},
115
- {"title": "Key Features", "desc": "Powerful fuzzing capabilities", "tips": [
116
- "Directory fuzzing: ffuf -u http://site/FUZZ -w wordlist.txt",
117
- "Parameter fuzzing: ffuf -u http://site/?FUZZ=value -w params.txt",
118
- "Extension fuzzing: ffuf -u http://site/FUZZ -w words.txt -e .php,.html",
119
- "Filter results: -fc 404 (filter code), -fs 1234 (filter size)"
120
- ]}
121
- ]
179
+ {
180
+ "title": "Basic Workflow",
181
+ "desc": "1. Use FUZZ keyword to mark position to fuzz\n 2. Apply filters (-fc, -fs, -fw) to reduce noise\n 3. Use -e flag to append extensions automatically\n 4. Review JSON output for results",
182
+ },
183
+ {
184
+ "title": "Key Features",
185
+ "desc": "Powerful fuzzing capabilities",
186
+ "tips": [
187
+ "Directory fuzzing: ffuf -u http://site/FUZZ -w wordlist.txt",
188
+ "Parameter fuzzing: ffuf -u http://site/?FUZZ=value -w params.txt",
189
+ "Extension fuzzing: ffuf -u http://site/FUZZ -w words.txt -e .php,.html",
190
+ "Filter results: -fc 404 (filter code), -fs 1234 (filter size)",
191
+ ],
192
+ },
193
+ ],
122
194
  },
123
195
  {
124
196
  "title": "Tips & Best Practices",
125
197
  "color": "yellow",
126
198
  "content": [
127
- ("Best Practices:", [
128
- "Use filters early to reduce noise (-fc 404,403)",
129
- "Start with common wordlists, expand as needed",
130
- "Match response codes carefully (-mc 200,204,301,302)",
131
- "Save JSON output for parsing and analysis",
132
- "Use -t to control threads (default 40)"
133
- ]),
134
- ("Common Issues:", [
135
- "Too many results: Add -fc or -fs filters",
136
- "Missing FUZZ keyword: Add FUZZ to URL or headers",
137
- "Rate limiting: Reduce -t threads or add delays",
138
- "No matches: Check filters aren't too restrictive"
139
- ])
140
- ]
141
- }
142
- ]
199
+ (
200
+ "Best Practices:",
201
+ [
202
+ "Use filters early to reduce noise (-fc 404,403)",
203
+ "Start with common wordlists, expand as needed",
204
+ "Match response codes carefully (-mc 200,204,301,302)",
205
+ "Save JSON output for parsing and analysis",
206
+ "Use -t to control threads (default 40)",
207
+ ],
208
+ ),
209
+ (
210
+ "Common Issues:",
211
+ [
212
+ "Too many results: Add -fc or -fs filters",
213
+ "Missing FUZZ keyword: Add FUZZ to URL or headers",
214
+ "Rate limiting: Reduce -t threads or add delays",
215
+ "No matches: Check filters aren't too restrictive",
216
+ ],
217
+ ),
218
+ ],
219
+ },
220
+ ],
143
221
  }
144
222
 
145
223
 
@@ -149,74 +227,74 @@ class FfufPlugin(PluginBase):
149
227
  category = "scanning"
150
228
  HELP = HELP
151
229
 
152
-
153
- def build_command(self, target: str, args: List[str] = None, label: str = "", log_path: str = None):
230
+ def build_command(
231
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
232
+ ):
154
233
  """Build command for background execution with PID tracking."""
155
234
  if not target:
156
235
  if log_path:
157
- with open(log_path, 'w') as f:
236
+ with open(log_path, "w") as f:
158
237
  f.write("ERROR: Target URL is required\n")
159
238
  return None
160
-
239
+
161
240
  # Add FUZZ placeholder if not present
162
- if 'FUZZ' not in target:
163
- target = target.rstrip('/') + '/FUZZ'
164
-
241
+ if "FUZZ" not in target:
242
+ target = target.rstrip("/") + "/FUZZ"
243
+
165
244
  # Validate URL (skip if FUZZ is present)
166
- if 'FUZZ' not in target:
245
+ if "FUZZ" not in target:
167
246
  try:
168
247
  target = validate_url(target)
169
248
  except ValidationError as e:
170
249
  if log_path:
171
- with open(log_path, 'w') as f:
250
+ with open(log_path, "w") as f:
172
251
  f.write(f"ERROR: Invalid URL: {e}\n")
173
252
  return None
174
-
253
+
175
254
  args = args or []
176
-
255
+
177
256
  # Replace <target> placeholder
178
257
  args = [arg.replace("<target>", target) for arg in args]
179
-
258
+
180
259
  # ffuf uses -u flag for URL
181
260
  cmd = ["ffuf", "-u", target]
182
-
261
+
183
262
  # Force JSON output
184
263
  if log_path and "-o" not in args:
185
264
  cmd.extend(["-o", log_path, "-of", "json"])
186
-
265
+
187
266
  # Add user args
188
267
  cmd.extend(args)
189
-
268
+
190
269
  # Set defaults if not in args
191
270
  if "-mc" not in args and "-fc" not in args:
192
271
  cmd.extend(["-mc", "200,204,301,302,307,401,403"])
193
-
272
+
194
273
  if "-t" not in args:
195
274
  cmd.extend(["-t", "40"])
196
-
197
- return {
198
- 'cmd': cmd,
199
- 'timeout': 1800
200
- }
201
275
 
202
- def run(self, target: str, args: List[str] = None, label: str = "", log_path: str = None) -> int:
276
+ return {"cmd": cmd, "timeout": 1800}
277
+
278
+ def run(
279
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
280
+ ) -> int:
203
281
  """Execute ffuf and write JSON output to log_path."""
204
282
 
205
283
  # Validate URL
206
- if not target.startswith(('http://', 'https://')):
284
+ if not target.startswith(("http://", "https://")):
207
285
  target = f"http://{target}"
208
286
 
209
287
  # ffuf needs FUZZ keyword in URL
210
- if 'FUZZ' not in target:
211
- target = target.rstrip('/') + '/FUZZ'
288
+ if "FUZZ" not in target:
289
+ target = target.rstrip("/") + "/FUZZ"
212
290
 
213
291
  try:
214
292
  # Don't validate if FUZZ is in URL (it's not a real URL)
215
- if 'FUZZ' not in target:
293
+ if "FUZZ" not in target:
216
294
  target = validate_url(target)
217
295
  except ValidationError as e:
218
296
  if log_path:
219
- with open(log_path, 'w') as f:
297
+ with open(log_path, "w") as f:
220
298
  f.write(f"ERROR: Invalid URL: {e}\n")
221
299
  return 1
222
300
  raise ValueError(f"Invalid URL: {e}")
@@ -245,7 +323,9 @@ class FfufPlugin(PluginBase):
245
323
 
246
324
  if not log_path:
247
325
  try:
248
- proc = subprocess.run(cmd, capture_output=True, timeout=600, check=False)
326
+ proc = subprocess.run(
327
+ cmd, capture_output=True, timeout=600, check=False
328
+ )
249
329
  return proc.returncode
250
330
  except Exception:
251
331
  return 1
@@ -253,11 +333,7 @@ class FfufPlugin(PluginBase):
253
333
  try:
254
334
  # ffuf writes JSON directly to output file
255
335
  proc = subprocess.run(
256
- cmd,
257
- capture_output=True,
258
- timeout=600,
259
- check=False,
260
- text=True
336
+ cmd, capture_output=True, timeout=600, check=False, text=True
261
337
  )
262
338
 
263
339
  # If there was an error, write it to log