首页 > 编程语言 > 详细

Javascript 混淆

时间:2015-09-25 23:01:15      阅读:275      评论:0      收藏:0      [点我收藏+]

 我们先看一段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的检查。

 

代码如下:

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


注意,上面这段看起来很混乱的代码并不是自动换行,而是三行(当然,你写在同一行也没有错)。编写一个页面运行一下(据说 IE 下不行),你就会发现这段代码的功能等同于 
alert(1) 
为什么会这样呢?我们来把这段代码拆开来分析。 
$=[] // $ 被赋值为一个空数组,所以 !$ 的值为 false. 
__ = !$ + $ // 加号会把 !$ 和 $ 都转换成字符串,所以 __ 的值变成了字符串 “false” 
_ = -~-~-~$ // 这里有一个 ~ 操作符,它表示 -($+1),所以 -~$ 的值为 1. _ 的值为 3. 
由此可以推导: 

 
代码如下:

(__ = !$ + $ )[ _ = -~-~-~$] => (”false”)[_] => (”false”)[3] => “false”[3] = “s” 
({} + $)[_/_] => (”[object Object]“)[_/_] => (”[object Object]“)[1] => “[object Object]“[1] = “o” 


接下来再拆 $$=($_=!”+$)[_/_]+$_[+$] : 
$_=!”+$ // 注意,!” 中是两个单引号,也就是对一个空字符串做非运算。所以变量 $_ 被赋值为字符串 “true”。 
由此可推: 
$$=($_=!”+$)[_/_]+$_[+$] => $$ = ( “true”)[1] + “true”[0] => “r” + “t” = “rt” 
所以 (__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!”+$)[_/_]+$_[+$]) 就是 “s” + “o” + “rt” ,也就是 “sort”. 
所以原来的表达式 

代码如下:

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


可以被替换成: 

代码如下:

($=[[]]["sort"])()[__[_/_]+__ 
[_+~$]+$_[_]+$$](_/_) 


接下来我们看 [__[_/_]+__[_+~$]+$_[_]+$$](_/_) 是什么东西。 
前面我们已经得知: 
__ = “false” 
_ = 3 
~$ = -1 
$_ = “true” 
$$ = “rt” 
所以 [__[_/_]+__[_+~$]+$_[_]+$$](_/_) => ["false"[1] + “false”[3-1] + “true”[3] + “rt”](3/3) => ["a" + "l" + "e" + "rt"](1) => ["alert"](1) 
所以原来的表达式最终可以被替换成: 
($=[[]]["sort"])()["alert"](1) 
这段代码是如何执行的呢?我们来逐步分析: 
a = [[]] // 创建一个数组 
b = a["sort"] // 获取数组的 sort 方法 
c = b() // 调用数组的 sort 方法,这里 b() 返回的是 window 对象 
d = c["alert"] // 获取 window.alert 方法 
d(1) // 调用 window.alert 方法。 
所以这堆乱七八遭的表达式最终的执行结果就是 window.alert(1). 
更多 请看原文 和 Reddit上的讨论。 
原文评论里也有人贴出了一个日本开发者写的小工具,可以把一段 JavaScript 代码编码成各种表情符号,而且可以执行,enjoy it. 
BTW, 上面这段代码除了做 XSS 攻击之外作用不大,但是可以从分析这段代码学习一点儿数据类型转换相关的东西,也可以领略到 JavaScript 的灵活。 
详细代码解析: 

代码如下:


$=[$=[]] // $ = [] 

(__= !$ + $) // __ = "false" 
[_=-~-~-~$] // _ = 3 
// (__)[3] = "s" 

({} + $) // ({} + $) = [object Object] 
[_/_] // _/_ = 1 
+ // ([object Object])[1] = "o" 
($$ = // 
($_=!‘‘ + $) // !‘‘+ $ = "true" ; $_ = "true" 
[_/_] // _/_ = 1; 
// $_[1] = "r" 

$_[+$] // +$ = 0; $_[0] = "t" 
) // $$= "rt" 
] // ["sort"] 
// []["sort"] = [].sort = function sort() { [native code] } 
// $ = []["sort"] 
)() // ($)() = [object Window] 

__[_/_] // __ = "false"; 
// __[1] = "a" 

__ [_+~$] //_ = 3; ~$ = -1; _ + ~$ = 2 
// __[2] = "l" 

$_[_] // $_ = "true" ; _ = 3; 
// $_[3] = "e" 

$$ // $$ = "rt" 
](_/_); // _ / _ = 1 
// window["alert"](1) 


这里需要注意的几点: 
1. javascript 里面 $, _ 均可以作为变量名 
2. 函数还可以这样调用: 比如 [1,2,4,1,9,1].sort() 可以写成 [1,2,4,1,9,1]["sort"](); 
3. ~ 对数字按位取反 
4. javascript 中在对不同类型的变量 使用 + 时候的规则 
5. 最后一个针对某些native code写的方法,执行会返回 window对象, 比如 
var s = [].sort ; t=s(); 则 t 是 window

 

Javascript 混淆

原文:http://www.cnblogs.com/abapscript/p/4839667.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!