How I could Steal Your Google Bug Hunter Account with Two Clicks in IE

This post is another evidence to show how difficult to parse a URL correctly. IE has URL parsing problem, this idea is originated from Sergey Bobrov. And then successfully exploited by filedescriptor in github. Credits to them. Now, this post show how we can defeat the login mechanism that Google Bug Hunter Dashboard site uses,  and steal your access token by two clicks in Internet Explorer.

Google has a vulnerability reward program, that is hosted with domain name withgoogle.com to serve the dashboard for bug hunters. The site URL is https://bughunter.withgoogle.com So for any bug hunters/pentester/hacker who see this, this would usually mean potential weak spots, because session/cookies cannot be shared cross domain, i.e. sessions in google.com cannot share with sessions in withgoogle.com . There must be some login mechanism implemented to log user in from google.com to withgoogle.com. If we can find a weak spot in the process, we can own it.

Login Mechanism

The dashboard for bughunter look like this.

google_bughunter_login

Once we click Sign In, the traffic happens under the hood look like this.

google_bughunter_login_traffic

  1. https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2Fbughunter.withgoogle.com&ltmpl
  2. Which will then redirect to https://appengine.google.com/_ah/conflogin?continue=https%3A%2F%2Fbughunter.withgoogle.com&pli=1&auth=[token]
  3. Which will then redirect to https://bughunter.withgoogle.com/_ah/conflogin?state=[state token]
  4. Final destination is https://bughunter.withgoogle.com, and in step 4, the cookies/session of user will be set finally.

In this flow, the most important part of auth token here is state parameter. If we are able to steal the state parameter, then we are able to takeover the researcher’s account with the token. You can see in this flow, there is so many redirect is going on under the hood, what if we can make final destination in step 4 to be our owned server, this would essentially mean leaking researcher’s token in the referrer header. So, by using this method, I have tried to change

https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2Fbughunter.withgoogle.com

to

https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2Fwww.mysite.com

It didn’t work, the state token returned in step 3 won’t be valid if I entered any other domain other than https://bughunter.withgoogle.com, this frustrated me of cause. And this is the moment where I choose to submit the report to Google Security Team and later found out my report is invalid because the state token returned in step 3 is invalid to login bug hunter dashboard, if i entered different domain name. It doesn’t sounds good because I made a mistake to submit the report without actually confirming the bug, so I decided to fix my mistake, by keep playing with this mechanism.

URL Encoding

Upon further investigation, I found out that the url decoding is inconsistent in these three domain.

  1. In Step 1, accounts.google.com won’t perform any url decode in the redirect
  2. In Step 2, appengine.google.com would perform at most 2 times in url decode, which mean, it will turn %25%36%32 to b, as well as %62 to b. Two times at most.
  3. In Step 3, bughunter.google.com would perform at most 1 time in url decode, which mean, it will turn %25%36%32 to %62 only. Nothing more, and this is the main subject of this post. Have a look on the traffic of step 3

screen-shot-2016-12-17-at-2-24-26-pm

Can you see the weird behaviour? https://bughunter.withgoogle.com become https://%62%75%67%68%75%6eter.withgoogle.com in Step 3. And this would work perfectly in Firefox and Chrome, as they will decode the Location Header correctly, and redirect user to https://bughunter.withgoogle.com, but not the same case for IE. IE in Windows 7,8.1 will redirect user to https://bughunter.withgoogle.comthgoogle.com If you want to don’t know why, you must have missed the link I provided in the beginning of the article. Since no one claimed comthgoogle.com, attacker could have claimed it and at least launch Open Redirect attack. But Google Security doesn’t like Open Redirect, no reward/fix will be implemented, if it is just Open Redirect.

How can we exploit this behaviour? First thing come to my mind is Referer Leak, at first, I thought by using the payload

Attack Payload:

https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2F%25%32%35%25%33%36%25%33%32%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%33%37%25%32%35%25%33%36%25%33%38%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%36%35ter.withgoogle.com&ltmpl

would be enough for Referer Leakage, as I thought 302 redirect in Location Header would atomically include the originated Link in the Referer Header, but I was wrong, 302 redirect won’t include its original site in Referer Header and this is the time I chose to update my submitted report to Google. Again, this is bad, because at that moment I do not know 302 redirect would not include the referer header if its just 302 redirect. I am telling everyone about this as a reminder to all of us, especially myself, confirm the vulnerability before submitting.

I got this report wrong twice, I have to be right in one last time. So I have to keep digging about this flaw, it has to be exploitable. Finally, this page was presented to me when use my attack payload .

screen-shot-2016-12-17-at-2-40-27-pm

Wait, why would this page appear? It turns out whenever I have more than 1 logged in Google Account, this page would prompt me to choose one of them before logging in bughunter.withgoogle.com . How could this help us in this case, it turns out it helps a lot! Like I said, 302 won’t include referer header of originated site. But this is not the same case if any user action is involved, like clicking a link/button/image. If user clicked on something, and got redirected to other site, the referer remains.

If user visit Site A and Click on Site B which then Redirect to Site C which then Redirect to Site D. All of the redirect request to B,C,D would include site A URL in Referer Header.

This is very important here, because this mean the state token of appengine.com will be leaked to bughunter.withgoogle.comthgoogle.com for IE user in Windows 7,8.1. And how useful is the state token? It turns out it is everything you need in order to have access to BugHunter Dashboard.

I made a few tests, and turns out anyone with the state token in appengine.com like the image I provided above, could takeover the user’s bughunter account. I checked the source code of the “Account Choosing” page.

leak

The important state token is loaded in the page of “Account Choosing”, this mean, if I could know the URL of Account Choosing Page, then I could takeover the victim’s bughunter account.

A quick recap of the vulnerability here.

  1. Visit https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2F%25%32%35%25%33%36%25%33%32%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%33%37%25%32%35%25%33%36%25%33%38%25%32%35%25%33%37%25%33%35%25%32%35%25%33%36%25%36%35ter.withgoogle.com&ltmpl
  2. If user has more than one logged in google account, it will present a page look https://appengine.google.com/_ah/loginform?state=[state token]
  3. User click on the Continue button, for fire fox and chrome user, they will be redirected to the correct site bughunter.withgoogle.com. But for IE user, they will be redirected to https://bughunter.withgoogle.comthgoogle.com, which is unclaimed. The referer header would be include the url in previous point.
  4. Owner of  https://bughunter.withgoogle.comthgoogle.com will now be presented with the url of https://appengine.google.com/_ah/loginform?state=[state token] in referer header, and he can now replay the visit, by using this link, and log in as the victim.

This is it, a small url decoding problem could cause you an account compromise. Upon further investigation, any combo appengine.google.com + *.withgoogle.com is vulnerable to this attack as well.

Bypassing Google Email Domain Check to Deliver Spam Email on Google’s Behalf

Welcome to this blog again, this is my second write up about my Bug Hunting Journey, if you missed the first write up about how I could buy anything for free in Yahoo, please go here to have a look.

Now, this write up is about how I use Google’s service to send email with any domain names, and with arbitrary title/content. You can safely say that I can hijack Google’s email service to send any email to anyone I want. Sounds severe right? I agree with you, but Google Security Team treat that as a low severity bug as they believe anyone could have send spam email, so this finding does not qualify for reward. Ok, they got a point, the process to find it is fun anyway. Let’s see how I manage to hijack their email service.

Google FireBase

Google’s FIrebase is a super useful service that could save developers tons of effort. It provides authentication service that could integrate with any platform you want, like web, iOS, android. So developers do not need to build an authentication mechanism from scratch.

There is some functions that firebase must provide in order to have a competent service, sending password reset email is one of those must have functions. From the screenshot below, we can see it allows us to user our own domain name and own template to deliver the password reset email. Firebase is nice, nice enough to allow developers to specify their own domain name to deliver the email. Before using custom domain name, we have to prove to Google that we actually own the domain.

Email Template
Email Template

 

But here is the problem, I can specify any domain name without proving I am the owner. Actually this is a classic example of how developers would make careless mistake, when we look at the front end, we cannot tamper with the domain name. However if we capture the traffic and look at the request body, and carefully change the domain name, we can actually bypass the check and use any domain name instantly.

In the request body, I notice there is a {“email”:”noreply@luminous-app-1234.firebase.com”}. So I change that to {“email”:”ron@attacker.com”}, and trigger the password reset. The final result is this.

Hijacked Domain Name
Hijacked Domain Name

So I documented all these finding and send it to Google Security Team and have it fixed within a week.

Of cause ron@attacker.com is very obviously a scam domain name, but imagine I used donation@google.com, with nicely crafted message, it is not difficult to deliver spam email effectively by abusing this bug.