一段Javascript的代码
我们先看一段Javascript的代码,如下所示:(你能看出来这是干什么的?)
[javascript]($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!”+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](_/_)[/javascript]
这段代码来自BlackHat DC 2011((黑帽安全大会,全世界最大两个黑客大会之一,另一个是Defcon)中的一个叫Ryan Barnett黑客做的XSS Street-Fight!的演讲(XSS是Web上比较经典的跨站式攻击,操作起来也有些复杂),一共69页,基本上都是一些比较枯燥的Javascript,不过这段代码挺有意思的,如果上面这段代码换个样子:
[javascript]($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!”+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](document.cookie)[/javascript]
你看到了document.cookie,于是你可能会想到这是偷用户帐号免登录cookie的。是的,就是这样。答案是,这代码等价于alert(document.cookie),而最上面的那个代码等价于alert(1)——当然,还不仅仅只是alert。看到这里,你可能会想起变态的C语言Hello World程序,以及如何加密/混乱C源代码,是的,这回的这个是Javascript版的,混乱Javascript的会比混乱C的更难懂,因为Javascript的变量类型是可以乱用的。
好,下面让我们来对这个代码做个解析。
首先,我们先明确一点,在Javascript和C中,混乱后的代码都是要使用一个或多个下划线(_)来当变量名使用的,所以,请把其中的下划线看成变量名。
其次,这段代码可以分成两个部分,第一个部门其实就是sort(),第二个部分才是alert()
[javascript title=”sort()”]($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!”+$)[_/_]+$_[+$])])()[/javascript]
[javascript title=”alert()”][__[_/_]+__[_+~$]+$_[_]+$$](_/_)[/javascript]
我们来看看细节的解释。
- $=[] 是一个空数组
- $=[$=[]] 是一个引用空数组的数组。所以 $ 的解引用就是数字 0。
- __ = (__ = !$ + $ ) 等价于字符串”false”
- _ = -~-~-~$ 中~是位运算符“非”,~$等于-1,所以-~$ 就是+1,基本上来说,~N就是 -(N+1),所以这个表达式的值为3。
- 因为_ = 3,所以 _/_ = 3/3 = 1
于是:
- (__ = !$ + $ )[ _ = -~-~-~$]
- (“false”)[_]
- (“false”)[3]
- “false”[3] = s
而:
- ({} + $)[_/_]
- (” object”)[_/_]
- (” object”)[1]
- ” object”[1] = o
再来:
- $ = ( $_ = !” + $)[_/_]
- $ = ( “true”)[1]
- “true”[1] = r
最后:
- $_[+$] = “true”[0] = t
因为
($$ = ( $_ = !” + $)[_/_] + $_[+$] ))
所以我们可以经过下面的推算得出$$的值
- !” = “true”
- $_ = (true)
- $_[1] = r
- $_[0] = t
- $$ = rt
所以第一部分就成了 sort(),也就是以下的代码
[javascript]($ = [ $=[]] ["s" + "o"+ "r"+ "t" ] )()[/javascript]
Sort 接受一个作为函数的参数来运行,从而执行了第二部份。
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
我们知道:
- $ = 0
- _ = 3
- __ = “false”
- $! = “true”
- $$ = “rt”
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
等价于
[__[1] + __[3 + -1] + $![3] + $$)(1);
等价于
[“false”[1] + “false”[3 + -1 ] + “true”[3] + “rt”] (1)
等价于
[ a + l + e + r + t ](1)
等价于
alert(1)
就是这样!于是这段代码可能绕过你的一些对Javascript的检查。
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《一段Javascript的代码》的相关评论
ho no~
有点像brainfuck
除了膜拜,再木有别的话说……
Sort 接受一个作为函数的参数来运行,从而执行了第二部份。
这个貌似是因为 ($ = [ $=[]] [“s” + “o”+ “r”+ “t” ] )() 返回了 window,然后window.alert(1)执行的吧
这还能说啥……
为什么加上[[]]就变成toString()的效果了? 比如new Date() + [[]]
实在是太bt了。。。
精辟~
这明明是乱码嘛…… 看到我眼花缭乱。
讲错了吧,之所以能执行alert是因为他取到了window 对象。
首选他拼出了字符串 “sort”,然后执行以下代码
($=[][“sort”])()
这个代码相当于 [][“sort”] 相当于 Array.prototype.sort,然后赋值到 window.$ 上。最后再调用 window.$()。window.$()调用中用的 this 是 window 而不是原先的数组了。而 Array.prototype.sort 的实现是返回 this。这就让他取到了 window
取到 window 以后, window[“alert”](0) 就很好理解了
@Atry
多谢指教!
两位大神 膜拜了~~
各位帅哥, 有没有办法输出字母v而不用任何数字或者字母? (像源程序一样)
由于是情人节, 尝试输出 “I love you”, 但是找不到v, 比较的尴尬。。。
((_=-~[])/–_+[])[_] 是 I
从 “true”, “false”, “Infinity”, “[object Object]”, “undefined” 立面可以找到其它几个字母
但是。。。 搞不定v, 残念。。。
在stackoverflow的帮助下。。。 还是达成了Firefox版本:
http://stackoverflow.com/questions/5001529/how-can-i-say-love-without-character-or-digits-in-javascript
示例
http://jsfiddle.net/Y4wqw/
code
($=($=[$=[]][(__=!$+$)[_=-~-~-~$]+(_$={}+$)[_/_]+ ($$=($_=!”+$)[_/_]+$_[+$])])())[__[_/_]+__ [_+~$]+$_[_]+$$]((_$_=(__$=-~[])/–__$+[])[__$]+_$[_+++_]+__[__$=-~-~[]]+_$[-~[]]+($[_$[$__=_+_]+_$[++$__]+_$[++$__]+_$[++$__]+_$[++$__]+_$[++$__]]+[])[
$__+$__+–_]+__[++_]+_$[$__=_+–_]+_$_[_+++_]+_$[_/_]+$_[__$]);
谢。。。
看的我再也不淡定了,Javscript还有好长的路要走。
android 支持C++。。但是不像Java那样开发容易。。API封装也没那么全。。当然人家谷歌官方明说了是需要高效率应用和喜欢使用C++开发的人用而提供NDK开发。。C++走了那么长的路。。以后还是会有很好的应用的。。
Im getting a teeny issue. I cant get my reader to pick up your rss feed, Im using aol reader by the way.
文章里面的代码,不能运行,我给稍微改了下:
(($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!”+$)[_/_]+$_[+$])]),$())[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
在chrome console运行,可以看到效果。
谢谢楼主分析透彻
”换成2个单引号。。。