前些天在 est 的博客上看到 《仅用 []()+! 就足以实现几乎任意Javascript代码》 一文,很是震惊。
([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+...
让人想到 Brainfuck。
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
然而 Brainfuck 是个 Turing Tarpit (极简化的 Turing-complete 机器),而上面这个 JavaScript From Hell,则是一门脚本语言的 hack (类型强制转换、字符串 == 字符数组、first class function 和几个 JavaScript 漏洞的把握)。
我们从最简单的 []
开始。
[]; // [],空数组
+[]; // 0,空数组视为 null,类型转换为 0
!+[]; // true
+!+[]; // 1
整形可以搞出来了,字符串也是如此。false + []
,返回的是 "false"
。比如要取到 “s”,就可以,(“false”)[3]:
(![]+[])[+!+[]+!+[]+!+[]]; // 3
完整的码表可以参考 est 的博客。还有一个,window 对象的取得。Array 对象的方法 [].sort.call()
返回的是 window 对象。也就是说,我们可以试着拼出 []["sort"]["call"]()[
"eval"]("alert('hi there')")
理解了原理之后是体力活,大牛们 已经做好了一个自动转换的工具)。
所以说这玩意看着很像 Brainfuck,其实是不一样的。最后隆重推荐 JavaScript From Hell,十足劲爆。