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
@@ -16,162 +16,182 @@ logger = get_logger(__name__)
16
16
 
17
17
  class SQLMapDataManager:
18
18
  """Manager for storing and retrieving SQLMap discoveries."""
19
-
19
+
20
20
  def __init__(self, db_path: str = None):
21
21
  self.db = Database(db_path)
22
-
23
- def add_database(self, engagement_id: int, host_id: int, database_name: str,
24
- dbms_type: str = None) -> Optional[int]:
22
+
23
+ def add_database(
24
+ self,
25
+ engagement_id: int,
26
+ host_id: int,
27
+ database_name: str,
28
+ dbms_type: str = None,
29
+ ) -> Optional[int]:
25
30
  """
26
31
  Add a discovered database.
27
-
32
+
28
33
  Args:
29
34
  engagement_id: Engagement ID
30
35
  host_id: Host ID
31
36
  database_name: Name of the database
32
37
  dbms_type: Type of DBMS (MySQL, PostgreSQL, etc.)
33
-
38
+
34
39
  Returns:
35
40
  Database ID if successful, None otherwise
36
41
  """
37
42
  try:
38
43
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
39
44
  cursor = conn.cursor()
40
-
45
+
41
46
  # Try to insert, or get existing ID
42
- cursor.execute("""
47
+ cursor.execute(
48
+ """
43
49
  INSERT OR IGNORE INTO sqli_databases
44
50
  (engagement_id, host_id, database_name, dbms_type)
45
51
  VALUES (?, ?, ?, ?)
46
- """, (engagement_id, host_id, database_name, dbms_type))
47
-
52
+ """,
53
+ (engagement_id, host_id, database_name, dbms_type),
54
+ )
55
+
48
56
  if cursor.rowcount > 0:
49
57
  db_id = cursor.lastrowid
50
58
  else:
51
59
  # Get existing ID
52
- cursor.execute("""
60
+ cursor.execute(
61
+ """
53
62
  SELECT id FROM sqli_databases
54
63
  WHERE engagement_id = ? AND host_id = ? AND database_name = ?
55
- """, (engagement_id, host_id, database_name))
64
+ """,
65
+ (engagement_id, host_id, database_name),
66
+ )
56
67
  row = cursor.fetchone()
57
68
  db_id = row[0] if row else None
58
-
69
+
59
70
  conn.commit()
60
71
  conn.close()
61
-
62
- logger.info(f"Added database: {database_name}", extra={
63
- "db_id": db_id,
64
- "dbms_type": dbms_type
65
- })
72
+
73
+ logger.info(
74
+ f"Added database: {database_name}",
75
+ extra={"db_id": db_id, "dbms_type": dbms_type},
76
+ )
66
77
  return db_id
67
-
78
+
68
79
  except Exception as e:
69
80
  logger.error(f"Failed to add database: {e}")
70
81
  return None
71
-
72
- def add_table(self, database_id: int, table_name: str,
73
- row_count: int = None) -> Optional[int]:
82
+
83
+ def add_table(
84
+ self, database_id: int, table_name: str, row_count: int = None
85
+ ) -> Optional[int]:
74
86
  """
75
87
  Add a discovered table.
76
-
88
+
77
89
  Args:
78
90
  database_id: Database ID
79
91
  table_name: Name of the table
80
92
  row_count: Number of rows in the table
81
-
93
+
82
94
  Returns:
83
95
  Table ID if successful, None otherwise
84
96
  """
85
97
  try:
86
98
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
87
99
  cursor = conn.cursor()
88
-
89
- cursor.execute("""
100
+
101
+ cursor.execute(
102
+ """
90
103
  INSERT OR IGNORE INTO sqli_tables
91
104
  (database_id, table_name, row_count)
92
105
  VALUES (?, ?, ?)
93
- """, (database_id, table_name, row_count))
94
-
106
+ """,
107
+ (database_id, table_name, row_count),
108
+ )
109
+
95
110
  if cursor.rowcount > 0:
96
111
  table_id = cursor.lastrowid
97
112
  else:
98
- cursor.execute("""
113
+ cursor.execute(
114
+ """
99
115
  SELECT id FROM sqli_tables
100
116
  WHERE database_id = ? AND table_name = ?
101
- """, (database_id, table_name))
117
+ """,
118
+ (database_id, table_name),
119
+ )
102
120
  row = cursor.fetchone()
103
121
  table_id = row[0] if row else None
104
-
122
+
105
123
  conn.commit()
106
124
  conn.close()
107
-
108
- logger.info(f"Added table: {table_name}", extra={
109
- "table_id": table_id,
110
- "row_count": row_count
111
- })
125
+
126
+ logger.info(
127
+ f"Added table: {table_name}",
128
+ extra={"table_id": table_id, "row_count": row_count},
129
+ )
112
130
  return table_id
113
-
131
+
114
132
  except Exception as e:
115
133
  logger.error(f"Failed to add table: {e}")
116
134
  return None
117
-
135
+
118
136
  def add_columns(self, table_id: int, columns: List[Dict[str, str]]) -> bool:
119
137
  """
120
138
  Add discovered columns for a table.
121
-
139
+
122
140
  Args:
123
141
  table_id: Table ID
124
142
  columns: List of column dicts with 'name' and optionally 'type'
125
-
143
+
126
144
  Returns:
127
145
  True if successful, False otherwise
128
146
  """
129
147
  try:
130
148
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
131
149
  cursor = conn.cursor()
132
-
150
+
133
151
  for col in columns:
134
- col_name = col.get('name') or col.get('column_name')
135
- col_type = col.get('type') or col.get('column_type')
136
-
137
- cursor.execute("""
152
+ col_name = col.get("name") or col.get("column_name")
153
+ col_type = col.get("type") or col.get("column_type")
154
+
155
+ cursor.execute(
156
+ """
138
157
  INSERT OR IGNORE INTO sqli_columns
139
158
  (table_id, column_name, column_type)
140
159
  VALUES (?, ?, ?)
141
- """, (table_id, col_name, col_type))
142
-
160
+ """,
161
+ (table_id, col_name, col_type),
162
+ )
163
+
143
164
  conn.commit()
144
165
  conn.close()
145
-
146
- logger.info(f"Added {len(columns)} columns", extra={
147
- "table_id": table_id
148
- })
166
+
167
+ logger.info(f"Added {len(columns)} columns", extra={"table_id": table_id})
149
168
  return True
150
-
169
+
151
170
  except Exception as e:
152
171
  logger.error(f"Failed to add columns: {e}")
153
172
  return False
154
-
155
- def add_dumped_data(self, table_id: int, data: List[Dict[str, Any]],
156
- csv_file_path: str = None) -> Optional[int]:
173
+
174
+ def add_dumped_data(
175
+ self, table_id: int, data: List[Dict[str, Any]], csv_file_path: str = None
176
+ ) -> Optional[int]:
157
177
  """
158
178
  Add dumped table data.
159
-
179
+
160
180
  Args:
161
181
  table_id: Table ID
162
182
  data: List of row dicts
163
183
  csv_file_path: Path to SQLMap's CSV dump file
164
-
184
+
165
185
  Returns:
166
186
  Dump ID if successful, None otherwise
167
187
  """
168
188
  try:
169
189
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
170
190
  cursor = conn.cursor()
171
-
191
+
172
192
  data_json = json.dumps(data)
173
193
  row_count = len(data)
174
-
194
+
175
195
  # Try to encrypt if crypto is available
176
196
  is_encrypted = 0
177
197
  try:
@@ -183,38 +203,47 @@ class SQLMapDataManager:
183
203
  except Exception as e:
184
204
  logger.warning(f"Could not encrypt dumped data: {e}")
185
205
  # Continue with unencrypted data
186
-
187
- cursor.execute("""
206
+
207
+ cursor.execute(
208
+ """
188
209
  INSERT INTO sqli_dumped_data
189
210
  (table_id, data_json, csv_file_path, row_count, is_encrypted)
190
211
  VALUES (?, ?, ?, ?, ?)
191
- """, (table_id, data_json, csv_file_path, row_count, is_encrypted))
192
-
212
+ """,
213
+ (table_id, data_json, csv_file_path, row_count, is_encrypted),
214
+ )
215
+
193
216
  dump_id = cursor.lastrowid
194
217
  conn.commit()
195
218
  conn.close()
196
-
197
- logger.info(f"Added dumped data", extra={
198
- "table_id": table_id,
199
- "row_count": row_count,
200
- "dump_id": dump_id,
201
- "encrypted": is_encrypted
202
- })
219
+
220
+ logger.info(
221
+ f"Added dumped data",
222
+ extra={
223
+ "table_id": table_id,
224
+ "row_count": row_count,
225
+ "dump_id": dump_id,
226
+ "encrypted": is_encrypted,
227
+ },
228
+ )
203
229
  return dump_id
204
-
230
+
205
231
  except Exception as e:
206
232
  logger.error(f"Failed to add dumped data: {e}")
207
233
  return None
208
-
209
- def get_databases(self, engagement_id: int, host_id: int = None) -> List[Dict[str, Any]]:
234
+
235
+ def get_databases(
236
+ self, engagement_id: int, host_id: int = None
237
+ ) -> List[Dict[str, Any]]:
210
238
  """Get all discovered databases for an engagement."""
211
239
  try:
212
240
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
213
241
  conn.row_factory = sqlite3.Row
214
242
  cursor = conn.cursor()
215
-
243
+
216
244
  if host_id:
217
- cursor.execute("""
245
+ cursor.execute(
246
+ """
218
247
  SELECT d.*, h.ip_address, h.hostname,
219
248
  COUNT(DISTINCT t.id) as table_count
220
249
  FROM sqli_databases d
@@ -223,9 +252,12 @@ class SQLMapDataManager:
223
252
  WHERE d.engagement_id = ? AND d.host_id = ?
224
253
  GROUP BY d.id
225
254
  ORDER BY d.discovered_at DESC
226
- """, (engagement_id, host_id))
255
+ """,
256
+ (engagement_id, host_id),
257
+ )
227
258
  else:
228
- cursor.execute("""
259
+ cursor.execute(
260
+ """
229
261
  SELECT d.*, h.ip_address, h.hostname,
230
262
  COUNT(DISTINCT t.id) as table_count
231
263
  FROM sqli_databases d
@@ -234,25 +266,28 @@ class SQLMapDataManager:
234
266
  WHERE d.engagement_id = ?
235
267
  GROUP BY d.id
236
268
  ORDER BY d.discovered_at DESC
237
- """, (engagement_id,))
238
-
269
+ """,
270
+ (engagement_id,),
271
+ )
272
+
239
273
  rows = cursor.fetchall()
240
274
  conn.close()
241
-
275
+
242
276
  return [dict(row) for row in rows]
243
-
277
+
244
278
  except Exception as e:
245
279
  logger.error(f"Failed to get databases: {e}")
246
280
  return []
247
-
281
+
248
282
  def get_tables(self, database_id: int) -> List[Dict[str, Any]]:
249
283
  """Get all tables for a database."""
250
284
  try:
251
285
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
252
286
  conn.row_factory = sqlite3.Row
253
287
  cursor = conn.cursor()
254
-
255
- cursor.execute("""
288
+
289
+ cursor.execute(
290
+ """
256
291
  SELECT t.*,
257
292
  COUNT(DISTINCT c.id) as column_count,
258
293
  CASE WHEN d.id IS NOT NULL THEN 1 ELSE 0 END as has_dumped_data
@@ -262,62 +297,70 @@ class SQLMapDataManager:
262
297
  WHERE t.database_id = ?
263
298
  GROUP BY t.id
264
299
  ORDER BY t.table_name
265
- """, (database_id,))
266
-
300
+ """,
301
+ (database_id,),
302
+ )
303
+
267
304
  rows = cursor.fetchall()
268
305
  conn.close()
269
-
306
+
270
307
  return [dict(row) for row in rows]
271
-
308
+
272
309
  except Exception as e:
273
310
  logger.error(f"Failed to get tables: {e}")
274
311
  return []
275
-
312
+
276
313
  def get_columns(self, table_id: int) -> List[Dict[str, Any]]:
277
314
  """Get all columns for a table."""
278
315
  try:
279
316
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
280
317
  conn.row_factory = sqlite3.Row
281
318
  cursor = conn.cursor()
282
-
283
- cursor.execute("""
319
+
320
+ cursor.execute(
321
+ """
284
322
  SELECT * FROM sqli_columns
285
323
  WHERE table_id = ?
286
324
  ORDER BY column_name
287
- """, (table_id,))
288
-
325
+ """,
326
+ (table_id,),
327
+ )
328
+
289
329
  rows = cursor.fetchall()
290
330
  conn.close()
291
-
331
+
292
332
  return [dict(row) for row in rows]
293
-
333
+
294
334
  except Exception as e:
295
335
  logger.error(f"Failed to get columns: {e}")
296
336
  return []
297
-
337
+
298
338
  def get_dumped_data(self, table_id: int) -> Optional[Dict[str, Any]]:
299
339
  """Get dumped data for a table."""
300
340
  try:
301
341
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
302
342
  conn.row_factory = sqlite3.Row
303
343
  cursor = conn.cursor()
304
-
305
- cursor.execute("""
344
+
345
+ cursor.execute(
346
+ """
306
347
  SELECT * FROM sqli_dumped_data
307
348
  WHERE table_id = ?
308
349
  ORDER BY dumped_at DESC
309
350
  LIMIT 1
310
- """, (table_id,))
311
-
351
+ """,
352
+ (table_id,),
353
+ )
354
+
312
355
  row = cursor.fetchone()
313
356
  conn.close()
314
-
357
+
315
358
  if row:
316
359
  result = dict(row)
317
- data_json = result['data_json']
318
-
360
+ data_json = result["data_json"]
361
+
319
362
  # Decrypt if encrypted
320
- if result.get('is_encrypted'):
363
+ if result.get("is_encrypted"):
321
364
  try:
322
365
  crypto = get_crypto_manager()
323
366
  if crypto.is_encryption_enabled():
@@ -328,63 +371,75 @@ class SQLMapDataManager:
328
371
  except Exception as e:
329
372
  logger.error(f"Failed to decrypt dumped data: {e}")
330
373
  return None
331
-
332
- result['data'] = json.loads(data_json)
374
+
375
+ result["data"] = json.loads(data_json)
333
376
  return result
334
377
  return None
335
-
378
+
336
379
  except Exception as e:
337
380
  logger.error(f"Failed to get dumped data: {e}")
338
381
  return None
339
-
382
+
340
383
  def get_summary(self, engagement_id: int) -> Dict[str, int]:
341
384
  """Get summary statistics for SQLMap discoveries."""
342
385
  try:
343
386
  conn = sqlite3.connect(self.db.db_path, timeout=30.0)
344
387
  cursor = conn.cursor()
345
-
388
+
346
389
  # Count databases
347
- cursor.execute("""
390
+ cursor.execute(
391
+ """
348
392
  SELECT COUNT(*) FROM sqli_databases
349
393
  WHERE engagement_id = ?
350
- """, (engagement_id,))
394
+ """,
395
+ (engagement_id,),
396
+ )
351
397
  db_count = cursor.fetchone()[0]
352
-
398
+
353
399
  # Count tables
354
- cursor.execute("""
400
+ cursor.execute(
401
+ """
355
402
  SELECT COUNT(*) FROM sqli_tables t
356
403
  JOIN sqli_databases d ON t.database_id = d.id
357
404
  WHERE d.engagement_id = ?
358
- """, (engagement_id,))
405
+ """,
406
+ (engagement_id,),
407
+ )
359
408
  table_count = cursor.fetchone()[0]
360
-
409
+
361
410
  # Count columns
362
- cursor.execute("""
411
+ cursor.execute(
412
+ """
363
413
  SELECT COUNT(*) FROM sqli_columns c
364
414
  JOIN sqli_tables t ON c.table_id = t.id
365
415
  JOIN sqli_databases d ON t.database_id = d.id
366
416
  WHERE d.engagement_id = ?
367
- """, (engagement_id,))
417
+ """,
418
+ (engagement_id,),
419
+ )
368
420
  column_count = cursor.fetchone()[0]
369
-
421
+
370
422
  # Count dumped tables
371
- cursor.execute("""
423
+ cursor.execute(
424
+ """
372
425
  SELECT COUNT(DISTINCT table_id) FROM sqli_dumped_data dd
373
426
  JOIN sqli_tables t ON dd.table_id = t.id
374
427
  JOIN sqli_databases d ON t.database_id = d.id
375
428
  WHERE d.engagement_id = ?
376
- """, (engagement_id,))
429
+ """,
430
+ (engagement_id,),
431
+ )
377
432
  dumped_count = cursor.fetchone()[0]
378
-
433
+
379
434
  conn.close()
380
-
435
+
381
436
  return {
382
- 'databases': db_count,
383
- 'tables': table_count,
384
- 'columns': column_count,
385
- 'dumped_tables': dumped_count
437
+ "databases": db_count,
438
+ "tables": table_count,
439
+ "columns": column_count,
440
+ "dumped_tables": dumped_count,
386
441
  }
387
-
442
+
388
443
  except Exception as e:
389
444
  logger.error(f"Failed to get summary: {e}")
390
- return {'databases': 0, 'tables': 0, 'columns': 0, 'dumped_tables': 0}
445
+ return {"databases": 0, "tables": 0, "columns": 0, "dumped_tables": 0}