安全圈 | 专注于最新网络信息安全讯息新闻

首页

基於phantomjs的xss動態檢測

作者 eppolito 时间 2020-02-29
all

XSS典型的瀏覽器端漏洞,由於用戶的輸入未經轉義直接輸出到頁面中,惡意程式碼在用戶的瀏覽器中被解析,從而造成危害。傳統的反射型XSS可以通過判斷頁面源碼是否含有特定字串來檢測。但由於Web 2.0的快速發展互動越來越複雜,DOM-XSS也層出不窮,導致傳統的檢測方案的漏報率很高。本文主要介紹了如何利用PhantomJS + Python完成動態檢測。

0x01 PhantomJS

既然是動態檢測,那麼就需要一個瀏覽器,但普通的瀏覽器在渲染頁面上花費了太多的資源和時間,並不適用。怎麼辦?當然開源世界早有解決方案:PhantomJS、PyQt、CEF等等。對比了一下上手難易程度、檔案豐富程度等,我選擇了PhantomJS進行開發。

PhantomJS是無介面的Webkit解析器,提供了JavaScript API。由於去除了視覺化介面,速度比一般Webkit瀏覽器要快很多。同時提供了很多監控和觸發介面,可以方便的操作頁面DOM節點,類比用戶操作等。

0x02漏洞判別標準

XSS漏洞,說到底還是用戶輸入被當成頁面程式碼解析了。解析的結果,可能是執行了JS程式碼,也可能是在頁面中創建/修改了某個DOM節點。所以我們將Payload分為兩類:

alert(1) <xsstest></xsstest>

根據這兩種Payload,自然而然的推出了漏洞判別標準:

window.alert document.getElementsByTagName('xsstest')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

page.onAlert = function(message){

if(message == xss_mark){

xss_exists = 1;

ret =“Success,xss exists”;

phantom_exit(ret);

}

console.log('Alert: ' + message);

return true;

};

function check_dom_xss_vul(){

return document.getElementsByTagName(dom_xss_mark).length;

}

為了驗證檢測程式碼,編寫一個簡單存在XSS漏洞的頁面。

1

2

3

<?php

echo $_GET['test'];

?>

經測試,訪問http://127.0.0.1:8000/xss.php?test=<img src=1 onerror=alert(1)>,我們的檢測程式碼成功檢測到了彈窗,並返回了正確的結果。但是,如果是下麵這種情況呢?

http://127.0.0.1:8000/xss.php?test=<img src=1 onerror=alert(1)>

1

2

3

4

5

<?php

$click = $_GET['test'];

echo“<div onclick=$click></div>”;

?>

0x03執行事件程式碼

很明顯,我們需要執行onclick中的程式碼,才能檢測到漏洞。首先我們想到的是觸發事件,僅僅是觸發click事件,很簡單,javascript本身就提供了click事件:document.getElementsByTagName('div')[0].click()。但是javascript也就僅僅提供了click事件的觸發函數而已。

onclick document.getElementsByTagName('div')[0].click()

但既然程式碼直接輸出在了onclick/onmouseover之類的内容裏,我們遍歷所有節點的内容,針對onxxxxx的屬性值,直接調用eval方法,執行對應的程式碼就可以了。

onclick/onmouseover

1

2

3

4

5

6

7

8

9

10

11

12

var nodes = document.all;

for(var i=0;i<nodes.length;i++){

var attrs = nodes[i].attributes;

for(var j=0;j<attrs.length;j++){

attr_name = attrs[j].nodeName;

attr_value = attrs[j].nodeValue;

if(attr_name.substr(0,2)==“on”){

console.log(attrs[j].nodeName + ':' + attr_value);

eval(attr_value);

}

}

}

訪問http://127.0.0.1:8000/xss.php?test=alert(1)成功執行程式碼,但新的問題很快出現:並不是所有的JS程式碼都是以內聯的形式寫入到HTML程式碼中的,程式猿們往往更喜歡通過document.addEventListener或者jQuery中的$('dom').click直接綁定事件。例子如下:

http://127.0.0.1:8000/xss.php?test=alert(1) document.addEventListener $('dom').click

1

2

3

4

5

6

7

<script type=“text/javascript”src=“http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js”></script>

<div class=“link-area”></div>

<?php

echo '<script>$(“#image”).click(function(){$(“.link-area”).html(“'.$_GET['test'].'”)});</script>';

?>

所以我們現在需要這樣的介面:能够觸發某個DOM節點的某個事件,包括但不僅限於click事件。PhantomJS和Javascript都可能存在這樣的介面,但是找遍了PhantomJS,甚至是CasperJS的介面,也只是發現了觸發click事件的介面。所以聚焦點重新回到Javascript上來。很快,我們發現了dispatchEvent函數。

dispatchEvent

1

2

3

4

var evt = document.createEvent('CustomEvent');

evt.initCustomEvent(click,true,true,null);

document.getElementsByTagName(“div”)[0].dispatchEvent(evt);

成功執行了click事件,但是如何能獲取到所有節點的綁定事件呢?有兩種方法:

addEventListener

方法一在遇到jQuery綁定事件的時候撲街了。方法二明顯比方法一節省資源,並且測試通過。覈心代碼如下:

1

2

3

4

5

6

_addEventListener = Element.prototype.addEventListener

Element.prototype.addEventListener = function(a,b,c){

save_event_dom(this,a);

_addEventListener.apply(this,arguments);

};

這樣,我們的JS程式碼也算告一段落,PhantomJS組件能够執行內聯程式碼及觸發所有的綁定事件。萬事具備,只欠一個調度系統了~

0x05調度系統

XSS掃描是URL細微性掃描,針對網站的每一個連結都要進行測試。XSS檢測系統的輸入值包括:

http://127.0.0.1:8000/xss.php?a=1&b=2

調度系統的功能就是處理這個URL,拼接對應的payload,並調用PhantomJS組件,檢測是否含有XSS漏洞。舉個例子,當payload為<img src=1 onerror=alert(1)>時,需要調用兩次PhantomJS組件,輸入的URL分別為:

<img src=1 onerror=alert(1)> http://127.0.0.1:8000/xss.php?a=<img src=1 onerror=alert(1)>&b=2 http://127.0.0.1:8000/xss.php?a=1&b=<img src=1 onerror=alert(1)>

當然Payload不止一個,會有很多種玩法,簡單提供幾個基礎Payload:

1

2

3

4

5

6

7

8

'“><img src=1 onerror=alert(1)>

'“><script>alert(1)</script>

';alert(1)//

“;alert(1)//

'“onmouseover=alert(1)

javascript:alert(1)

'“></script><img src=1 onerror=alert(1)>

“'></textarea><xsstest>

0x06更多思考

採用了Webkit解析器來檢測XSS漏洞,提高了檢測的覆蓋率,也大幅降低了誤報率。但有些僅在IE下有效的漏洞,就無法覆蓋到了。上述種種,已經基本將動態XSS檢測的思路分析透徹。XSS有很多種玩法,在payload中可以帶進一些有意思的攻擊程式碼,比如釣魚、打Cookie(配合XSS平臺)、甚至探測網絡狀況等等不再贅述。

最後,再次歡迎對XSS利用有各種猥瑣想法的同學來交流,微博@Fr1day