漏洞簡介
跨站腳本攻擊又名XSS,全稱為Cross Site Scripting,為了區(qū)別層疊樣式表(CSS)所以簡稱XSS阶捆。XSS漏洞是指惡意攻擊者向Web界面插入惡意的Script代碼倦卖,當(dāng)被攻擊者訪問該界面時觸發(fā)惡意的Script代碼,從而完成惡意攻擊者的攻擊蕉斜。
XSS漏洞是Web應(yīng)用系統(tǒng)中出現(xiàn)頻率最多的漏洞之一逾柿,圖1為OWASP項目提出的”十大Web應(yīng)用安全風(fēng)險”缀棍,簡稱為OWASP Top 10。OWASP Top 10對安全問題從威脅和脆弱性進(jìn)行可能性分析鹿寻,并結(jié)合技術(shù)和商業(yè)影響的分析睦柴,輸出目前一致公認(rèn)、最嚴(yán)重的十類web應(yīng)用安全風(fēng)險排名毡熏√沟校可以看到圖片中分別為2013年版以及2017年版,XSS漏洞分別出現(xiàn)在A3以及A7痢法,雖然較2013版排名有所滑落狱窘,但是仍擠在十大Web應(yīng)用安全風(fēng)險之列。
(圖 1)
漏洞風(fēng)險
XSS漏洞可導(dǎo)致用戶的認(rèn)證信息被盜财搁,被釣魚蘸炸,掛馬,還可以組合CSRF漏洞造成更嚴(yán)重的漏洞尖奔,如控制業(yè)務(wù)數(shù)據(jù)增刪改查等等搭儒,當(dāng)然也可以配合其他漏洞進(jìn)行更深層次的滲透攻擊,內(nèi)網(wǎng)滲透等等提茁。
漏洞分類
首先我們介紹下常見的XSS漏洞的分類淹禾,通常分為三大類型,反射型XSS,存儲型XSS,以及DOM型XSS怎囚。
反射型XSS:非持久化攻擊睡互,惡意攻擊者在url鏈接構(gòu)造好攻擊鏈接,但是需要引導(dǎo)被攻擊者去訪問觸發(fā)攻擊腳本,當(dāng)被觸發(fā)后不可二次觸發(fā)。
存儲型XSS:持久化攻擊,惡意攻擊者通過Web界面的可編輯存儲功能向服務(wù)器插入惡意代碼纺且。如留言板,個人信息編輯功能等等稍浆。每當(dāng)被攻擊者訪問該功能界面都會觸發(fā)惡意代碼载碌。
DOM型XSS:DOM型XSS其實是一種特殊類型的反射型XSS,它是基于DOM文檔對象模型的一種漏洞粹湃。允許程序或者腳本動態(tài)的訪問或者更新文檔內(nèi)容恐仑,經(jīng)過DOM解析觸發(fā)XSS攻擊,DOM型XSS不同與反射型XSS和存儲型XSS为鳄,DOM型XSS不需要服務(wù)端參與解析響應(yīng)裳仆,只是通過瀏覽器端的DOM進(jìn)行解析。
漏洞原理
從白盒的角度上分別解析下三類漏洞孤钦。
反射型XSS示例代碼如下(圖 2)
(圖 2)
前端提供了表單的輸入歧斟,通過GET請求提交傳入的xss參數(shù)纯丸,后端對截取的xss參數(shù)進(jìn)行輸出,由于沒有對用戶輸入的xss參數(shù)未進(jìn)行過濾静袖,可直接構(gòu)造XSS攻擊腳本觸發(fā)觉鼻。
存儲型XSS示例代碼如下:(圖?3)
(圖 3)
前端表單可傳入xss參數(shù),將傳入的xss參數(shù)保存在數(shù)據(jù)庫中队橙,在觸發(fā)端界面調(diào)用數(shù)據(jù)庫的內(nèi)容坠陈,我們看到輸入輸出端都沒有進(jìn)行有效的過濾,則構(gòu)造XSS攻擊腳本存儲在服務(wù)器捐康,在前端界面調(diào)用該內(nèi)容仇矾,造成XSS漏洞。
DOM型XSS示例代碼如下:(圖?4)
(圖 4)
后端將傳入的name值重新定義解总,在前端輸出部分重新定義一個屬性贮匕,該屬性可能是一個帶有JS代碼的事件處理程序。將獲取text的值輸出在print內(nèi)花枫,而text的值有來源于name刻盐,DOM-XSS 的數(shù)據(jù)流向是:URL-->瀏覽器,前后端均沒有對傳入的參數(shù)進(jìn)行過濾控制劳翰,則構(gòu)造XSS攻擊腳本可直接觸發(fā)XSS攻擊敦锌。
漏洞輸出形式
根據(jù)上面XSS定義的闡述,我們可以得知XSS漏洞的產(chǎn)生是由于沒有控制用戶的輸入磕道,不管是存儲型XSS還是反射型XSS供屉。反射型XSS通常參數(shù)可被用戶定義行冰,且該參數(shù)的值能夠回顯到HTML中溺蕉。通常出現(xiàn)在網(wǎng)站查詢功能等。存儲型XSS一般可提交內(nèi)容保存到服務(wù)器悼做,如個人信息修改疯特,論壇發(fā)帖,留言等等肛走。
至于XSS的輸出漓雅,主要分以下兩種情況,「結(jié)果輸出在標(biāo)簽之間」朽色,「結(jié)果輸出在標(biāo)簽之內(nèi)」邻吞,如圖5,輸出的內(nèi)容顯示在<pre>標(biāo)簽之間葫男。
(圖 5)
另外一種情況為「輸出的內(nèi)容在標(biāo)簽之內(nèi)」抱冷,如圖6,輸出的結(jié)果在<input>標(biāo)簽內(nèi)部梢褐。
(圖 6)
兩種結(jié)果輸出方式?jīng)Q定了如何去構(gòu)造XSS攻擊腳本旺遮≌匝叮「結(jié)果輸出在標(biāo)簽之間」可直接構(gòu)造攻擊腳本;「結(jié)果輸出在標(biāo)簽之內(nèi)」耿眉,如果要觸發(fā)XSS攻擊边翼,需要閉合語句再構(gòu)造語句,如圖6所示鸣剪,需要閉合語句组底,閉合方式和SQL注入較為類似。
如何讓區(qū)分「結(jié)果輸出語句在標(biāo)簽內(nèi)」和「結(jié)果輸出語句在標(biāo)簽外」筐骇,查看該瀏覽器輸出段的源代碼斤寇,以查詢功能為例,隨意輸入內(nèi)容拥褂,查看該內(nèi)容在前端源代碼的顯示位娘锁,(圖7)我們可以看到結(jié)果輸出位在標(biāo)簽之間。
(圖 7)
漏洞挖掘
判斷XSS的輸出方式饺鹃,根據(jù)輸出方式選擇XSS的構(gòu)造方法莫秆。一些網(wǎng)站在開發(fā)時會對一些傳參進(jìn)行簡單的控制,如使用黑名單的方法控制過濾用戶傳入的參數(shù)悔详。如圖8為例镊屎,對傳入的數(shù)據(jù)進(jìn)行正則匹配過濾,函數(shù)用于正則表達(dá)式的搜索和替換茄螃,這使得雙寫繞過缝驳、大小寫混淆繞過不再有效或過濾敏感的關(guān)鍵詞。
(圖 8)
(圖 9)
『黑名單』本身就是存在缺陷的归苍,從上面的代碼可以發(fā)現(xiàn)用狱,如果構(gòu)造的腳本不觸發(fā)黑名單的規(guī)則,則攻擊仍會執(zhí)行拼弃。以圖8為例夏伊,雖然對script對大小寫混寫,雙寫繞過進(jìn)行了繞過吻氧,但是并未對其他的標(biāo)簽進(jìn)行過濾溺忧,如<a><img><svg>等標(biāo)簽進(jìn)行安全防護(hù),圖9等同盯孙,雖然過濾了大部分的常見關(guān)鍵詞鲁森,但是仍然存在很多的遺漏。如觸發(fā)事件on系列就存在以下很多種的觸發(fā)方式(圖10)振惰,如遇到以上過濾歌溉,可嘗試不同的觸發(fā)事件進(jìn)行繞過。
(圖 10)
針對黑名單過濾报账,主要以嘗試為主研底,盡可能的找尋黑名單以外的標(biāo)簽或事件埠偿。除了全面的嘗試,還存在其它可繞過XSS過濾的方法榜晦。
首先說一下HTML實體編碼繞過冠蒋,在 HTML 中,某些字符是預(yù)留的乾胶。是用一個編號寫入 HTML代碼中來代替一個字符抖剿,在使用瀏覽器訪問網(wǎng)頁時會將這個編號解析還原為字符以供閱讀,如果過濾了<>,我們可以使用HTML實體編碼繞過(圖11)识窿。
(圖 11)
以十進(jìn)制斩郎,或十六進(jìn)制等進(jìn)行編碼,十六進(jìn)制需要以&#x開頭喻频。假設(shè)alert被過濾缩宜,Payload即可使用十進(jìn)制進(jìn)行編碼。
<img/src=1 onerror=alert(1)>
但是如果XSS的參數(shù)在GET請求中甥温,需要注意的是锻煌,&字符以及#字符在URL的解析中都是存在特殊含義的,所以需要對該字符進(jìn)行URL編碼姻蚓。
當(dāng)然還可以使用字符集進(jìn)行繞過宋梧,如UTF-7,US-ascll狰挡,UTF-16等瀏覽器支持的字符集進(jìn)行payload的編碼捂龄。如使用UTF-7編碼攻擊腳本。
%2BADw-script%2BAD4-alert%281%29%2BADw-/script%2BAD4-
還可以使用JS轉(zhuǎn)義加叁,假使過濾了alert這個關(guān)鍵詞倦沧。使用Unicode轉(zhuǎn)義關(guān)鍵字中的字符,如使用l的unicode編碼\u006c殉农,構(gòu)造的攻擊腳本刀脏。
<script>a\u006cert(1);</script>
另一個可以繞過的就是空字符局荚,空字符 (%00) 使得過濾器不能看到完整的 <SCRIPT> 標(biāo)簽超凳,但是只適用 IE 6.0, IE 7.0 。
<SCR%00IPT>alert("XSS")</SCRIPT>
使用evel函數(shù)來動態(tài)構(gòu)造字符串耀态。
<script>evel(‘a(chǎn)l’+’ert’(1))<script>
當(dāng)然還可以適當(dāng)?shù)氖褂每崭窕剀囈约癟AB鍵進(jìn)行插入轮傍,執(zhí)行成功主要是依托與JS的特性,JS主要以分號結(jié)尾首装,如果執(zhí)行時碰到TAB等會繼續(xù)向下執(zhí)行创夜,直至分號結(jié)尾,構(gòu)造出Payload仙逻。
<img/src=javascript:alert(1)>
大小寫混寫有的時候也許也是一線生機(jī)驰吓。
<ImG/SrC=1 OnerrOr=alErt(1)>
有時還會碰到這種情況涧尿,當(dāng)閉合語句時,輸入單引號,雙引號檬贰,但是卻回顯為\’姑廉,\”。這種情況一般都出現(xiàn)在PHP的網(wǎng)站中翁涤,主要是因為PHP中開啟了magic_quotes_gpc桥言,開啟后會把一些特殊字符進(jìn)行輪換,這個時候我們可以使用javascript中的String.fromCharCode(...)進(jìn)行繞過葵礼。假設(shè)alert被過濾号阿,可使用String.fromCharCode(...)進(jìn)行繞過,tring.fromCharCode()是javascript中的字符串方法鸳粉,用來把ASCII轉(zhuǎn)換為字符串構(gòu)造payload扔涧。
<script>String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88,83, 83, 34, 41, 59)</script>
使用base64進(jìn)行編碼,構(gòu)造出的payload如下
<META HTTP-EQUIV="refresh"?CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
在構(gòu)造一些XSS攻擊腳本時會調(diào)用空格届谈,如空格被過濾可使用/**/進(jìn)行替換
<img/src=1/**/onload=alert(1)>
測試思路
上面介紹了方法扰柠,總結(jié)一下如何去挖掘XSS。
以搜索框為例疼约,可以先嘗試輸入一些閉合字符檢測程序是否會報錯卤档,或者直接插入標(biāo)簽檢測是否響應(yīng)。閉合字符為單引號’程剥,雙引號”劝枣,尖括號<>等等,直接插入標(biāo)簽织鲸,如<br><h1>標(biāo)簽等等舔腾。閉合字符主要對應(yīng)的場景是「結(jié)果輸出在標(biāo)簽內(nèi)」,直接插入標(biāo)簽對應(yīng)的場景是「結(jié)果輸出在標(biāo)簽外」搂擦。
比較常用的一個檢測字符串'';!--"<XSS>=&{()}稳诚。可以用此字符串檢測是否閉合以及頁面是否異常瀑踢。
接下來插入帶有攻擊載荷的標(biāo)簽扳还,也可以插入<h1>標(biāo)簽進(jìn)行檢測。插入后檢測標(biāo)簽是否響應(yīng)橱夭,接下來再輸入攻擊腳本氨距,檢測標(biāo)簽是否被過濾,如若被過濾可更換各類標(biāo)簽棘劣、事件等或?qū)ayload進(jìn)行編碼混淆處理俏让。
工具介紹
進(jìn)行手動XSS的挖掘可以配合使用HackBar去進(jìn)行XSS檢測,Hackbar提供了幾種常見XSS的編碼混淆方式。圖12為Hackbar界面首昔。
(圖 12)
當(dāng)然也可以選擇更方便的自動化檢測工具寡喝,如XSStrike、XSSFork勒奇、XSSer等等拘荡,可直接進(jìn)行XSS的掃描探測。圖13為XSStrike的操作界面撬陵。
(圖 13)
XSS防御
至于XSS的防御珊皿,剛才也大概的提及到幾點,目前XSS的主要防御方法是對輸入(和URL參數(shù))進(jìn)行過濾巨税,對輸出進(jìn)行編碼蟋定。如沒有類型要求的話,盡可能的使用白名單去防御XSS草添。針對Cookie的安全防護(hù)驶兜,可以使用HttpOnly屬性去進(jìn)行安全控制。