簡(jiǎn)介
什么是XSS
XSS 漏洞胃碾,通常指的是網(wǎng)站對(duì)用戶輸入數(shù)據(jù)未做有效過(guò)濾陆爽,攻擊者可以將惡意腳本注入網(wǎng)站頁(yè)面中胶逢,達(dá)到執(zhí)行惡意代碼的目的曹体。攻擊者只需要誘使受害者打開特定的網(wǎng)址俗扇,就可以在受害者的瀏覽器中執(zhí)行被注入的惡意代碼,從而竊取用戶身份箕别,執(zhí)行一些敏感操作铜幽,或是進(jìn)行其他的危害行為。在常見的Web 漏洞中串稀,XSS(Cross-site Script除抛,跨站腳本)漏洞是最多見的,跨站腳本(Cross-site Script),按理應(yīng)該簡(jiǎn)稱為 CSS母截,但為了與層疊樣式表(CSS)區(qū)分開到忽,特意改為 XSS。
XSS的起源
最早的XSS 漏洞可追溯到 1999 年末清寇,微軟安全工程師發(fā)現(xiàn)一些網(wǎng)站遭到攻擊喘漏,網(wǎng)站被插入了一些惡意腳本和圖像標(biāo)簽。隨后华烟,微軟對(duì)此類漏洞進(jìn)行研究分析翩迈,并在 2000 年 1 月,正式使用“cross-site scripting”這個(gè)名稱盔夜,然后逐漸被業(yè)界采用负饲,留傳至今。
XSS漏洞的分類
反射型 XSS
反射型 XSS 又被稱為非持久型跨站腳本喂链,它是將攻擊代碼放在 URL 參數(shù)中绽族,而不是存儲(chǔ)到服務(wù)器,因此需要誘使用戶點(diǎn)擊才能觸發(fā)攻擊衩藤。
如:通過(guò)向 name 參數(shù)輸入以下代碼即可觸發(fā)漏洞
<script>alert(1)</script>
在 Chrome 瀏覽器中,用“檢查”功能看下網(wǎng)頁(yè)源碼涛漂,可以發(fā)現(xiàn)我們輸入的代碼被解析并執(zhí)行了:
漏洞代碼也非常簡(jiǎn)單赏表。從 GET 參數(shù) name 獲取用戶輸入后,未經(jīng)過(guò)濾就直接調(diào)用 echo 函數(shù)輸出到頁(yè)面匈仗,最終導(dǎo)致 XSS的產(chǎn)生瓢剿。漏洞代碼如下:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
存儲(chǔ)型XSS
存儲(chǔ)型被稱為持久型跨站腳本。攻擊者將惡意代碼存儲(chǔ)到服務(wù)器上悠轩,只要誘使受害者訪問被插入惡意代碼的頁(yè)面即可觸發(fā)间狂。存儲(chǔ)型 XSS 經(jīng)常出現(xiàn)在一些可以發(fā)表評(píng)論的地方,如帖子火架、博客鉴象。
如:一個(gè)留言本的功能忙菠,支持用戶發(fā)表評(píng)論,然后將用戶輸入的數(shù)據(jù)直接存儲(chǔ)到數(shù)據(jù)庫(kù)纺弊,并輸出到頁(yè)面上牛欢。這個(gè)過(guò)程中因?yàn)槲醋鋈魏蔚倪^(guò)濾,導(dǎo)致了 XSS 漏洞的產(chǎn)生淆游。存儲(chǔ)型 XSS 的特點(diǎn)就是不需要在誘使用戶訪問的URL中包含攻擊代碼傍睹,因?yàn)樗呀?jīng)存儲(chǔ)到了服務(wù)器中,只需要讓用戶訪問包含輸出攻擊代碼的頁(yè)面即可
漏洞代碼
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = mysql_real_escape_string( $message );
// Sanitize name input
$name = mysql_real_escape_string( $name );
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
//mysql_close();
}
?>
從 POST 參數(shù)中獲取 mtxMessage 和 txtName 參數(shù)后犹菱,雖然經(jīng)過(guò)一定過(guò)濾才插入到數(shù)據(jù)庫(kù)中拾稳,但是中括號(hào)不會(huì)被過(guò)濾
在 Message 中輸入“<script>alert(1)</script>”,點(diǎn)擊“Sign Guestbook”提交腊脱,即可觸發(fā)漏洞访得。
查看頁(yè)面源碼
DOM 型 XSS
DOM 型 XSS是基于文檔對(duì)象模型(Document Objeet Model,DOM虑椎,用于將 Web 頁(yè)面與腳本語(yǔ)言連接起來(lái)的標(biāo)準(zhǔn)編程接口)的一種漏洞震鹉,它不經(jīng)過(guò)服務(wù)端,而是通過(guò) URL 傳入?yún)?shù)去觸發(fā)捆姜,因此也屬于反射型 XSS传趾。
由于客戶端的JavaScript可以訪問瀏覽器頁(yè)面中的 DOM 對(duì)象,因此它能夠決定如何處理當(dāng)前頁(yè)面的 URL泥技,比如獲取 URL 中的相關(guān)數(shù)據(jù)進(jìn)行處理浆兰,然后動(dòng)態(tài)更新到頁(yè)面上。這導(dǎo)致 DOM 型 XSS 的漏洞代碼常位于網(wǎng)頁(yè)的 JavaScript 代碼中珊豹。
看例子:
點(diǎn)擊事件函數(shù)
用戶輸入內(nèi)容后點(diǎn)擊"click me"回調(diào)函數(shù)執(zhí)行:
第一行代碼先通過(guò)
document.getElementById("text").value
獲取 ID 為“text”的元素內(nèi)容簸呈。其實(shí)這就是輸入框的內(nèi)容,輸入框的 ID就叫“text”店茶。第二行代碼是將獲取的輸入框內(nèi)容傳遞給 ID 為“dom”的元素蜕便,并將其寫入
innerHTML
,也就是輸出到 HTML 頁(yè)面中贩幻,整個(gè)過(guò)程對(duì)用戶輸入數(shù)據(jù)都未做任何過(guò)濾轿腺。直接輸入 test 看下:
如此,我們直接利用 JavaScript 偽協(xié)議來(lái)構(gòu)造鏈接觸發(fā) JS 代碼的執(zhí)行丛楚,輸入代碼javascript:alert(1)
族壳,然后點(diǎn)擊"clickme",等回調(diào)函數(shù)執(zhí)行完,點(diǎn)擊“whatdo you see?”鏈接后即可觸發(fā)
DOM 型 XSS 的相關(guān) DOM 操作函數(shù)有很多,如 eval趣些、document.write 等可觸發(fā)漏洞的數(shù)據(jù)輸出位置仿荆。
這是一份關(guān)于 DOM XSS 的數(shù)據(jù)污染源(Source,即用戶輸入數(shù)據(jù))和漏洞觸發(fā)點(diǎn)(Sink)的列表(雖然不夠全面,但可以作為參考)
若數(shù)據(jù)從 Source 傳到 Sink 過(guò)程中拢操,未做任何過(guò)濾锦亦,就有可能存在 DOM XSS。這個(gè)思路也常作為動(dòng)靜態(tài)檢測(cè) DOM XSS 的重要思路庐冯。