大家好,我是ConardLi。
上周有个朋友在群里发了一段代码,复制到浏览器发现居然是可以运行的:
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+!+[]]+([][[]]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])()
研究了一下,挺有意思的,只用 []()!+ 这六个字符就可以实现一段可执行的 JavaScipt 代码,这是咋实现的呢?
JavaScript 是弱类型的编程语言,我们在写代码的时候充斥着大量的类型转换,在我之前的文章 【JS进阶】你真的掌握变量和类型了吗 中有过相关的介绍:
其实上面代码的核心就是用到了下面三个类型转换:
通过上面的方法,我们可以尝试做一些简单的转换:
false => ![]
true => !![]
undefined => [][[]]
NaN => +[![]]
怎么用这几个符号来表示数字呢?最简单的 0 :
+[] === 0
这个很好理解,根据上面表格中的总结我们知道,空数组转换成数字是 0,我们只需要在 [] 前面加上 + 让它转换成数字就可以得到 0 。
那么 1 可以怎么得到呢?
+!+[] === 1
因为 +[] 转换成了 0 , 0 是一个假值,那么 !+[] 就是一个真值,把一个真值转换成数字就会得到 1 ,所以我们只需要在 !+[] 前面加上 + 就可以得到 1。
那么 2 就简单了,让两个 1 相加就可以了:
!+[]+!+[] === 2
以此类推, 3456789 都可以这样表示。
如果是一个非常大的数呢?要一直相加代码就太复杂了,我们可以用另一种方法,先转换成字符串再转换成数字:
[+!+[]] === [1]
[+[]]] === [0]
[+!+[]] + [+[]]] === [1]+[0] === '10'
+[[+!+[]]+[+[]]] === 10
这样,任意一个大数都可以表示了 ...
字母怎么得到呢?
首先我们尝试得到一个 undefined :
[][0] === undefined //获取一个空数组的第0个元素
[][ +[] ] === undefined //用 +[] 表示0
下面我们利用一下第三条法则: +[]前面的字符会被转换成字符串
[][+[]] +[] === 'undefined'
这样我们就得到了 'undefined' 这样一个字符串,也就是可以拿到 u n d e f i 这其中任意一个字符,比如我们要拿到字符 u :
"undefined" [ 0] === "u"
[ "undefined" ][ 0][ 0] === "u"
[ undefined +[] ][+[]][+[]] === "u"
[ [][[]] +[] ][+[]][+[]] === "u"
怎么拿到字符 a 呢,同理,我们可以从 false 里面获取:
"false"[1] === 'a'
"false"[+!![]] === 'a'
(false +[]) [+!![]] === 'a'
(![] +[]) [+!![]] === 'a'
首先,我们把字符拼接起来可以得到一个方法名:
// 拿到想要的字母
"undefined"[4] // "f"
"undefined"[5] // "i"
"undefined"[6] // "n"
"undefined"[3] // "d"
// 拼接字母
"f"+"i"+"n"+"d" // "find"
然后我们通过 [] 调用方法:
[]["f"+"i"+"n"+"d"]
[]["find"]
[] .find
调用一个空数组的 find 方法有啥用呢?
没啥用 ... 我们尝试把这个方法再转换成字符串:
[]["find"] +[] === "function find() { [native code] }"
太妙了,我们又有很多新的字符( a c d e f i n o t u v )可以用了 ...
根据已有的字符,我们可以拼接成一个 constructor 字符串,也就是构造方法,当我们尝试对一些原始值读取它的 constructor 时,就可以拿到它的构造器了:
0 ["constructor"] // Number
"" ["constructor"] // String
[] ["constructor"] // Array
false ["constructor"] // Boolean
然后我们把构造器再转换成字符串:
0["constructor"]+[] // "function Number() { ... }"
我们又有了更多的新字符: m b S g B A F ...
用这样的方法,我们可以先把一些关键字或表达式转换成字符串,再去获取其中的字母,就可以表示所有的字母了...
字符串的 fontcolor() 方法可以用于按照指定的颜色来显示字符串,实际上它就是包了一个 html Font 标签:
我们通过一个空字符串去访问 fontcolor 方法,就得到了下面的字符串:
""["fontcolor"]() // "<font color="undefined"></font>"
这样,这些特殊字符 < > = " / 就可以用了 ...
通过前面的方法,我们基本可以表示任意字符串了,怎么怎么可以把任意字符串表示成任意可执行的代码呢?
答案是 Function 构造函数,我们可以通过 Function 构造函数来创建一个新的 Function 对象,也就是一个新的函数:
然后我们在后面加上 () 就可以执行这个函数:
Function("alert(1)")()
那么怎么获取到 Function 构造函数呢?
在前面的章节我们提到,通过 []["find"] 可以拿到数组的 find 方法,那么 find 方法的构造函数其实就是 Function 了,所以:
[]["find"]["constructor"] === Function
我们可以像这样执行一个字符串代码:
const str = "alert(1)";
[]["find"]["constructor"](str)()
下面我们来尝试把上面的代码全部通过 []()!+ 表示:
表示 f:
(![]+[])[+[]]
表示 find:
(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+([][[]]+[])[!+[]+!+[]]
表示 constructor:
([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]
表示 alert:
(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]
表示 []["find"]["constructor"]("alert(1)")() :
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])()
通过这个网站可以在线转换任意代码: http://www.jsfuck.com/
好了,去装逼吧 ...
来源:code秘密花园
最近在做加解密这块的开发,使用频率最高的就是 Nodejs 的 crypto 模块了,中间出现了很多种不同的编码方式。一直对这些编码方式处于熟练拼写的状态,但是到底有什么区别处于一知半解,借此机会正好整理下这之间的关系。
不管是爬虫获取的,浏览器收到的还是从本地硬盘读取的,都是二进制,选择正确的编码类型,才能把二进制或者说01序列解析为正确的字符。也就是用何种方式解析01数字
在这篇文章中,我描述了JavaScript中常见的5种不良编码习惯。重要的是,本文会给出一些可行的建议,如何的摆脱摆脱这些习惯。
之前一次使用post请求上传图片过多,post请求理论上对参数的大小没有限制,但是服务器有限制,导致上传失败,这时设置一下Tomcat的server.xml里面的maxPostSize就可以了。不过还是建议使用Form表单提交文件
Don Roberts 提出的一条重构准则:第一次做某件事时只管去做;第二次做类似的事时会产生反感,但无论如何还是可以去做;第三次再做类似的事时,你就应该重构
通过改变charset=utf-8中的utf-8就可以改变网页的编码。 一般我们在写CSS文件时候也需要在CSS文件顶部使用@charset utf-8;来定义此CSS文件编码类型。一般html源代码和css文件编码要统一,如果不统一会导致CSS hack
我们知道一个字节可表示的范围是 0 ~ 255(十六进制:0x00 ~ 0xFF), 其中 ASCII 值的范围为 0 ~ 127(十六进制:0x00 ~ 0x7F);而超过 ASCII 范围的 128~255
十几年前,国内 UTF-8 还不太流行,新手开发过程中,乱码问题是很常见的。记得我刚毕业那会,公司的系统是这样的:数据库 MySQL 使用的是 Latin-1 编码(IOS8859-1)
在我们进行前端开发时,针对项目优化,常会提到一条:针对较小图片,合理使用Base64字符串替换内嵌,可以减少页面http请求。并且还会特别强调下,必须是小图片,大小不要超过多少KB,等等。
在前端开发中,最常见的字符编码方案是 UTF-8。UTF-8是一种可变长度的 Unicode 编码方案,可以表示几乎所有的字符,并且与 ASCII 兼容。由于互联网的广泛应用和多语言的支持
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!