首頁  >  文章  >  web前端  >  探秘JavaScript中的六個字符

探秘JavaScript中的六個字符

高洛峰
高洛峰原創
2016-10-14 09:27:591068瀏覽

JavaScript 是一個奇怪而有趣的語言,我們可以寫一些瘋狂但仍然有效的程式碼。它試圖幫助我們把事情轉換到基於我們如何對待他們的特定類型。

如果我們加入一個字串,JavaScript會假定我們希望為文字形式表示,所以將它轉換為一個字串。如果我們加上一個正負前綴符號,JavaScript會假定我們希望為數值形式表示,如果可能的話,對我們來說並將字串轉換為一個數字。如果我們加入一個否定符號,JavaScript會將字串轉換為一個布林值。

我們可以用Javascript[,],(,),! and +這六個符號寫一些神奇的程式碼。如果你現在不是在手機,你可以打開瀏覽器的控制台,你可以將任何程式碼範例貼到控制台,並且程式碼值為true。

讓我們從最基本的開始,要記住一些黃金規則:

!後面跟的字符會被轉換成布爾值

+後面跟的字符會被轉換成數值

[]後面跟的字符會被轉換成字串

來看下面的例子:

![] === false
+[] === 0
[]+[] === ""

另一件事你應該知道的是,它可以從字串使用方括號檢索特定的字母,像這樣:

"hello"[0] === "h"

還記得可以使多個數字號碼透過添加字串表示在一起,然後把整個表達式轉換成一個數字:

+("1" + "1") === 11

我們們繼續把一些東西結合在一起得到字母a

![] === false
![]+[] === "false"
+!![] === 1
------------------------
(![]+[])[+!![]] === "a"  // same as "false"[1]

舉一反三!

我們可以透過true 和 false得到相似的字母a,e,f,l,r,s,t,u,那麼我們可以從其他地方得到的字母嗎?

我們可以透過一些特別的式子如[][[]]得到undefined,利用我們上面講到的黃金法則得到另外的字母d,i 和 n。

`[][[]] + [] === "undefined"`

到目前為止,利用我們已經獲得的所有字母,我們可以拼fill, filter 和 find。當然也有一些其他的單詞,我們也可以拼寫,但這些單詞最重要的是,他們都是數組的方法。這意味著他們是數組物件的一部分,可以直接呼叫數組實例,如:[2,1].sort()。

現在,了解JavaScript的另一個重要的特性是一個物件的屬性可以透過點符號.或方括號[]來存取。上述數組方法是數組物件本身的屬性,我們可以使用方括號代替點符號來呼叫這些方法。

所以[2,1]["sort"]() 等效於 [2,1].sort().

我們繼續看看,當我們試圖使用一個數組的方法會發生什麼,我們可以使用到目前為止我們拼寫的但沒有調用的字母。

[]["fill"]

這會得到function fill() { [native code] },我們可以把這個方法頭作為一個字符串再次使用我們的黃金法則:

[]["fill"]+[] === "function fill() { [native code] }"

所以現在我們又得到其他的字符:c,o, v,(,),{,[,],}。

隨著我們新得到的c和o,我們現在可以形成constructor這個單字。建構函數是一個方法,所有JS物件僅傳回自己的建構子。

到目前為止我們已經處理的對象,我們可以得到它用字串表示的建構子函數:

true["constructor"] + [] === "function Boolean() { [native code] }"  
0["constructor"] + []    === "function Number() { [native code] }"  
""["constructor"] + []   === "function String() { [native code] }"
[]["constructor"] + []   === "function Array() { [native code] }"
({})["constructor"] + [] === "function Object() { [native code] }"

透過這些式子,我們可以將下面的字元加入我們的庫中:

探秘JavaScript中的六個字符

現在我們可以建構一個我們可以使用方括號的函數"toString"`,我們可以這樣呼叫:

(10)["toString"]() === "10"

使用我們的黃金法則,我們已經可以將任何我們想要轉換成一個字串,但是上面這個式子怎麼用呢?

好吧,我告訴你,Number類型的toString方法有一個稱為radix(“基數”)的秘密的論點。它可以將數值在轉換為字串之前先經過基數換算,像這樣:

(12)["toString"](10) === "12"  // 十进制
(12)["toString"](2) === "1100" // 二进制
(12)["toString"](8) === "14"   // 八进制
(12)["toString"](16) === "c"   // 十六进制

但是為什麼基數只寫到16?最大值是36,包括所有的字元0-9 和 a-z,所以現在我們可以得到任何我們想要的字母數字:

(10)["toString"](36) === "a"
(35)["toString"](36) === "z"

太棒了!但是其它符號如標點符號和大寫字母呢?我們接著深入探索。

這取決於你的JS執行時,它可能會或可能不會存取特定的預先定義的物件或資料。如果你在瀏覽器中運行它,那麼你可以訪問一些存在的HTML包裝器方法。

例如,bold是一個包裝在標籤中的字串方法。

"test"["bold"]() === "<b>test</b>"

透過這個我們得到和/兩個字元。

你可能聽過escape方法,它主要將字串轉換為一個URI友善的格式,可以讓簡單的瀏覽器解釋。如果我們傳遞一個空格字符,我們得到的"%20"。

這裡有一個工具可以自動將每個字元自動轉換。 工具位址:http://www.jsfuck.com/ 原始碼位址:https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js

為什麼這幾個字符有用?

它不是易趣網做的一些不好的事情,不久前允許賣家將執行JS在頁面中使用只能使用這些字符,但它是一個相當罕見的攻擊向量。有些人說混淆,但事實上,有更好的方法混淆。

最後,希望你會喜歡這次探秘之旅。

資源:

https://en.wikipedia.org/wiki/JSFuck

https://esolangs.org/wiki/JSFuck

http://patriciopalladino.com/blog/2012/08/09/ non-alphanumeric-javascript.html

https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn