非字母javascript

你尝试过写javascript不用字母和数字吗?最近准备个xss的分享,记起了之前看到过老外一篇文章,内容是关于non-alpha javascript的,拿到代码分析下。
先看这段猥琐的javascript代码:

_=+[];$=_++;__=(_<<_);___=(_<<_)+_;____=__+__;_____=__+___;$$=({}+"")[_____]+({}+"")[_]+({}[$]+"")[_]+(($!=$)+"")[___]+(($==$)+"")[$]+(($==$)+"")[_]+(($==$)+"")[__]+({}+"")[_____]+(($==$)+"")[$]+({}+"")[_]+(($==$)+"")[_];$$$=(($!=$)+"")[_]+(($!=$)+"")[__]+(($==$)+"")[___]+(($==$)+"")[_]+(($==$)+"")[$];$_$=({}+"")[_____]+({}+"")[_]+({}+"")[_]+(($!=$)+"")[__]+({}+"")[__+_____]+({}+"")[_____]+ ({}+"")[_]+({}[$]+"")[__]+(($==$)+"")[___]; ($)[$$][$$]($$$+"('"+$_$+"')")();

看到这里你肯定抓狂了,但是这段代码是可以运行的,运行的结果是 alert('cool code');

javascript分析

这段代码能够运行,原因是javascript是弱类型的脚本语言,而且语法相对松散。例如下面的javascript是正确的,而且是有出乎意料结果的:

true+true;//2
undefined+''//'undefined'
(true+"")[0];//'t'
[]=='';//true
''==0;//true
typeof (+'');//number,0
({}+'');//"[object Object]"
({}[0]);//undefined

所以我们想得到一个0就可以使用:

_= +[];
_= +'';

下一步通过位运算,++等运算可以得到0~9所有数字。

因为0就是false,则!0就是true({}[0]);可以得到undefined({}+'')可以得到字符串:[object Object],字符串中的字符,可以组成新的字符串,于是通过组合,我们就得到了:"constructor"

javascript中的点(.)运算符和[]的作用都是一样的,只不过[]可以接收传入变量、字符串,所以我们可以得到一个Function对象,即:

(0)['constructor']['constructor'];

另外我们也知道,下面的代码是运行的:

Function('alert(1);')();

所以,我想剩下的你就懂了……