#!/usr/bin/env python3
import subprocess
import urllib.parse
import datetime
import argparse
# Configuration
TARGET_URL = 'http://localhost:8080'
TIMEOUT = 8
OUTPUT_FILE = "waf_test_results.log"
DEFAULT_USER_AGENT = "WAF-Test-Script/1.0" # Default User-Agent
# Colors for output
GREEN = '\033[0;32m'
RED = '\033[0;31m'
BLUE = '\033[0;34m'
YELLOW = '\033[0;33m'
NC = '\033[0m'
def test_url(url, description, expected_code, headers=None, body=None, default_user_agent=None):
url_encoded = urllib.parse.quote(url, safe=':/?=&')
curl_cmd = [
'curl', '-s', '-k', '-w', '%{http_code}', '--connect-timeout', str(TIMEOUT),
'--max-time', str(TIMEOUT), '-o', '/dev/null'
]
if headers:
headers_to_use = headers.copy()
if 'User-Agent' not in headers_to_use and default_user_agent:
headers_to_use['User-Agent'] = default_user_agent
elif default_user_agent:
headers_to_use = {'User-Agent': default_user_agent}
else:
headers_to_use = None
if headers_to_use:
for key, value in headers_to_use.items():
curl_cmd.extend(['-H', f"{key}: {value}"])
if body:
curl_cmd.extend(['-d', body])
curl_cmd.append(url_encoded)
try:
process = subprocess.run(curl_cmd, capture_output=True, text=True, check=False)
response = process.stdout.strip()
curl_status = process.returncode
if curl_status != 0:
print(f"{RED}[!]{NC} {description:<70} [CURL Error: {curl_status}]")
with open(OUTPUT_FILE, "a") as f:
f.write(f"[ERROR] {description} - URL: {url}, Headers: {headers_to_use}, Body: {body}, Expected: {expected_code}, CURL Status: {curl_status}\n")
return False
if response == str(expected_code):
print(f"{GREEN}[✓]{NC} {description:<70} [{response}]")
with open(OUTPUT_FILE, "a") as f:
f.write(f"[PASS] {description} - URL: {url}, Headers: {headers_to_use}, Body: {body}, Expected: {expected_code}, Got: {response}\n")
return True
else:
print(f"{RED}[✗]{NC} {description:<70} [{response}] (Expected: {expected_code})")
with open(OUTPUT_FILE, "a") as f:
f.write(f"[FAIL] {description} - URL: {url}, Headers: {headers_to_use}, Body: {body}, Expected: {expected_code}, Got: {response}\n")
return False
except Exception as e:
print(f"{RED}[!] {description:<70} [Exception: {e}]{NC}")
with open(OUTPUT_FILE, "a") as f:
f.write(f"[ERROR] {description} - URL: {url}, Headers: {headers_to_use}, Body: {body}, Expected: {expected_code}, Exception: {e}\n")
return False
test_cases = [
# SQL Injection (SQLi) Tests
("SQLi", f"{TARGET_URL}/?q=1", "SQLi (Level 1) - Basic Parameter", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'", "SQLi (Level 2) - Single Quote", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' -- -", "SQLi (Level 3) - Comment Injection", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' OR '1'='1", "SQLi (Level 4) - Simple OR Bypass", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND 1=1", "SQLi (Level 5) - Simple AND Bypass", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1; SELECT 1--", "SQLi (Level 6) - Statement Terminator", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=union select null,null--", "SQLi (Level 7) - Basic Union", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=union/*comment*/select null,null--", "SQLi (Level 8) - Union with Comment", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=un/**/ion select null,null--", "SQLi (Level 9) - Union with Inline Comment", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=%2575nion select null,null--", "SQLi (Level 10) - Union URL Encoded", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' ORDER BY 1--", "SQLi (Level 11) - Order By Clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' GROUP BY 1--", "SQLi (Level 12) - Group By Clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' HAVING 1=1--", "SQLi (Level 13) - Having Clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1;EXEC xp_cmdshell 'dir'--", "SQLi (Level 14) - xp_cmdshell", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1;CREATE TABLE test (id INT)--", "SQLi (Level 15) - CREATE TABLE", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; INSERT INTO users (username) VALUES ('test')--", "SQLi (Level 16) - INSERT Statement", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; UPDATE users SET username = 'test' WHERE id = 1--", "SQLi (Level 17) - UPDATE Statement", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; DELETE FROM users WHERE id = 1--", "SQLi (Level 18) - DELETE Statement", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND (SELECT COUNT(*) FROM users)=1--", "SQLi (Level 19) - Subquery", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND EXISTS (SELECT * FROM users)--", "SQLi (Level 20) - EXISTS Clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND ASCII(SUBSTR((SELECT USER()),1,1))>1--", "SQLi (Level 21) - Blind SQL (ASCII)", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND LENGTH((SELECT USER()))>1--", "SQLi (Level 22) - Blind SQL (Length)", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1; IF (1=1) SELECT 1 ELSE SELECT 0;--", "SQLi (Level 23) - Conditional Statement", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND CASE WHEN (1=1) THEN 1 ELSE 0 END=1--", "SQLi (Level 24) - Case Statement", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=SLEEP(5)", "SQLi (Level 25) - Time-Based Blind", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1 AND benchmark(5000000,MD5('A'))--", "SQLi (Level 26) - MySQL Time-Based", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=CAST(1 AS INT)", "SQLi (Level 27) - Data Type Conversion", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=CONVERT(INT,1)", "SQLi (Level 28) - Data Type Conversion (MSSQL)", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=EXTRACTVALUE(xmltype('1'),'/x/y')", "SQLi (Level 29) - Error-Based (XML)", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=CTXSYS.DRITHSX.SN(user_tables,'1=1')", "SQLi (Level 30) - Oracle Error-Based", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SHOW DATABASES;--", "SQLi (Level 31) - MySQL Stacked Query", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; EXEC sp_databases;--", "SQLi (Level 32) - MSSQL Stacked Query", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=CREATE USER testuser WITH PASSWORD 'password';", "SQLi (Level 33) - PostgreSQL Stacked Query", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=SELECT CASE WHEN (1=1) THEN to_char(current_timestamp) ELSE '' END", "SQLi (Level 34) - PostgreSQL Conditional", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=SELECT utl_inaddr.get_host_name('localhost') FROM dual", "SQLi (Level 35) - Oracle Function Call", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=SELECT top 1 name FROM sys.databases", "SQLi (Level 36) - MSSQL Information Schema", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=SELECT table_name FROM information_schema.tables", "SQLi (Level 37) - MySQL Information Schema", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' OR 1=1 -- -", "SQLi (Level 38) - OR Bypass with Comment", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND 1=0 -- -", "SQLi (Level 39) - AND Bypass with Comment", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' /**/OR/**/1=1--", "SQLi (Level 40) - OR Bypass with Complex Comment", 403, None, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 1) - Simple Header Injection", 403, {"X-Custom-SQL": "'"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 2) - Union in Header", 403, {"X-Custom-SQL": "union select 1,2--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 3) - Complex Union", 403, {"X-Custom-SQL": "/*!UNION*/ SELECT null, concat(0x7162717671,version(),0x716b717a71), null--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 4) - User-Agent Injection", 403, {"User-Agent": "test' OR '1'='1"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 5) - Referer Injection", 403, {"Referer": "' OR '1'='1"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Header Level 6) - Custom Header with Union", 403, {"X-Custom-SQL-Union": "union select 1,2--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Cookie Level 1) - Simple Cookie Injection", 403, {"Cookie": "sql_injection='"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Cookie Level 2) - Basic Union", 403, {"Cookie": "sql_injection=union select 1,2--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Cookie Level 3) - Error Based", 403, {"Cookie": "sql_injection=1' AND (SELECT CHAR(75)||CHAR(97)||CHAR(122)||CHAR(99)||CHAR(75))>0--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Cookie Level 4) - Cookie with OR Bypass", 403, {"Cookie": "sql_injection=1' OR '1'='1--"}, None),
("SQLi", f"{TARGET_URL}/", "SQLi (Cookie Level 5) - Cookie with Stacked Query", 403, {"Cookie": "sql_injection=1'; SELECT 1;--"}, None),
("SQLi", f"{TARGET_URL}/?q=1' AND (SELECT 1 FROM dual WHERE 1=1)--", "SQLi (Level 41) - Oracle Subquery", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND (SELECT 'a' FROM (SELECT 1) AS x)--", "SQLi (Level 42) - Subquery Aliasing", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; DECLARE @a INT; SET @a = 1; SELECT @a;--", "SQLi (Level 43) - MSSQL Variable Declaration", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1' AND EXISTS (SELECT 1 FROM users WHERE id=1)--", "SQLi (Level 44) - EXISTS Clause with Condition", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; CALL testProcedure();--", "SQLi (Level 45) - Stored Procedure Call", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SELECT COUNT(*) FROM users WHERE username LIKE 'a%';--", "SQLi (Level 46) - LIKE clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SELECT * FROM users WHERE id IN (1,2);--", "SQLi (Level 47) - IN clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SELECT * FROM users WHERE id BETWEEN 1 AND 3;--", "SQLi (Level 48) - BETWEEN clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SELECT * FROM users WHERE id = 1 LIMIT 1;--", "SQLi (Level 49) - LIMIT clause", 403, None, None),
("SQLi", f"{TARGET_URL}/?q=1'; SELECT * FROM users WHERE id = 1 FETCH FIRST 1 ROWS ONLY;--", "SQLi (Level 50) - FETCH clause", 403, None, None),
# Cross-Site Scripting (XSS) Tests
("XSS", f"{TARGET_URL}/?x=test", "XSS (Level 1) - Plain Text", 200, None, None),
("XSS", f"{TARGET_URL}/?x=", "XSS (Level 2) - Basic Script Tag", 403, None, None),
("XSS", f"{TARGET_URL}/?x=
", "XSS (Level 3) - IMG Onerror", 403, None, None),
("XSS", f"{TARGET_URL}/?x=
", "XSS (Level 4) - Obfuscated IMG Onerror", 403, None, None),
("XSS", f"{TARGET_URL}/?x=javascript:alert(1)", "XSS (Level 5) - JavaScript Protocol", 403, None, None),
("XSS", f"{TARGET_URL}/?x=JaVaScRiPt:alert(1)", "XSS (Level 6) - Mixed Case JavaScript Protocol", 403, None, None),
("XSS", f"{TARGET_URL}/?x=%3Cscript%3Ealert(1)%3C/script%3E", "XSS (Level 7) - URL Encoded Script", 403, None, None),
("XSS", f"{TARGET_URL}/?x=%253Cscript%253Ealert(1)%253C%252Fscript%253E", "XSS (Level 8) - Double URL Encoded", 403, None, None),
("XSS", f"{TARGET_URL}/?x=