IT技术博客大学习 共学习 共进步

一段Javascript的代码

酷壳 - CoolShell.cn 2011-02-14 21:26:04 浏览 4,182 次

    我们先看一段Javascript的代码,如下所示:(你能看出来这是干什么的?)

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!\'\'+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](_/_)

    这段代码来自BlackHat DC 2011((黑帽安全大会,全世界最大两个黑客大会之一,另一个是Defcon)中的一个叫Ryan Barnett黑客做的XSS Street-Fight!的演讲(XSS是Web上比较经典的跨站式攻击,操作起来也有些复杂),一共69页,基本上都是一些比较枯燥的Javascript,不过这段代码挺有意思的,如果上面这段代码换个样子:

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!\'\'+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](document.cookie)

    你看到了document.cookie,于是你可能会想到这是偷用户帐号免登录cookie的。是的,就是这样。答案是,这代码等价于alert(document.cookie),而最上面的那个代码等价于alert(1)――当然,还不仅仅只是alert。看到这里,你可能会想起变态的C语言Hello World程序,以及如何加密/混乱C源代码,是的,这回的这个是Javascript版的,混乱Javascript的会比混乱C的更难懂,因为Javascript的变量类型是可以乱用的。

    好,下面让我们来对这个代码做个解析。

    首先,我们先明确一点,在Javascript和C中,混乱后的代码都是要使用一个或多个下划线(_)来当变量名使用的,所以,请把其中的下划线看成变量名。

    其次,这段代码可以分成两个部分,第一个部门其实就是sort(),第二个部分才是alert()

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!\'\'+$)[_/_]+$_[+$])])()
[__[_/_]+__[_+~$]+$_[_]+$$](_/_)

    我们来看看细节的解释。

  • $=[] 是一个空数组
  • $=[$=[]] 是一个引用空数组的数组。所以 $ 的解引用就是数字 0。
  • __ = (__ = !$ + $ ) 等价于字符串”false”
  • _ = -~-~-~$ 中~是位运算符“非”,~$等于-1,所以-~$ 就是+1,基本上来说,~N就是 -(N+1),所以这个表达式的值为3。
  • 因为_ = 3,所以 _/_ = 3/3 = 1
  •     于是:

  • (__ = !$ + $ )[ _ = -~-~-~$]
  • (“false”)[_]
  • (“false”)[3]
  • “false”[3] = s
  •     而:

  • ({} + $)[_/_]
  • (” object”)[_/_]
  • (” object”)[1]
  • ” object”[1] = o
  •     再来:

  • $ = ( $_ = !” + $)[_/_]
  • $ = ( “true”)[1]
  • “true”[1] = r
  •     最后:

  • $_[+$] = “true”[0] = t
  •     因为

        ($$ = ( $_ = !” + $)[_/_] + $_[+$] ))

        所以我们可以经过下面的推算得出$$的值

  • !” = “true”
  • $_ = (true)
  • $_[1] = r
  • $_[0] = t
  • $$ = rt
  •     所以第一部分就成了 sort(),也就是以下的代码

    ($ = [ $=[]] ["s" + "o"+ "r"+ "t" ] )()

        Sort 接受一个作为函数的参数来运行,从而执行了第二部份。

        [__[_/_]+__[_+~$]+$_[_]+$$](_/_)

        我们知道:

  • $ = 0
  • _ = 3
  • __ = “false”
  • $! = “true”
  • $$ = “rt”
  •     [__[_/_]+__[_+~$]+$_[_]+$$](_/_)

        等价于

         [__[1] + __[3 + -1] + $![3] + $$)(1);

        等价于

         ["false"[1] + “false”[3 + -1 ] + “true”[3] + “rt”] (1)

        等价于

         [ a + l + e + r + t ](1)

        等价于

         alert(1)

        就是这样!于是这段代码可能绕过你的一些对Javascript的检查。

    建议继续学习

    1. cookie窃取和session劫持 (阅读 14,425)
    2. curl 命令使用cookie (阅读 9,844)
    3. 前端开发中Cookie那些事儿 (阅读 7,207)
    4. 如何设置一个永远无法删除的Cookie (阅读 6,263)
    5. 几种极其隐蔽的XSS注入的防护 (阅读 5,542)
    6. 在浏览器中加密Cookie (阅读 5,384)
    7. 网站统计:第一方Cookie和第三方Cookie (阅读 4,963)
    8. Cookie安全漫谈 (阅读 4,542)
    9. 新浪微博的XSS攻击 (阅读 4,002)
    10. 使用Http-only Cookie来防止XSS攻击 (阅读 3,902)