SSL/TLS協議安全系列:SSL的Padding Oracle攻擊
0x00 前言
在上一講中,我們已經介紹了Padding Oracle攻擊的背景知識和基本原理。簡單來說,攻擊就是利用密文解密後填充是否正確這一資訊,以此得到明文的部分資訊甚至恢復出全部明文。在這一講裡,我們會按照時間序梳理一遍與此攻擊相關並影響SSL協議安全性的重要學術文章,簡單介紹文章的貢獻,給出其影響及對現實應用的指導意義。
0x01 Padding Oracle的學術線
1998年,貝爾實驗室研究員瑞士密碼學家Daniel Bleichenbacher在頂級密碼學會議CRYPTO上發表了一篇名Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS#1的文章,這算是Padding Oracle攻擊的開山之作。文章給出了可用於實際攻擊那些使用了PKCS#1v1.5填充規範的RSA的協議的一種有效方法,這些協議中就包含了當時已被廣泛使用的SSL協議。此外,這篇文章的學術意義還在於,它也第一次表明了考慮加密方案的適應性選擇密文攻擊安全性是有實際意義的,實際中可以發起選擇密文攻擊(對於使用1024bit金鑰加密的密文,恢復出對應明文需要大約一百萬次Oracle查詢,作者對此的描述為though not entirely as efficient)。文中給出的解決方案是,不要使用PKCS#1 1.5版本中的填充方案,而是轉而使用OAEP。
然而在2001年,James Manger在CRYPTO上發表了文章A Chosen Ciphertext Attack on RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in PKCS#1 v2.0,結果就是OAEP這種填充機制也是可以進行Padding Oracle攻擊的,並且解密一條1024bit加密的密文,只需要大約1000次Oracle查詢。這裡需要額外提一句的是,SSL協議並不支援OAEP填充,所以目前TLS1.2中,使用的填充仍舊是v1.5中的方案。
以上都針對RSA的攻擊,對應在SSL協議中,握手過程交換預主金鑰的訊息是攻擊的點。而對於對稱加密方案,首先提出Padding Oracle攻擊的是Serge Vaudenay。在2002年EUROCRYPT上,在瑞士聯邦理工大學(Swiss Federal Institute of Technologies,EPFL)領導安全及密碼實驗室(Security and Cryptography Laboratory,LASEC)的Serge Vaudenay教授在發表了名為Security Flaws Induced by CBC Padding Applications to SSL, IPSEC, WTLS . EUROCRYPT 2002的文章,論文中表明Padding Oracle的攻擊思想在對稱密碼領域也是可行的。這開啟了Padding Oracle攻擊的一扇新的大門,其意義從後面的文章直接將CBC模式下的Padding Oracle攻擊稱為Vaudenay攻擊就可見一斑。
CBC模式下Padding Oracle的詳細攻擊原理和方法在上一講中已給出了詳細講述,這裡還要再提一下的是,在02年的這篇文章中,攻擊者判斷Padding是否正確的依據,是利用Padding檢查不透過和訊息驗證碼(Authentication)檢查不透過時,SSL回覆的Alert值不同這一特點。但其實Alert值是加密傳送的,所以這個方法並不實際。儘管這樣,在這之後,各個SSL相關的庫都將Padding檢查失敗和Authentication檢查失敗返回的Alert值不做區分。
緊接著在03年,Serge Vaudenay在CRYPTO上發表了文章Password interception in a SSL/TLS Channel,在文章中提出使用時間旁路資訊來區分padding檢查失敗和authentication檢查失敗,這是因為在實現時,如果padding檢查失敗,就不會做authentication檢查,因此padding不正確時,伺服器的響應時間會比正確時要短,利用這個旁路資訊,攻擊者就可以獲得了一個有效的padding oracle。
很自然地,各個庫對應的響應方式就是無論padding檢查正確或失敗,都進行authentication檢查,這樣程式所表現出的時間差異就被彌補了。
這之後很長一段時間,對於SSL協議的Padding Oracle攻擊因為無法在實際中獲取到可用的oracle,就一直沉寂了。直到2013年,Lucky13攻擊的出現才又將padding oracle攻擊帶回大眾的視野,並且引發了很強烈的反響。下面我們就來詳細介紹Lucky13攻擊,看看它是如何又開啟一個資訊旁路資訊通道,使得padding oracle再次生效。
這裡需要多提一下的是,14年的POODLE攻擊又將Padding Oracle攻擊推到了風口浪尖,並宣告了SSLv3的死刑,但是這個攻擊只是一個並沒有利用其它的旁路資訊,透過連線的繼續與斷開作為padding合法與否的反饋資訊,在學術上沒有新的貢獻點,因此只是在工業界掀起了一陣風潮。
0x02 Lucky13攻擊
下面我們先來簡單回顧一下,Vaudenay攻擊要求攻擊者能夠識別出何時填充是正確的,在TLS中,即使訊息驗證失敗也要可以。通常情況下,驗證應該在解密之前做,而TLS顯然沒有這麼做,這就導致了在CBC模式下的Padding Oracle攻擊。
Vaudenay最初的攻擊利用的是在填充檢查失敗和驗證失敗時TLS會返回不同的警告值,但顯然這無法構成實際攻擊,因為警告值是加密傳送的。隨後,Vaudenay又發現可以利用時間旁路資訊來識別填充是否正確,這是因為若填充不正確則不會執行驗證,伺服器所用的時間定會多於填充正確時的時間。修補方法就是不論填充檢查是否成功,都進行驗證。
但是在這種情況下,攻擊者仍舊可以精心構造特定長度的訊息,使得伺服器在處理填充合法和不合法的情況下,所用的時間是不同的,也就是仍舊可以得到一條時間旁路通道進行攻擊。這就是我們接下來要詳細介紹的Lucky13攻擊。
2013年,AlFardan和Paterson在頂級會議Security&Privacy上發表了文章Lucky Thirteen: Breaking the TLS and DTLS Record Protocols,文中提出了對於全部版本的SSL協議的一種Padding Oracle攻擊方法。
文中利用的旁路資訊,仍舊是伺服器處理padding正確和不正確的訊息時所用的時間,只不過這個時間的不同是因處理不同長度訊息時進行訊息驗證過程中呼叫壓縮函式的次數不同造成的。換句話說,壓縮函式的呼叫次數與訊息長度有關,而處理的訊息長度值又與填充長度有關,因此填充的合法與否會間接導致壓縮函式的呼叫次數不同,從而導致伺服器處理訊息的時間不同。
原理解析
假設使用TLS_RSA_WITH_AES_128_CBC_SHA密碼套件,有一條待解密訊息如下:
ContentType || Version || Length || Civ||C1||C2||C3||C4
|-----1位元組-----|-----2位元組----|-----2位元組----|------16位元組 * 5--------|
伺服器收到訊息後,將5位元組的頭訊息去掉,解密Civ||C1||C2||C3||C4,解密後的訊息長度為64位元組,格式如下:
Message || MAC || Padding
在之前的設定中,為消除時間旁路資訊,伺服器在檢查Padding後,不論Padding是否正確,都進行驗證。因此伺服器首先檢查Padding,如果Padding合法,則去掉相應長度的Padding,否則,認為Padding長度為0。之後去掉20位元組的MAC,然後驗證MAC,去做HMAC的訊息如下:
HMAC( Seq || ContentType || Version || Length_M || Message)
|--8位元組--|-----1位元組-----| --2位元組--|---2位元組----|
可以看到在Message前面附加了13位元組的內容。下面我們重點關注計算HMAC過程中呼叫的壓縮函式的次數。HMAC的計算如下:
HMAC(K, m) = H( (K ⊕ opad) || H((K ⊕ ipad)||m) )
若使用SHA1作為雜湊函式,那麼每個壓縮函式處理的訊息長度是64位元組(下稱為一個block)。 (K ⊕ ipad)是一個block,如果訊息m的長度不是64的倍數,則要先對訊息進行填充,填充機制如下:
m || 0x80 || 0x00 … 0x00 || Length(8位元組)
可以看出,若訊息需要填充,則至少填充9位元組。
(K ⊕ ipad)是一個block,因此外層雜湊會呼叫2次壓縮函式,若m填充後是一個block(也就是m至多有55位元組)時,則內層雜湊函式呼叫2次壓縮函式,HMAC共有4次呼叫;否則會共5次呼叫。
因此攻擊者在看到訊息ContentType || Version || Length || Civ||C1||C2||C3||C4後,可以實施如下攻擊:
- 將C3的最後兩個位元組異或某一個值後傳送給伺服器解密
伺服器解密後,Message||MAC||Padding共64位元組,此時檢查Padding:
- 如果Padding不合法(很大可能),則當做Padding長度為0,去掉20位元組MAC,剩餘44位元組Message,Hmac的接收到m的長度為44+13=57位元組,因此會呼叫5次壓縮函式;
- 如果最後一個位元組為0x00,那麼padding合法,去掉Padding和MAC後Message長度為43位元組,m長度為56位元組,仍舊有5次壓縮函式呼叫;
- 而如果Padding最後兩個位元組都為0x01的話,m的長度就剛好是55位元組,只會有四次壓縮函式呼叫。
攻擊者將一次壓縮函式呼叫的時間差作為旁路資訊來區分Padding正確與否,進行常規的Padding Oracle攻擊。
漏洞修補
很容易想到,針對Lucky13的修補,就是不論可能的Padding是什麼,都要用恆定的時間計算MAC。實際中,不同的密碼庫有其不同的實現方法,大概可以分為兩類:
加入dummy function處理,比如當padding不正確時,PolarSSL庫就會計算需要額外執行的壓縮函式數目,然後呼叫一個叫做md_process的函式;
for(j = 0; j < extra_run; j++)
md_process(&ssl->transform_in->md_ctx_dec, ssl->in_msg);
加入dummy data,直接執行壓縮函式,使不論Padding正確與否,都執行可能的最大數目壓縮函式呼叫,OpenSSL和Mozilla NSS就是採用了這種方式。
這兩種方法單從時間上看,都成功封堵掉了時間旁路這個通道,但是對於利用dummy function的處理方式,若攻擊者能夠透過某種方式得到dummy function是否執行了的資訊,則可以仍舊發起Lucky13攻擊,將這個資訊用作旁路資訊,得到一個Padding Oracle。
0x03 Lucky13捲土重來?
上一小節講到,如果攻擊者能夠得到dummy function是否被執行的資訊,Lucky13就還可以攻擊成功。今年AsiaCCS上的一篇文章Lucky 13 Strikes Back,就成功地得到了dummy function執行與否的資訊,從而讓Lucky13復活。
文章作者構建的攻擊場景是在雲中,攻擊者與攻擊目標是執行在同一臺物理機器上的兩個虛擬機器。攻擊者運用Flush+Reload
的技術,獲取到目標機執行dummy function的情況。從作者給出的結果來看,這個新的旁資訊比原本Lucky13攻擊利用的網路時間旁路資訊要更加準確,平均恢復每個位元組需要查詢的次數要少。
下面就來簡單說明一下這個關鍵的Flush+Reload技術。它是一種強有力的基於cache的旁路攻擊方法。我們知道cache位於CPU和RAM之間,利用時空局域性原則(principle of locality),將最近訪問的memory中的內容放到快取中來,以減少平均訪存時間。訪問cache要比訪問memory快很多。因此,Flush+Reload的大致做法就是先將特定的程式碼從cache中清除掉,等目標程式執行後,再執行那段程式碼,透過載入程式碼的時間長短來判斷程式是否在cache中,若是,則說明目標程式也執行了這段程式碼。
此外,發起這個攻擊需要滿足以下兩個要求:
- 攻擊者與目標機執行在同一臺物理機器上
- 物理機器上開啟了記憶體去重(Memory Deduplication)特性,這是一種最初被作為Kernel Samepage Merging(KSM)引入Linux的記憶體最佳化技術,不同程式使用了相同的頁會被指向同一塊實體記憶體。
這個攻擊相比原本的Lucky13攻擊來說,不需要透過收到伺服器的響應去測算所用時間,因此避免了很難處理的網路通道噪聲,但是仍舊需要處理來自微架構的噪聲(如指令預取等)。此外,對於補丁做得比較到位的庫(如OpenSSL,Mozilla NSS等)此攻擊無法奏效。目前確認受影響的庫包括GnuTLS,PolarSSL和CyaSSL。
要使這個攻擊失效,可以從兩個方面入手,一是密碼庫的實現,對於填充合法和不合法的情況,採用同樣的函式處理,並且保證同樣的執行流(分支不依賴於訊息);另一方面可使Flush+Reload技術失效,比如可以關閉去重功能,對快取進行分割槽,或者載入快取時進行掩碼(基於硬體)。
0x04 POODLE攻擊
以上攻擊講完,似乎Padding Oracle攻擊所需的padding oracle已無從尋找,從實現上來講,在padding正確與否時,伺服器都儘量做到了響應保持一致。但這並不意味著無法找到差別,畢竟伺服器在收到正確的訊息後,要完成正常的業務處理,而訊息不對時則會拒絕服務。因此,找到一個特殊修改密文的方法使得伺服器正常接受,同時最後一個位元組可以預測,則就得到了一個可用的padding oracle。
14年的貴賓犬攻擊用到的就是這個思想,但只能對sslv3攻擊成功,是因為它利用了SSLv3訊息的不確定填充機制,也就是填充的最後一個位元組表示填充的長度,而對填充的其他部分則不做要求。對於密文Civ||C1||C2||C3||C4,若明文長度剛好為分組的倍數,也就是最後一個分組全部都是填充那麼將C2到C4的位置,若替換後的密文被伺服器接受,則可得知解密後最後一個位元組,也就恢復除了C2所對應的明文的最後一個位元組。
可見這個攻擊的要求還是較為苛刻的,首先要保證最後一個分組全部都是填充,此外因只能恢復分組的最後一個位元組,因此還要設法使待解密位元組處在分組的最後一個位元組,同時保證最後一個分組全部是填充。
附:這裡是一個可用的poc。
0x05 結語
SSL的Padding Oracle攻擊就介紹到這裡,在下一講中,我們會對SSL中弱PRNG帶來的安全問題進行深入剖析,敬請期待。
相關文章
- SSL/TLS協議安全系列:SSL/TLS概述2020-08-19TLS協議
- SSL/TLS協議安全系列- SSL中間人攻擊防範方案概述2020-08-19TLS協議
- [SSL/TLS] SSL/TLS協議綜合總結2013-07-15TLS協議
- SSL與TLS協議2020-12-13TLS協議
- SSL/TLS協議安全系列:再見,RC42020-08-19TLS協議
- 關於TLS/SSL協議2018-12-19TLS協議
- SSL/TLS協議詳解2014-04-19TLS協議
- SSL/TLS協議安全系列:CBC 模式的弱安全性介紹(一)2020-08-19TLS協議模式
- 車聯網通訊安全之 SSL/TLS 協議2022-04-15TLS協議
- 聊聊HTTPS和SSL/TLS協議2014-11-24HTTPTLS協議
- SSL協議安全系列:SSL中弱PRNG帶來的安全問題2020-08-19協議
- 協議森林17 我和你的悄悄話 (SSL/TLS協議)2016-10-08協議TLS
- SSL/TLS協議執行機制的概述2014-02-05TLS協議
- SSL/TLS協議的執行原理淺析2014-09-25TLS協議
- 國密SSL協議與標準TLS協議的區別2022-08-11協議TLS
- 安全協議:SSL、TSL、SSH概述2015-09-24協議
- SSL,TLS2015-04-20TLS
- https與TLS/SSL 握手協議、record protocol簡介2019-05-04HTTPTLS協議Protocol
- HTTPS協議詳解(四):TLS/SSL握手過程2018-03-13HTTP協議TLS
- 淺談 HTTPS 和 SSL/TLS 協議的背景與基礎2015-04-02HTTPTLS協議
- SSL協議安全系列:PKI體系中的證書吊銷2020-08-19協議
- 完全吃透 TLS/SSL2018-06-25TLS
- [HTTPS]SSL/TLS2024-07-04HTTPTLS
- 新的TLS加密破壞攻擊也會影響新的TLS 1.3協議2019-02-12TLS加密協議
- TLS 1.2 協議現漏洞 ,POODLE攻擊捲土重來2019-02-14TLS協議
- SSL和TLS 區別2019-04-03TLS
- 聊一聊 TLS/SSL2023-09-22TLS
- Secure gRPC with TLS/SSL2017-07-12RPCTLS
- SSL/TLS 深入淺出2024-07-29TLS
- gotofail:蘋果 SSL/TLS 重大安全漏洞的細節2014-02-24GoAI蘋果TLS
- 關於SSL協議未開啟2020-05-09協議
- Akka-CQRS(10)- gRPC on SSL/TLS 安全連線2019-06-17RPCTLS
- SSL/TLS協議原理與證書籤名多種生成方式實踐指南2024-08-02TLS協議
- HTTPS的SSL協議速度慢嗎❓2018-12-24HTTP協議
- mutual-tls-ssl: 為Java伺服器和客戶端設定 SSL/TLS 的分步指南2022-05-11TLSJava伺服器客戶端
- 黑帽大會:HTTPS和SSL協議存在安全漏洞2019-05-12HTTP協議
- SSL協議與數字證書原理2014-04-13協議
- SSL/TLS 握手過程詳解2019-03-04TLS