XSS (Cross-Site Scripting) 跨站腳本攻擊,目前在網路上仍非常常見。
何謂XSS? 所謂XSS泛指惡意攻擊者在Web網頁上插入惡意html代碼,以達到特殊目的(控制網站元素、取走cookies)。

很多人會說XSS就是能在Web上跳出警告視窗並修改其內容,其實是不完全正確的。
正確來說,XSS是利用惡意程式碼,常見是Javascript,將惡意code輸入到網頁,再誘使user連線到已被攻擊的網頁,並不只是show message視窗。

你發現了嗎? XSS只是修改網頁資料傳給其他使用者,並不會回傳到Server,所以其實不難察覺有異常。

XSS介紹:
XSS漏洞一般來說最常見的是網站可以被插入惡意字元,像是< > / " ' ; ....等等。

現今網站都會防禦使用者動作,像是禁止你回傳惡意字元到server或是直接將其去除,這是所謂server端的防禦,通常會藉由code或Firewall等設備去防禦,通常是有效的。

有些網站在server端並沒有做任何防禦,認為只要在使用者端(Client)做防禦即可,像是使用語法檢查輸入格式、跳出警告視窗...等等,其實這都是無效的。只能防君子,難防小人。

上完Allen Own大神的課之後我學得最透徹的大概就是他的口頭禪:

任何在Client端的防禦都是無效的。

XSS攻擊非常氾濫,但是屬於被動式的攻擊手法。

XSS的攻擊流程最普遍來說是惡意人士會在第三方網站,如pchome、google進行XSS攻擊,再利用社交工程誘使受害者點擊URL連線到已受到XSS攻擊的網頁,惡意人士便可以利用此漏洞show出cookies以偽造使用者的身份,最終目的就是將使用者資料傳回惡意人士電腦。

這麼說可能不是很清楚XSS到底在做什麼事,簡單來說就是駭客修改網頁內容,讓user去點擊並回傳資料。

日本有一個網站可以提供XSS練習,共有30個stage可以打,每個層級的防禦手段都不一樣,我們來實作到stage8。

http://xss-quiz.int21h.jp/

上面寫說只要能讓網頁彈出警告視窗並寫document.domain即算成功。

Stage1.

做XSS攻擊,首先要知道目標網頁有哪些防禦,我們可以插入特殊字元進行測試
例如: aaa<bbb>ccc/ddd'eee"fff;ggg:hhh
然後查看原始碼,看哪些字元被屏蔽,哪些字元可以被利用。


我們可以發現,stage1並沒有對任何字元進行屏蔽,所以我們只要簡單的javascript即可成功。

<script> alert(document.domain) </script>

插入以上惡意javascript即可發現成功進到第二關。


Stage2.

我們故技重施,使用aaa<bbb>ccc/ddd'eee"fff;ggg:hhh來檢查網站的防禦。



可以發現老招無效,但是原始碼也告訴你,這段語法出錯了,難道是結束字元出錯?
讓我們再試試aaa">,嘗試以">來結束value並利用其中空隙插入語法。

看起來好像可行,那我們試著插入javascript,並在前面加上">試試。

"><script> alert(document.domain) </script>

順利過關,可以發現跟stage1差別只是需要將上一段語法先結束掉,再利用空間插入語法而已。

Stage3.



試試老方法,可以發現我們的aaa<bbb>ccc/ddd'eee"fff;ggg:hhh被變成
"aaa&lt;bbb&gt;ccc/ddd&#039;eee&quot;fff;ggg:hhh"
惡意字元會變自動轉換成其他字元組合。

但旁邊還有個dropdownlist,似乎是個可以運用的弱點?

想要修改DropDownList的回傳值我們需要利用Brup-Suite來修改。
將proxy設為Brup-Suite來攔截封包並修改。



會發現網頁一直送不出去直到你在Brup-Suite按下Forward,因為你的封包正被攔截。
我們來試著插入 <script> alert(document.domain) </script> 在japan那個欄位試試。



按下Forward,成功過關!可以發現stage3只防禦了一個欄位,在下拉式選單沒有做防禦,是個只能防新手的防禦方式。

Stage4.

這一關和stage3看似一模一樣,但我們一樣使用Brup-Suite攔截封包查看,會看到一個奇怪的欄位。

有一個在網頁上並未顯示的欄位,內容寫著hack me。
好吧都被宣戰了當然要試試看。
一樣在那個欄位插入<script> alert(document.domain) </script>試試。



居然失敗,查看原始碼可以發現一樣是未結束語句導致Javascript無法生效。
試試 "><script> alert(document.domain) </script>

果然成功通過!!
stage4跟3都一樣主要測試攔截封包並修改的能力,stage4還混合stage2的應用。

stage5.

老招aaa<bbb>ccc/ddd'eee"fff;ggg:hhh一樣試一次,可以發現有做字數限制的防禦。
但前面提到重要觀念
任何在Client端的防禦都是無效的。
所以我們利用FireFox插件Web Developer來關掉這個限制就成功破解了。

可見Client防禦真的只能防君子,不能防小人。
那我們一樣試試aaa<bbb>ccc/ddd'eee"fff;ggg:hhh。

查看原始碼可以發現一樣是語法錯誤,我們修正一下。
"><script> alert(document.domain) </script>
跟stage4使用同樣語句,成功過關。
可見stage5只是要告訴我們,Client端的防禦是無效的。

stage6.



使用老招aaa<bbb>ccc/ddd'eee"fff;ggg:hhh可以發現惡意字元會被置換。
輸入< > / 就會被換成其他字元組合,旁邊也沒有其他欄位可以利用。
那前面提到,XSS攻擊不是只能插入JavaScript,我們使用html語法包裝一下,讓惡意語句裡的< > / 都換成別的。

" onclick=alert(document.domain); "

這樣的寫法,一樣可以show出視窗,且語法裡沒有< > /,成功過關。


所以stage6主要考驗駭客是不是只會寫<script>...</script>的javascript語句而已。
這非常實用,因為多數網站仍是使用這種方式防禦,過濾字元。
殊不知換個寫法一樣可以成功攻擊。


stage7.

我們故技重施aaa<bbb>ccc/ddd'eee"fff;ggg:hhh
會發現連 " 都會置換了


我們看到原始碼,輸入"即可結束上一段語句。
所以跟stage6一樣," onclick=alert(document.domain); ",一樣可以成功過關。

stage8.


可以發現這關會將input變成超連結。
那我們是不是把<script> alert(document.domain) </script> 貼進去就好了?
失敗!因為點擊<script> alert(document.domain) </script> 會變成404 Not Found
那我們換個寫法,使用javascript點擊觸發執行

javascript alert(document.doamin);



再去點擊javascript alert(document.domain);這個URL,即可成功執行。


後面幾關都在考驗XSS的改寫能力,可見XSS寫法非常廣泛。



總結:

stage1-8為基礎XSS攻擊實作,再往後面就比較深奧了。
我們可以發現XSS寫法非常多元,漏掉任何一點都可能成為漏洞。

目前防禦就是改寫程式碼這麼簡單,卻也不容易的一件事。
別想在Client端做任何防禦抵擋XSS,因為駭客在Client做的事情你是不會知道的。
所以重申重點

任何在Client的防禦都是無效的。

如果要測試自己網站是否能有效抵擋XSS,不妨試試以上8種攻擊手法,如果都能成功防禦,那代表程式碼在撰寫上已經ok了,可以擋掉大部分的攻擊。

目前XSS還是很熱門的攻擊手段,僅次於SQL Injection,但卻容易被忽略,因為她並沒修改server端任何資料,所以OWASP也將XSS列為高度風險漏洞,在設計網站務必注意防護XSS的部分。

如果有任何意見或認為我解釋錯誤歡迎留言或來信,謝謝指教。



           2016-10-02 03:41 , David in Taipei