`
kidneyball
  • 浏览: 326536 次
  • 性别: Icon_minigender_1
  • 来自: 南太平洋
社区版块
存档分类
最新评论

一段有趣的Javascript代码及分析

阅读更多
在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

$(); //10


现在来一行行看:
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)


最后只想再感慨一次:黑客的想象力是无限的。理解代码并不难,问题是一开始时他们是怎么能想出来的。。。
分享到:
评论
56 楼 leaow567 2011-04-26  
knightzhuwei 写道
kstg750718 写道
clue 写道
IE下,字符串无法使用下标访问:
"abc"[1] // undefined


好像IE8可以.

我这里ie8不行

我的IE8 可以 为什么有的可以 有的不可以??
55 楼 乌鸦* 2011-04-25  
我想知道,他能实现什么呢?
54 楼 beiizl 2011-04-25  
naiyi 写道
果然能把字母打到格子外面。。。。。。。为啥呢。。。。



因为没用word-break:break-all
53 楼 303132376 2011-04-02  
牛叉!真不愧为高手
52 楼 naiyi 2011-04-01  
果然能把字母打到格子外面。。。。。。。为啥呢。。。。
51 楼 limk 2011-03-30  
   看到这样的黑客,这些写程序很有压力。。
50 楼 Einsdan 2011-03-25  
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
49 楼 supperbbq 2011-03-25  
神人,膜拜一下!实在太犀利了
48 楼 fch415 2011-03-23  
说白了就是为了绕过JS代码文本的安全检查:
使用“较安全”的运算符做到保留字能做到的事。

像以下这些字符串,都可以通过纯运算符运行出来:
function
true
false
object
input
select
.....
以及完全包含26个字母了吧。几乎可以得到任何KEYWORD(保留字)了。

其实老外这段代码,是想引起关注:目前XSS漏洞解决方案仅靠输出时的check+filter仍旧不安全!

47 楼 java110eye 2011-03-22  
膜拜。。。
46 楼 hui_windows 2011-03-17  
太BT了,黑客是超级牛人呀
45 楼 bingufo 2011-03-16  
见都没见过啊,,厉害
44 楼 chelsi916 2011-03-16  
黑客就是黑客
43 楼 sliverxxm 2011-03-16  
这种代码其实也不是什么高深的东西,
问题在于你怎么能想到这种方式.
看来我的创造能力确实有够低啦,要不咱也干黑客~\(≧▽≦)/~啦啦啦!
42 楼 yutian2211 2011-03-16  
太牛了,直接看晕了,楼主能分析出来,也不是一般的强啊
41 楼 449302900 2011-03-15  
呵呵,这些一般都是闲着没事,吃饱撑着了、、、
然后泡一杯茶,慢慢品味、、、
高智商,高品位。。
40 楼 yangleisx 2011-03-15  
加95443740 一起学习java
39 楼 Kupid 2011-03-15  
俺是来膜拜的,V5……
38 楼 damoqiongqiu 2011-03-14  
FireFox3.6测试通过,可以运行,赞。。。
37 楼 yadihaoku 2011-03-14  
佩服啊!!!!
膜拜。。。

相关推荐

    基于机器学习的JavaScript恶意代码检测系统的研究与实现

    随着Web技术的发展,网站与用户交互的方式越来越丰富,这 就导致了用户在网站上的隐私或者资料容易被不法分子截获...保持较高的准确率,基本解决了第一段提出的问题。 2)通过对恶意代码进行类别分类,我们提出了基于深

    14-编译器和解释器:V8是如何执行一段JavaScript代码的?_For_vip_user_0011

    1. 在编译型语的编译过程中,编译器先会依次对源代码进词法分析、语法分析,成抽象语法树 2. 在解释型语的解释过程中,同样解释器也会对源代码进词法分析、语法

    通过javascript的匿名函数来分析几段简单有趣的代码

    想起自己很久以前学习javascript的经历,也曾经碰到过几个由匿名函数造成的困扰(其中一个就是由闭包引起的),下面就整理几段简单代码讨论一下,让我们大家一起进步。

    12行JS代码的DoS攻击分析及防御

    有一段12行的JavaScript代码,可以让Firefox、Chrome、Safari浏览器崩溃,而且还能让iPhone重启、安卓闪退,本文作者对这12行代码进行了分析解读并且提出了相应的防御办法,欢迎大家一同探讨。 Ajax与pjaxAjax即...

    javascript中eval函数用法分析

    如果编译成功则开始执行这段代码,并返回字符串中的最后一个表达式或语句的值;如果最后一个表达式或语句没有值,则最终返回undefined。如果字符串抛出异常,则该异常将把该调用传递给eval(); eval(&#41...

    深入理解jquery和javascript系列

    深入理解JavaScript系列,超实用的jQuery代码段,jQuery源码分析系列。

    12行代码的浏览器DoS攻击分析及防御

    有一段12行的JavaScript代码,可以让firefox、chrome、safari浏览器崩溃,而且还能让iphone重启、安卓闪退,本文作者对于该12行代码进行了分析解读并且提出了相应的防御办法,欢迎大家一同探讨。AJAX(阿贾克斯),...

    JavaScript王者归来part.1 总数2

     11.3.2.1 模拟对话框--创建一个窗口对话框及一个对话框阻塞进行的例子   11.3.2.2 showModalDialog和showModelessDialog--非W3C或ECMAScrip标准   11.3.3 状态栏   11.4 框架--上层的Window对象   11.4.1 ...

    JavaScript运行原理分析

    (可参考你不知道的JS这本书),当JS控制器转到一段可执行的代码时(这段可执行代码就是编译阶段生成的),会创建与之对应的执行上下文(Excution Context简称EC)。执行上下文可以理解为执行环境(执行上下文只能由JS...

    javascript函数的解释

    然后再执行下面一段代码:g('a_'+n).style.backgroundColor='#ff0000';(将当前点击的按钮显示为红色,n指当前点击按钮的编号,是点击菜单传递的一个参数值). function g(o){return document.getElementById(o);}这...

    JavaScript运行机制实例分析

    这篇博客的内容源于前段时间写一个微信小程序前端,发现页面的渲染顺序总与自己的预想相违背,因此近期看了一些关于JavaScript运行机制的博客及文档,有了一些基本的框架,接下来就来详细看一下我所了解到的内容。...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    javascript中有趣的反柯里化深入分析

    反科里化的话题来自javascript之父Brendan Eich去年的一段twitter. 近几天研究了一下,觉得这个东东非常有意思,分享一下。先忘记它的名字,看下它能做什么. 不要小看这个功能,试想下,我们在写一个库的时候,时常...

    JS-Profiler:一个Javascript代码段,用于描述功能完成所需的时间,并具有对大型数据集进行递归测试的功能

    JS分析器一个Javascript代码段,用于描述功能完成所需的时间,并具有对大型数据集进行递归测试的功能。

    基于PHP+javascript的计算机网站设计毕业论文

    分析了设计一个网站所用的编辑工具和编程语言及网站的软硬件开发环境。并根 据分析的结果,主要采用 Dreamweaver 编辑器,结合 PHP(javascript,html)编 程编程语言,进行网站的页面设计;网站主要实现了新闻、下载...

    JavaScript预解析及相关技巧分析

    本文实例讲述了JavaScript预解析及相关技巧。分享给大家供大家参考,具体如下: 变量 同样,以这两个小例子的错误对比提示开始。 alert(y1); //代码段1 var y1 = 'dddd'; alert(y2); //代码段2 // ...

    javascript内存分配原理实例分析

    本文实例讲述了javascript内存分配原理。分享给大家供大家参考,具体如下: JavaScript中的变量分为两种,原始值和引用值。原始值指的是原始数据类型的值,比如...我们来看一段代码: function Person(id,name

Global site tag (gtag.js) - Google Analytics