鍍金池/ 教程/ HTML/ 淺談 javascript 函數(shù)劫持
淺談 JavaScript 之事件綁定
淺談 javascript 中字符串 String 與數(shù)組 Array
淺談 javascript 中基本包裝類型
淺談 JavaScript Math 和 Number 對象
淺談 Javascript 的靜態(tài)屬性和原型屬性
淺談 JavaScript 中定義變量時有無 var 聲明的區(qū)別
淺談 JavaScript Array 對象
淺談 JavaScript 函數(shù)參數(shù)的可修改性問題
淺談 javascript 中的 instanceof 和 typeof
淺談 JavaScript 中 Date (日期對象),Math 對象
淺談 Javascript 執(zhí)行順序
淺談 javascript 函數(shù)屬性和方法
淺談 JavaScript 中面向對象技術的模擬
淺談 javascript 的原型繼承
淺談 javascript 事件取消和阻止冒泡
根據(jù)一段代碼淺談 Javascript 閉包
淺談 Javascript 面向對象編程
淺談 javascript 六種數(shù)據(jù)類型以及特殊注意點
淺談 Javascript 變量作用域問題
淺談 javascript 函數(shù)內部屬性
淺談 javascript 中自定義模版
淺談 JavaScript 字符集
淺談 javascript 面向對象編程
淺談 JavaScript 框架分類
淺談 JavaScript 中的 Math.atan() 方法的使用
淺談 Javascript 數(shù)組與字典
淺談 JavaScript 數(shù)據(jù)類型及轉換
淺談 javascript 的調試
淺談 Javascript 嵌套函數(shù)及閉包
淺談 javascript 回調函數(shù)
淺談 JavaScript Date 日期和時間對象
淺談 Javascript 中的 Function 與 Object
淺談 JavaScript 數(shù)據(jù)類型
淺談 javascript 中 this 在事件中的應用
淺談 javascript 中的閉包
淺談 javascript 函數(shù)劫持
淺談 Javascript 中深復制
淺談 JavaScript 函數(shù)節(jié)流
淺談 JavaScript 中的 String 對象常用方法
淺談 JavaScript 事件的屬性列表
淺談 JavaScript 函數(shù)與棧
淺談 JavaScript 的事件
淺談 javascript 中的作用域
淺談 JavaScript 的執(zhí)行效率
淺談 Javascript 事件模擬
淺談 JavaScript function 函數(shù)種類
淺談 javascript 歸并方法
淺談 javascript 迭代方法
淺談 JavaScript 編程語言的編碼規(guī)范
淺談 JavaScript 實現(xiàn)面向對象中的類
淺談 Javascript 鼠標和滾輪事件
淺談 Javascript Base64 加密解密
淺談 Javascript 中勻速運動的停止條件
淺談 javascript 實現(xiàn)八大排序
淺談 javascript 的分號的使用
淺談 javascript 中 createElement 事件
淺談 javascript 的數(shù)據(jù)類型檢測
淺談 javascript 對象模型和 function 對象
淺談 Javascript 如何實現(xiàn)勻速運動
淺談 JavaScript 字符串與數(shù)組
淺談 javascript 面向對象程序設計
淺談 Javascript 事件處理程序的幾種方式

淺談 javascript 函數(shù)劫持

概述

JavaScript 函數(shù)劫持,也就是老外提到的 javascript hijacking 技術。最早還是和劍心同學討論問題時偶然看到的一段代碼,大概這樣寫的:

window.alert = function(s) {}; 

覺得這種用法很巧妙新穎,和 API Hook 異曲同工,索性稱之為 javascript function hook,也就是函數(shù)劫持。通過替換 js 函數(shù)的實現(xiàn)來達到劫持這個函數(shù)調用的目的,一個完整的 hook alert 函數(shù)例子如下:

<!--1.htm--> 
[js] view plaincopy
<script type="text/javascript">   
<!--   
var _alert = alert;   
window.alert = function(s) {   
if (confirm("是否要彈框框,內容是 \"" + s + "\"?")) {   
_alert(s);   
}   
}   
//-->   
</script>   
<html>   
<body>   
<input type="button" onclick="javascript: alert('Hello World!')" value="test" />   
</body>   
</html>  

搞過 API Hook 的同學們看到這個代碼一定會心的一笑,先保存原函數(shù)實現(xiàn),然后替換為我們自己的函數(shù)實現(xiàn),添加我們自己的處理邏輯后最終再調用原來的函數(shù)實現(xiàn),這樣這個 alert 函數(shù)就被我們劫持了。原理非常簡單,下面舉些典型的應用來看看我們能利用它來做些什么。

應用舉例

1.實現(xiàn)一個簡易的 javascript debugger,這里說是 debugger 比較標題黨,其實只是有點類似于 debugger 的功能,主要利用 js 函數(shù)劫持來實現(xiàn)函數(shù)的 break point,來看看個簡單的例子:

<script type="text/javascript">   
<!--   
var _eval = eval;   
eval = function(s) {   
if (confirm("eval 被調用 \ n\n 調用函數(shù) \ n" + eval.caller + "\n\n 調用參數(shù) \ n" + s)) {   
_eval(s);   
}   
}   
//-->   
</script>   
<html>   
<head>   
</head>   
<body>   
<script type="text/javascript">   
<!--   
function test() {   
var a = "alert(1)";   
eval(a);   
}   
function t() {   
test();   
}   
t();   
//-->   
</script>   
</body>   
</html>  

通過 js 函數(shù)劫持中斷函數(shù)執(zhí)行,并顯示參數(shù)和函數(shù)調用者代碼,來看一個完整例子的效果:

>help 
debug commands: 
bp <function name> - set a breakpoint on a function, e.g. "bp window.alert". 
bl - list all breakpoints. 
bc <breakpoint number> - remove a breakpoint by specified number, e.g. "bc 0". 
help - help information. 
>bp window.alert 
* breakpoint on function "window.alert" added successfully. 
>bl 
* 1 breakpoints: 
0 - window.alert 
>bc 0 
* breakpoint on function "window.alert" deleted successfully. 

這里演示設置斷點,察看斷點和刪除斷點,完整代碼在本文附錄[1]給出。

2.設置陷阱實時捕捉跨站測試者,搞跨站的人總習慣用 alert 來確認是否存在跨站,如果你要監(jiān)控是否有人在測試你的網(wǎng)站 xss 的話,可以在你要監(jiān)控的頁面里 hook alert 函數(shù),記錄 alert 調用情況:

<script type="text/javascript">   
<!--   
function log(s) {   
var img = new Image();   
img.style.width = img.style.height = 0;   
img.src = "http://yousite.com/log.php?caller=" + encodeURIComponent(s);   
}   
var _alert = alert;   
window.alert = function(s) {   
log(alert.caller);   
_alert(s);   
}   
//-->   
</script>  

當然,你這個函數(shù)要加到頁面的最開始,而且還要比較隱蔽一些,赫赫,你甚至可以使 alert 不彈框或者彈個警告框,讓測試者抓狂一把。

3.實現(xiàn) DOM XSS 自動化掃描,目前一般的 XSS 自動化掃描的方法是從 http 返回結果中搜索特征來確定是否存在漏洞,但是這種方法不適用于掃描 DOM XSS,因為 DOM XSS 是由客戶端腳本造成的,比如前段時間劍心發(fā)現(xiàn)的 google 的跨站 (見附錄 [2]) 原理如下:

document.write(document.location.hash); 

這樣的跨站無法反映在 http response 里,所以傳統(tǒng)掃描方法沒法掃描出來。但是如果你從上個例子里受到啟發(fā)的話,一定會想到設置陷阱的辦法,DOM XSS 最終導致 alert 被執(zhí)行,所以我們 hook alert 函數(shù)設置陷阱,如果 XSS 成功則會去調用 alert 函數(shù),觸發(fā)我們的陷阱記錄結果,這樣就可以實現(xiàn) DOM XSS 的自動化掃描,陷阱代碼類似于上面。

4.靈活的使用 js 劫持輔助你的頁面代碼分析工作,比如分析網(wǎng)頁木馬時,經(jīng)常會有通過 eval 或者 document.write 來進行加密的情況,于是我們編寫段 hook eval 和 document.write 的小工具,輔助解密:

<script type="text/javascript">   
<!--   
var _eval = eval;   
eval = window.execScript = window.document.write = window.document.writeln = function(s) {   
document.getElementById("output").value = s;   
}   
//-->   
</script>   
<html>   
<body>   
input:   
<textarea id="input" cols="80" rows="10"></textarea>   
<input type="button" onclick="javascript: _eval(document.getElementById('input').value);" value="decode" />   
<br />   
output:   
<textarea id="output" cols="80" rows="10"></textarea>   
</body>   
</html>  

在 input 框里輸入加密的代碼:

eval(unescape("%61%6C%65%72%74%28%31%29%3B")); 

在 output 框里輸出解碼后的代碼:

alert(1); 

當然你還能想到更多的靈活應用。