XSS攻擊需要具備兩個條件:需要向web頁面注入惡意代碼雪侥;這些惡意代碼能夠被瀏覽器成功的執(zhí)行
XSS反射型漏洞
反射型XSS,顧名思義在于“反射”這個一來一回的過程缝左。反射型XSS的觸發(fā)有后端的參與神年,而之所以觸發(fā)XSS是因為后端解析用戶在前端輸入的帶有XSS性質(zhì)的腳本或者腳本的data URI編碼玄货,后端解析用戶輸入處理后返回給前端,由瀏覽器解析這段XSS腳本瓤帚,觸發(fā)XSS漏洞描姚。因此如果要避免反射性XSS,則必須需要后端的協(xié)調(diào)缘滥,在后端解析前端的數(shù)據(jù)時首先做相關(guān)的字串檢測和轉(zhuǎn)義處理轰胁;同時前端同樣也許針對用戶的數(shù)據(jù)做excape轉(zhuǎn)義,保證數(shù)據(jù)源的可靠性
基本原理 就是通過給別人發(fā)送帶有惡意腳本代碼參數(shù)的URL朝扼,當(dāng)URL地址被打開時赃阀,特定的代碼參數(shù)會被HTML解析,執(zhí)行擎颖,如此就可以獲取用戶的COOIKE榛斯,進(jìn)而盜號登陸。
特點是 非持久化 必須用戶點擊帶有特定參數(shù)的鏈接才能引起搂捧。
XSS反射型攻擊驮俗,惡意代碼并沒有保存在目標(biāo)網(wǎng)站,通過引誘用戶點擊一個鏈接到目標(biāo)網(wǎng)站的惡意鏈接來實施攻擊的允跑。
XSS存儲型攻擊王凑,惡意代碼被保存到目標(biāo)網(wǎng)站的服務(wù)器中搪柑,這種攻擊具有較強(qiáng)的穩(wěn)定性和持久性,比較常見場景是在博客索烹,論壇工碾、OA、CRM等社交網(wǎng)站上百姓,比如:某CRM系統(tǒng)的客戶投訴功能上存在XSS存儲型漏洞渊额,黑客提交了惡意攻擊代碼,當(dāng)系統(tǒng)管理員查看投訴信息時惡意代碼執(zhí)行垒拢,竊取了客戶的資料旬迹,然而管理員毫不知情,這就是典型的XSS存儲型攻擊
LOW
隨便輸入 admin 出現(xiàn)hello admin
輸入<script>alert('xss')</script> 試試
php 輸出已經(jīng)變成了求类,'<pre>Hello <script>alert('xss')</script></pre>' 然后輸出到頁面時奔垦,直接運行 <script>alert(1)</script> 這就是 XSS,原本這個地方應(yīng)該是輸入數(shù)據(jù)的仑嗅,但是卻變成運行代碼了
源碼
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
$html .= '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
沒有對傳入的數(shù)據(jù)進(jìn)行任何處理
medium
輸入<script>alert('xss')</script>
應(yīng)該是過濾了<script>關(guān)鍵字
輸入<scri<script>pt>alert('xss')</script>
另一種方法宴倍,大小寫混淆繞過:
輸入:<SCriPt>alert(/xss/)</ScRipt>
源碼
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
high
輸入<script>alert('xss')</script>
<script>和alert()可能都被過濾了
構(gòu)造出<scri<script>pt>alalertert('xss')</scr</script>ipt>
發(fā)現(xiàn)無法提交 猜測對提交的數(shù)據(jù)長度做了限制
看一下源碼
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
。仓技。鸵贬。。脖捻。阔逼。發(fā)現(xiàn)猜測錯誤
源碼對任何形式的script做了過濾
所以可以采用不使用 script 的方式。
比如利用 img 的 onerror 函數(shù) 地沮,意思是說嗜浮,如果圖片的地址是錯誤的,就執(zhí)行alert(1)
函數(shù)使用正則表達(dá)式的搜索和替換摩疑,這樣使得雙寫繞過和大小寫混淆不可行危融。
我們可以考慮通過img、body等標(biāo)簽的事件或者iframe等標(biāo)簽的src注入惡意的js代碼雷袋。
輸入:<img src=1 onerror=alert(/xss/)>
impossible
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
不可能級別添加了 anti-token 防御機(jī)制吉殃,和htmlseecialchars函數(shù)來防御
那么什么是HTML實體?
1楷怒、 在 HTML 中蛋勺,某些字符是預(yù)留的。
2鸠删、在 HTML 中不能使用小于號(<)和大于號(>)抱完,這是因為瀏覽器會誤認(rèn)為它們是標(biāo)簽,當(dāng)然在HTML中還有其他實體
3刃泡、如果希望正確地顯示預(yù)留字符巧娱,我們必須在HTML源代碼中使用字符實體(character entities)碉怔。
4、如需顯示小于號禁添,我們必須這樣寫:< 或 <使用實體名而不是數(shù)字的好處是眨层,名稱易于記憶。不過壞處是上荡,瀏覽器也許并不支持所有實體名稱(對實體數(shù)字的支持卻很好)。