Friday, 22 July 2016

United to XSS United


Hello there,

In this blog post, I will explain how I was able to bypass some client-side based XSS so called "protection".

While I was looking for cheap flights, I recalled that United offer a bug bounty program that rewards free mileage to researchers who report security vulnerabilities.

As I started looking testing their websites, I found a couple of bugs and reported them, then I came accross the subdomain http://checkin.united.com.


Visiting the above link redirected me to another page on the same subdomain, with a GET parameter called "SID". I started testing that parameter and noticed that it's value gets reflected in the document 60+ times, none of which is well sanitized against special characters, allowing me to break out of the tags it reflects in in 100% of the times it does.

I simply entered "><svg onload=confirm(1)> to get the alert box I'm looking for, but weird enough, no alert boxes were there at all, I then inspected the source of the page and found that my injection actually lands untouched exactly the same 60+ times, yet the JS payload doesn't execute.

Some of the payload reflections in the document

I started digging more into the script tags and what codes do they contain, until I reached the source of my misery, a JS file that is included into the page and contains the following code:

JS code that caused the trouble

Basically, the code overrides the native alert(), confirm(), prompt(), unescape(), and document.write() functions and nullifies them, so calling them does absolutely nothing. This was implemented as an "XSS protection".

So after some research, I managed to restore document.write() to it's default state by calling document.write = HTMLDocument.prototype.write;document.write('STRUKT');, but again, what good does that do with all the main functions I want to access sabotaged.

Using document.write() to print into the document
 

I started playing around with the help of my friend and teacher @brutelogic, he provided me with this link, which talks about the JS defense in place. The article also mentioned that we could get the overridden functions back to their defaults by using the word delete. We tried the keyword and it happened to be blacklisted as well, then I had an idea. What if I inject empty iframe tags (without the src attribute) and then set the main window's alert() function to any of these iframes' native alert functions, it will then be reset to the default alert() function any document has.

I tried the new idea and it actually worked, bypassing all the "XSS protections" in place and circumventing the overrides implemented by the developers.

The beloved alert box finally popping up
Then my friend @brutelogic managed to optimize the payload to a much shorter one, with the ability to work in Chrome and bypass Auditor (Because there's also an unsanitized reflection in a <script> tag context).

Brute's payload working in Firefox
Brute's payload bypassing Chrome's XSS Auditor

Then I've decided to go further and check if United's main website contains any flaws. After spending less than 10 minutes of investigation, I found out that the exact same vulnerable path found on http://checkin.united.com exists on United's main website, with absolutely the same imported libraries and the 60+ vulnerable reflections, killing two birds with one stone.

XSSing United's main website with the same payload

Finally, I would like to thank my teacher and friend @brutelogic for his continuous support and generosity in providing me with brilliant and unexpected information.

See you in another post ;) 

Monday, 4 July 2016

Apple and the 5 XSSes

Hello guys and welcome back,

On the 10th of March, 2016 I decided to start looking for Cross Site Scripting vulnerabilities in Apple's websites, I really can't remember what motives drove me to start looking for bugs there, but it was a good idea anyways.

I first started enumerating the targets as usual, found a big list of subdomains and started to look for XSS bugs on each of them.

Spending a couple of hours looking for XSSes and finding nothing at all, I started to notice that most of the subdomains need the users to be logged in first to start using them, so I created an Apple ID and started logging in each of the subdomains to have some deeper look into each of them.

The first XSS I found was a reflective XSS on the subdomain https://checkcoverage.apple.com, which is designed for users that want to check their Apple products' warranty status and whether they are eligible for support and extended coverage or not.

While surfing the subdomain I just mentioned, I found a GET parameter called "sn", which is -obviously- the placeholder of the serial number of the product the user wants to check, I started probing to see if the parameter's value gets reflected in the page, so I used a string as simple as <"xss' to check if any of those special characters gets removed or encoded. See the following screenshot:


The injected payload is reflected inside a <script> tag with no encoding or sanitization of the special characters at all, thus injecting "-alert(document.domain)-" was enough to trigger the following alert box:


The second XSS is a stored one and lies in the subdomain https://iadworkbench.apple.com/, this subdomain is for advertising purposes and business related stuff, where I found that the organization's name gets reflected inside a <script> tag without any sanitization.

Again, using "-alert(document.domain)-", I was able to come up with the following alert box:


The third XSS I found was on the subdomain https://appleid.apple.com, if you click on that link, you will find the message "Your account for everything Apple." written between two <h2> tags. Yes, this subdomain is there for users to manage their Apple IDs, which allows them to access everything they use, related to Apple.

I started missing around with the parameters I see, until I came across the GET parameter "key", which over and over again, gets reflected inside a <script> context without any cleansing, leaving one of Apple's most important online services vulnerable to one of the simplest, yet very devastating attacks. See the following screenshot:


This time, just to change the XSS vector, I decided to close the <script> tag prematurely and inject my own <script> tag, and I noticed that <script> and </script> were getting removed completely from the input, but </script/strukt> for example is not removed, so I tried to inject </script/x><script/x>alert(1)</script/x>, but the alert box didn't appear.

I found out that <script/x> was still removed, so I tried </script/x><scr<script>ipt>alert(1)</script/x> and this time it worked, showing that Apple was protecting one of their most important online services with one of the worst approaches ever.


The fourth XSS affects the subdomain http://mynews.apple.com, and honestly, this is one of the weirdest and easiest XSSes I have ever met.

Developers often do some mistakes, like getting parameter values and letting them into the page source with inappropriate handling first. But in this case, the case was pretty different, the developers were getting he value of the "locale" GET parameter, appending it to some URL, and then using it as the action attribute of a <form> on the page, nothing strange, right ?!

Actually no, the very bizarre thing here was that they were correctly encoding the " and < of the injected payload correctly, but they used the value of the action parameter unquoted. See the following screenshot for more understanding:

Breaking out of the action attribute then was a piece of cake, adding a %20 (space) after the value of the "locale" parameter and adding an event handler with a payload such as "onmouseover=alert(document.domain)" was all that is needed to do the job.


The fifth and last XSS in this series was found on the subdomain https://atlaslms.apple.com, this XSS was pretty straight forward, a GET parameter called "criteria" was being inserted as the value attribute of some hidden <input> tag and no sanitization at all was there, so I just injected the string "><svg onload=alert(document.domain)> to alert.





Conclusion:

While Apple may be doing a good job securing their OSs and devices, they fail big time when it comes to protecting their own online services, including those who are somewhat critical to users.
The other thing I'd like to mention is that Apple, being a tech giant, doesn't pay bounties to whitehats. Which, from my point of view, is the main reason why they're not well secured, as well as the reason why a blackhat was happy to get paid to hack into the iPhone the U.S government was trying to convince Apple to get them access to.

Finally, I would like to mention that, after more than 3 months of reporting the issues, some of the bugs are still reproducible at the time this post is released. Also, I was asked to provide my information on the 23rd of March to enter Apple's Hall of Fame for https://appleid.apple.com's XSS, yet my name still doesn't appear there.

Thanks for reading, see you in another post.