一、XSS概述
XSS全稱Cross Site Script,跨站腳本攻擊。
通常指攻擊者通過“HTML注入”篡改網頁,插入惡意腳本,進而在使用者浏覽網頁時,控制使用者浏覽器的一種攻擊手段 。
到底什麼是XSS呢?我們直接來看一個例子。
我們先寫一個前端頁面,要求使用者輸入使用者名,并傳給後端處理:
後端處理頁面,網頁将接收到的使用者名直接輸出到頁面上:
通路前端頁面,輸入使用者名Monster:
點選送出,頁面傳回後端處理結果:
如果我們送出一段HTML惡意代碼,就會發現代碼在目前頁面執行了。
例如送出
<script>alert('hacker')</script>
,頁面出現彈窗:
檢視網頁源代碼,會發現惡意代碼被插入到目前頁面中了:
這就是一個簡單的反射型XSS,雖然這裡看上去沒有什麼大的危害,但其實XSS攻擊可以做到更多事,例如盜取使用者cookie,修改網頁内容,惡意挂載木馬等等。
二、XSS分類
XSS一共有三種類型,分别是反射型XSS、存儲型XSS以及DOM型XSS。
(1)反射型XSS:
反射型XSS也稱為非持久性XSS,正如上面的例子,這種攻擊方式隻是簡單的把使用者輸入的資料“反射”給浏覽器,隻對目前URL連結生效。因而攻擊者需要引誘使用者點選惡意連結才行。
(2)存儲型XSS
存儲型XSS又稱為持久性XSS,會把惡意代碼存儲在伺服器端,危害性極強。例如攻擊者發表了一篇帶有惡意js代碼的文章,那麼所有通路該文章的使用者都會中招。
(3)DOM型XSS
DOM型XSS也是一種反射型XSS,需要向伺服器輸入資料,與正常的反射型XSS不同,DOM型XSS需要通過修改頁面的DOM節點來形成XSS。
接下來我們先通過DVWA平台low等級看看這三種XSS的成因。
反射型XSS
本頁面要求我們輸入使用者名:
前端代碼,通過GET方法将name參數傳遞給後端:
後端代碼,接收$_GET傳遞的參數後,不做任何過濾,直接輸出到頁面:
輸入
<script>alert('hacker')</script>
js代碼執行,頁面出現彈窗:
和前面舉的例子一樣,可以看出XSS産生的原因有兩點:
- 使用者能夠控制顯示點
- 對輸入輸出内容過濾不嚴
存儲型XSS
該頁面是一個留言闆
輸入姓名和資訊即可留言,例如輸入Name為Monster,Message為Hello,world!
每次通路該頁面,都會加載留言資訊,如下:
如果在此處插入一個js惡意腳本,每次有人通路該頁面,都會加載這個惡意腳本,這就是存儲型XSS。
檢視後端源代碼:
我們來對其中一些函數進行解釋:
-
函數移除字元串兩側的空白字元或其他預定義字元。trim():
-
删除反斜杠stripslashes():
-
函數會對字元串中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)進行轉義,用于防SQL注入。mysqlrealescape_string(string,connection):
由代碼可知,并未對輸入做過多限制,name和message欄都存在XSS注入漏洞。
直接在message欄輸入
<script>alert('hacker')</script>
,之後每次通路該頁面都會彈窗:
DOM型XSS
注入頁面如下,需要我們選擇語言:
後端源代碼如下:
我們選擇French,會發現URL變成了:
http://192.168.211.151/vulnerabilities/xss_d/?default=French
修改url中default=88888888,目前頁面随之修改:
直接檢視網頁源代碼,會發現有一段js代碼:
修改了頁面的DOM節點,将我們輸入的内容直接插入到了HTML頁面中:
修改url中
default=<script>alert(1)</script>
,出現彈窗:
檢視網頁源代碼,惡意代碼被插入網頁中:
這就是一個簡單的DOM型XSS的成因,效果和反射型XSS相似。
DVWA平台XSS通關
DVWA平台XSS頁面分為4種安全等級,從low等級到impossible等級。
low安全等級主要是展示漏洞成因,安全等級往上遞增,會增加不同的防禦手段,impossible等級不存在漏洞。
通關指南,直接搬運如下:
【XSS漏洞】一步步教你通關DVWA
三、XSS的利用
1、利用XSS盜取使用者cookie
【XSS漏洞】利用XSS竊取使用者Cookie
2、利用XSS進行網頁挂馬
【XSS漏洞】通過XSS實作網頁挂馬
3、配合 CSRF 攻擊完成惡意請求
【CSRF漏洞】通過實驗教你學會CSRF攻擊 Part3
4、利用XSS進行網頁釣魚
【XSS漏洞】利用XSS進行網頁釣魚
四、XSS挖掘技巧
1、利用字元編碼
一些網站會對我們輸入的特殊字元加
“\”
進行轉義,例如php在
magicquotesgpc = On
的情況下,如果輸入的資料有
單引号
(’)
、雙引号
(”)
、反斜線
(\)
與
NULL
(NULL 字元)等字元都會被加上反斜線。
我們來看一個例子:
在
magic_quotes_gpc =Off
時,輸入
?x=1";alert(1)//
即可彈窗:
現在我們開啟
magic_quotes_gpc=On,
輸入
?x=1";alert(1)//
:
會發現雙引号被轉義,無法彈窗。
但是,如果傳回頁面像本網頁一樣是
GBK/GB2312
編碼的話,我們也可以使用寬位元組進行逃逸。
當網頁使用了GBK編碼時,會認為兩個字元為一個漢字,例如
%df%5c
就是一個漢字(前一個ascii碼大于128才能到漢字的範圍),是以經過轉義後,
%df%5c(%5c為 \)
就會變成一個漢字,把轉義符吃掉。
輸入
?x=1%df";alert(1)//
,成功彈窗:
2、不完整的黑名單
有些網站會使用黑名單的方式,過濾掉一些敏感js标簽,例如:
過濾掉了大多數js标簽,輸入alert(1)試試:
但這裡的黑名單漏掉了eval()函數,這就是黑名單不如白名單安全的原因,黑名單會出現遺漏的情況。
為了避免被過濾,将alert(1)轉換為ASCII碼形式:
五、XSS的防護
1、開啟HttpOnly
JS 原生的 API提供了擷取cookie的方法:
document.cookie
,在XSS攻擊中,常常被用于盜取使用者的cookie。
如果能夠盜取網站管理者的cookie,那麼就可以用管理者的身份直接登入網站背景,而不必非要去獲得管理者賬号和密碼。
在正常網頁通過
document.cookie
可以擷取目前頁面cookie,例如在以下頁面插入js代碼:
通路該頁面,彈窗使用者cookie值:
通過以下惡意腳本,可以将使用者cookie發送至遠端伺服器,完成竊取。
但是一旦我們給該頁面cookie添加上HttpOnly屬性,就可以防止這種惡意行為,修改代碼如下:
HttpOnly屬性用來設定cookie是否能通過 js去通路,預設情況下該選項為空,用戶端可以通過js代碼去通路(包括讀取、修改、删除等)cookie。
當cookie帶httpOnly選項時,用戶端則無法通過js代碼去通路了,是防禦XSS攻擊的常用手段之一。
再次通路該頁面,無法擷取到該頁面的cookie:
2、輸入輸出檢查
防護XSS首先可以從輸入入手,因為我們預設所有使用者的輸入都是不可信的,是以需要過濾掉輸入中的敏感字元,有時候也需要檢查輸入内容格式是否合規。
當我們需要将内容輸出到網頁時,為了確定即使包含XSS特殊字元,也不會被執行,我們可以對輸出内容編碼後再進行輸出。
可以從以下幾個角度來考慮:
(1)黑名單、白名單
通過黑名單比對XSS特征,例如、javascript等敏感字元,但是可能出現遺漏而被繞過的情況。相較而言白名單則更加安全,比對成功則放行。
(2)電話、郵件、日期等格式要求
比如電話号碼使用is_numeric()函數進行檢查,必須是純數字才行。郵件、日期也都有其相應的格式,輸入的字元串是否超過最大長度等,這種方法類似白名單。
(3)利用編碼函數
對
\、'、"
等特殊字元,進行過濾或者編碼。
使用編碼函數可以有效防止XSS攻擊,以php為例。
addslashes():
strip_tags():
htmlentities():
htmlspecialchars():