Another day, another filter bypass. This time, it is XSS without slashes!
XSS Without Slashes – Introduction
Just like my Referer XSS post, I had someone come to me with an XSS issue they were having.
An application was vulnerable to reflected XSS, but it was via one part of the path. This meant that input couldn’t contain forward slashes, as that part of the path would have ended.
This might be a shorter post, so I’ll walk through my process and a few of my filed attempts.
In this case, I removed any forward slashes from the string in the value parameter, which is functionally the same vulnerability.
Here is my vulnerable form (value parameter): <form> <input type="text" value="<?php echo preg_replace('/\//', '', ($_GET['value'])); ?>"> </form>
Testing the Filter
As expected, when I pass input without any slashes, it ends up in the form.
That said, when my input contains forward slashes, the filter properly removes them.
As you can see, the server is receiving the request as expected.
Next, I verified that HTML injection was possible with a tag that I did not need to close.
When I attempt a basic XSS payload, the filter breaks the trailing script tag, and the payload does not execute.
XSS Without Slashes – Failed Attempts
With basic understanding of the filter complete, it was time to bypass it.
Next, I tried the same idea, only setting everything after my payload to an arbitrary variable. I’m guessing that this broke once it reached the double-quote in console.log, but I’m not certain.
Finally, I tried the form feed character as a separator, as suggested in this StackOverflow answer. Unfortunately, this did not work either. That said, this could have just been issue with being inside of a form tag for my demo.
I also thought about using JSFuck, but this was too long for a URL parameter in most cases.
After a bit more searching and thinking, I realized that I did not need to close the img tag.
In this case, I used a standard ‘img src’ onerror XSS payload, and set everything afterwards to my arbitrary attribute. This worked, and I was able to pop an alert!
That said, I wasn’t satisfied with this payload, as it was not fully weaponized. I realized that, while HTML encoding is usually the enemy, it is just fine when you are already inside of a tag.
In this case, I HTML encoded my XSS polyglot from ‘//r4y.pw’ to ‘//r4y.pw’. I then URL encoded it to prevent any issues with the symbols, and ended up with ‘%26%23x2f%3B%26%23x2f%3Br4y.pw’.
When I set this as the script src, the payload fired, and the exploit was complete.
Note that this needed a closing script tag somewhere, like my Short XSS payload.
XSS Without Slashes – Conclusion
This was still a simple filter to bypass, but another one that we found in the wild.
I may try to reproduce the actual version from the URL path, but I may not do another post for this.
I’ve still got plenty more post to catch up on, but let me know if there is anything specific that you would like to see!
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.