Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
File size: 5,517 Bytes
d543fc1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | import uuid
import hashlib
import hmac
import secrets
import base64
import subprocess
from typing import *
import os
import sys
import re
import json
import time
import urllib3
import requests
import socket
import logging
import threading
import concurrent.futures
import ipaddress
import ssl
from urllib.parse import urlparse, urljoin, urlencode, quote
from collections import defaultdict
from bs4 import BeautifulSoup
from datetime import datetime, timezone
"""
evasion.py β WAF Evasion / Payload Encoding Helpers
=====================================================
Advanced WAF bypass techniques used by scanner modules.
FIXES (June 2026):
BUG-13: mixed_case() β lambda closure referenced undefined `i` variable.
Refactored to use enumerate() with a proper loop instead of a lambda.
ENH-1: Added HTML entity, Unicode codepoint, and SQL comment splice encoders.
ENH-2: Added case-splice SQL comment technique.
"""
def url_encode(s: str) -> str:
return urllib.parse.quote(s, safe="")
def double_url_encode(s: str) -> str:
return urllib.parse.quote(urllib.parse.quote(s, safe=""), safe="")
def unicode_encode(s: str) -> str:
return "".join(f"%u{ord(c):04X}" for c in s)
def hex_encode(s: str) -> str:
return "".join(f"\\x{ord(c):02x}" for c in s)
def utf16_encode(s: str) -> str:
return "".join(
f"%00{ord(c):02x}" if ord(c) < 256 else f"%u{ord(c):04X}" for c in s
)
def html_entity_encode(s: str) -> str:
"""Encode each char as HTML entity (useful for XSS context evasion)."""
return "".join(f"&#{ord(c)};" for c in s)
def sql_comment_splice(s: str) -> str:
"""
Inject /**/ between every character (common SQL WAF bypass).
E.g., SELECT β S/**/E/**/L/**/E/**/C/**/T
"""
return "/**/".join(list(s))
def mixed_case(s: str, variant: int = 0) -> str:
"""
Return a mixed-case version of `s`.
Variant 0 β uppercase even positions
Variant 1 β lowercase even positions
Variant 2 β swapcase entire string
BUG-13 FIX: Previously used a lambda with `i` from enumerate() but the
lambda was defined in a list comprehension where `i` was not in scope.
Now uses a simple loop with index tracking.
"""
result = []
alpha_idx = 0 # count only alphabetic chars
for ch in s:
if ch.isalpha():
if variant == 0:
result.append(ch.upper() if alpha_idx % 2 == 0 else ch.lower())
elif variant == 1:
result.append(ch.lower() if alpha_idx % 2 == 0 else ch.upper())
else: # variant 2
result.append(ch.swapcase())
alpha_idx += 1
else:
result.append(ch)
return "".join(result)
ENCODERS = [
("plain", lambda s: s),
("url", url_encode),
("double_url", double_url_encode),
("unicode", unicode_encode),
("utf16", utf16_encode),
("hex", hex_encode),
("html_entity", html_entity_encode),
("sql_comment_splice",sql_comment_splice),
("mixed_case_1", lambda s: mixed_case(s, 0)),
("mixed_case_2", lambda s: mixed_case(s, 1)),
("mixed_case_3", lambda s: mixed_case(s, 2)),
]
def generate_variants(payload: str) -> list[tuple[str, str]]:
results = []
for name, encoder in ENCODERS:
try:
encoded = encoder(payload)
if encoded != payload:
results.append((name, encoded))
except Exception:
pass
return results
WAF_EVASION_PREFIXES = [
("tab", "%09"), # \t β URL-encoded to avoid urllib ValueError
("newline", "%0a"), # \n β URL-encoded to avoid urllib ValueError
("carriage", "%0d"), # \r β URL-encoded to avoid urllib ValueError
("null_byte", "%00"), # \x00 β URL-encoded to avoid urllib ValueError
("comment", "/**/"),
("multiline_comment", "/*!*/"),
("backticks", "``"),
("parenthesis_overflow", "(((("),
("tab_before", "%09/"), # \t/ β URL-encoded
("path_param", "/;/"),
("sp_prefix", "%20"), # space β URL-encoded to avoid urllib ValueError
("plus_prefix", "+"), # URL-decoded space
]
# Additional SQL-specific suffix tricks
WAF_EVASION_SUFFIXES = [
("sql_dash_comment", "-- -"),
("sql_hash_comment", "#"),
("sql_block_comment", "/*"),
]
def waf_evade(payload: str) -> list[tuple[str, str]]:
"""
Return a deduplicated list of (evasion_name, evaded_payload) tuples.
Includes prefix tricks, encoding tricks, and SQL comment suffixes.
"""
seen: set[str] = set()
variants: list[tuple[str, str]] = []
def _add(name: str, val: str):
if val != payload and val not in seen:
seen.add(val)
variants.append((name, val))
# Plain payload always first (for baseline)
_add("plain", payload)
# Prefix-based evasion
for name, prefix in WAF_EVASION_PREFIXES:
_add(f"prefix_{name}", prefix + payload)
# Encoding-based evasion
for name, encoded in generate_variants(payload):
_add(f"encode_{name}", encoded)
return variants
|