[Pikachu 靶場] 2-跨站指令碼
0x00 XSS(Cross-Site Scripting,跨站指令碼)
本名 CSS,但是為了區別於層疊樣式表(Cascading Style Sheets)而改姓 X 了。XSS 屬於常青的漏洞型別,只要涉及 HTML 和使用者內容釋出、檢視,就得考慮 XSS。插句題外話,人們日常離不開的企鵝軟體在暑假裡也發現了 XSS,具(抽)體(象)流程為:收藏→編輯→返回→觸發 XSS。
%3Cscript%3Ealert%281%29;%3C/script%3E&r=software
XSS 的核心原理是 HTML 標籤的錯誤閉合(與瀏覽器解析特性緊密相關),所以重點不是跨站,而是指令碼。當程式未對輸入和輸出做正確的處理時,“精心構造”的字元在前端可能被瀏覽器當成有效程式碼並解析執行,從而產生不良後果。
XSS 一般分為:
- 反射型;
- 儲存型;
- (DOM 型)。
本節分題較多。
0x01 反射型 XSS(GET)
1. 測試
輸入'
、"
、<>
特殊符號都會直接顯示在頁面上,沒有什麼過濾。
2. 長度限制
寫alert('1')
時卻發現長度被限制為 20,確實不太夠。需要審查元素手動修改屬性:
不過本題的本意應該是將 Payload 寫在 URL 中。
3. 觸發
另外檢視服務端原始碼即可知,這一部分未對輸入做任何處理,僅僅直接輸出到前端。
0x02 反射型 XSS(POST)
1. 登入
首先登入,使用者名稱為 admin,密碼為 123456。
2. 觸發
與 GET 型不同,POST 型提交的內容不會顯示在 URL 中,因此無法通過測試找到承載 Payload 的引數。不過審查元素找到測試時輸入的字串也不是什麼難事。這裡直接輸入就能觸發。
0x03 儲存型 XSS
1. 測試
輸入特殊字元發現沒有過濾。
2. 觸發
審查元素髮現仍舊是將輸入直接插入到前端頁面中了,因此直接輸入即可觸發 XSS。
每次點選這一頁都會重新觸發一次 XSS,說明是永續性的 XSS。
3. 原始碼
檢視 xss_stored.php 的原始碼可知,這一部分會先判斷message
是否存在且是否為空,再進行轉義,防止 SQL 注入。
將所有留言渲染到前端的方式也是簡單粗暴——全部獲取。
題外話:看原始碼的時候不小心瞄到了一眼彩蛋。
0x04 DOM 型 XSS
1. 什麼是 DOM
DOM 指 Document Object Model,文件物件模型,是 HTML 和 XML 的程式設計介面。
HTML DOM 定義了訪問和操作 HTML 文件的標準方法。
DOM 以樹結構表達 HTML 文件。
所謂的 DOM 型操作當前 HTML 的標籤結構(比如提前閉合),有點 SQL 注入的意味。
2. 測試
測試輸入,發現輸出與輸入不同:
3. 原始碼
函式getElementById
獲取標籤id
的值,傳遞到str
,str
通過字串拼接進入a
標籤中。這裡就需要閉合掉前面的a
標籤。
4. 兩種方案
輸入 Payload:'><img src="#" onmouseover="alert('xss')">'
,在滑鼠移動到圖片位置時觸發彈窗:
輸入 Payload:' onclick="alert('xss')">
,點選 what do you see,觸發彈窗:
0x05 DOM 型 XSS-X
1. 原始碼
檢視網頁原始碼:
從text
框取值,插入到a
標籤中。比如輸入為 test,之後點選連結就會跳轉到 http://略略略略/xss/test 中。
2. 兩種方案
閉合a
標籤,然後用新的標籤裝載惡意部分。
輸入 Payload:'><img src="#" onmouseover="alert('xss-x')">
,點選“請說出你的傷心往事”,再點選“有些費盡心機想要忘記的事情,後來真的就忘掉了”,將滑鼠移至圖片位置即可觸發 XSS。
輸入 Payload:' onclick="alert('xss-x')">
,點選“有些費盡心機想要忘記的事情,後來真的就忘掉了”,再點選“就讓往事都隨風,都隨風吧”,即可觸發。
0x06 XSS 盲打
盲打是一種攻擊場景。攻擊者投放的 Payload 不會在前端觸發,而是在後臺管理員檢視時觸發。
1. 輸入
這裡只需要輸入最為常規的形式即可:<script>alert('xss')</script>
,提交後會響應一段文字,應當是提交到後臺了。
謝謝參與:
2. 後臺
訪問後臺(不是管理工具處的後臺):/vul/xss/xssblind/admin_login.php,用 admin 和 123456 登入即可。
0x07 XSS 之過濾
1. 測試
對 Payload 文字進行過濾,比如此處輸入<script>
就被過濾了:
2. 原始碼
檢視頁面原始碼,是對<script
進行過濾,替換為空格,但是隻針對了小寫字元。大寫繞過即可。
3. 觸發
輸入:<SCRIPT>alert('xss-filtered')</SCRIPT>
,即可觸發。
4. 補充
現實中沒有先看原始碼再打的好事,繞過過濾的姿勢需要在奇怪的道路上越走越遠。當發現 script 這個詞被過濾時,也可以考慮用其它標籤替代。比如:<img src=x onmouseover="alert('xss')">
或者<img src=x onerror="alert('ssx')">
。
0x08 XSS 之 htmlspecialchars
1. 定義
在 PHP 中,函式htmlspecialchars()
被用於將一些預定義的字元轉換為 HTML 實體,返回轉換後的新字串,原字串不變。如果字串包含無效內容,則返回空字串(除非設定了ENT_IGNORE
或者ENT_SUBSTITUTE
)。
預定義的字元有:
&
→&
"
→"
'
→'
<
→<
>
→>
輸入上述的特殊字元,檢視前端原始碼,發現已經轉義過了。
但是'
不會被轉義。使用這個單引號構造 Payload:\#' onclick='alert(/xss/)
,第一個單引號閉合href
屬性的雙引號,第二個單引號閉合href
屬性的閉合雙引號。
2. 觸發
點選即可觸發。
0x09 XSS 之 href 輸出
1. 測試
沿用上一題的 Payload,但發現單引號失效了。
所以乾脆捨棄單引號。
2. 偽協議
href
屬性可以使用 JavaScript 協議,所以嘗試偽協議繞過。
Payload:javascript:alert(/xss/)
。點選“閣下自己輸入的url還請自己點一下吧”即可觸發。
0x0A XSS 之 js 輸出
1. 測試
輸入測試<script>alert(/xss/)</script>
,並檢視頁面原始碼:
輸入內容被賦給 js 中的$ms
,可以構造閉合。
2. 觸發
輸入</script><script>alert(/xss/)</script>
或';alert(1);//
即可。