Wednesday, January 13, 2010

Url-Eval XSS II

I did some searching around to see if there has been any research done on the maximum supported URL length for various browsers and/or servers, as I was curious how much javascript could be stored in the url (described in this post). I found an article over at boutell.com that had exactly what I was looking for:

Client/ServerMax Bytes
MSIE 2,083, max path: 2,043
Firefox 100,000+
Safari 80,000+
Opera 190,000+
Apache Server 4,000 (supposed: 8,192)
MS ISS default: 16,384
Perl HTTP::Daemon ~8,000

It seems like the shortest supported url length is 2,083 (MSIE). This would leave us with somewhere around 1900-2000 bytes to store javascript functions (taking out 100-200 bytes for the url and path), which is a decent amount. Then again, if you don't care about IE, then you've got a lot more room.

The more I think about this, the more useful I can see it being. Hosting your javascript files elsewhere can be risky when one is trying not to get caught. Being able to store your "external" javascript in the url would be one way to still include a lot of code that can be used through the use of a single eval(unescape(location.href)) call. Not only that, but because it would take a relatively small number of bytes to eval() the url-stored javascript, this would work in many cases where the server truncates user input.

I wonder if others have thought of this before though. I'm sure I'm not the first to think of this.. Others have: here (lots of chinese characters) and translated, courtesy of Google. The author of this paper (luoluo from the Ph4nt0m Security Team) goes about it slightly differently, requiring the attacker to know the exact length of the full URL. He also uses document.URL, which is shorter than location.href by one byte:
eval(document.URL.slice(80));

The advantage to using the new-line method, is that one must not know the size or location of the javascript in the url. The author does also have several other very interesting ideas, such as using document.referrer as a way to store javascript:
eval(document.referrer.slice(80))

Again, this could be made successful using slicing, splitting, or my new-line method. Also, if it can be assumed that the stored script is always the last part of the url and if the attacker knows how long his script is (he should!), he could work from the end of the url:
eval(document.URL.substr(-##,##))

luoluo also talks about using the clipboard to store the payload. Suppose a user is on your (the attacker's) site. You store the javascript into the victim's clipboard while he's on your site:
clipboardData.setData("text", "alert(document.cookie)");

Then you make him go to a site with XSS vulnerabilities, eval()'ing the data that was stored in the clipboard while the victim was on your site:
http://some.site.come/with/xss/vulns?input=<script>eval(clipboardData.getData("text"))</script>

luoluo also goes over how to use the window.name variable to store the javascript. When you open a new window from javascript, you can specify the name of the window:
window.open(URL, NAME, OPTIONS, REPLACE)

Thus you could do something like this:
window.open("http://some.site.com/with/xss/vuln?input=eval(name)", "alert('xss')")
Cool stuff!

No comments:

Post a Comment