日期:2014-05-16  浏览次数:20488 次

黑客写的JS(收藏)

看了这个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"。??**换句话说,在$为空数组时,使用 “+$”的方式可以将任何一个值转为字符串**?