0x00 HTTPS
在傳統流行的web服務中,由於http協議沒有對資料包進行加密,導致http協議下的網路包是明文傳輸,所以只要攻擊者攔截到http協議下的資料包,就能直接窺探這些網路包的資料。
HTTPS 協議就是來解決這個問題的,關於HTTPS協議的原理由於不是本文的主要討論內容,所以大家可以到大型網站的 HTTPS 實踐(一)—— HTTPS 協議和原理這裡檢視。
簡而言之,HTTPS協議在應用層的http協議和以及傳輸層TCP協議之間的會話層加入了 SSL/TLS協議,用作加密資料包。會話層的這個加密協議,在真正資料傳輸之前,進行握手通訊,握手的資訊交換主要包括:雙方確認加密協議的版本,確認身份(其中瀏覽器客戶端的身份有時是不需要確認的),確認傳輸真正資料的加密密碼(對稱加密)。
在用作資訊傳輸的加密密碼確認之後,接下來的通訊資料都會加密後再傳輸,從而達到防竊取的作用。
0x01 HTTPS 協議降級
那麼使用了https就能確保安全傳輸了嗎?
可以說理想上是的,現實卻不是。
原因簡單來說就是:設計和實現SSL/TLS協議出現了漏洞,導致攻擊者同樣可以攻擊一些舊版本的SSL/TLS協議。當SSL/TLS加密協議漏洞爆出來之後,最新版本的SSL/TLS協議修復了已知漏洞,但舊版本的加密協議卻變得不安全了。
那麼什麼又是“HTTPS協議降級”?
在上一小節我們提到SSL/TLS協議通過握手來確定通訊資訊,其中握手雙方要統一加密協議版本。
在握手過程中這樣確認加密協議版本:
- 由客戶端(如瀏覽器)傳送第一個資料包 ClientHello,這個資料包中儲存著客戶端支援的加密協議版本。
- 伺服器收到這個ClientHello資料包,檢視裡面客戶端支援的加密協議版本,然後匹配伺服器自己支援的加密協議版本,從而確認雙方應該用的加密協議版本。
- 伺服器傳送ServerHello資料包給客戶端,告訴客戶端要使用什麼加密協議版本。
在上述過程中,如果客戶端傳送給伺服器的ClientHello資料包中說自己僅支援某個有漏洞的舊版本加密協議(比如僅支援SSLv3.0),伺服器有兩種可能:
- 伺服器支援很多版本,其中包括有漏洞的舊版本和新版本(包括了SSLv3.0協議),那麼伺服器會認可使用有漏洞的舊版本協議,從而告訴客戶端使用有漏洞的舊版本(可以使用SSLv3.0)。
- 伺服器不支援有漏洞的舊版本,拒絕客戶端的這次請求,握手失敗。
對於攻擊者,作為中間人只能監聽到加密過的資料,如果這些資料通過沒有漏洞的加密版本加密,攻擊者並不能做什麼。
但是,如果伺服器提供有漏洞的舊版本加密協議的支援,而同時攻擊者又能作為中間人控制被攻擊者的瀏覽器發起漏洞版本的HTTPS請求,那雖然攻擊者監聽到的也是加密過的資料,但因為加密協議有漏洞,可以解密這些資料,所以資料就和明文傳輸沒有什麼差別了。
這就是HTTPS協議降級。
0x02 SSLv3.0 的AES加密原理
攻擊者通過握手將HTTPS通訊協議降低到SSLv3.0之後,將會攔截到經過SSLv3.0加密過的資料,Padding Oracle攻擊可以解密這些資料。
為什麼叫 Padding,我們從SSLv3.0的加密原理說起。
也是在第一小節,HTTPS握手過程中,通訊雙方還確認了一個“加密密碼”,這個密碼是雙方在握手過程中使用非對稱加密的方式協商出來的對稱加密密碼。攻擊者能攔截到的資料就是被這個密碼加密的。
這個對稱加密使用AES加密,AES塊密碼會把要加密的明文切分成一個個整齊的塊(如將明文以16個位元組為一塊分成很多塊),如果最後一塊不足一塊,則會填充(Padding)滿一塊,再進行加密。這個填充就是Padding Oracle攻擊的關鍵。
AES是典型的塊密碼,塊密碼的加密方式有很多種,如果你不瞭解,可以檢視塊密碼的工作模式。
SSLv3.0中使用AES-CBC模式加密,我們來看加密和解密流程:
加密過程圖示:
解密過程:
- 將密文內容分為若干個密文塊,每個密文塊和加密時的明文塊長度一樣,此時由於加密時經過了填充,密文內容肯定能整齊的分割成整數個密文塊。
- 對於第一個密文塊,使用加密key解密之後,與加密時的初始化響亮異或獲得第一個明文塊。
- 對於其他的密文塊,如第N個,使用加密key解密之後,與第N-1個密文塊異或,獲得相應的明文。
這就是SSLv3.0的加密原理過程。
0x03 CBC模式加密 的 Padding Oracle攻擊
上一節我們解釋了CBC模式加密過程,這種模式使用不當會遭到針對於Padding的攻擊。
對於SSL協議,需要加密的資料包括資訊本身和資訊的MAC摘要值,在協議設計初期,由於大家考慮不周,使用了“先做資訊摘要MAC DATA,再做加密”的方式(MAC-then-encrypt)。
MAC-then-encrypt,這種方式可能遭到Padding Oracle攻擊。SSL協議在這種方式下,資料格式如圖:
解密過程:
- 將密文內容分為若干個密文塊,每個密文塊和加密時的明文塊長度一樣,此時由於加密時經過了填充,密文內容肯定能整齊的分割成整數個密文塊。
- 對於第一個密文塊,使用加密key解密之後,與加密時的初始化響亮異或獲得第一個明文塊。
- 對於其他的密文塊,如第N個,使用加密key解密之後,與第N-1個密文塊異或,獲得相應的明文。
這就是SSLv3.0的加密原理過程。
0x03 CBC模式加密 的 Padding Oracle攻擊
上一節我們解釋了CBC模式加密過程,這種模式使用不當會遭到針對於Padding的攻擊。
對於SSL協議,需要加密的資料包括資訊本身和資訊的MAC摘要值,在協議設計初期,由於大家考慮不周,使用了“先做資訊摘要MAC DATA,再做加密”的方式(MAC-then-encrypt)。
MAC-then-encrypt,這種方式可能遭到Padding Oracle攻擊。SSL協議在這種方式下,資料格式如圖:
加密過程:
- 明文首先被分成很多明文塊,所有明文塊的位元組長度都一樣,其中最後一個明文塊經過了填充,若假設最後一個填充位元組值為L,則填充內容為值為L的位元組重複L次(不包括最後一個位元組本身) 。
- 加密從第一個明文塊開始鏈式依次進行,其中,第一個明文塊先和初始化的向量進行異或,之後使用加密key加密,生成第一個密文塊。
- 將第一個密文塊與第二個明文塊異或,然後使用加密key加密,生成第二個密文塊。
- 以此類推,第N個密文塊,由第N-1個密文塊和第N個明文塊異或,然後使用加密key加密獲得。
- 將所有獲得的密文塊依次拼接起來,就得到了最後的加密資料,這個資料是暴露在網路流量中的資料,也是攻擊者可能截獲的資料。
解密過程圖示:
解密過程:
- 將密文內容分為若干個密文塊,每個密文塊和加密時的明文塊長度一樣,此時由於加密時經過了填充,密文內容肯定能整齊的分割成整數個密文塊。
- 對於第一個密文塊,使用加密key解密之後,與加密時的初始化響亮異或獲得第一個明文塊。
- 對於其他的密文塊,如第N個,使用加密key解密之後,與第N-1個密文塊異或,獲得相應的明文。
這就是SSLv3.0的加密原理過程。
0x03 CBC模式加密 的 Padding Oracle攻擊
上一節我們解釋了CBC模式加密過程,這種模式使用不當會遭到針對於Padding的攻擊。
對於SSL協議,需要加密的資料包括資訊本身和資訊的MAC摘要值,在協議設計初期,由於大家考慮不周,使用了“先做資訊摘要MAC DATA,再做加密”的方式(MAC-then-encrypt)。
MAC-then-encrypt,這種方式可能遭到Padding Oracle攻擊。SSL協議在這種方式下,資料格式如圖:
這是一次請求要傳遞的資料結構示意,其中Data為最重要的資料,包括 cookie甚至使用者名稱密碼等資訊,HMAC 如圖示是Data以及其他一些序列資料的MAC摘要,最後是補充位元組的Padding。
在這種資料結構下,加密資料傳輸到接收者手裡,會解密然後依次驗證Padding資料和HMAC資料,來確認資料是正確的。
因此,接收者解密驗證時主要有三種可能發生的情況:
- Padding資料錯誤,拒絕,返回。
- HMAC資料錯誤,拒絕,返回。
- 正確接收。
這3種返回給予了攻擊者啟示,我們再來看解密過程:
留意最後一個密文塊,這個密文塊首先會用加密key進行解密,然後與倒數第二個密文塊進行異或。
攻擊者是能夠截獲到所有的密文內容的。
我們提到過Padding資料的規則是:若假設最後一個填充位元組值為L,則填充內容為值為L的位元組重複L次(不包括最後一個位元組本身) 。而驗證padding的過程也是按照規則來的:讀取最後一個位元組的值,並移除最後一個位元組,然後驗證剩下的padding為L個值為L的位元組。
也就是說,當最後一個位元組值為 0x00 的時候,padding驗證會直接通過。
假設:
- 倒數第二個密文塊的最後一個位元組值為 x(攻擊者可見的)。
- 最後一個密文塊,解密後最後一個位元組值為 a (攻擊者不可見)。
- 最後一個明文塊最後一個位元組為 m (攻擊者不可見)。
可知, a = x 異或 m 並且 m = x 異或 a。
然後攻擊者不斷修改x的值,傳送給接收者,那麼m的值也會不斷變化,併發生padding資料驗證失敗返回。除非 m 變成 0x00, 此時不會返回padding資料驗證失敗,而會返回HMAC資料驗證失敗。假設此時, m 的值被改為了 c,如圖。
可知, a = c 異或 0x00。
由於 a = x 異或 m 並且 m = x 異或 a。
所以 m 也就是明文, m = x 異或 c 異或 0x00。其中, x攻擊者已知, c通過不同的返回獲知。 從而破解了明文中的最後一個位元組。
有了 m 的值,也同時得到了 a 的值, 可以通過修改 x 的值控制m,比如修改 x 的值使
m = 0x01 = x 異或 a。
將 m 設定成 0x01 的時候,遍歷倒數第二個密文塊的倒數第二個位元組(最多256次),通過判斷是否通過padding驗證,就能同理求出另外一個位元組了。
以此類推可以解密整個資料包。
0x04 Padding Oracle攻擊的防範
通過上一節可以看到攻擊者是通過padding驗證返回 和 mac驗證返回結果不同來獲得資訊的,實際上,即使padding驗證失敗和mac驗證失敗都返回同樣結果,攻擊者也可以通過響應時間的不同通過 timing的方式獲得資訊。
所以在協議中將驗證失敗的響應時間和響應結果統一,使攻擊者不能區分能防範這種攻擊。
而對於SSL/TLS協議的使用者,我們可以響應號召在自己伺服器的加密協議支援列表上去掉SSLv3.0 。
0x05 參考資料
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式