大家好,我是 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"]+[]==="functionfind(){[nativecode]}"太妙了,我們又有很多新的字符(a c d e f i n o t u v)可以用了 ...
根據已有的字符,我們可以拼接成一個 constructor 字符串,也就是構造方法,當我們嘗試對一些原始值讀取它的 constructor 時,就可以拿到它的構造器了:
0["constructor"]//Number""["constructor"]//String[]["constructor"]//Arrayfalse["constructor"]//Boolean然後我們把構造器再轉換成字符串:
0["constructor"]+[]//"functionNumber(){...}"我們又有了更多的新字符:m b S g B A F ...
用這樣的方法,我們可以先把一些關鍵字或表達式轉換成字符串,再去獲取其中的字母,就可以表示所有的字母了...
特殊字符字符串的 fontcolor() 方法可以用於按照指定的顏色來顯示字符串,實際上它就是包了一個 HTML Font 標籤:

我們通過一個空字符串去訪問 fontcolor 方法,就得到了下面的字符串:
""["fontcolor"]()//"<fontcolor="undefined"></font>"這樣,這些特殊字符 < > = " / 就可以用了 ...
怎麼執行任意代碼?通過前面的方法,我們基本可以表示任意字符串了,怎麼怎麼可以把任意字符串表示成任意可執行的代碼呢?
答案是 Function 構造函數,我們可以通過 Function 構造函數來創建一個新的 Function 對象,也就是一個新的函數:

然後我們在後面加上 () 就可以執行這個函數:
Function("alert(1)")()那麼怎麼獲取到 Function 構造函數呢?
在前面的章節我們提到,通過 []["find"] 可以拿到數組的 find 方法,那麼 find 方法的構造函數其實就是 Function 了,所以:
[]["find"]["constructor"]===Function我們可以像這樣執行一個字符串代碼:
conststr="alert(1)";[]["find"]["constructor"](str)()嘗試一下下面我們來嘗試把上面的代碼全部通過 []()!+ 表示:
表示 f:
(![]+[])[+[]]
表示 find:
(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+([][[]]+[])[!+[]+!+[]]
表示 constructor:
([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]
表示 alert:
(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]
表示 []["find"]["constructor"]("alert(1)")():
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])()
通過這個網站可以在線轉換任意代碼:http://www.jsfuck.com/
好了,去裝逼吧 ...
順手點讚在看支持一波吧👬👬