Thursday, November 08, 2007

Inside History of hacking rsnake for fun and pagerank.

Well the research made for the exploit for the joke for rsnake is sort of interesting, so I'll try to explain what was needed (even do it was unsuccesfull).

This was made with the help of the research made by the members of sla.ckers like ascii, gareth heyes, rsnake, Jeremiah Grossman, thornmaker, Wisec, kuza55 and me.

It exploited a bug and a feature from ha.ckers.org:

And a feature from Firefox:

Some bugs from NoScript:
  • XBL Frame Injection to bypass NoScript IFrame protection.
  • setter/name NoScript anti XSS filter bypass.
(this bugs have been patched since version 1.1.7.8 of NoScript)

You can read the comments from Robert Hansen, and Giorgio Maone about this exploit at ha.ckers.org and hackademix.net (oh jeremiah grossman also talked about this here and some others in langs that I dont understand).

The only thing the exploit required was that rsnake had ha.ckers.org white-listed on NoScript, but it didn't succeed for that and some other secret reasons.

For targeting the exploit just for rsnake, and hiding it from other persons, we did 3 things.

First we checked if rsnake had ha.ckers.org/blog/wp-admin/post-new.php on his history via CSS History check without javascript.

If this was unsuccesfull because of the "SafeHistory" plugin, or any other reason, we checked if his IP had access to ha.ckers.org/blog/wp-admin/wp-admin.css stylesheet, if he had, we would try to exploit it.

For doing that we played with display:block/display:none properties of iframes, but in the case that rsnake had NoScript iframe protection enabled, then the exploit would be unsuccesfull, so we added a -moz-binding, for detecting NoScript presence, and replacing it with a frameset/frame.

With that, we just redirected rsnake to the payload, the problem was that NoScript detects reflected XSS attacks, so we needed to find a way to bypass it, and we did.. (http://ha.ckers.org/xss.swf?a=0:0;a/**/setter=eval;b/**/setter=atob;a=b=name;)

That in un-obfuscated code is:

eval(atob(window.name)).

atob=decode base64.

The reason this bug works was a mistery at the begining, but after Wisec re-constructed the as2 bytecode he saw that there where some variables appending to the url, and then after some more research this is the reason this guys found out (explained by kuza55):

the Flash file looked like this:

getURL("javascript:('XSS')", "_self", "GET");
stop();

That third parameter turned out to be the key (though we only found this by an absolute fluke), initially we just assumed that the third parameter was just saying it should be a GET request, but the third argument does more actually:

[www.adobe.com]

getURL(url [, window [, "variables"]])

[snip]

variables: A GET or POST method for sending variables. If there are no variables, omit this parameter. The GET method appends the variables to the end of the URL, and is used for small numbers of variables. The POST method sends the variables in a separate HTTP header and is used for sending long strings of variables.

Now, seeing as in AS2, all variables which are passed on the URL are imported into the global scope (like register_globals), we get it sent with the request. Now seeing as there was no semi-colon at the end of the first argument, we were able to abuse the fact that the ? is not only the thing separating the variables in the URL from the file, but it is also the javascript ternary operator.

So we simply used this to finish off a valid statement using the ternary operator, and then specified our XSS.

The window.name trick doesn't require a javascript doing window.name="payload".. it required just a frame named as we wanted.. (< iframe name="payload">) since NoScript strips any char matching [^a-z0-9_\-] with space in window.name, then we needed to encode the payload in base64 and remove all the "+" and "/" chars of it via whitespacing where they where shown.

So, we posted a comment with a link that may attract the attention of rsnake when moderating the comments, and we only needed to wait..

Then, we saw the anti-climax.. the comment was aprooved, and the payload wasnt triggered.. lol (hey spammers)

So we did another post, now with a link that appeared to be spam, and we did..
http://owaspnj.blogspot.com.

Any way, that comment wasnt aprooved, and the exploit in there (that was clearly more hidden than the ultimatehxr.googlepages.com) was not necessary.

So you can see the exploit here (it's commented :D):

http://www.sirdarckcat.net/blah2.html


if you want to know what's blah1.html, it's just how we where trying to detect the wp-admin.css.

The last thing is to explain the functionment of the payload.

1.- via XMLHttpRequest, it asked for /post-new.php source code.
2.- it created an iframe, and writted inside that iframe the source code with a.. "< base target="/wp-admin">"
3.- Then he submited the first form modifying the title, content, and tags fields, and clicking on publish (yeah we wanted the payload to had tags).
4.- And that was all, no RegEx.match for finding nonces, and nothing :P..

You can see the content of the post as it would appear if the exploit suceeded here:
http://rsnakex.wordpress.com/

Greetz!!

No comments:

Post a Comment