Google Apps for business is a set of Google services for companies including email,
online storage, calendars, etc. This allows companies to avoid the hassle of having to manage all these services in house and simply outsource it. One of those services is email. A company can have their personal email domain but still working under the gmail platform.
I realized that when I enter a valid email address from a company using Google Apps, the response code is 302 with the location header containing an internal url. As you may know, 302 is used to indicate
the browser that the resource is in a different place, specifically where the location header points to.
There is no need to enter a password at all. Going to accounts.google.com and entering a valid email will return a 302, an invalid email will return a 200.
Let’s take for example National Geographic which uses Google Apps as their email service. If we try to login with DOESNOTEXIST@ngs.org we get an error asking to enter the password. If instead we try firstname.lastname@example.org we get redirected to a portal under National Geographic’s domain.
Requests and responses
The request contains tons of parameters and headers but you can actually remove most of it and reduce it to something like:
Just the email is necessary and couple headers, that simple! We get the 302 and a leaked URL in the Location header. Sometimes the URLs do not work meaning that they are just accessible over VPN. One more reason to believe that companies don’t like those internal URLs leaked.
Let’s go harvest
We just saw how we can tell if a username/email is valid or not. We also saw that the response leaks internal URLs that in many cases are not suppose to be of public knowledge. A very simple script that crafts requests and parses responses could perfectly bruteforce valid email addresses. We can optimize this by using public available dictionaries, multithreading, etc.
I wrote a proof of concept that you can find in my github repository. This script could be optimized in many ways but my goal is not providing a tool to take advantage of this issue, just a POC.
Once an attacker has a list of valid emails, how can he profit from it?
- A malicious hacker writes a crawler to retrieve all companies that use Google Apps.
This job is facilitated by google who lists all their clients publiclySeems that Google shut this site down after I reported this to them (which does not mean that was the reason why they did it of course).
- He crawls every company’s website to find listed emails (contact, support, etc) with the goal of obtaining the valid domain for the email addresses (National Geographic is @ngs.org for example).
- Once he has a list of email domains to attack, he uses a dictionary to brute force valid usernames/email addresses and also internal URLS.
- The attackers is in possession of a list of valid usernames/emails addresses and internal urls (usually for logins) and
- Starts a phishing campaign sending emails implying that there was a problem in the login portal (uses the leaked url) for that username and that the passwords needs to be reseted. If the attacker harvests an email like “email@example.com” he could spoof that email to gain even more credibility.
- Sells the email addresses to SPAM companies
- Launches targeted SPAM campaign (based on the company’s activities)
- Targets the company’s servers using the URL leaked as entry point.
Google has a different opinion
I reported this issue to Google and after trying couple times I finally got a response.
I did not dig into other ways of obtaining valid usernames/emails but I don’t share their opinion. The fact that there is other ways to find that information does not make this “a feature” rather than a privacy issue. Given that we are talking about their clients accounts and not Google accounts, did they even ask their opinion? Is it Google that does not consider it a vulnerability or should be their clients who decide if it is a problem or not? What do you think?