在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
__ = !$+$; //2
_ = -~-~-~$; //3
$_=!''+$; //4
$$ = $_[_/_] + $_[+$]; //5 $= [$][
__[_] + //6
({}+$)[_/_] + //7
$$ //8
]; //9 $(); //

现在来一行行看: 
1. $先赋值为一个空数组  (后面会被覆盖)

2. __ = ![] + [] = false + [] = "false"  这里利用了javascript运算的强制类型转换特性。首先空数组是一个非null值,因此![]的结果是false(布尔型)。在计算false + []时,由于数组对象无法与其他值相加,在加法之前会先做一个toString的转换,空数组的toString就是"",因此事实上在计算false + ""。这时false被自动转换为字符串。最终结果是"false"+"" = "false"。  **换句话说,在$为空数组时,使用 “+$”的方式可以将任何一个值转为字符串**

3. 在计算~[]时,~需要一个数字操作数,空数组无法直接转换为数字,则作为0处理。因此~[] = ~0 = -1。

参考:
~3 = -4
~[3] = -4
~[3,2] = -1 (无法转为数字)
~"3" = -4
~"abc" = -1

因此: _ = -~-~-~[] = -~-~-(-1) = -~-~1 = -~-(-2) = -~2 = -(-3) = 3  理论上,可以用这种方式得出1-9所有数字

4. !''是true,使用+$将其变为字符串 "true"

5. 这里需要注意的是,之前一直用“值+[]”来获得“值”的字符串形式。而“+[]”则是0(正号导致[]被自动转换为数值0)。因此:$$ = "true"[3/3] + "true"[+[]] = "true"[1] + "true"[0] = "rt"

6. __[_] = "false"[3] = "s"

7. ({} + [])导致空对象{}被转换为字符串"[object Object]", 因此({}+$)[_/_] = "[object Object]"[1] = "o"

9. 这里把$覆盖为 [[]]["s"+"o"+"rt"]。注意这里[[]]本身是一个包含空数组的数组,其实对这一步来说,任何一个数组都没有关系(不一定要是嵌套数组),但作者巧妙地把$的首次赋值式放在了数组内部,使代码更为紧凑。最终结果是,$ = [[]]["sort"] = [[]].sort = Array.prototype.sort

10. 调用$(),作为整个表达式最终的取值。需要注意,$是全局范围的,是window的一个属性,相当于window.$。而Array.prototype.sort会返回this。对于window.$来说,this就是window。因此,整个第一部分的值,就是window本身!当然,这个过程的正确运作依赖于当前浏览器的Array.prototype.sort实现能对this为window的情况容错。

通过第一部分,我们已经获得将任何值转换为字符串的简单方法,并能产生任意的数值,理论上就可以从javascript的取值系统中提取出大部分字母(不知道是不是全部,需要考证)。并且,我们获取到了window的引用。下面就可以开始上下其手,为所欲为了。木哈哈哈哈哈!

可以看出,上面的第10步是与浏览器的具体实现相关的,因此也存在着某些浏览器下需要对代码作出修改的可能。

现在看第二部分,事实上已经非常明朗了,唯一需要注意的是,现在$是一个函数,因此~$ = ~0 (无法直接转换为数字则作为0处理) = -1。

[__[_/_]+__[_+~$]+$_[_]+$$](_/_) = ["false"[1]+"false"[3+(-1)]+"true"[3]+"rt"](1) = ["a"+"l"+"e"+"rt"](1)

所以,整条式子相当于:

window["alert"](1)

最后只想再感慨一次:黑客的想象力是无限的。理解代码并不难,问题是一开始时他们是怎么能想出来的。。。

转自:http://www.javaeye.com/topic/947149

开源工具

使用JS开发的编码工具

一个“神奇”的工具:把 JavaScript 代码转为 ()[]{}!+ 字符

Javascript:alert(1)可以这样写以绕过filter的更多相关文章

  1. 在标记的HREF属性中javascript:alert(this.innerHTML)会怎么样?

    原文:在标记的HREF属性中javascript:alert(this.innerHTML)会怎么样? <a href="javascript:alert(this.innerHTML ...

  2. <a href="javascript:void(0);" id='test' onclick="javascript:alert('即将上线,敬请期待!');"><em class="rmwd"></em>征稿平台</a>

    <a href="javascript:void(0);" id='test' onclick="javascript:alert('即将上线,敬请期待!');&q ...

  3. 同事问如何判断同花顺,我用javascript的二维数组写了个简易demo

    有个前同事在群里问如何判断是否为同花顺我用javascript的二维数组写了个简易demo. <!DOCTYPE html> <html> <body> <s ...

  4. testXSS <img src="aa" onerror="javascript:alert('XSS');"/>

    adsa  </p><img src="aa" onerror="javascript:alert('XSS');"/><p> ...

  5. JavaScript alert()函数的使用方法

    这里向大家简单介绍一下JavaScript alert()函数的使用,alert--弹出消息对话框,并且alert消息对话框通常用于一些对用户的提示信息. JavaScript alert()函数 a ...

  6. javaScript(js)手写原生任务定时器源码

    javaScript(js)手写原生任务定时器 功能介绍 定时器顾名思义就是在某个特定的时间去执行一些任务,现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务 ...

  7. JavaScript Alert 函数执行顺序问题

    * { color: #3e3e3e } body { font-family: "Helvetica Neue", Helvetica, "Hiragino Sans ...

  8. javascript的 热点图怎么写

    在gis中,你如果用js来写热点图 不借助后台怎么搞,as的话比较容易有相应的类库甚至官方都有.而且用js不借助arcgis发布rest服务,(注:热点图可以借助服务的形式发布,arcgis for ...

  9. javascript alert,confirm,prompt弹框用法

    1. alert是弹出警告框,在文本里面加入\n就可以换行. 2. confirm弹出确认框,会返回布尔值,通过这个值可以判断点击时确认还是取消.true表示点击了确认,false表示点击了取消. 3 ...

随机推荐

  1. 【Unity】打包安卓APK常见问题

    问题:unity error invalid command android 原因:Android版本较新,Unity版本太旧(如4.X),Unity打包APK时调用Android工具使用的命令已被安 ...

  2. FortiGate防火墙HA下联堆叠交换机

    1.拓扑图 2.防火墙配置 3.交换机配置 interface GigabitEthernet1/0/47 switchport access vlan 30 switchport mode acce ...

  3. 93. Restore IP Addresses产生所有可能的ip地址

    [抄题]: Given a string containing only digits, restore it by returning all possible valid IP address c ...

  4. EasyWeChat使用(laravel框架下)

    最近做了个项目是关于微信网页开发的,今天记录下在做项目中的关于微信这块遇到的一些坑 关于微信这块,用的是EasyWeChat,提高了开发的效率.在看EasyWeChat这个文档的时候发现了有专门针对l ...

  5. python07 函数式编程

    1.作用域 1.1  pass关键字表示,暂时不写该方法 1.2表示返回值为方法 输出结果333 1.3函数作用域:和函数调用没关系,和声明的位置有关系, 结果为444 2.匿名函数 lanmbda ...

  6. php上传多张图片

    第一种:加后缀 代码实现(就是普通的上传图片,只是在外面加个foreach循环) $allow_file_types = '|GIF|JPG|PNG|BMP|SWF|DOC|XLS|PPT|MID|W ...

  7. C++静态库与动态库(比较透彻)

    这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一本书<程序员的自 ...

  8. python_day12_css

    目录: 简介 选择器(selecttor) 常用属性 页面布局 一.简介 1.CSS 定义 CSS是Cascading Style Sheets的简称,中文称为层叠样式表. CSS 规则由两个主要的部 ...

  9. 《Miracle_House团队》第一次作业:团队亮相

    Our Team:Miracle_House part 1 团队成员组成: NO.1  汝春瑞   201571030125   (组长) Style:乐观开朗,认真踏实,责任心强,还有就是爱笑.随和 ...

  10. 深入C#的String类