souleyez 2.43.29__py3-none-any.whl → 3.0.0__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 (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 +9564 -2881
  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 +564 -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 +409 -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 +417 -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 +913 -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 +219 -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 +237 -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 +23034 -10679
  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.29.dist-info → souleyez-3.0.0.dist-info}/METADATA +2 -2
  353. souleyez-3.0.0.dist-info/RECORD +443 -0
  354. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.29.dist-info/RECORD +0 -379
  356. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/top_level.txt +0 -0
@@ -31,13 +31,13 @@ HELP = {
31
31
  "- Capture output to a job log and convert confirmed issues into Findings — include proof-of-concept details and remediation guidance.\n"
32
32
  "- Always follow rules of engagement and consider getting explicit written permission for DB-level testing.\n"
33
33
  ),
34
- "usage": "souleyez jobs enqueue sqlmap <target_url> --args \"--batch\"",
34
+ "usage": 'souleyez jobs enqueue sqlmap <target_url> --args "--batch"',
35
35
  "examples": [
36
- "souleyez jobs enqueue sqlmap \"http://example.com/page.php?id=1\" --args \"--batch\"",
37
- "souleyez jobs enqueue sqlmap \"http://example.com/page.php?id=1\" --args \"--batch --dbs\"",
38
- "souleyez jobs enqueue sqlmap \"http://example.com/login\" --args \"--batch --forms\"",
39
- "souleyez jobs enqueue sqlmap \"http://example.com/page.php?id=1\" --args \"--batch --level=5 --risk=3\"",
40
- "souleyez jobs enqueue sqlmap \"http://example.com/page.php\" --args \"--batch --data='username=admin&password=pass' -p username\"",
36
+ 'souleyez jobs enqueue sqlmap "http://example.com/page.php?id=1" --args "--batch"',
37
+ 'souleyez jobs enqueue sqlmap "http://example.com/page.php?id=1" --args "--batch --dbs"',
38
+ 'souleyez jobs enqueue sqlmap "http://example.com/login" --args "--batch --forms"',
39
+ 'souleyez jobs enqueue sqlmap "http://example.com/page.php?id=1" --args "--batch --level=5 --risk=3"',
40
+ 'souleyez jobs enqueue sqlmap "http://example.com/page.php" --args "--batch --data=\'username=admin&password=pass\' -p username"',
41
41
  ],
42
42
  "flags": [
43
43
  ["--batch", "Never ask for user input, use default behavior"],
@@ -64,197 +64,378 @@ HELP = {
64
64
  {
65
65
  "name": "Quick Test",
66
66
  "args": ["--batch", "--level=1", "--risk=1"],
67
- "desc": "Quick SQL injection test (safe, low risk)"
67
+ "desc": "Quick SQL injection test (safe, low risk)",
68
68
  },
69
69
  {
70
70
  "name": "Standard Test",
71
71
  "args": ["--batch", "--level=2", "--risk=1"],
72
- "desc": "Standard detection (includes cookies/headers)"
72
+ "desc": "Standard detection (includes cookies/headers)",
73
73
  },
74
74
  {
75
75
  "name": "Extensive Test",
76
76
  "args": ["--batch", "--crawl=2", "--risk=2", "--level=3"],
77
- "desc": "Deep detection (includes cookies/headers and crawl 2 levels)"
78
- }
77
+ "desc": "Deep detection (includes cookies/headers and crawl 2 levels)",
78
+ },
79
79
  ],
80
80
  "form_crawl": [
81
81
  {
82
82
  "name": "Forms Quick",
83
83
  "args": ["--batch", "--forms", "--level=1"],
84
- "desc": "Test forms only (no crawl)"
84
+ "desc": "Test forms only (no crawl)",
85
85
  },
86
86
  {
87
87
  "name": "Forms + Crawl",
88
88
  "args": ["--batch", "--forms", "--crawl=2"],
89
- "desc": "Test forms and crawl 2 levels"
90
- }
89
+ "desc": "Test forms and crawl 2 levels",
90
+ },
91
91
  ],
92
92
  "enumeration": [
93
93
  {
94
94
  "name": "Current User Info",
95
95
  "args": ["--batch", "--current-user", "--current-db", "--hostname"],
96
- "desc": "Get current user, database, and hostname"
96
+ "desc": "Get current user, database, and hostname",
97
97
  },
98
98
  {
99
99
  "name": "Discover Databases",
100
- "args": ["--batch", "--dbs", "--forms", "--level=3", "--crawl=2", "--risk=2"],
101
- "desc": "Enumerate databases with deep crawl"
100
+ "args": [
101
+ "--batch",
102
+ "--dbs",
103
+ "--forms",
104
+ "--level=3",
105
+ "--crawl=2",
106
+ "--risk=2",
107
+ ],
108
+ "desc": "Enumerate databases with deep crawl",
102
109
  },
103
110
  {
104
111
  "name": "Enumerate Tables",
105
112
  "args": ["--batch", "-D", "<DB_NAME>", "--tables", "--crawl=2"],
106
- "desc": "List tables in database (replace <DB_NAME>)"
113
+ "desc": "List tables in database (replace <DB_NAME>)",
107
114
  },
108
115
  {
109
116
  "name": "Enumerate Columns",
110
- "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "--columns", "--crawl=2"],
111
- "desc": "List columns in table (replace <DB_NAME> and <TABLE>)"
117
+ "args": [
118
+ "--batch",
119
+ "-D",
120
+ "<DB_NAME>",
121
+ "-T",
122
+ "<TABLE>",
123
+ "--columns",
124
+ "--crawl=2",
125
+ ],
126
+ "desc": "List columns in table (replace <DB_NAME> and <TABLE>)",
112
127
  },
113
128
  {
114
129
  "name": "Check Privileges",
115
130
  "args": ["--batch", "--privileges"],
116
- "desc": "Check DB user privileges"
131
+ "desc": "Check DB user privileges",
117
132
  },
118
133
  {
119
134
  "name": "Is DBA",
120
135
  "args": ["--batch", "--is-dba"],
121
- "desc": "Check if current user is DBA"
122
- }
136
+ "desc": "Check if current user is DBA",
137
+ },
123
138
  ],
124
139
  "data_extraction": [
125
140
  {
126
141
  "name": "Extract Table Data",
127
- "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "--dump", "--crawl=2"],
128
- "desc": "Dump entire table (replace <DB_NAME> and <TABLE>)"
142
+ "args": [
143
+ "--batch",
144
+ "-D",
145
+ "<DB_NAME>",
146
+ "-T",
147
+ "<TABLE>",
148
+ "--dump",
149
+ "--crawl=2",
150
+ ],
151
+ "desc": "Dump entire table (replace <DB_NAME> and <TABLE>)",
129
152
  },
130
153
  {
131
154
  "name": "Extract Column Data",
132
- "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "-C", "<COLUMNS>", "--dump", "--crawl=2"],
133
- "desc": "Dump specific columns (e.g., username,password)"
155
+ "args": [
156
+ "--batch",
157
+ "-D",
158
+ "<DB_NAME>",
159
+ "-T",
160
+ "<TABLE>",
161
+ "-C",
162
+ "<COLUMNS>",
163
+ "--dump",
164
+ "--crawl=2",
165
+ ],
166
+ "desc": "Dump specific columns (e.g., username,password)",
134
167
  },
135
168
  {
136
169
  "name": "Dump Users & Passwords",
137
170
  "args": ["--batch", "--users", "--passwords"],
138
- "desc": "Dump all DB users and password hashes"
139
- }
171
+ "desc": "Dump all DB users and password hashes",
172
+ },
140
173
  ],
141
174
  "exploitation": [
142
175
  {
143
176
  "name": "OS Shell",
144
177
  "args": ["--batch", "--os-shell"],
145
- "desc": "Get interactive OS shell via SQLi"
178
+ "desc": "Get interactive OS shell via SQLi",
146
179
  },
147
180
  {
148
181
  "name": "OS Command",
149
182
  "args": ["--batch", "--os-cmd=whoami"],
150
- "desc": "Execute single OS command (replace whoami)"
183
+ "desc": "Execute single OS command (replace whoami)",
151
184
  },
152
185
  {
153
186
  "name": "Read File",
154
187
  "args": ["--batch", "--file-read=/etc/passwd"],
155
- "desc": "Read server files via SQLi (replace path)"
188
+ "desc": "Read server files via SQLi (replace path)",
156
189
  },
157
190
  {
158
191
  "name": "Write File",
159
- "args": ["--batch", "--file-write=<local_file>", "--file-dest=<remote_path>"],
160
- "desc": "Upload files to server (replace paths)"
161
- }
192
+ "args": [
193
+ "--batch",
194
+ "--file-write=<local_file>",
195
+ "--file-dest=<remote_path>",
196
+ ],
197
+ "desc": "Upload files to server (replace paths)",
198
+ },
162
199
  ],
163
200
  "waf_bypass": [
164
201
  {
165
202
  "name": "WAF Bypass - Space",
166
203
  "args": ["--batch", "--tamper=space2comment"],
167
- "desc": "Bypass space-based WAF detection"
204
+ "desc": "Bypass space-based WAF detection",
168
205
  },
169
206
  {
170
207
  "name": "WAF Bypass - Generic",
171
208
  "args": ["--batch", "--tamper=between,randomcase"],
172
- "desc": "Generic WAF evasion techniques"
209
+ "desc": "Generic WAF evasion techniques",
173
210
  },
174
211
  {
175
212
  "name": "WAF Bypass - Full",
176
- "args": ["--batch", "--tamper=space2comment,between,randomcase,charencode"],
177
- "desc": "Aggressive WAF bypass (multiple tampers)"
178
- }
179
- ]
213
+ "args": [
214
+ "--batch",
215
+ "--tamper=space2comment,between,randomcase,charencode",
216
+ ],
217
+ "desc": "Aggressive WAF bypass (multiple tampers)",
218
+ },
219
+ ],
180
220
  },
181
221
  "presets": [
182
222
  # Flattened list for backward compatibility - matches preset_categories order
183
223
  # Basic Detection
184
- {"name": "Quick Test", "args": ["--batch", "--level=1", "--risk=1"], "desc": "Quick SQL injection test (safe, low risk)"},
185
- {"name": "Standard Test", "args": ["--batch", "--level=2", "--risk=1"], "desc": "Standard detection (includes cookies/headers)"},
186
- {"name": "Extensive Test", "args": ["--batch", "--crawl=2", "--risk=2", "--level=3"], "desc": "Deep detection (includes cookies/headers and crawl 2 levels)"},
224
+ {
225
+ "name": "Quick Test",
226
+ "args": ["--batch", "--level=1", "--risk=1"],
227
+ "desc": "Quick SQL injection test (safe, low risk)",
228
+ },
229
+ {
230
+ "name": "Standard Test",
231
+ "args": ["--batch", "--level=2", "--risk=1"],
232
+ "desc": "Standard detection (includes cookies/headers)",
233
+ },
234
+ {
235
+ "name": "Extensive Test",
236
+ "args": ["--batch", "--crawl=2", "--risk=2", "--level=3"],
237
+ "desc": "Deep detection (includes cookies/headers and crawl 2 levels)",
238
+ },
187
239
  # Form Crawl
188
- {"name": "Forms Quick", "args": ["--batch", "--forms", "--level=1"], "desc": "Test forms only (no crawl)"},
189
- {"name": "Forms + Crawl", "args": ["--batch", "--forms", "--crawl=2"], "desc": "Test forms and crawl 2 levels"},
240
+ {
241
+ "name": "Forms Quick",
242
+ "args": ["--batch", "--forms", "--level=1"],
243
+ "desc": "Test forms only (no crawl)",
244
+ },
245
+ {
246
+ "name": "Forms + Crawl",
247
+ "args": ["--batch", "--forms", "--crawl=2"],
248
+ "desc": "Test forms and crawl 2 levels",
249
+ },
190
250
  # Enumeration
191
- {"name": "Current User Info", "args": ["--batch", "--current-user", "--current-db", "--hostname"], "desc": "Get current user, database, and hostname"},
192
- {"name": "Discover Databases", "args": ["--batch", "--dbs", "--forms", "--level=3", "--crawl=2", "--risk=2"], "desc": "Enumerate databases with deep crawl"},
193
- {"name": "Enumerate Tables", "args": ["--batch", "-D", "<DB_NAME>", "--tables", "--crawl=2"], "desc": "List tables in database (replace <DB_NAME>)"},
194
- {"name": "Enumerate Columns", "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "--columns", "--crawl=2"], "desc": "List columns in table (replace <DB_NAME> and <TABLE>)"},
195
- {"name": "Check Privileges", "args": ["--batch", "--privileges"], "desc": "Check DB user privileges"},
196
- {"name": "Is DBA", "args": ["--batch", "--is-dba"], "desc": "Check if current user is DBA"},
251
+ {
252
+ "name": "Current User Info",
253
+ "args": ["--batch", "--current-user", "--current-db", "--hostname"],
254
+ "desc": "Get current user, database, and hostname",
255
+ },
256
+ {
257
+ "name": "Discover Databases",
258
+ "args": [
259
+ "--batch",
260
+ "--dbs",
261
+ "--forms",
262
+ "--level=3",
263
+ "--crawl=2",
264
+ "--risk=2",
265
+ ],
266
+ "desc": "Enumerate databases with deep crawl",
267
+ },
268
+ {
269
+ "name": "Enumerate Tables",
270
+ "args": ["--batch", "-D", "<DB_NAME>", "--tables", "--crawl=2"],
271
+ "desc": "List tables in database (replace <DB_NAME>)",
272
+ },
273
+ {
274
+ "name": "Enumerate Columns",
275
+ "args": [
276
+ "--batch",
277
+ "-D",
278
+ "<DB_NAME>",
279
+ "-T",
280
+ "<TABLE>",
281
+ "--columns",
282
+ "--crawl=2",
283
+ ],
284
+ "desc": "List columns in table (replace <DB_NAME> and <TABLE>)",
285
+ },
286
+ {
287
+ "name": "Check Privileges",
288
+ "args": ["--batch", "--privileges"],
289
+ "desc": "Check DB user privileges",
290
+ },
291
+ {
292
+ "name": "Is DBA",
293
+ "args": ["--batch", "--is-dba"],
294
+ "desc": "Check if current user is DBA",
295
+ },
197
296
  # Data Extraction
198
- {"name": "Extract Table Data", "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "--dump", "--crawl=2"], "desc": "Dump entire table (replace <DB_NAME> and <TABLE>)"},
199
- {"name": "Extract Column Data", "args": ["--batch", "-D", "<DB_NAME>", "-T", "<TABLE>", "-C", "<COLUMNS>", "--dump", "--crawl=2"], "desc": "Dump specific columns (e.g., username,password)"},
200
- {"name": "Dump Users & Passwords", "args": ["--batch", "--users", "--passwords"], "desc": "Dump all DB users and password hashes"},
297
+ {
298
+ "name": "Extract Table Data",
299
+ "args": [
300
+ "--batch",
301
+ "-D",
302
+ "<DB_NAME>",
303
+ "-T",
304
+ "<TABLE>",
305
+ "--dump",
306
+ "--crawl=2",
307
+ ],
308
+ "desc": "Dump entire table (replace <DB_NAME> and <TABLE>)",
309
+ },
310
+ {
311
+ "name": "Extract Column Data",
312
+ "args": [
313
+ "--batch",
314
+ "-D",
315
+ "<DB_NAME>",
316
+ "-T",
317
+ "<TABLE>",
318
+ "-C",
319
+ "<COLUMNS>",
320
+ "--dump",
321
+ "--crawl=2",
322
+ ],
323
+ "desc": "Dump specific columns (e.g., username,password)",
324
+ },
325
+ {
326
+ "name": "Dump Users & Passwords",
327
+ "args": ["--batch", "--users", "--passwords"],
328
+ "desc": "Dump all DB users and password hashes",
329
+ },
201
330
  # Exploitation
202
- {"name": "OS Shell", "args": ["--batch", "--os-shell"], "desc": "Get interactive OS shell via SQLi"},
203
- {"name": "OS Command", "args": ["--batch", "--os-cmd=whoami"], "desc": "Execute single OS command (replace whoami)"},
204
- {"name": "Read File", "args": ["--batch", "--file-read=/etc/passwd"], "desc": "Read server files via SQLi (replace path)"},
205
- {"name": "Write File", "args": ["--batch", "--file-write=<local_file>", "--file-dest=<remote_path>"], "desc": "Upload files to server (replace paths)"},
331
+ {
332
+ "name": "OS Shell",
333
+ "args": ["--batch", "--os-shell"],
334
+ "desc": "Get interactive OS shell via SQLi",
335
+ },
336
+ {
337
+ "name": "OS Command",
338
+ "args": ["--batch", "--os-cmd=whoami"],
339
+ "desc": "Execute single OS command (replace whoami)",
340
+ },
341
+ {
342
+ "name": "Read File",
343
+ "args": ["--batch", "--file-read=/etc/passwd"],
344
+ "desc": "Read server files via SQLi (replace path)",
345
+ },
346
+ {
347
+ "name": "Write File",
348
+ "args": [
349
+ "--batch",
350
+ "--file-write=<local_file>",
351
+ "--file-dest=<remote_path>",
352
+ ],
353
+ "desc": "Upload files to server (replace paths)",
354
+ },
206
355
  # WAF Bypass
207
- {"name": "WAF Bypass - Space", "args": ["--batch", "--tamper=space2comment"], "desc": "Bypass space-based WAF detection"},
208
- {"name": "WAF Bypass - Generic", "args": ["--batch", "--tamper=between,randomcase"], "desc": "Generic WAF evasion techniques"},
209
- {"name": "WAF Bypass - Full", "args": ["--batch", "--tamper=space2comment,between,randomcase,charencode"], "desc": "Aggressive WAF bypass (multiple tampers)"}
356
+ {
357
+ "name": "WAF Bypass - Space",
358
+ "args": ["--batch", "--tamper=space2comment"],
359
+ "desc": "Bypass space-based WAF detection",
360
+ },
361
+ {
362
+ "name": "WAF Bypass - Generic",
363
+ "args": ["--batch", "--tamper=between,randomcase"],
364
+ "desc": "Generic WAF evasion techniques",
365
+ },
366
+ {
367
+ "name": "WAF Bypass - Full",
368
+ "args": ["--batch", "--tamper=space2comment,between,randomcase,charencode"],
369
+ "desc": "Aggressive WAF bypass (multiple tampers)",
370
+ },
210
371
  ],
211
372
  "help_sections": [
212
373
  {
213
374
  "title": "What is SQLMap?",
214
375
  "color": "cyan",
215
376
  "content": [
216
- {"title": "Overview", "desc": "SQLMap is the industry-standard automated SQL injection detection and exploitation tool that identifies injectable parameters and extracts database contents."},
217
- {"title": "Use Cases", "desc": "SQL injection testing and validation", "tips": [
218
- "Detect and confirm SQL injection vulnerabilities",
219
- "Fingerprint database engines (MySQL, PostgreSQL, etc.)",
220
- "Extract database schemas and data",
221
- "Test fix effectiveness after remediation"
222
- ]}
223
- ]
377
+ {
378
+ "title": "Overview",
379
+ "desc": "SQLMap is the industry-standard automated SQL injection detection and exploitation tool that identifies injectable parameters and extracts database contents.",
380
+ },
381
+ {
382
+ "title": "Use Cases",
383
+ "desc": "SQL injection testing and validation",
384
+ "tips": [
385
+ "Detect and confirm SQL injection vulnerabilities",
386
+ "Fingerprint database engines (MySQL, PostgreSQL, etc.)",
387
+ "Extract database schemas and data",
388
+ "Test fix effectiveness after remediation",
389
+ ],
390
+ },
391
+ ],
224
392
  },
225
393
  {
226
394
  "title": "How to Use",
227
395
  "color": "green",
228
396
  "content": [
229
- {"title": "Basic Workflow", "desc": "1. Start with detection mode (--batch --level=1)\n 2. Fingerprint database (--dbs, --current-db)\n 3. Enumerate schema (--tables, --columns)\n 4. Extract data with limits (--dump --limit 100)"},
230
- {"title": "Key Options", "desc": "Essential SQLMap parameters", "tips": [
231
- "--batch: Non-interactive mode (required)",
232
- "--dbs: List all databases",
233
- "--forms: Auto-detect and test forms",
234
- "--level/--risk: Control test intensity (1-5/1-3)"
235
- ]}
236
- ]
397
+ {
398
+ "title": "Basic Workflow",
399
+ "desc": "1. Start with detection mode (--batch --level=1)\n 2. Fingerprint database (--dbs, --current-db)\n 3. Enumerate schema (--tables, --columns)\n 4. Extract data with limits (--dump --limit 100)",
400
+ },
401
+ {
402
+ "title": "Key Options",
403
+ "desc": "Essential SQLMap parameters",
404
+ "tips": [
405
+ "--batch: Non-interactive mode (required)",
406
+ "--dbs: List all databases",
407
+ "--forms: Auto-detect and test forms",
408
+ "--level/--risk: Control test intensity (1-5/1-3)",
409
+ ],
410
+ },
411
+ ],
237
412
  },
238
413
  {
239
414
  "title": "Tips & Best Practices",
240
415
  "color": "yellow",
241
416
  "content": [
242
- ("Best Practices:", [
243
- "Always use --batch for non-interactive mode",
244
- "Start with low --risk and --level, increase if needed",
245
- "Use --limit to avoid extracting entire databases",
246
- "Save proof-of-concept to job log for findings",
247
- "ONLY run with explicit written authorization"
248
- ]),
249
- ("Common Issues:", [
250
- "No injection found: Try higher --level or --risk",
251
- "Too slow: Reduce --level or use specific techniques",
252
- "WAF blocking: Use --tamper scripts for evasion",
253
- "False positives: Manually verify all findings"
254
- ])
255
- ]
256
- }
257
- ]
417
+ (
418
+ "Best Practices:",
419
+ [
420
+ "Always use --batch for non-interactive mode",
421
+ "Start with low --risk and --level, increase if needed",
422
+ "Use --limit to avoid extracting entire databases",
423
+ "Save proof-of-concept to job log for findings",
424
+ "ONLY run with explicit written authorization",
425
+ ],
426
+ ),
427
+ (
428
+ "Common Issues:",
429
+ [
430
+ "No injection found: Try higher --level or --risk",
431
+ "Too slow: Reduce --level or use specific techniques",
432
+ "WAF blocking: Use --tamper scripts for evasion",
433
+ "False positives: Manually verify all findings",
434
+ ],
435
+ ),
436
+ ],
437
+ },
438
+ ],
258
439
  }
259
440
 
260
441
 
@@ -264,20 +445,22 @@ class SqlmapPlugin(PluginBase):
264
445
  category = "exploitation"
265
446
  HELP = HELP
266
447
 
267
- def build_command(self, target: str, args: List[str] = None, label: str = "", log_path: str = None):
448
+ def build_command(
449
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
450
+ ):
268
451
  """Build sqlmap command for background execution with PID tracking."""
269
452
  args = args or []
270
-
453
+
271
454
  # Handle plain IP/hostname - add protocol if missing
272
- if not target.startswith(('http://', 'https://')):
455
+ if not target.startswith(("http://", "https://")):
273
456
  target = f"http://{target}"
274
-
457
+
275
458
  # Validate URL
276
459
  try:
277
460
  target = validate_url(target)
278
461
  except ValidationError as e:
279
462
  if log_path:
280
- with open(log_path, 'w') as f:
463
+ with open(log_path, "w") as f:
281
464
  f.write(f"ERROR: Invalid URL: {e}\n")
282
465
  return None
283
466
 
@@ -290,16 +473,15 @@ class SqlmapPlugin(PluginBase):
290
473
  cmd = ["sqlmap", "-u", target] + args
291
474
  else:
292
475
  cmd = ["sqlmap"] + args
293
-
476
+
294
477
  # Replace <target> placeholder if present in args
295
478
  cmd = [arg.replace("<target>", target) for arg in cmd]
296
479
 
297
- return {
298
- 'cmd': cmd,
299
- 'timeout': 3600 # 1 hour timeout for deep scans
300
- }
480
+ return {"cmd": cmd, "timeout": 3600} # 1 hour timeout for deep scans
301
481
 
302
- def run(self, target: str, args: List[str] = None, label: str = "", log_path: str = None) -> int:
482
+ def run(
483
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
484
+ ) -> int:
303
485
  """
304
486
  Execute sqlmap scan and write output to log_path.
305
487
 
@@ -313,17 +495,17 @@ class SqlmapPlugin(PluginBase):
313
495
  int: Exit code (0=success, non-zero=error)
314
496
  """
315
497
  args = args or []
316
-
498
+
317
499
  # Handle plain IP/hostname - add protocol if missing
318
- if not target.startswith(('http://', 'https://')):
500
+ if not target.startswith(("http://", "https://")):
319
501
  target = f"http://{target}"
320
-
502
+
321
503
  # Validate URL
322
504
  try:
323
505
  target = validate_url(target)
324
506
  except ValidationError as e:
325
507
  if log_path:
326
- with open(log_path, 'w') as f:
508
+ with open(log_path, "w") as f:
327
509
  f.write(f"ERROR: Invalid URL: {e}\n")
328
510
  return 1
329
511
  raise ValueError(f"Invalid URL: {e}")
@@ -340,14 +522,16 @@ class SqlmapPlugin(PluginBase):
340
522
  else:
341
523
  # -u already in args, don't add target again
342
524
  cmd = ["sqlmap"] + args
343
-
525
+
344
526
  # Replace <target> placeholder if present in args
345
527
  cmd = [arg.replace("<target>", target) for arg in cmd]
346
528
 
347
529
  if not log_path:
348
530
  # Fallback for direct calls (shouldn't happen in background jobs)
349
531
  try:
350
- proc = subprocess.run(cmd, capture_output=True, timeout=3600, check=False) # 1 hour
532
+ proc = subprocess.run(
533
+ cmd, capture_output=True, timeout=3600, check=False
534
+ ) # 1 hour
351
535
  return proc.returncode
352
536
  except Exception:
353
537
  return 1
@@ -356,7 +540,9 @@ class SqlmapPlugin(PluginBase):
356
540
  try:
357
541
  with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
358
542
  fh.write(f"Command: {' '.join(cmd)}\n")
359
- fh.write(f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n\n")
543
+ fh.write(
544
+ f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n\n"
545
+ )
360
546
  fh.flush()
361
547
 
362
548
  proc = subprocess.run(
@@ -364,10 +550,12 @@ class SqlmapPlugin(PluginBase):
364
550
  stdout=fh,
365
551
  stderr=subprocess.STDOUT,
366
552
  timeout=3600, # SQLMap can take 1+ hours for deep scans
367
- check=False
553
+ check=False,
368
554
  )
369
555
 
370
- fh.write(f"\nCompleted: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n")
556
+ fh.write(
557
+ f"\nCompleted: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n"
558
+ )
371
559
  fh.write(f"Exit Code: {proc.returncode}\n")
372
560
 
373
561
  return proc.returncode