javascript的混淆與駭客技術

 Sun, 25 Apr 2010 16:58:16 +0800

這兩天參加OSDC.TW,聽到一些有趣的技術,例如polyglot,可以把php, perl, javascript, ruby等程式碼嵌入到gif, jpg, png等圖檔或是ELF格式的執行檔中,而且可以執行。在嵌入javascript的部份,講者有提到一些嵌入看似字串卻可執行的javascript的技巧,突然想起前一陣子在John Resig的twitter中有看過類似的東西,所以回頭翻了一下。

John Resig提到幾個網站,裡面的混淆技巧很有意思:

這些技巧主要是利用Javascript的陣列literal配合邏輯運算或加減等運算子、cast規則、reflection等,利用[]()+!等符號做出可執行的javascript程式碼。原理在上述的網站上都可以看到,但是他沒有詳細說明為何可以執行。今天一時興起手動分析http://discogscounter.getfreehosting.co.uk/js-noalnum.php產生的程式碼,最後發現他利用了幾個ECMA-262規則來讓程式執行:

([]['sort']['call']()['eval'])('alert("test")')
上面這段javascript程式
  1. [] : 產生一個Array物件
  2. ['sort'] : 取得Array物件的sort方法,他是Function物件的instance,所以可以用
  3. ['call'] ; 來改變這個函數執行的context,如果call不帶參數,預設就是global物件
  4. () : 執行sort函數,這個函數會傳回this,但是因為透過call,現在this變成global物件了
  5. ['eval'] : 接下來就可以呼叫global物件的eval方法來執行任何字串
  6. ('alert("test")') : 執行alert就可以了

除了這個方法,還有一個方法是利用Function建構子函數當作eval,同樣利用Array物件:

([]['pop']['constructor']('alert("test")'))();
("Function constructor call as a function"時,跟new Function()是一樣的)

這個例子可以不使用sort方法,對任何方法都有效,因為他們都是Function物件。

上面的sort、call、pop、constructor都可以進一步用上面網站提到的混淆技巧用幾個符號代換,避過關鍵字檢查。eval、Function中執行的字串亦同。很恐怖吧?


2010-4-25 21:22 補充

剛剛翻了一下ECMA-262 Edition5,Functiona.prototype.call的問題已經修正了,沒有參數時不會傳回Global Object。另外,"Function constructor call as a function"沒有改,所以到ECMA-262 Edition5依然會有問題。