Paid Advertising
web application security lab

Archive for June, 2007

The Virtues of WAF Egress

Friday, June 8th, 2007

I’ve been thinking about this for a long time, and I haven’t seen anyone else talk about it, so here goes. As anyone who’s read this site for any length of time knows, I’ve never had much of a soft spot in my heart for web application firewalls for various reasons: cost, false positives, false negatives, can fail to fix the problem completely, etc…. However, recently I’ve been asked to look at more and more people’s technology (as part of our consulting practice) and decide what I do and don’t like. I was talking to a new startup a week or two ago about their new WAF appliance that they are building and all the virtues, blah blah. Of course I had to start punching holes in it the second I heard the concept, “What about DOM based XSS?” The CEO replies, “No idea.” Hurray, I win! Or did I?

The problem with DOM based XSS is that it isn’t actually sent to the server (in most cases - and those are the cases I’m interested in for this problem). Generally those fall into anchor tags like, http://example.com#exploit-goes-here The anchor tag is not sent to the server (as we found during the UXSS in Adobe reader in Firefox). Try as they might, all the King’s horses and all the King’s WAFs couldn’t write rules to block it inbound, all they could do is modify the mime types to deliver the payload more securely. There were lessons learned there, but let’s focus on DOM based XSS in JavaScript, rather than in client side technologies for a moment.

Knowing that we can’t stop DOM based XSS at the server level because it can’t see it, nor can it be seen at the network level, short of auditing the code, all we really can do is wait for someone to exploit it and then re-write the code. But therein lies a problem with all patching. In many cases it’s deathly slow. So why not set up an egress filter on a WAF to programmatically change the JavaScript in transit to be safe? Think about it, if you know you have an insecure function on a page, but it will take 6 weeks of building tickets, fixing the bug, testing, deploying, or a ten minute change on a WAF, that’s a huge value in time savings.

There’s one more advantage to this - if you can set the egress filter to deliver specific content to specific IP addresses, you can actually use the WAF filter to test the changes you are suggesting to your developers ahead of time. Often security guys know how to make the changes better than anyone, so if they can deploy the change in the WAF, test it themselves before it rolls out to anyone else, they’ve reduced the risk of a global deployment of code that failed the fix the problem, or worse yet, code that completely breaks the functionality of the site in some way.

There are other virtues, like if you see database strings that clearly shouldn’t ever appear, like ODBC errors, you could completely block the output, etc… Don’t get too excited, I’m still not on the WAF bandwagon, but I’m starting to see more interesting applications for it, above and beyond a simple short term inbound patching mechanism.

Cross Domain Basic Auth Phishing Tactics

Friday, June 8th, 2007

I’ve talked about this problem before - using basic authentication to phish users across domains. But it might be good to do a quick refresher for those of you who don’t know what I’m talking about. A bad guy can include a reference to an image on a domain that is protected by an Apache module, or protects itself. That then pops up a basic authentication dialog on the site that you want to phish credentials from. The only problem with this is that the basic auth dialog has the name of the URL in the title. Well Alex found a few potential workarounds to that issue:

I’ve found some nice bugs in Opera and IE (7.0), which could trick a user in thinking that he/she’s on the right server, ’cause the server’s hostname looks like what they do expect it to. Opera truncates the server’s hostname after the 34th character and adds three points “…” at the end. This could be overseen. I’ve reported that to the vendors of Opera and they don’t know a solution. Well, sounds very funny. The could display the whole string like other browsers do, but they don’t want to change their layout of the dialogue … They were not very happy with all my other suggestions I had (explicit warning message, etc.) for them. So, there will be no change in the future, I think. Due to the missing status bar (default setting) you can’t see where it probably came from => “Waiting for phishers.com …” (And if you go to enable it, there will be no output on the bar. *G*)

Don’t forget, that there’s no link you must click on. An embedded image is good enough.

(Use Opera for testing: http://testing.bitsploit.de/test.html )

The second bug, which leads to phishing is in MSIE 7. If you use IDN domain names like microsoft.de with a cyrillic, little o instead of a latin one, you won’t see the real hostname in the HTTP-Auth dialogue (www.xn--blabla.de). Only the status bar is showing the real hostname while showing the dialogue. That’s bad, but Ronald van den Heetkamp told me, that this shouldn’t be a big problem. (Don’t know how, ’cause IE7 ignores something like status=no and e.g. Firefox gives no access to rewrite the status bar string as a default setting.)

I’ve informed MS, but they didn’t respond so far.

The IDN thing is interesting because I’m sure if you were in the field a few years back this will sound familiar - people setting up fake websites that looked in every way like the target website, except one letter would be Cyrillic. That mostly affected Firefox, and Netscape (because it used the Gecko rendering engine), but now it looks as if IE might also run into problems. Not that I think a ton of people fall for this sort of thing, but even if it’s only vaguely useful, it’s still something we should consider as a workable attack vector.

Jeremiah Grossman Named One Of Top 25 CTOs

Friday, June 8th, 2007

I’ve known this might be coming for a while, but I was holding my breath (didn’t want to jinx anything). But it turns out our very own Web Application Security guru Jeremiah Grossman was named one of Infoworld’s top 25 CTOs for 2007. You can click here for a direct link. This is actually really impressive to me. A year ago almost no one cared about web app sec. It was a niche inside of a niche, but what we’ve been able to accomplish as a community over that year is nothing short of remarkable. And that is in large part to Jeremiah Grossman of Whitehat Security.

I think we owe him a debt of gratitude in many ways. He’s been a public face to our issues, a punching bag for some, and all and all a really nice guy through the process. He’s got a tough job - keeping up with the technology but keeping his eye on the security industry as well. I know we take that kind of thing for granted, but I, for one, appreciate it.

The JavaScript Paradox

Thursday, June 7th, 2007

Last week I presented a talk at OWASP on how security and user interface often co-mingle. Amongst other issues, I talked about the fact that many sites require the use of JavaScript for key functionality (such as login). After the talk a woman came up to me and told me that her bank requires the use of JavaScript to login, and asked me if I thought if it would be a good idea for her to call her bank and ask them to remove that as a requirement. What an interesting question. It actually took me by surprise, and I was even more surprised with what I heard my mouth saying in response.

Without thinking I said that it wouldn’t make any difference if she did or didn’t. There are two types of people that this problem breaks the user public down into. People who surf with JavaScript turned on by default - and that represents about 99.99% of users (based on the last Omniture report I saw, which may or may not be accurate), and the users who inherently surf without it as a security precaution, which represents a hair of a fraction compared to the larger group. Now, let’s for a second assume that the bank did as she asked and removed the restriction on JavaScript for authentication. We have to assume the JavaScript was there for a reason. The JavaScript probably has some security functionality as it’s a bank. Maybe typing speed biometrics, for instance - who knows? So by disabling it, they actually remove one security function which may have some limited value. But what about the other users?

The way people most often disable JavaScript, that I’ve seen is through the use of Noscript. Noscript enables whitelisting by domain, so by turning it off per domain, you have effectively only opened yourself to those domains, which should be safe theoretically, given that you have agreed to open yourself up to them. So it would seem that the people who surf without JavaScript will continue to surf without JavaScript despite the fact that companies force them to at least temporarily enable it. In this case, the JavaScript has provided more good than bad, and forcing the bank to remove it has negatively impacted 99.99% of users by removing security functionality, rather than positively impacting them to mitigate the chance that they may stumble across something malicious elsewhere.

The reason we turn off JavaScript is to protect ourselves from XSS, session riding, history theft, and a barrage of other bad things. With the exception of credential theft and a few other things, attackers can do many of the same things with just straight HTML and CSS that they can do with JavaScript, so even that hasn’t helped much. Clearly turning off JavaScript does provide value from a security perspective - I don’t think many people would disagree there. But let’s say for a moment that we could rid the Internet of JavaScript dependencies, would that even solve the problem? People would still have it turned on by default.

Even if it wasn’t a dependency and people did all their validation server side, people still find it to be a convenience. So I doubt that 99.99% JavaScript user base would drop much. So herein lies the paradox - while turning off JavaScript is a security precaution, it doesn’t matter if everyone removes their dependencies on it from a security perspective. Additionally, disabling it may actually make the sites who depend on it less secure. The reason is that users will continue to demand the rich features of things like dynamic maps, real time updates, etc… They don’t turn it off, not because they are forced to keep it on, but because they want to keep it turned on. There might be a very small handful of people who don’t fall into that bucket who would turn it off if they could but refuse to use tools like Noscript, but that’s most likely a very small group of people that are the exception that proves the rule.

Of course, I have no idea how blind people using the Lynx browser use that bank, given that Lynx doesn’t render JavaScript - maybe they have to go and visit the bank in person, but I’m pretty sure that’s grounds for an ADA accessibility lawsuit. And even if Lynx did render JavaScript, how is a blind person going to “look for the lock” or the other visual cues that we tell our users to be wary of. But putting that aside, even though my mouth was talking ahead of my brain as I answered that question and even though I wasn’t sure I was right, after a week of reflection considering human nature and the statistics of the problem, I think I have finally come to terms with my own answer.

Additional Image Bypass on Windows

Wednesday, June 6th, 2007

Michael Schramm posted about another way to do image filter bypassing using alternate file streams on NTFS file systems. Pretty cool stuff (thinking outside the box of what a file really means on different systems). Here’s his English translation:

It’s all about the alternate file streams (ads) in NTFS file system (it’s a “feature”), you probably have heard of them. With ads, it’s possible to insert additional data streams to a file beside of its basic contents. For example you could insert ads.txt into the file foobar.txt with “type ads.txt>foobar.txt:somedescriptor”. A User won’t recognize that there is additional data in this file (even if the ads contains several gigabytes), the file foobar.txt will still appear with its original size and contents in file system. But anyway, this is not really essential for understanding what I’ve found out, I think you can inform yourself about ads if you want.

Every file in a NTFS-Volume has at least one data stream, this is the stream named “:$DATA” containing the contents of the file itself. For example if you want to create a file “foo.txt” you could do so with “echo something>C:\foo.txt”. Okay, this isn’t really something new so far, but let’s give a try with “echo something>C:\foo.txt::$DATA”. This will take the same effect as the command before: A file “foo.txt” will be created at C:\ containing the string “something”.

We now know that it’s possible to create “.txt”-files on the file system without really using the file extension “.txt”. Most web apps are validating uploaded files by their file extension because almost everything else is fakeable.

Due to the fact that programming languages/scripting languages are simply calling the api’s of the underlaying os, I thought it should be possible to pass a file with “::$DATA” attached to its name to a php upload-script (php is for example, could be also asp or something). I checked this out with the “filemanager” in the current release of fck-editor (gna, I’ve tried to exploit it damn often in the past - without success).

Fck-editor has a configfile containing a blacklist with denied file extensions, of course there’s “.php” included. And in fact, I was able to bypass this check of denied file extensions! I passed filename “foobar.php::$DATA” and it was saved as “foobar.php” without having problems!

This is only an example, but it should be possible to get this working in many other web apps too. As I mentioned, it only works on webservers running under windows (yes, not only IIS - Apache too!). The need of NTFS should not really be a problem, because almost _all_ Servers running Windows are using NTFS.

I’d love to hear any anecdotes where this actually works. I’m curious if anyone else can replicate this sort of thing. Pretty slick, and similar in some ways to injecting null bytes to bypass exact string match. Nice work, Michael!

XSS Cheat Sheet Errata

Tuesday, June 5th, 2007

I just made three quick changes to the XSS cheat sheet as pointed out by Andrey Bayora. It looks like I made three typos in the event handlers (it’s weird no one else noticed for the last year and a half - including me!) Here are the typos that I’ve corrected:

onRowDelete() should have been onRowsDelete()

onRowInserted() should have been onRowsInserted()

onSynchRestored() should have been onSyncRestored()

So if anyone wrote filters based on those exact strings they should probably update them to match what they really should be. I haven’t seen these used in any actual attacks, but I wouldn’t risk it. Thanks to Andrey!

Malware Uses Browser Plugin Sniffing

Tuesday, June 5th, 2007

Similar to Mr T, Łukasz Pilorz sent me a link to some malware that is actually doing browser sniffing. This was something we had thought was probably going on, but it was more of a theoretical attack. Now it’s clear it is actually being used in the wild. The interesting part of the code reads as follows:

if (win && ie) {
xd = _hwaPlugIE("SWCtl.SWCtl.1") ? "1" : "0";
sf = _hwaPlugIE("ShockwaveFlash.ShockwaveFlash.1") ? "1" : "0";

if (_hwaPlugIE("PDF.PdfCtrl.1")) pdf = "1";
if (_hwaPlugIE('PDF.PdfCtrl.5')) pdf = "1";
if (_hwaPlugIE('PDF.PdfCtrl.6')) pdf = "1";

qt = _hwaPlugIE("QuickTimeCheckObject.QuickTimeCheck.1") ? "1" : "0";
rp = _hwaPlugIE("rmocx.RealPlayer G2 Control.1") ? "1" : "0";
wm = _hwaPlugIE("MediaPlayer.MediaPlayer.1") ? "1" : "0";
} else if (!win || moz) {
for (var i=0; i < n.mimeTypes.length; i++)
_hmime += n.mimeTypes[i].type.toLowerCase();

xd = _hwaPlugMoz("application/x-director") ? "1" : "0";
sf = _hwaPlugMoz("application/x-shockwave-flash") ? "1" : "0";
pdf = _hwaPlugMoz("application/pdf") ? "1" : "0";
qt = _hwaPlugMoz("video/quicktime") ? "1" : "0";
rp = _hwaPlugMoz("audio/x-pn-realaudio-plugin") ? "1" : "0";
wm = _hwaPlugMoz("application/x-mplayer2") ? "1" : "0";
}

You can download the entire source here. It’s pretty interesting code, if you haven’t seen it before. Clearly it’s malicious so be careful about executing it, since it does use full paths. Interesting though. Thanks to Łukasz!

Passing Malicious PHP Through getimagesize()

Monday, June 4th, 2007

I traded emails this afternoon with Michael Schramm who brought up an interesting issue where you can inject PHP through image functions that attempt to insure that images are safe by using the getimagesize() function. I’m not sure how often that is used alone, but I’m sure it happens. Here’s a snippet from the emails (edited only for readability and to re-link the images):

Yesterday, I’ve found out that it’s possible to include PHP-code in GIF-files which will still be recognized as a valid image by the PHP-function getimagesize().

If getimagesize() gives a positive Integer for the width, height, and type of the passed file, they just save it on their server with its original filename. Some webmasters are additionally checking the Content-Type of the file given in the HTTP-Header of the upload-request - but everybody knows that this is fakeable.

My basic file was a 8 by 8 pixels GIF-image (renamed to: something.php) which looks like this in a hex-editor: basicgif.jpg If you now insert some php-code into the payload of the image and call getimagesize('something.php'); it will give a valid result - but if you call something.php with a browser it will say something like “php error: illegal characters in input file” (I think this is because of the null-chars in the header of the image).

So I tried to insert /* in the GIF before the illegal chars to make php ignoring all chars behind this point. After a while I’ve got this file working: finalgif.jpg

This file passes the getimagesize()-function and executes the phpinfo() if called in a browser.

Sure, this issue is only dangerous if an image is only checked by getimagesize() and is saved with its original filename then, but there are many fools out there which do so!

Indeed! I’ve seen a lot of really strange ideas on how to secure uploads, and this is no doubt used in some places. Even still sometimes being able to get PHP into a system, even if it’s not named .php may provide some value if the attacker can execute local files but can’t include them remotely. This is an interesting follow on to yesterday’s post. I bet there is a lot of issues left to uncover with uploads.

Image Upload XSS

Sunday, June 3rd, 2007

I’ve talked about this before but I thought I should actually make a tool to make this attack more practical. But one thing I have seen a number of times, is places that upload images, and even check to make sure they are valid but don’t rename them to make sure that the file names themselves aren’t malicious. Well I finally created a tool to help with this type of testing. Here’s an example of something you might test for:

<IMG SRC="$filename">

So you upload this file:

http://ha.ckers.org/image-xss/"onerror="alert('XSS')"a=".jpg

This ends up making the page look like:

<IMG SRC=""onerror="alert('XSS')"a=".jpg">

So I built that script at /image-xss/ to allow anything after it to render with a valid (small) image that will pass any validation algorithms. So this may only have questionable applications but it is something I haven’t see any of the scanning vendors do. The moral of the story is make sure if you do allow uploads that you rename them to something safe. Nuff said.

OWASP Live CD

Saturday, June 2nd, 2007

If you do a lot of application security you may have already heard of the OWASP Live CD. To quote the website, “The OWASP Live CD (LabRat) is a bootable CD akin to knoppix but dedicated to Application Security. It shall serve as a vehicle and distrubition (sic) medium for OWASP tools and guides.” Pretty cool idea, and I’ve used it before, but a few things came to mind as I was re-reading the documentation this morning.

Firstly, I’d like to see something similar to this, but instead of just being an OWASP collection it should be a collection of ALL web application security tools. That would be a lot more useful. Secondly, it should have a browser that is already tweaked and ready to go with all the extensions that we all tend to use while doing penetration tests. I think that would make a big difference, and it’s one of the reasons I tend not to use pre-canned CDs much for my own testing.

But one other thing came to mind as I was reading this that I think is worth talking about. Why haven’t we seen a secure webserver package? For you to install Apache on your machine you have to download it or run it out of ports (hopefully knowing ahead of time which .so objects you want to compile into it), you have to configure it, to be in the right place, right port, SSL/keys, right security, and right rules if you run mod_security, et al. The permissions are hokey, things like TRACE are turned on by default, the webserver signature is turned on, there are tons of default images to help fingerprinting, blah blah. Why isn’t there a distro of Apache that is built with security in mind out of the box?