XSS漏洞
一、文章簡介
XSS漏洞是Web應(yīng)用程序中最常見的漏洞之一享怀。如果您的站點沒有預(yù)防XSS漏洞的固定方法逾苫,那么很可能就存在XSS漏洞。
這篇文章將帶你通過代碼層面去理解三個問題:
什么是XSS漏洞部服?
XSS漏洞有哪些分類?
如何防范XSS漏洞拗慨?
二饲宿、XSS 漏洞簡介
跨站腳本攻擊是指惡意攻擊者往Web頁面里插入惡意Script代碼厦酬,當(dāng)用戶瀏覽該頁之時胆描,嵌入其中Web里面的Script代碼會被執(zhí)行瘫想,從而達到惡意攻擊用戶的目的。
xss漏洞通常是通過php的輸出函數(shù)將javascript代碼輸出到html頁面中昌讲,通過用戶本地瀏覽器執(zhí)行的国夜,所以xss漏洞關(guān)鍵就是尋找參數(shù)未過濾的輸出函數(shù)。
常見的輸出函數(shù)有: echo printf print print_r sprintf die var-dump var_export
.
xss 分類:(三類)
反射型XSS:<非持久化> 攻擊者事先制作好攻擊鏈接, 需要欺騙用戶自己去點擊鏈接才能觸發(fā)XSS代碼(服務(wù)器中沒有這樣的頁面和內(nèi)容)短绸,一般容易出現(xiàn)在搜索頁面车吹。
存儲型XSS:<持久化> 代碼是存儲在服務(wù)器中的,如在個人信息或發(fā)表文章等地方醋闭,加入代碼窄驹,如果沒有過濾或過濾不嚴(yán),那么這些代碼將儲存到服務(wù)器中证逻,每當(dāng)有用戶訪問該頁面的時候都會觸發(fā)代碼執(zhí)行乐埠,這種XSS非常危險,容易造成蠕蟲囚企,大量盜竊cookie(雖然還有種DOM型XSS丈咐,但是也還是包括在存儲型XSS內(nèi))。
DOM型XSS:基于文檔對象模型Document Objeet Model龙宏,DOM)的一種漏洞棵逊。DOM是一個與平臺、編程語言無關(guān)的接口银酗,它允許程序或腳本動態(tài)地訪問和更新文檔內(nèi)容辆影、結(jié)構(gòu)和樣式,處理后的結(jié)果能夠成為顯示頁面的一部分黍特。DOM中有很多對象蛙讥,其中一些是用戶可以操縱的,如uRI 衅澈,location键菱,refelTer等〗癫迹客戶端的腳本程序可以通過DOM動態(tài)地檢查和修改頁面內(nèi)容经备,它不依賴于提交數(shù)據(jù)到服務(wù)器端,而從客戶端獲得DOM中的數(shù)據(jù)在本地執(zhí)行部默,如果DOM中的數(shù)據(jù)沒有經(jīng)過嚴(yán)格確認侵蒙,就會產(chǎn)生DOM XSS漏洞。
三傅蹂、XSS 漏洞原理
3.1 反射型XSS
在黑盒測試中纷闺,這種類型比較容易通過漏洞掃描器直接發(fā)現(xiàn)算凿,我們只需要按照掃描結(jié)果進行相應(yīng)的驗證就可以了。
相對的在白盒審計中犁功, 我們首先要尋找?guī)?shù)的輸出函數(shù)氓轰,接下來通過輸出內(nèi)容回溯到輸入?yún)?shù),觀察是否過濾即可浸卦。
無案例不足以求真署鸡,這里我們選用echo()函數(shù)
作為實例來分析:
新建 XssReflex.php,代碼如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="input">
<input type="submit">
</form>
<br>
<?php
$XssReflex = $_GET['input'];
echo 'output:<br>'.$XssReflex;
?>
</body>
</html>
這是一個很簡單限嫌、也很常見的頁面:
變量 $XssReflex 獲取 get 方式傳遞的變量名為 input 的變量值(值為一個字符串)靴庆,然后直接通過echo()函數(shù)輸出,注意這中間并未對用戶輸入進行任何過濾怒医。
打開Firefox輸入url:localhost/codeaudit/xss/XssReflex.php
:
當(dāng)我們輸入 1
炉抒,頁面返回 1 :
當(dāng)我們輸入hello
時,頁面返回 hello :
以上都為正常的輸出稚叹,但如果我們輸出一些javascript
代碼呢焰薄?
比如我們輸入<script>alert('xss')</script>
:
可以看到瀏覽器成功彈窗,說明我們輸出的JavaScript代碼成功被執(zhí)行了入录。
我們查看網(wǎng)頁html代碼:
第12行增加了:
<script>alert('xss')</script>
這個彈窗并沒有什么實際的意義蛤奥,但通過它我們知道輸入javascript代碼是可以被執(zhí)行的,當(dāng)我們輸入一些其他函數(shù)僚稿,比如document.cookie
就可以成功盜取用戶的cookie信息凡桥,或者讀取用戶瀏覽器信息等,為我們進一步深入攻擊做鋪墊蚀同。
3.2 存儲型XSS
和反射性XSS的即時響應(yīng)相比缅刽,存儲型XSS則需要先把利用代碼保存在比如數(shù)據(jù)庫或文件中,當(dāng)web程序讀取利用代碼時再輸出在頁面上執(zhí)行利用代碼蠢络。但存儲型XSS不用考慮繞過瀏覽器的過濾問題衰猛,屏蔽性也要好很多。
存儲型XSS攻擊流程:
存儲型XSS的白盒審計同樣要尋找未過濾的輸入點和未過濾的輸出函數(shù)刹孔。
使用cat命令查看 XssStorage.php 代碼
shiyanlou:~/ $ cat XssStorage.php
代碼如下:<參考自JackholeLiu的博客
>
<span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<html>
<head>
<title>XssStorage</title>
</head>
<body>
<h2>Message Board<h2>
<br>
<form action="XssStorage.php" method="post">
Message:<textarea id='Mid' name="desc"></textarea>
<br>
<br>
Subuser:<input type="text" name="user"/><br>
<br>
<input type="submit" value="submit" onclick='loction="XssStorage.php"'/>
</form>
<?php
if(isset($_POST['user'])&&isset($_POST['desc'])){
$log=fopen("sql.txt","a");
fwrite($log,$_POST['user']."\r\n");
fwrite($log,$_POST['desc']."\r\n");
fclose($log);
}
if(file_exists("sql.txt"))
{
$read= fopen("sql.txt",'r');
while(!feof($read))
{
echo fgets($read)."</br>";
}
fclose($read);
}
?>
</body>
</html></span>
頁面功能簡述:
這個頁面采用POST提交數(shù)據(jù)啡省,生成、讀取文本模擬數(shù)據(jù)庫髓霞,提交數(shù)據(jù)之后頁面會將數(shù)據(jù)寫入sql.txt卦睹,再打開頁面時會讀取sql.txt中內(nèi)容并顯示在網(wǎng)頁上,實現(xiàn)了存儲型xss攻擊模擬方库。
打開Firefox輸入url:localhost/codeaudit/xss/XssStorage.php
:
我們隨意輸出一些內(nèi)容:
可以看到頁面正常顯示頁面留言信息结序。
當(dāng)我們在Message中輸入<script>alert('xss')</script>
時,頁面成功彈窗 :
并且我們重啟瀏覽器之后再加載該頁面纵潦,頁面依然會彈窗,這是因為惡意代碼已經(jīng)寫入數(shù)據(jù)庫中徐鹤,每當(dāng)有人訪問該頁面時垃环,惡意代碼就會被加載執(zhí)行!
我們查看網(wǎng)頁html代碼:
這就是所謂的存儲型XSS漏洞返敬,一次提交之后遂庄,每當(dāng)有用戶訪問這個頁面都會受到XSS攻擊,危害巨大救赐。
3.3 DOM XSS
這種XSS用的相對較少涧团,并且由于其特殊性,常見的漏掃工具都無法檢測出來经磅,這里先不做講解。
記個待辦钮追,以后來補预厌!
四、XSS漏洞防范
4.1 反射型xss漏洞防范
php中xss的漏洞防范方法總結(jié):<參考自Segmentfault>
A.PHP直接輸出html的元媚,可以采用以下的方法進行過濾:
1.htmlspecialchars函數(shù)
2.htmlentities函數(shù)
3.HTMLPurifier.auto.php插件
4.RemoveXss函數(shù)
B.PHP輸出到JS代碼中轧叽,或者開發(fā)Json API的,則需要前端在JS中進行過濾:
1.盡量使用innerText(IE)和textContent(Firefox),也就是jQuery的text()來輸出文本內(nèi)容
2.必須要用innerHTML等等函數(shù)刊棕,則需要做類似php的htmlspecialchars的過濾
C.其它的通用的補充性防御手段
1.在輸出html時炭晒,加上Content Security Policy的Http Header
(作用:可以防止頁面被XSS攻擊時,嵌入第三方的腳本文件等)
(缺陷:IE或低版本的瀏覽器可能不支持)
2.在設(shè)置Cookie時甥角,加上HttpOnly參數(shù)
(作用:可以防止頁面被XSS攻擊時网严,Cookie信息被盜取,可兼容至IE6)
(缺陷:網(wǎng)站本身的JS代碼也無法操作Cookie嗤无,而且作用有限震束,只能保證Cookie的安全)
3.在開發(fā)API時,檢驗請求的Referer參數(shù)
(作用:可以在一定程度上防止CSRF攻擊)
(缺陷:IE或低版本的瀏覽器中当犯,Referer參數(shù)可以被偽造)
這里我們選用htmlentities()函數(shù)進行測試:
htmlentities() 函數(shù)把字符轉(zhuǎn)換為 HTML 實體垢村。
新建Xss_htmlentities.php, 代碼如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="input">
<input type="submit">
</form>
<br>
<?php
$XssReflex = $_GET['input'];
echo 'output:<br>'.htmlentities($XssReflex);#僅在這里對變量 $XssReflex 做了處理.
?>
</body>
</html>
在Firefox輸入url:localhost/codoaudit/xss/Xsshtmlentities.php
:
當(dāng)我們輸入<script>alert('xss')</script>
:
可以看到頁面并沒有彈窗嚎卫。
我們再查看網(wǎng)頁html代碼:
可以看到htmlentities()函數(shù)對用戶輸入的<>
做了轉(zhuǎn)義處理,惡意代碼當(dāng)然也就沒法執(zhí)行了嘉栓。
還有其他過濾函數(shù),紙上學(xué)來終覺淺拓诸,有興趣的同學(xué)可以自己去嘗試一番
4.2 存儲型xss漏洞防范
存儲型XSS對用戶的輸入進行過濾的方式和反射型XSS相同侵佃,這里我們使用htmlspecialchars()
函數(shù)進行演示:
htmlentities() :把預(yù)定義的字符 "<" (小于)和 ">" (大于)轉(zhuǎn)換為 HTML 實體
htmlspecialchars和htmlentities的區(qū)別:
htmlspecialchars 只轉(zhuǎn)義 & 、" 恰响、' 趣钱、< 、>
這幾個html代碼胚宦,而 htmlentities 卻會轉(zhuǎn)化所有的html代碼首有,連同里面的它無法識別的中文字符也會轉(zhuǎn)化燕垃。
新建Xss_htmlspecialchars_Storage.php ,代碼如下:
<span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<html>
<head>
<title>XssStorage</title>
</head>
<body>
<h2>Message Board<h2>
<br>
<form action="Xss_htmlspecialchars_Storage.php" method="post">
Message:<textarea id='Mid' name="desc"></textarea>
<br>
<br>
Subuser:<input type="text" name="user"/><br>
<br>
<input type="submit" value="submit" onclick='loction="XssStorage.php"'/>
</form>
<?php
if(isset($_POST['user'])&&isset($_POST['desc'])){
$log=fopen("sqlStorage.txt","a");
fwrite($log,htmlspecialchars($_POST['user'])."\r\n"); # 在此對用戶輸入數(shù)據(jù)$_POST['user']進行過濾
fwrite($log,htmlspecialchars($_POST['desc'])."\r\n"); # 在此對用戶輸入數(shù)據(jù)$_POST['desc']進行過濾
fclose($log);
}
if(file_exists("sqlStorage.txt"))
{
$read= fopen("sqlStorage.txt",'r');
while(!feof($read))
{
echo fgets($read)."</br>";
}
fclose($read);
}
?>
</body>
</html></span>
在Firefox輸入url:localhost/codoaudit/xss/Xss_htmlspecialchars_Storage.php
:
當(dāng)我們在Message中輸入<script>alert('xss')</script>
:
可以看到頁面并沒有彈窗井联。
我們再查看網(wǎng)頁html代碼:
可以看到htmlspecialchars()函數(shù)對用戶輸入的<>
做了轉(zhuǎn)義處理卜壕。
五、總結(jié)及回顧
- XSS漏洞原理和相關(guān)函數(shù):
eval() assert() preg_replace() 回調(diào)函數(shù) 動態(tài)執(zhí)行函數(shù)
- XSS漏洞的防范
如果你覺得這篇文章講的不錯的話烙常,可以關(guān)注我的其他文章和課程:
- 【課程】SQL 注入基礎(chǔ)原理介紹
-
【課程】滲透測試方法論之 Linux 提權(quán)實戰(zhàn) (專屬優(yōu)惠碼
7MaDpzNc
轴捎,可以享受折上折哦!) - 【GitHub】滲透測試方法論/OSCP備考資源
- 【文章】滲透測試方法論之靶機系列
- 【文章】跨站腳本漏洞(XSS)基礎(chǔ)講解