Sunday, February 12, 2012

Checking for HTTPS with JavaScript

SSLStrip is a really sweet tool that came out a couple years ago. While I won't go into detail here, sslstrip allows a man-in-the-middle attack against secured web connections by parsing out all HTTPS links and replacing them with regular HTTP. Sslstrip will even add a lock favicon to help convince the user HTTPS is in use, but most people probably won't even notice, which is why the attack is so brilliant. The server won't see anything out of the ordinary, and unless the target checks their URL, they won't receive any warnings either.

You can learn more about sslstrip here and here.

This attack got me thinking about ways that a website itself could help ensure an encrypted connection. Web browsers themselves are code delivery systems (HTML, JS, etc) are essentially code interpreted by the client), which means web developers should be able to offer at least a little bit of help. (MITM detection software exists, but usually proactively needs to be installed and ran by the user.)

It should be noted that many "secure" websites will still offer unencrypted connections, on the off-chance that a user's browser doesn't support HTTPS. Most browsers today, however, support secured connections. Even mobile browsers issue warnings, even if they are varied.

Note: the following is best solved by setting HSTS headers, which most browsers are beginning to support. This is just an experiment for a programmatic solution.

In our scenario, we're going to assume we have an HTTPS-only web app with a user who's been MITM'd with sslstrip. The goal was to help slap the user up and make them notice a lack of encryption. To do this, we can send them a piece of embedded javascript to check the current URL. This is a naive detection method, as javascript could be blocked by the attacker or tampered with. To help get our script through to the user, we can heavily obfuscate it on the server-side, and preferably add some element of randomness to help avoid a constant signature that could be regex'd out of our page. This is important, as an attacker that notices what's happening could easily defeat our checks before we get a chance to warn our user.

With fingers crossed, our attacker isn't aware of our code snippet (and is, perhaps, just passively grepping sslstrip output for credentials).

Example JS
//This check should run on pageload
var sslFlag = (window.location.protocol == "https:");
if (!sslFlag) {
alert("This connection isn't secured. An attacker is possibly intercepting traffic.");
}
//If sslFlag returns false or we never receive an AJAX report, make a log and possibly take action, such as a temporary password reset
ajaxReporting(ourDomain, sslFlag);
Homograph Attack
Sslstrip can also perform what's called a homograph attack, wherein the attacker uses look-alike characters to pose as the webpage they are attacking. While the above code wouldn't be very helpful in this scenario (as the connection is still HTTPS), we could instead check the character code of each letter in the URL. If the URL isn't correct, then we could fire off our warnings.

The homograph attack requires the attacker to have targeted a specific site, at least to register their false domain, so the chance of them noticing our code increases significantly.

Summary
I want to make it clear that I am by no means knocking the awesomeness of sslstrip or implying that this is a foolproof detection method. I'm very aware that this can be easily defeated if someone is expecting it. This simply adds one more step that needs to be taken care of for a successfully sneaky attack to take place.

That said, in my experience as a developer, websites often absolve themselves of responsibility for attacks that occur on local networks, and this simply struck me as one possible way to sneak some extra help to users in possibly hostile environments. In a critical situation where it's better to be safe than sorry, any extra layer of warning helps.

Monday, February 6, 2012

Detecting Firebug

Lately I've noticed a few sites that attempt to check if Firebug is enabled. Sometimes this is for legitimate purposes, sometimes not so much. For example, some web apps warn you about performance degradation, while some malicious websites will attempt to attack browsers with debug tools enabled.

Until recently, firebug was easily detectable by the window.console.firebug object, which would return the version of firebug installed, if applicable. This has since been removed by the developers.

Regardless of your intentions, for now you can still detect Firebug by analyzing console properties. Any unique properties that firebug adds to window.console can be used (ex. exception, memoryProfile, memoryProfileEnd). This can be implemented as
if (window.console && (window.console.firebug || window.console.exception)) {
/* firebug is active! alert(), fire ajax, crash browser, redirect, whatever */
}
You can read about this technique in more detail at StackOverflow, as well as some other interesting hacks for detection.