Update 1: Well hello reddit and hackernews.
1) I didn't write this JavaScript.
2) I didn't find this JavaScript.
I saw it in a slide deck from BlackHat DC 2011. Called XSS Street-Fight. Most of the presentation was dry JavaScript /mod_security, but this caught my eye.
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](_/_)
Care to guess what that does?
How about if I type it like this.
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](document.cookie)
That's right this is an alert() if it lands anywhere in
an executable section of JavaScript/dom it pops up the cookie.
Go ahead and put it in a script tag in your browser it will pop up a "1"
That's when I couldn't put this down.
First there are really two lines here.
($ = [ $=[]] [ (__ = !$ + $ )[ _ = -~-~-~$] + ({} + $)[_/_] + ( $$ = (
$_ = !'' + $)[_/_] + $_[+$] ) ] )()
becomes sort()
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
becomes alert(1)
Let's start to tear this apart.
$=[] is a blank array
$=[$=[]] is an array with a reference to an array.
So $ derefs to the value 0.
Now we have a 0 we can freely reference.
__ = "false"via (__ = !$ + $ )
_ = -~-~-~$
(The ~ operator in JavaScript means -(N+1) so -~ = +1
if $ = 0 then -~-~-~$ = 3
_ = 3
thus _/_ = 3/3 = 1
(__ = !$ + $ )[ _ = -~-~-~$]
("false")[_]
("false")[3]
"false"[3] = s
({} + $)[_/_]
(" object")[_/_]
(" object")[1]
" object"[1] = o
$$ = ( $_ = !'' + $)[_/_]
$$ = ( "true")[1]
"true"[1] = r
$_[+$] = "true"[0] = t
$_ = "true"null
$$ = rt via
($$ = ( $_ = !'' + $)[_/_] + $_[+$] ))
!'' = "true"
$_ = (true
$_[1] = r
$_[0] = t
$$ = rt
Thus the first line becomes sort()
($ = [ $=[]] ["s" + "o"+ "r"+ "t" ] )()
Sort takes a function as it's parameter to
execute thus firing the second line. It turns out this assumption was wrong on my first go. Scroll to the bottom for the updated explanation I quote from
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
_ = 3
__ = "false"
$_ = "true"
$$ = "rt"
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
becomes
[__[1] + __[3 + -1] + $_[3] + $$)(1);
becomes
["false"[1] + "false"[3 + -1 ] + "true"[3] + "rt"] (1)
[ a + l + e + r + t ](1)
alert(1)
From Benjaminsen @ reddit.
"
($=[]["sort"])()["alert"](1)
We can further break that into
a = [] // Create array
b = a["sort"] // Get reference to sort method
c = b() // Execute sort outside the context of an array to return a reference to window
d = c["alert"] // Get reference to window.alert
d(1) // Execute window.alert with the argument 1
So what happens is
window["alert"](1)
not
[1,2].sort(alert)
"Enjoy!
Okay, after I picked my brains up off the floor the first thing I thought of was "Can someone build a translator for this?" - kinda of like rsnakes xss cheatsheet page? because Hoooooooly crap.
ReplyDeletei wonder if behavioral protection can do something for these. i mean products like finjan(m86). ever had a chance to test?
ReplyDeleteif this is a case for anything, its a BRILLIANT SHINING example of why devs should always whitelist instead of blacklisting or relying on magic quotes.
ReplyDeleteThis just made my head hurt (thanks!) ...
ReplyDeletewhat the ****!!!
ReplyDeleteHere's a full converter using a subset of the characters used above: http://discogscounter.getfreehosting.co.uk/js-noalnum_com.php
ReplyDeleteAnd the forum thread where this technique was explored at length: http://sla.ckers.org/forum/read.php?24,33349,33405
Superfun. :D
Bet this won't run in IE ;)
ReplyDeleteDang! just dang.. I'll try again when I finished this coffee.
ReplyDeleteGah!
ReplyDeleteI'm wondering where did you find the slide?
ReplyDeleteFirst of all, that made my head hurt... Many whitelists would fail to protect from this type of XSS attack as well, this is a brilliant example of why input validation isn't a walk in the park.
ReplyDeletetoo much time on your hands? ;)
ReplyDeletecan a Genetic algorithm write these?
ReplyDeleteHi,
DeleteI can see that there is no response to your query. But do you have some ideas in this direction? In other words, what made you think to this query? I am interested in this direction and may be, we can discuss more.
thanks
what the? someone needs to stop smoking crack
ReplyDeletecool
ReplyDeletehybridus - yes, the M86 SWG (formerly Finjan) deals with such samples just fine.
ReplyDeleteBasically, this is plain (standard) JavaScript. While not very much readable to the human eye, the SWG engine couldn't care less.
I have to read your post a couple of times before understanding some of it -.-
ReplyDeleteMy addition to the above analysis can be found here: http://www.reddit.com/r/programming/comments/f6xto/_/c1dr729
ReplyDeletewhat would be the best approach to prevents XSS' like these?
ReplyDeleteWhen you see it, you'll shit bricks.
ReplyDeleteThanks. Every once in a while I need a reminder that I'm not as good at some programming skill as I thought I was. At first glance, I would have bet money that the JavaScript above was invalid. Wow.
ReplyDeletethis thing just scared the living heck out of me !
ReplyDeleteYou might want to check this out: http://utf-8.jp/public/aaencode.html
ReplyDelete:)
Nice one
ReplyDeleteThe perfect gag gift for a new dev team member.
ReplyDelete"this is an example of our coding style"
A few of months ago I posted something about
ReplyDeletehttp://extraexploit.blogspot.com/2010/10/dollars-javascript-code-yet-another_06.html
enjoy it!
Terima kasih infonya ,Brother
ReplyDeletesangat bermanfaat untuk menambah wawasan ^^
kunjungan baliknya yah brother:
http://aikoponsel76.blogspot.com
Blog seputar dunia Handphone
thangkiuuuu ^^
Mozilla has a script in early-stage development that detects code like this submitted in add-ons to addons.mozilla.org. It's here:
ReplyDeletehttps://github.com/mattbasta/amo-validator/blob/master/validator/testcases/scripting.py
The idea is that if you emulate the behavior of the JS interpreter by evaluating expressions that involve literals and predefined, static functions, you can programmatically determine when a script is being malicious.
Certainly there are more sophisticated ways to carry out an attack like this, but anything more complicated would likely attract the attention of a human editor for AMO.
This makes me actually miss COBOL, and want to finally go learn Python.
ReplyDeleteYour explanation is close, but not quite right.
ReplyDeleteYou say "$ derefs to the value 0." That's not true. $ is an empty array for the entire expression that retrieves the Array.prototype.sort method. It's just that this empty array is used in string/number contexts (i.e. its toString() method is being called when used in these contexts) that allows the code to produce what it needs.
So, because the binary + operator does string concatenation, and [].toString() returns an empty string:
1) ![] + "" === "false"
2) ({}+"") === "[object Object]"
3) !'' + "" === "true" (as a string, not a boolean)
And the others:
4) bitwise not (~) with any non-numeric value === -1
5) +[] === 0 (Unary + tries to convert its operand to number, which actually calls Array.prototype.toString for its primitive value (as Array.prototype.valueOf does not return a primitive), and then converts that empty string to a 0)
But otherwise, good job figuring this out ;-)
Wow.. too much complexity.. too much enjoyment :p
ReplyDeleteIf people are interested in more details on this style of JavaScript, I did a video presentation on the basics a few months ago: http://vimeo.com/15961577
ReplyDelete$=[] is a blank array
ReplyDelete$=[$=[]] is an array with a reference to an array.
So $ derefs to the value 0.
------------------
at the first time, $ value is only a blank array (toInt == 0)
once all inside the second [], the $ value become "function sort()" .. but the $ never value "an array with a reference to an array"
and in the second part, for the "l" of "alert" :
__[_+~$]
the ~$ == ~Array.prototype.sort == -1
and this don't work on IE because IE don't autorize to execute "sort()" on "no object".
ReplyDeleteI DID make a translator of that kind : https://github.com/TiTi/jswtf
ReplyDeleteI did it only with thoses caracters : ()![]+{}
Nice trick here:
a = [];
b = a["sort"];
c = b();
c
:D
I'd like to see something that was valid brainfuck and JavaScript - because this looks like extended brainfuck to me :)
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteKoxpcu
ReplyDeleteTimur taş hoca
Evcil Hayvan Forum
Yemek Tarifleri
This exact same proof-of-concept was done by @sirdarckcat and @thornmaker in their talk at BH Las Vegas 2009. Great explanation though, Adam!
ReplyDelete-Pooja
http://www.brightaxis.com
GEEZUS!
ReplyDeletethanks for all information
ReplyDeletebağcılar profilo servisi
bayrampaşa profilo servisi
bakırköy profilo servisi
avcılar ariston servisi
bağcılar ariston servisi
bahçelievler ariston servisi
bayrampaşa ariston servisi
beylikdüzü ariston servisi
Earnlancer.com is a global outsourcing solution and
ReplyDeletefreelance jobs website. Here you can find freelance coders,
writers, programmers, designers, marketers and more.The
worlds largest outsourcing marketplace ,it is freelance jobs
website. We have thousands of freelance jobs online for
freelance programmers, web designers, graphic designers.
http://www.earnlancer.com
This is a nice article..
ReplyDeleteIts very easy to understand ..
And this article is using to learn something about it..
c#, dot.net, php tutorial
Thanks a lot..!
I’m really Glad i ran across this web site.Added pompeiitours.org to my bookmark!
ReplyDeletecheap cialis
I have just started learning computer programming. I found this website very informative. It will help me to get some good programming concepts.
ReplyDeletejava tutorial
feeling well by reading this awesome article i m student and now learning Seo visit my blog Freelance Jobs
ReplyDeleteIt seems like little bit complex to understand but it was really interesting to know and learn something about the JavaScript thru ur blog !
ReplyDeleteweb design company
I can't get this to work. I get TypeError: Cannot convert undefined to object:
ReplyDelete>>> a = []
[]
>>> b = a['sort']
sort()
>>> c = b()
TypeError: can't convert undefined to object
Online Hile
ReplyDeleteSinema Burda
I truly wish My spouse and i we had not witnessed this kind of as I want 1 currently!
ReplyDeletehttp://www.buylovejewelry.com/
http://gamepartygogo.com/
Thanks for sharing this useful information! Hope that you will continue with the kind of stuff you are doing.
ReplyDeleteCheap Wildcard SSL
Good news.This is a great post. I like this topic.This site has lots of advantage. I found many interesting things from this site. It helps me many away..So i want some information for sharing this side with some of my friend. Thanks
ReplyDeleteSEO Services
The provided code doesn't work any more in any of the major browsers - Opera 12, FF11+, Webkit 533+
ReplyDelete