JSON Web加密中的高危漏洞
- 2019 年 10 月 8 日
- 筆記
前言
JSON Web加密容易受到經典的Invalid Curve攻擊,這篇文章可以幫助您了解這會對您產生什麼影響以及您應該如何應對。
如果您使用的是帶有ECDH-ES的go-jose,node-jose,jose2go,Nimbus JOSE + JWT或jose4,請把它更新到最新版本。RFC 7516又稱JSON Web加密(JWE),它和實現此規範的軟體庫曾經遭受經典的Invalid Curve攻擊。這可以允許攻擊者使用帶有Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES)密鑰協議的JWE一方的密鑰,這樣發送方可以從中提取接收方的私鑰。
在這篇博文中,我假設您已經了解了elliptic curves以及其在密碼學中的應用。如果您想進一步了解的話,您可以訪問(https://safecurves.cr.yp.to/) 。另外DJB和Tanja在31c3的講話中(見第43分鐘)也有對這種攻擊的解釋,此外Juraj Somorovsky等人的研究也為學習者提供了便利。
值得注意的是,這項研究的開始和靈感來自於Google的Quan Nguyen,後由Adobe的Antonio Sanso進行了完善。
介紹
JSON Web Token(JWT)是在 OAuth specification family中定義的,基於JSON的一個開放標準(RFC 7519),它用於創建access tokens。該Javascript Object Signing和Encryption (JOSE) IETF專家小組隨後為JWT形成了一套正式的簽名和加密方法,從而發布了RFC 7515,又名JSON Web Signature (JWS),以及RFC 7516,又名JSON Web Encryption (JWE)。在這篇文章中,我們將重點關注JWE。
典型的JWE是點分隔字元串,它包含五個部分:
1.The JWE Protected Header 2.The JWE Encrypted Key 3.The JWE Initialization Vector 4.The JWE Ciphertext 5.The JWE Authentication Tag
以下是從規範中獲取JWE的一個例子:
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg. 48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji SdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ
此JWE使用RSA-OAEP進行密鑰加密,使用A256GCM給內容加密:

一個名為RFC 7518,又稱JSON Web演算法(JWA)單獨列出了所有可用演算法。我們今天討論的是Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES)的關鍵協議。該演算法允許導出暫時的共享密鑰(Neil Madden的這篇博文給出了如何進行短暫密鑰協議的具體示例)。
在這種情況下,JWE Protected Header還列出了用於密鑰協議的elliptic curve:

一旦計算了共享密鑰,密鑰協商結果可以通過以下兩種方式使用:
1.在直接密鑰協議模式中,直接作為"enc"演算法的內容加密密鑰(CEK) 2.在具有密鑰包裝模式的密鑰協議中,作為一種使用A128KW,A192KW或A256KW演算法,封裝CEK的對稱密鑰。
這超出了本文的範圍,但對於其他演算法,JOSE Cookbook展示了如何將ECDH-ES與AES-GCM或AES-CBC加上HMAC結合使用。
原始數據
正如Quan在2017年RWC的演講中強調的那樣:
解密/簽名驗證輸入始終受到攻擊者的控制
正如我們將在本文中看到的那樣,這個簡單的原始數據足以恢復接收者的私鑰,但首先我們需要在elliptic curve的片段上挖掘一點。
elliptic curve
elliptic curve是由以下形式的等式定義的解集:
y^2 = x^3 + ax + b
這種方程稱為Weierstrass方程。橢圓曲線如下:

y^2 = x^3 + 4x + 20
為了將橢圓曲線理論應用於密碼學,我們需要查看那些點在有限域Fq中具有坐標的橢圓曲線。然後,在大小為191的有限域上,相同的曲線將如下所示:

y^2 = x^3 + 4x + 20 (超過有限域191)
對於JWE,橢圓曲線的範圍是Suite B和(僅在最近)DJB曲線中定義的曲線。在這兩者之間,到目前為止使用量更高的曲線是著名的P-256。
是時候打開Sage了,讓我們定義P-256:

曲線的序列非常大,因此攻擊者無法利用該曲線(如果軟體正確實現了ECDH)猜測協議中使用的私鑰。
攻擊
這裡描述的攻擊實際上是經典的無效曲線攻擊,這種攻擊既簡單又強大,它利用了Weierstrass的標量乘法公式沒有考慮曲線方程的係數b這一點:
y^2 = ax^ + ax + b。
原版的P-256等式是:

如上所述,這條曲線的序列非常大。因此,我們現在需要為攻擊者找到一條更方便的曲線。有了Sage就會非常簡單:

從上圖中我們可以看到,我們找到了一條更好的曲線(從攻擊者的角度來看),該曲線具有許多小因子的序列。然後我們在曲線上找到了一個點P,它的序列非常小(在這個例子中為2447)。
現在我們可以構建惡意JWEs(參見下面的Demo Time部分),並在恆定時間內提取密鑰模組2447的值。
攻擊成功的關鍵是讓受攻擊的對象不斷重複自己共同密鑰的那一部分。換句話說,這意味著受攻擊對象的私鑰應該與每個密鑰協議相同。這就是Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES))密鑰協議運行的工作原理。事實上,ES代表Ephemeral-Static,即Static是受害者共同密鑰的那一部分。
在這個階段,我們可以多次重複這些操作(找到一條新曲線,製作惡意JWE,恢復小序列的密鑰),並收集有關密鑰的資訊。
在最後快要結束的時候,還有一個問題,所有庫都忽視了驗證接收到的公鑰(包含在JWE Protected Header中的曲線),你可以看到下面的Vulnerable Libraries部分來查看各個庫如何解決這個問題。
您可以在原始論文中找到攻擊的詳細資訊。
演示時間
demo演示點擊這裡(https://afternoon-fortress-81941.herokuapp.com/)

說明
為了展示攻擊如何運行,我在Heroku中設置了一個實況演示。在(https://obscure-everglades-31759.herokuapp.com/) 中啟動並運行一個Node.js伺服器應用程式,在這種情況下它將充當受害者對象。假設是這樣的:為了與此Web應用程式通訊,您需要使用Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES)密鑰協議來加密令牌。密鑰協議所需的伺服器靜態公鑰位於https://obscure-everglades-31759.herokuapp.com/ecdh-es-public.json:

如果應用程式想要此伺服器的POST數據,首先需要使用上面的伺服器公鑰執行密鑰協議,然後加密具有JWE格式的共享密鑰的有效負載。一旦JWE到位,就可以發布到https://obscure-everglades-31759.herokuapp.com/secret 如果一切順利(即如果它可以解密有效載荷內容),則web應用將以200響應狀態回應,並且如果由於某種原因,接收到的令牌丟失或無效,則將以400響應狀態回應。這對任何潛在攻擊者都是一樣的,其方式與前一個「攻擊」部分中顯示的方式相同。
我在https://afternoon-fortress-81941.herokuapp.com/中設置了攻擊者應用程式。
您可以單擊「恢復密鑰」按鈕訪問它,觀察攻擊者如何能夠逐個從伺服器恢復密鑰。請注意,這只是一個演示應用程式,因此為了減少等待時間,恢復的密鑰會非常小。在實踐中,密鑰將會更大(因此恢復密鑰需要的時間將會更多一些)。
如果你現場演示中遇到了問題,或者只是想看看底下的程式碼,你可以在Github中找到演示程式碼:
https://github.com/asanso/jwe-receiver 包含易受攻擊的伺服器的程式碼。 https://github.com/asanso/jwe-sender 包含攻擊者的程式碼。
Vulnerable Libraries
在這裡,您可以看到這張表,上面列有目前為止易受此特定攻擊影響的庫:
- node-jose v0.9.3包括幾周前發布的必要修復程式。 這是原始POC的要點。
- jose2go的修復程式登陸在1.3版本中。
- Nimbus JOSE+JWT為Maven central推出了一個固定的工件,即v4.34.2。 這是原始POC的要點。
- 自從v0.5.5起,jose4已經解決了這個問題。這是原始POC的要點。
- go-jose(這是Quan Nguyen發現的易受攻擊的原始庫)
一些庫是用程式語言實現的,這種程式語言已經阻止了這種攻擊,以防這種攻擊檢查標量乘法的結果是否在曲線上:
最新版本的Node.js似乎不受這種攻擊的影響,在沒有web加密支援的情況下使用瀏覽器時仍然可能容易受到攻擊。
受影響的是附帶1.8.0_51之前版本的Java的Java SUN JCA提供程式。後來的Java版本和BouncyCastle JCA提供程式似乎沒有受到影響。
提高JWE標準
我通過郵件將這個漏洞提交給了JOSE工作組。我們一直認為,列出問題的勘誤表非常受到歡迎,這篇文章嘗試著提高對這一特定問題的意識。
除此之外:使用Auth0保護應用程式
您構建過B2C,B2B或B2E工具嗎?Auth0可以幫助您專註於最重要的事項。。Auth0可以通過無密碼,破解密碼監控和多因素身份驗證等最先進的功能幫助您確保產品的安全。 我們將非常慷慨地提供免費套餐,這樣就可以使用現代身份驗證技術。
鳴謝
作者要感謝go-jose,node-jose,jose2go,Nimbus JOSE + JWT和jose4的維護者對問題的積極響應。Francesco Mari幫助開發演示應用程式,Tommaso Teofili和Simone Tripodi進行故障排除工作,最後,如上所述,我要感謝來自Google的Quan Nguyen,如果不是他開了個好頭,我們不會有現在的成果。
原文鏈接:https://auth0.com/blog/critical-vulnerability-in-json-web-encryption/