在Black Hat 2016大會上,兩名比利時的安全研究人員展示了他們今年的研究成果。他們發現了一個WEB攻擊方式可以繞過HTTPS加密得到明文信息。他們把這種攻擊方式叫做HEIST攻擊。HEIST的全稱是Encrypted Information can be Stolen through TCP-Windows。
HEIST攻擊的利用條件十分簡單,只需要幾行簡單的javascript代碼即可,并且無需借助中間人攻擊。
原始的論文內容
接下來我會詳細介紹論文中的內容
理論基礎
Fetch API
關于Fetch API有兩個比較重要的點:
1.Fetch API作為Cache,Service Workers等API的基礎,可以獲取任何資源,包括需要認證的跨域資源。
2.fetch()返回的是一個Promise對象,一旦Response對象接收到了第一個字節的數據,Promise對象就開始resolve,并且已經可以訪問Response對象,這時候Response對象仍然會有數據流入。
Performance API
瀏覽器獲取網頁時,會對網頁中每一個對象(腳本文件、樣式表、圖片文件等等)發出一個HTTP請求。performance.getEntries方法以數組形式,返回這些請求的時間統計信息。
攻擊過程
首先從TCP層看一下一個典型的HTTP請求,在三次握手之后,客戶端發出一個包含請求的TCP包,通常只有幾百字節,到達服務器之后,服務器生成一個response并發回給客戶端。如果response的尺寸大于MSS(最大傳輸單元除去TCP+IP頭,對于以太網來說是1460字節),服務器會將response拆成多個分組,這些分組會根據TCP慢啟動算法來發送。
慢啟動的算法如下(cwnd全稱Congestion Window,擁塞窗口):
連接建好的開始先初始化cwnd = initcwnd,表明可以傳initcwnd個MSS大小的數據。
每當收到一個ACK,cwnd++; 呈線性上升
每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升
還有一個ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免算法”(這里不涉及這個算法)
Linux 3.0之后把cwnd初始化成了10個MSS。
通過fetch(),我們可以知道第一次TCP數據返回的時間,如果我們再知道數據完全返回的時間,我們就能知道數據是一次TCP返回的,還是多次返回的。
這時候就要另一個Performance API來配合,通過資源的responseEnd來得到資源完全下載需要的時間。
我們把發起請求的時間記為T0,第一次TCP返回時間記為T1,完全接收時間記為T2。如果是一次返回的,那么T2-T1將是一個很小的值,通常在1ms內。如果是兩次及以上的,時間會明顯增加很多。
這時候看起來還是沒什么卵用。然而,下一步就是利用這一點得到response的確切大小(這個大小是經過gzip,以及加密過的)。
首先來看看一次返回的情況,很多時候一個請求參數在請求的結果里會有返回,然后就可以利用這一點。我們把response分為兩部分,一部分是我們想得到的實際大小,一部分是攻擊者控制的請求參數,暫且稱之為反射參數吧。通過重復調整反射參數,我們可以得到第一次TCP返回的最大可能尺寸(對每個服務器來說一般是個固定值)。之后,只要減去HTTP和SSL/TLS的header的尺寸就可以了,而這兩個都是可以預計的。
舉例來說,當把反射參數調到708字節長時,正好可以一次TCP請求返回,而709就需要兩次了,拿10*MSS(14600字節)- 528字節的http頭 –26字節的SSL/TLS頭 –708,得到response的實際大小為13337字節。論文里介紹了兩種對該算法的優化方法,這里暫時跳過。
除了反射參數這種情況,還可以對目標網站發布大量不同尺寸的內容,通過調整正常的query參數來查看返回內容的大小達到同樣的目的。
對于多次TCP返回的情況,會受到慢啟動算法的影響,攻擊者會向一個已知尺寸的資源發起一個請求,然后再向目標資源發起請求,服務器會將擁塞窗口提高。通過調整第一個請求資源的尺寸多次分析也可以得到結果。
接下來,只要配合BREACH/CRIME等攻擊,就可以輕松獲取E-mail地址,社保號等信息了,而不像BREACH攻擊一樣還要借助中間人攻擊去得到資源的大小。
另外,在HTTP2下,利用一些新特性,這種攻擊的情況還會更加糟糕。
CRIME/BREACH攻擊
針對于HTTPS的攻擊,多存在于中間人攻擊的環境,攻擊者要先能監聽用戶和網站之間的流量。
HTTP/TLS一般都啟用了壓縮算法,通過改變請求正文,對比被壓縮后的密文長度,可以破解出某些信息。
HTTP壓縮采用了Deflate算法。該算法可以將重復出現的字符串以一個實例的形式存儲在HTML文件之中,并以此來縮小數據流所占的空間。當代碼需要使用這一字符串時,系統會自動用一個指針來進行索引,這樣就可以最大程度地節省空間了。一般而言,如果一個數據流中存在大量的重復字符串,那么這也就意味著在經過了壓縮處理之后,可以顯著地減少數據所占的空間。值得注意的是,Deflate算法是同時使用了LZ77算法與哈夫曼編碼(Huffman Coding)的一個無損數據壓縮算法。
CRIME攻擊
CRIME通過在受害者的瀏覽器中運行JavaScript代碼并同時監聽HTTPS傳輸數據,能夠解密會話Cookie,主要針對TLS壓縮。
Javascript代碼嘗試一位一位的暴力破解Cookie的值。中間人組件能夠觀察到每次破解請求和響應的密文,尋找不同,一旦發現了一個,他會和執行破解的Javascript通信并繼續破解下一位。
比如,攻擊者可以構造出這樣的請求
在secret=后面加上各種字符進行推測,當匹配到X的時候,密文因為被壓縮會變的更短,就得到了第一位的X。依次往下推,就可以得到完整的cookie。
BREACH攻擊
BREACH攻擊是CRIME攻擊的升級版,攻擊方法和CRIME相同,不同的是BREACH利用的不是SSL/TLS壓縮,而是HTTP壓縮。所以要抵御BREACH攻擊必須禁用HTTP壓縮。
攻擊防范
從上面可以看出,CRIME/BREACH攻擊的條件都相對苛刻,而HEIST攻擊則大大降低了其門檻,很容易被惡意廣告利用。
HEIST攻擊目前涉及到了瀏覽器, HTTP, SSL/TLS,TCP等多個層。
在瀏覽器層,目前修改Fetch API似乎是不太可能的,大概能做的只有禁用第三方cookie了,這樣沒辦法攻擊到一些需要登錄或授權才能訪問的資源。但對于依賴廣告收入的谷歌來說,也不太會去觸碰廣告商的命根。
在HTTP層,瀏覽器可以禁止非法的請求(分析Origin或者referer,但可以繞過),server端可以通過關閉SSL/TLS壓縮和HTTP壓縮來避免CRIME/BREACH攻擊,但是就無法享受到壓縮帶來的好處了。
在網絡層,一種做法是將TCP擁塞窗口隨機化,另一種做法也是類似,就是對返回的數據進行隨機padding,但是也都是不太可能做的。
目前針對HEIST攻擊暫時沒有特別好的方法來防范,所以這類攻擊方式在最近這幾年或許會變得頻繁起來。所以這兩名研究人員也希望通過Black Hat大會一同尋找和制定一個合理有效的解決方案。
*本文原創作者:Sunnieli,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載