Сookie-based XSS exploitation | $2300 Bug Bounty story

Max
Max
Jul 17 · 8 min read

For quite a long time I have been hunting for vulnerabilities on the HackerOne platform, allocating a certain amount of time outside the main work to check out my favorites and new programs. Countless times I had to stumble upon a cookie-based XSS vulnerability, which will become the main character of this article. This type of vulnerability occurs when the value of the cookie parameter is reflected on the page. By default, they are considered self-XSS if we, in our turn, do not prove their danger. Today I will tell you how to exploit cookie-based XSS vulnerabilities, and also give an example from one company testing, from which I received $7,300 in general for the research.

In order to execute javascript on the user’s side, we need to find a way to set a cookie and, if necessary, lure the victim to a page where, in its turn, the cookie is embedded. Possible ways to exploit this bug:

1. CRLF injection. This vulnerability occurs when there is no proper checking and blocking of newline characters. We can inject a Set-cookie header in the response with the desired name, as well as the value of the cookie and set it in the browser. Real-life example: Slippery CRLF injection on twitter.com domain in the redirect, — https://twitter.com/login?redirect_after_login=/jjjkkk嘊嘍Set-Cookie:jjjjj=a;domain=twitter.com

Reports about this type of vulnerability can be read on HackerOne https://hackerone.com/hacktivity?order_direction=DESC&order_field=popular&filter=type%3Apublic&querystring=crlf%20injection.

2. XSS vulnerability on a subdomain. It is necessary that XSS is publicly available and located on wildcard * .vulnerabledomain.com. For many bug bounty programs, subdomains are out of scope, i.e, in most cases, bugs are either not accepted at all, or are accepted but marked as “not eligible for the bounty”. In such cases, you should not retreat, but for the sake of a bunch with cookie-based XSS, you can invest your time searching for XSS to get a reward. If XSS is detected, we can set or remove cookies using the document.cookie function.
Increasing Impact: Often the victim trusts the main domain vulnerabledomain.com more than, for example, jira.vulnerabledomain.com, and also with the URL /plugins/servlet/oauth/users/icon-uri?consumerUri=https://maliciousdomain.com. It is more likely that the victim will go to the main domain, rather than a subdomain, if this subdomain is not associated with a personal account or authorization. Based on the foregoing, we can use an in-site redirect functionality for redirecting to the subdomain https://vulnerabledomain.com/login?redirectUrl=https://jira.vulnerabledomain.com/path for the best effect.
If the victim has an active session, the redirect will be automatic; — if not, authorization is needed. When the user clicks on such a link, the cookie will be set and from the subdomain, on which Reflected XSS is presented, it can be sent further downstream — to the cookie-based XSS page, where the exploit can trigger, which, in turn, will capture the CSRF token value and perform the request for changing the email address. Thus, a combination of two XSS vulnerabilities can lead to account takeover, if there are no associated problems, such as additional confirmation of changing email with a password or entering a code from an old mailbox.

3. Detection of test files that allow you to set cookies. It is enough to turn on the content discovery tool (dirb, dirserach, etc), start digging, and if the developers forgot to perform the cleanup, you can stumble upon such files.
Recently I discovered a test servlet html page on which it was possible to set a cookie with an arbitrary name and value. Of course, there was no protection on the POST request, so if the victim would have visited the CSRF exploit (or you can change the POST to GET), it would be possible to set a cookie in her browser.

This bug was qualified as an under-alternative to CRLF injection, fixed by removing /examples/ and paid $150 as for the low-severity bug. Although the h1 triager set medium, the developers were still tended to think that it was low severity.

4. Man in the middle attack (MITM). This method can be applied only if there is no secure flag on the cookie. If you don’t know what this flag is or just want to refresh your memory, I advise you to view the “Cookie security” presentation from OWASP London 2017 https://www.owasp.org/images/a/a0/OWASPLondon20171130_Cookie_Security_Myths_Misconceptions_David_Johansson.pdf.
For a successful attack, it is necessary that the victim is located in the attacker’s network or the dns resolving can be influenced. In order to check the vulnerability, you must:
1) to host index.php file with the following content:
<?php if ($_SERVER[‘HTTP_HOST’] == ‘non-existed-subdomain.vulnerabledomain.com’) { setrawcookie(“VID”,’\’+alert(123123123)+\’’, time()+36000, “/”, “.vulnerabledomain.com”,0,1); } ?>

2) Add the following line to your /etc/hosts/ file: 127.0.0.1 non-existed-subdomain.vulnerabledomain.com
3) Visit non-existed-subdomain.vulnerabledomain.com and then open the page on which the cookie will be reflected.
A remarkable example of MITM exploitation on e.mail.ru, — https://hackerone.com/reports/312548, — as you can see, MITM was enough to prove a small level of vulnerability danger, but the reward did not match the level of Stored XSS, as there was shown only “local” exploitation example, not “in-the-wild”. If the researcher had spent some time searching for XSS or CRLF injection (which countless) on *.mail.ru, it would be possible to increase the reward greatly.
But not all the hackerone programs accept cookie-based XSS via MITM. If scope exclusions say “Self XSS”, then this exploitation can be considered as Self XSS and report status can be changed to informative or n/a, which is not always pleasant. Now I will talk about a similar case that happened to me during the regular hunt on the platform.

While testing the site, I suddenly noticed that the value of the **redacted** cookie is reflected in one of the subdirectories of the site. The first thing I checked is the displaying of the characters ’ “/<>. It turned out that only <> characters are filtered, which tells us that we cannot go beyond <script> </ script>, but it also becomes clear that the rest of the characters are not filtered. Without thinking for a long time, we embed ‘-alert(document.domain)-’ and js is executed.
Since the developers did not give the cookie the secure flag, in this case the MITM method works. I decided to send the report to the program with the following impact:

HackerOne staff (triager) made it clear that this is self-XSS and I should try-harder:

After that, I began to surf the site and try to find CRLF injection or XSS to prove the danger.
I had to expand the list of the subdomains with the help of brute-force with a large dictionary, scraping them with SSL certificates and with the help of some other tricks. The result was not long in coming, as I run most of the tools in VPS. From time to time other bugs were also found in passing, which I was reporting, turning out-of-scope bugs to in-scope, if necessary. There were a lot of Open Redirects and even Improper Access Control bug for $5000, but the necessary vulnerabilities for the bundle could not be caught. The above-mentioned bug is quite interesting and dangerous, a whole subdomain was taken offline immediately after the report, perhaps in the future, I will reveal the report on the page hackerone.com/w2w if the program becomes public.

A week later, I went through the results of the script for content discovery, where endpoint /verification was found, to which I did not attach much importance to at first, but I still set a script on it — the /verification/login subdirectory was found. After I went through the URL, the /verification/login/?redirect_uri=https://vulnerabledomain.com page was shown, which redirected to the redirect_uri value after logging in or immediately redirected if there was a session. After the flight to the intruder, open redirect protection bypass was discovered — vulnerabledomain.com@anotherdomain.com. I tried to escalate the bug to XSS — payload javascript:alert(1) failed, javascript:alert(1)// too. But payload javascript://https://vulnerabledomain.com/%250A1alert(1):0 shot, because due to the presence of https://vulnerabledomain, the parameter passed the white-list validation.

*never gonna give you up song starts playing*

After driving madly the mouse around the alert window (I always do this lol), I immediately switched to my cookie-based XSS. With the help of javascript:https://vulnerabledomain.com/%0A1?document%2ecookie%20%3d%20%27SID%3d137gf6g67f76fg6766123%5c%27-alert%28document%2edomain%29-%5c%27%3b%20expires%3dFri%2c%203%20Aug%202019%2020%3a47%3a11%20UTC%3b%20path%3d%2f%3b%20domain%3d%2evulnerabledomain%2ecom%3b%27%3a0, a cookie successfully set on *.vulnerabledomain.com. After visiting the page with the cookie, the coveted alert window has appeared! Double XSS, hooray! :) I updated a report and was waiting for an answer.

On the same day, a nice catch arrived from the triager (if we can call it like this), and the bounty was paid. God bless the companies that pay on the triage!

For the DOM-based XSS, with which I installed the cookie, the bounty also came to my account.

Testing results: $1000 + $1000 + $200 (OR)+ $100(OR) = $2300

This program has been operating for more than a year, but in less than a month I was able to take first place in it and get away with testing quite far, I tried to fuzzing most endpoints, evaluate their reaction, understand how the site works and even tested the desktop application. This bug bounty has become one of my favorite programs on HackerOne. I hope you will find the same one too! :)

Also, precisely this program gave me a new boost (mail.ru is the first) and with the help of it, I got to 2500 reputation (hello hoodie) and got 36th place in the leaderboard for reputation in 90 days, which should give me fresh private invites. Though it seems that private invites come regardless of my presence in the leaderboard, I often cancel old ones and wait for new ones in the queue.

Short brief:

  • Cookie-based XSS is quite exploitable. If you try and dig a little deeper, you can get a bounty instead of n/a, signal destruction and -5 reputation.
  • If the program is old, it doesn’t mean that it doesn’t have vulnerabilities. If the fruitages hang on a tree for a long time, low-hanging fruits will be picked and immediately taken home (subdomain takeovers, etc.). Other fruits continue to hang, but higher. In order to get them, you need to make some effort.
  • Sometimes it‘s better to focus on one program for a long time, find as many vulnerabilities as possible and constantly monitoring it. It is better to find the program that you prefer and break it.
  • Perseverance and the desire to understand how a web application works, as well as certain functionalities and their interaction with each other, is the key to successful finding vulnerabilities in a bug bounty.

If you want to stay in touch with my latest articles and news, I recommend subscribing on twitter profile.

Max

Written by

Max

Impassioned about finding vulnerabilities in web apps. H1 http://hackerone.com/w2w. Linkedin: /in/w2w/. Telegram channel [RU only] http://t.me/vulns

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade