XSS WAF Bypass Techniques
We all hate web application firewall! Most likely you have encountered those while testing for cross-site-scripting. If you manage to get HTML injection which is the initial step, you know that there must be a bug out there. Let me help you to bypass this annoying thing and get that bounty on the table! It’s time to head dive into more techniques for bypassing some web protection. We will explore how those protections are implemented and how we can find ways to overcome them.
Initial Setup
This is the setup I will be using:
On the left, we can see the client, a CloudFlare firewall in the middle will be as a proxy server to the CTF server on the right. The CTF server is labs.hackxpert.com which is made by XSSRat. He has some nice content related to XSS as well. Instead of going directly to labs.hackxpert.com, the requests will be sent through my CloudFlare, just to demonstrate from the defensive side, how it looks, how engineers are making blocking rules, to prevent those attacks, and the ways from the attacker side, how you can bypass those rules. I use this custom k1t.uk domain as a proxy for that CTF website built by Uncle Rat.
User-Agent Blocks
The CloudFlare web application firewall comes with a lot of security tools out of the box. Before even setting up any rules, it usually checks for malicious user agents and one tool that actually has this own user agent is sqlmap. Even though this post is meant for XSS, the sqlmap also detects for XSS! It will work the same for any other XSS CLI utility, just in case the CLI utility has a unique user agent.
If I run sqlmap, it will show a 403 error with a status code, with an access denied error:
And if you try to check from the defensive side – the security events, it will show the user agent of sqlmap:
To bypass this rule, I want to trick the web application firewall so that my requests look like coming from a regular browser. To check the user agent – you can use developer tools or like me, I’m using the User Agent Editor plugin:
Copy this and try running sqlmap just by supplying a custom header:
IP and Country Blocks
After testing a single website for a while, you might send too many requests that could annoy the cyber security team. The security engineer could decide to create a custom rule – just to block your IP address. The IP block rule would look like this:
If deploy this rule and try to access this website again, it will show that I am blocked:
My simplest solution for this is to use a VPN. I will use NordVPN service in my terminal to connect to Germany IP:
So in this case, I will use another IP address and try to refresh this page. As it uses a different IP, this rule will be bypassed:
There could be another case – for example, when there is a rule just only accepts certain countries for that website, for instance, the United Kingdom. So once again, I use a VPN tool just for the United Kingdom, to bypass this:
I have been using this VPN provider for 3 years already since they have a lot of servers and a lot of IPs for different countries like the United Kingdom. It will be a pretty low chance that you will end up on an already blocked IP. Whenever you are deciding which VPN to use, I recommend to avoid using free ones as they are mostly slow or contain many blacklisted IPs.
Simple XSS Block Rules
If you bypass previous blocks which are most common, you’re finally ready to fuzz specific endpoints. Even before testing cross-site scripting, you want to start gently to be sure it’s worth more investigation. The first step is HTML injection. I think the best one is to use other tags like underlining or italics like this:
<u>aaa</u>
OR
<i>aaa</i>
Just check if this payload will be reflected somewhere and if I try to submit it on k1t.uk, as you can see, it is injected:
The next step is to try to use a script tag:
'`"//><script>alert()</script>
I’ve added ‘`”//> characters because those are usually good for escaping the context, so if I hit, it passes to the query and it will be reflected back:
Sometimes the security engineers can take the naive approach and try to block by URL query string, which contains a script tag. The deployed WAF rule will look similar to this:
That rule just checks if the URL query will contain words like this – “script”.
As the attacker, how you can avoid it? Just use some mix of uppercase and lowercase letters:
A bit more advanced defense technique from cyber security engineers could be to create a rule which will convert URL query to lowercase and later compare it to the string “script“.
So in this case, even though you are using uppercase letters, the web application firewall could still block you if it sees the string “script” no matter which case you use. The next thing that you want to do is try using other tags like this by using certain handlers:
This payload will use img HTML tag, create an error, and use an onerror event handler to run the specified alert() function. That naive rule will be bypassed.
Some security engineers might include more HTML tags or even event handlers. In cases like this, I recommend doing some extra research as there is a cheat sheet for this. The Portswigger has amazing research on this. There are a lot of, that could be used along with some event handlers that do not require interaction. You might want to copy all of those tags, pass it to the intruder, on the burp suite and check which ones are accepted or not.
Last Thoughts
We have barely scratched the surface of bypassing firewalls. Although it was pretty basic things but you can use those techniques, to avoid the most common blocks. Those were just bypasses for custom rules against XSS attacks. In the real-world scenario, it could be more security-hardened on websites with automatic request detection. There are some amazing security features of Cloudflare or any other web application firewall with inbuilt AI request comparison. So, sometimes it could be much harder to bypass the firewall.
If you find this information useful, please share this article on your social media, I will greatly appreciate it! I am active on Twitter, check out some content I post there daily! If you are interested in video content, check my YouTube. Also, if you want to reach me personally, you can visit my Discord server. Cheers!