Showing posts with label html5 security. Show all posts
Showing posts with label html5 security. Show all posts

Thursday, December 16, 2010

Cracking hashes in the JavaScript cloud with Ravan

Password cracking and JavaScript are very rarely mentioned in the same sentence. JavaScript is a bad choice for the job due to two primary reasons - it cannot run continuously for long periods without freezing the browser and it is way slower than native code.

HTML5 takes care of the first problem with WebWorkers, now any website can start a background JavaScript thread that can run continuously without causing stability issues for the browser. That is one hurdle passed.

The second issue of speed is becoming less relevant with each passing day as the speed of JavaScript engines is increasing at a greater rate than the increase of system speed. It might surprise most people how fast JavaScript actually is, 100,000 MD5 hashes/sec on a i5 machine (Opera). Thats the best number I could get from my system, in most cases it would vary between 50,000 - 100,000 MD5 hashes/sec. This is still about 100-115 times slower than native code on the same machine but that's alright. What JavaScript lacks in outright speed can be more than made up for by its ability to distribute.

It is trivial to get someone to execute your JavaScript in their browsers, just get them to visit a link and you have remote code execution of the JavaScript kind, they don't have to download or install any applications on their system or have any special privileges. It is ridiculously easy to distribute computation with JavaScript. And with about 110 browsers pointed to your site you have already achieved the speed of native code on one machine. With 1100 browser that is equivalent to 10 machines cracking passwords in native code.

To demonstrate this I have built Ravan a JavaScript Distributed Computing System that can crack MD5, SHA1, SHA256, SHA512 hashes. Details on how it works and how to use it are available here. It was released at BlackHat Abu Dhabi last month and has already had over 700 hash submissions. Both the cracking of the hashes and management of the distribution process is done in JavaScript.

The commercial cloud might have made cracking hashes super cheap but the JavaScript cloud has made it free.

Wednesday, December 15, 2010

Performing DDoS attacks with HTML5 Cross Origin Requests & WebWorkers

Update: Shellex has performed detailed performance analysis of this technique.

DDoS attacks are the rage this year, atleast in the latter part of the year. There have been numerous instances of successful DDoS attacks just in the past few months. Some of the current DoS/DDoS options seem to be LOIC, HTTP POST DoS and Jester's unreleased XerXes.

This post is about a DDoS technique I spoke about at BlackHat Abu Dhabi that uses two HTML5 features - WebWorkers and Cross Origin Requests. It is a very simple yet effective technique - start a WebWorker that would fire multiple Cross Origin Requests at the target. This is possible since Cross Origin Requests that use the GET method can be sent to any website, the restriction is only on reading the response which is anyway not of interest in this case. Sending a cross domain GET request is nothing new, you can even do that by embedding a remote URL in the IMG or the SCRIPT tag but the interesting part here is performance. My tests on Safari and Chrome showed that both the browsers were able to send more than 10,000 Cross Origin Requests in one minute.

So simply by getting someone to visit a URL you can get them to send 10,000 HTTP requests/minute to a target of your choice. Now if you pick a juicy target URL, one that would make the server do some heavy processing then just 10,000 requests/minute might overwhelm it. Lets scale this a little, say 60 people visit the URL containing the DoS JavaScript, that is 10,000 requests/second at the target. With just 6000 visitors to this URL we can send around 1 million requests/second to the target. Getting 6000 Chrome and Safari users to visit a particular URL is no big deal really.

Maybe its not that simple, there are few things to consider here. When you send the first request to a particular page and the response does not contain the 'Access-Control-Allow-Origin' header with a suitable value then the browser refuses to send more requests to the same URL. This however can be easily bypassed by making every request unique by adding a dummy query-string parameter with changing values. The number of requests/minute is also a variable. The browser sends a certain number of requests and when it receives the responses for those it sends in the next set of requests and so on. So as the server slows down the browser's requests/minute rating would also slow down. The figure 10,000 requests/minute was clocked against a server located in the internal network, against a target in the Internet it would realistically be between 3000-4000 requests/minute. If the attacker is planning to target an internal server by getting the employees of that company to visit this malicious URL then the 10,000 requests/minute rating would apply.

I am not going to release any PoC as this might probably be a bad time to do that but it shouldn't be very difficult to put together something for testing once you understand how it works. It should be relatively easy to block this attack at the WAF since all Cross Origin Requests contain the 'Origin' header, that way you can differentiate between legitimate and malicious requests.

Saturday, December 11, 2010

Port Scanning with HTML5 and JS-Recon

This was one of the newer topics that I covered at BlackHat Abu Dhabi. HTML5 has two APIs for making cross domain calls - Cross Origin Requests and WebSockets. By using them JavaScript can make connections to any IP and to any port(apart from blocked ports), making them ideal candidates for port scanning.

Both the APIs have the 'readyState' property that indicates the status of the connection at a given time. The time duration for which a specific readyState value lasts has been found to vary based on the status of the target port to which the connection is being made. This means that by observing this difference in behavior we can determine if the port being connected to is open, closed or filtered. For Cross Origin Requests it is the duration of readyState 1 and for WebSockets it is readyState 0.

I tried to do some calibration of the time duration for the different port states and the data is below. These numbers only hold good when the target is in the internal network. If you are scanning a target on the internet then the network latency should be taken in to account.

Since this is not a socket-level but an application-level scan the success also depends on the nature of the application running on the target ports. When a request is sent to certain type of applications they read the request and remain silent keeping the socket open, probably expecting more input or input in the format they expect. If the target is running such a application then its status cannot be determined.

Since even closed ports can be identified we can extend this technique to perform network scanning as well as internal IP detection. I have written a tool called JS-Recon which can perform these. More details on the how JS-Recon works is here. These techniques only work when run from Windows machines, on *nix systems it is not possible to determine closed ports and the timing figures are quite different.

Monday, November 8, 2010

HTML5 goodness at BlackHat Abu Dhabi this week

Just three more days to go for my 'Attacking with HTML5' talk at BlackHat Abu Dhabi. In addition to covering some of the interesting HTML5 attacks already released during 2010 by myself and other researchers, it has two new sections - HTML5 based port scanning and HTML5 Botnets. I would be talking about a new way to perform JavaScript based port scans that gives very accurate results. How accurate? you can determine if the remote port is open/closed/filtered - that accurate. I am also going to release a tool called JSRecon that would perform port and network scans by using these techniques. Under HTML5 botnets I am going to talk about how you could send spam mails, perform a DDoS attack on a website and perform distributed cracking of hashes at incredible speeds - all using JavaScript. I am also going to release Ravan - a web based tool to perform distributed cracking of hashes in a legitimate way. I am pretty happy with the way Ravan has shaped up and am very excited to see how folks react to it. Initial reactions have been good. The whole point of the talk is that I am NOT bypassing any of the restrictions placed by the browser sandbox but instead am working well inside those restrictions - its just that the sandbox has got a whole lot looser :)

The tools and details would be online next week when I am back from Abu Dhabi. Stay tuned!

Sunday, June 27, 2010

Chrome and Safari users open to stealth HTML5 AppCache attack

Google Chrome, Safari, Firefox and Opera(Beta) have implemented the HTML5 Offline Application Cache feature. Using this feature a website can have greater control over the caching process to enable Offline access of websites.

When a website is trying to create an Offline Application Cache, Firefox and Opera ask for user permission and only after the user permitting, the site is able to create this cache. With Google Chrome and Safari this step is skipped, any website can create an Application Cache without the user even knowing about it.

The thing with caches is that they can be poisoned very easily the moment you connect to an unsecured network, like open Wi-Fi. By poisoning a cached JavaScript file of Facebook or Twitter an attacker can eventually take control of your account. But with normal cache, HTTP content can be easily poisoned, but it is difficult to poison a page that is only served over HTTPS. So none of Gmail’s files can be poisoned, they are all over HTTPS.

Now enter HTML5 Application Cache. Unlike a traditional cache, with Application Cache any file can be cached. For example, the root file ‘/’ of a site can be cached. Let’s say an application cache is created for ‘/’ of www.facebook.com. Then every time the user types in www.facebook.com in their browser this cached page would be fetched. If this was done with normal cache then when the user requests this page the browser would send a request to the server for this resource and only if the server responds with a 304 Not Modified response, would the cache be served. But for '/’ all sites would respond back with a 200 OK with the index page’s content and that is what would be loaded and not the cache

The point is that with Application Cache, root files can be cached, this cannot be done with a normal cache. An attacker could then create a malicious cache for the index page of every HTTP site as soon as the victim connects to an unsecured WiFi. For example for Facebook, if the index page is controlled by the attacker then he can capture the username and password of the victim. Facebook being a HTTP site (post authentication) can anyway be compromised by poisoning the normal cache. But Gmail?

Almost all users open Gmail by typing in gmail.com in the address bar and this means its http://gmail.com (remember SSLstrip??). The server responds to this with a redirect to http://mail.google.com/mail/. And when requested for http://mail.google.com/mail/ the server responds with https://www.google.com/accounts/ServiceLogin?service=mail&blahblah... There are two HTTP requests before the server redirects the user to an HTTPS page. Either of those can be cached using Application Cache, http://gmail.com/ or http://mail.google.com/mail/.

This is how the entire attack works:

Step1: The victim connects to an unsecured network controlled by the attacker.

Step2: The victim browses to any random website, even opening the browser would do as it would send a request for the home page.

Step3: The attacker responds to this request with a page which contains an hidden iframe pointing to http://mail.google.com/mail/ .

Step4: The victim’s browser sends a request for http://mail.google.com/mail/.

Step5: The attacker responds to this with his own copy of the Gmail login page that would look exactly like the actual login page but would include a backdoor to steal the victim’s credentials when entered. This page also includes the manifest attribute in the HTML element so that the page is cached.

Step6: Victim goes back to secured network (home/office) and types in gmail.com, gets redirected by Google server to http://mail.google.com/mail/

Step7: The browser would load the fake login page.

Step8: User enters his Gmail credentials in to it, the credentials are sent over to the attacker.

By poisoning or creating a malicious Application Cache, the victim’s credentials to all HTTPS-only websites can be stolen by an attacker.

I have made a POC for this attack using Imposter. The POC comes with a config file loaded with the payloads for Facebook and Gmail. The cached pages would load fake login pages from www.andlabs.org through an iframe. Once the victim enters his username and password these are stored locally in the victim’s browser in the LocalStorage of www.andlabs.org and the credentials are passed on to the parent frame using HTML5 PostMessage API. The parent frame logs the user in using these credentials. The entered credentials can be viewed by visiting, http://www.andlabs.org/hacks/viewcreds.html. The credentials are not sent to the AnD Labs server so it’s safe to try out the POC.

There is a video of the entire attack using the POC here. POC can be downloaded here.

One point of interest is the Manifest file. Everytime a cached file is requested for, the browser would request the server for the Manifest file and if the server responds with a 404 then the cache would be removed. Picking an existing file on the server as the Manifest file would solve this issue as the server would return a 200. This would not result in a update of the cache because the server would not include “text/cache-manifest” in the Content-Type header. Even without this the cache would be served the first time but would be removed after that, using this technique can keep the cached file alive till it is deleted by the user.

Coming back to Chrome and Safari, when I first realized that they were not prompting for user permission I thought it was a serious oversight. I even contacted both the security teams, however they didn’t consider this to be a security issue. But on closer look their stance made sense, it is because they treat Application Cache the same way as normal cache. When you delete cache in these browsers all Application Cache is also deleted. But in Firefox they are handled separately. Deleting normal cache does not delete Application Cache, it has to be deleted explicitly. It is difficult to say which approach is better but the idea of user permission prompt is more reassuring to me. Till then browsing in private/incognito mode should keep user’s safe.

Update:
Chris Evans pointed out on FD that root resources can been cached even by using the normal cache mechanism, so using Application Cache for that reason alone might not gives an edge to the attacker.
However, using Application Cache does have a major advantage over normal cache.
When a root resource is cached using normal cache, it is removed the moment the user hits refresh on that page, but Application Cache stays. This can give an attacker continued access to the victim's browser until the user explicitly clears the cache. In Firefox this has to be done explicitly for Offline Website data.

Sunday, June 13, 2010

HTML5 Security Articles and Live Demos

HTML5 is increasingly getting more attention from the developer community as it brings features that most developers would have never used before. Client-side storage with Web SQL Database, Offline Storage, Cross Origin Requests, Offline Application Cache, Cross Origin Messaging are some of these features that are going to have developers drooling over the next few years at the thought of all the cool things they could do.

With all these new possibilities we are going to have many new types of vulnerabilities and attacks. Security has been a prime consideration in the design of the HTML5 spec , for instance the design of the Web SQL Database API naturally encourages Prepared Statements and it is actually a little harder to introduce SQL Injection vulnerabilities. However implementation mistakes are going to be many and it would be interesting to study them. To help developers avoid more obvious mistakes when implementing these features I have written two detailed articles explaining what could go wrong and how it can be avoided. These articles are on the Web SQL Database and the Cross Origin Request features. Some of the points mentioned might look very obvious but I have personally in my experience doing Penetration tests seen much more obvious mistakes with very serious consequences.

The two articles are:
  1. Web SQL Database Security - http://code.google.com/p/html5security/wiki/WebSQLDatabaseSecurity
  2. Cross Origin Request Security - http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity

My original idea was to write about them in a series of blog posts but I was in luck because at around the same time Mario announced his HTML5 Security CheatSheet project. And when contacted he liked my idea and was nice enough to add me to his project. So now it is in the form of a Wiki page which is great because it can be updated constantly based on feedback/ideas from readers and findings of other researchers.

There is also a HTML5 Security Quick Reference Guide along with Live Demos of secure and insecure implementation of some features at http://www.andlabs.org/html5.html

All comments/suggestions/feedback are welcome.