日期:2014-05-16 浏览次数:20497 次
看了这个js后就别说自己js很牛了
转载:http://www.iteye.com/topic/947149
?
在2011年的BlackHat DC 2011大会上Ryan Barnett给出了一段关于XSS的示例javascript代码:?
?
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_)?
?
这是一段完全合法的javascript代码,效果相当于alert(1)。它可以在大部分浏览器上运行。(虽然目前我测试过手头的浏览器都能运行,但理论上不能保证所有浏览器都能正确运行,原因见下文)?
这段代码的好处(对于黑客)是,它不包含任何字符或数字,可以逃过某些过滤器的检查。比如说,如果假定一个AJAX请求将返回一个只包含数字的JSON,于是很可能会简单判断了一下其中不含字母就直接eval了,结果给黑客们留下了后门。上面的代码功能很简单,只是alert(1),但使用同样的原理,完全可以干出更复杂的事,例如alert(document.cookie)。更重要的是,这段代码再一次提醒我,黑客的想象力是无限的……正如Ryan Barnett的演讲标题:"XSS:The only rule is no rule"。?
那么这段代码是如何工作的呢??
我们可以把它分为两个部分来理解:?
第一部分:?
?
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()?
?
第二部分:?
?
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)?
?
其中第一部分是核心,我们首先对它进行分析,先缩进一下:?
?
($= [$=[]][ (__=!$+$)[_=-~-~-~$] + ({}+$)[_/_] + ($$= ($_=!''+$)[_/_] + $_[+$]) ] )() $ = []; //1??
?
显然,最外层是(...)()形式的函数调用,我们需要看看这里究竟调用了什么函数,返回了什么。下一步,我们把原来代码中赋值表达式提取出来,将其改写为以下等价形式:?
?
$ = []; //1 __ = !$+$; //2 _ = -~-~-~$; //3 $_=!''+$; //4 $$ = $_[_/_] + $_[+$]; //5 $= [$][ __[_] + //6 ({}+$)[_/_] + //7 $$ //8 ]; //9 $(); //10?
?
现在来一行行看:?
1. $先赋值为一个空数组? (后面会被覆盖)?
2. __ = ![] + [] = false + [] = "false"? 这里利用了javascript运算的强制类型转换特性。首先空数组是一个非null值,因此![]的结果是false(布尔型)。在计算false + []时,由于数组对象无法与其他值相加,在加法之前会先做一个toString的转换,空数组的toString就是"",因此事实上在计算false + ""。这时false被自动转换为字符串。最终结果是"false"+"" =?"false"。??**换句话说,在$为空数组时,使用 “+$”的方式可以将任何一个值转为字符串**?