乾貨|白話SSL/TLS預設重協商漏洞原理與安全重協商對抗機制

中興開發者社群發表於2017-11-14

  點選上方“中興開發者社群”,關注我們

每天讀一篇一線開發者原創好文640?wx_fmt=png&wxfrom=5&wx_lazy=1

SSL/TLS協議是現代網際網路安全的基礎,任何網上銀行、電子商務、電子政務、電子醫療等等網際網路重要應用,都要基於SSL/TLS提供的安全、保密、可信機制才能正常執行。所以,任何SSL/TLS的安全漏洞都值得我們深入研究並理解。


什麼是重協商?

640?wx_fmt=png&wxfrom=5&wx_lazy=1

在SSL/TLS協議中,協商是指通訊雙方客戶端和伺服器,選取相同演算法、傳遞數字證書、互驗對方身份、交換共享金鑰等一系列的動作。重協商(即,重新協商)是指在已經協商好的SSL/TLS TCP連線上重新協商,用以更換演算法、更換數字證書、重新驗證對方身份、更新共享金鑰等等。SSL/TLS協議本身支援重協商,且RFC文件建議SSL/TLS實現(指OPENSSL等庫)也應該預設支援重協商。

重協商包括兩種方式,分別如圖A和圖B所示:


640?wx_fmt=png&wxfrom=5&wx_lazy=1

  • 圖A是客戶端主動發出ClientHello2進行重協商。

  • 圖B是伺服器通過發出Hello Request訊息,請求客戶端發起重協商。如果客戶端同意重協商,則才會發起ClientHello2。

不管是哪一方發起的重協商,如果接收方不同意的話,都會通過SSL Alert響應以拒絕重協商。


幾年之前,美國某安全公司的研究人員發現SSL/TLS協議重協商機制有嚴重的安全漏洞,中間人可以利用這個漏洞,將自己的資料注入到客戶端與伺服器的SSL/TLS“安全連線”之中。該漏洞被發現的第二年,通過RFC 5746引入新的“安全重協商”機制,來解決這個漏洞。本文先介紹一下預設重協商機制的安全漏洞的原理,再介紹一下安全重協商機制是如何對抗這個漏洞的。


什麼是中間人?

所謂中間人,通常可能有如下三種形式。

第一種是通過偽造ARP訊息,對區域網內使用者流量進行重定向,令其所有流量都通過中間人中轉,從而中間人有機會對流量的內容進行監視或篡改。

第二種是通過偽造DNS訊息,對網際網路使用者訪問指定網站的流量重定向,令其與該網站之間的流量都通過中間人中轉,從而中間人有機會對該網站相關的流量內容進行監視或篡改。

第三種是企業閘道器、企業防火牆、電信運營商GGSN/PGW閘道器裝置等,使用者的流量必須經過這些裝置才能正常上網,這些裝置天生就可以從“轉發者”轉變為“中間人”從而對流經的流量進行監視或篡改。

普通使用者可能通常不會遇到前兩種情況,但是第三種情況很有可能發生。所以,作為客戶端和伺服器的軟體開發者、以及SSL/TLS庫的開發者,出於為使用者的安全著想,應該確保拒絕不安全的重協商,或者只支援安全的重協商。


重協商的安全漏洞原理

0?wx_fmt=png

  1.  客戶端首先發出一個ClientHello1,客戶端期待進行首次協商。(注意:客戶端認為ClientHello1是首次協商)

  2.  中間人收到ClientHello1之後,按理說它應該將其轉發給伺服器。但是中間人這時決定“作惡”,將ClientHello1快取起來暫不轉發。中間人自己構造一個ClientHello2,對伺服器發起首次協商,協商好後中間人將精心偽造的資料傳送給伺服器。(注意:伺服器認為ClientHello2是首次協商)

  3.  伺服器收到這些資料,會認為這是正常的資料。因為伺服器的APP程式通常需要處理粘包,所以中間人如果瞭解APP協議(如HTTPS)的話,則會精心構造不完整的資料,讓伺服器的APP程式認為發生粘包,將資料暫緩不處理,繼續等待後續的資料上來。

  4.  這時,中間人調出之前暫緩的ClientHello1,將其在同一個SSL/TLS TCP連線中,傳送給伺服器。(注意:ClientHello1訊息本身是加密的,因為其是在ClientHello2協商好後的加密SSL/TLS連線中傳輸)

  5.  伺服器收到ClientHello1後,認為這是一次重協商,協商好後,客戶端傳送真正的資料給伺服器。

  6.  伺服器的APP程式,收到客戶端的真正資料後,將其與之前快取的中間人精心構造的資料粘合起來,進行業務處理。

從而,中間人在不需要劫持、解密SSL/TLS連線的情況下,成功地將自己偽造的資料插入到使用者真正資料之前。這個安全漏洞可以讓心機卓絕的中間人做好多事情,比如偽造一個HTTP GET訊息,然後用HTTP的IGNORE欄位遮蔽掉真正資料的HTTP GET頭,但是卻保留了使用者的Cookie資訊,從而利用使用者的Cookie去訪問網站內容,比如可能利用此法刪掉使用者之前發的帖子等。

這個漏洞成因在於,客戶端認為的首次協商卻被伺服器認為是重協商,以及首次協商和重協商之間缺少關聯性。RFC 5746引入明確首次協商與重協商的方法,以及確認首次協商和重協商的關聯性校驗,從而確保中間人的攻擊行為可以被識別並拒絕,保證重協商安全。

0?wx_fmt=png

  1. 客戶端發起ClientHello1。

  2. 中間人快取ClientHello1,精心構造ClientHello2,與伺服器進行首次協商。這裡假設中間人在ClientHello2中不攜帶安全重協商標識。

  3. 中間人與伺服器協商成功,傳送偽造的資料給伺服器。

  4. 中間人將之前快取的ClientHello1傳送給伺服器。

  5. 如果伺服器禁止重協商,則這時看到ClientHello1,會認為發生了重協商,不允許,所以中斷連線。

  6. 如果伺服器禁止不安全的重協商、但允許安全的重協商,則因為之前中間人構造的首次協商訊息ClientHello2中指示不支援安全重協商,所以現在收到ClientHello1認為發生了不安全的重協商,所以中斷連線。

因此,這種情況以及各種子情景都沒有問題,不會有安全漏洞。

0?wx_fmt=png

  1. 客戶端發起ClientHello1。

  2. 中間人快取ClientHello1,精心構造ClientHello2,與伺服器進行首次協商。這裡假設中間人在ClientHello2中攜帶支援安全重協商標識。

  3. 中間人與伺服器協商成功,傳送偽造的資料給伺服器。在這時,因為雙方都支援安全重協商,所以伺服器會要求中間人將伺服器傳送的Finish訊息中的首次協商會話摘要資訊記錄下來,以便重協商時再帶給伺服器;當然,伺服器自己也會將這個首次協商會話摘要資訊記錄到自己的記憶體中)

  4. 中間人將之前快取的ClientHello1傳送給伺服器。

  5. 如果伺服器禁止不安全的重協商、但是允許安全的重協商,且如果ClientHello1中支援安全重協商,則按照RFC 5746是不合理的,只有首次協商ClientHello才允許帶有支援安全重協商標識,重協商階段的ClientHello是不允許攜帶該標識的。所以,伺服器認為可能是遇到攻擊,中斷連線。

  6. 如果伺服器禁止不安全的重協商、但是允許安全的重協商,且如果ClientHello1中不攜帶支援安全重協商標識,則伺服器會認為這是正常的重協商。然後,伺服器會提取出前邊第3步中記錄的首次協商會話摘要資訊,按照RFC 5746,ClientHello1中應該帶有相同的這個首次協商會話摘要資訊。但是,一方面客戶端的ClientHello1是不可能帶有這個資訊的,所以伺服器校驗失敗;另一方面,如果中間人將這個資訊插入給ClientHello1,那麼雖然伺服器現在校驗成功,但是後續伺服器校驗協商會話完整性時還是會失敗。


總而言之,安全重協商機制會補上重協商的漏洞隱患,讓中間人攻擊無機可乘。

參考文獻:

1. RFC 5246 The Transport Layer Security (TLS) Protocol Version 1.2

2. RFC 5746 Transport Layer Security (TLS) Renegotiation Indication Extension



擴充閱讀

乾貨|公鑰密碼學在勒索病毒中的應用原理圖解

640?wx_fmt=jpeg

相關文章