ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

求む!TLS1.3の再接続を完全に理解した方(Challenge CVE-2020-13777)

1. GnuTLSの深刻な脆弱性(CVE-2020-13777)

先日、GnuTLSで深刻な脆弱性が見つかりました。

GNUTLS-SA-2020-06-03: CVE-2020-13777

It was found that GnuTLS 3.6.4 introduced a regression in the TLS protocol implementation.
This caused the TLS server to not securely construct a session ticket encryption key considering the application supplied secret, allowing a MitM attacker to bypass authentication in TLS 1.3 and recover previous conversations in TLS 1.2.
See #1011 for more discussion on the topic.
Recommendation: To address the issue found upgrade to GnuTLS 3.6.14 or later versions.
.
GnuTLS 3.6.4では、TLSプロトコルの実装にリグレッションが入っていることが判明しました。
これによりTLS サーバは、アプリケーションから渡された秘密鍵を使ってセッションチケットを暗号化する鍵が安全に生成されませんでした。
TLS 1.3では中間攻撃者が認証をバイパスすることができます。TLS 1.2では過去の通信を復号することができます。
このトピックに関する詳細な議論は、#1011を参照してください。
推奨: 発見された問題に対処するには、GnuTLS 3.6.14 以降のバージョンにアップグレードしてください。

issueを見ると、なんと stateless なTLS再接続を実現するTLSのセッションチケット情報が、TLSサーバ立ち上がりの数時間はオール0の暗号鍵で暗号化されていたというバグでした。

2年近く前、チケットの暗号鍵にTOTP(Time-Based One-Time Password Algorithm)のような機能を導入し、暗号鍵が定期的に変わるように変更したようなのですが、その際初期化のところでバグが入っていたようです。

これはなかなか衝撃的で痺れる脆弱性です。脆弱性に該当するバージョンを利用している方は直ちにアップデートしてください。

TLSセッションチケットの中身を守ることは、TLS通信の安全性を確保する要の一つです。脆弱性対象のGnuTLSを利用している全てのTLSサーバで、このチケットを暗号化する鍵が危殆化してしまったのですからそりゃ大変です。

ネット上では、このTOTPは意味はないのに入れちゃって、かえって致命的なバグを混入させたとして、GnuTLSに対する信頼性について批判するような意見も見受けられています。

issue見ると、日本人の名前の方がGnuTLSのメンテをされているようです。大変なご苦労かと思います。 ここではGnuTLSがどうだこうだと言うつもりはなく、純粋に技術的な観点からこの脆弱性の影響について考えてみたいと思っています。

2.ものは試し Challenge CVE-2020-13777

この脆弱性、実際にPoCを書いてみると非常に奥が深いです。TLS 1.3をちゃんと理解していないと無理です。

TLS 1.2 と TLS 1.3 でなぜ影響に違いがあるのか、そこはTLS 1.3の進化が見えるところです。またアナウンスには記述されていませんが、TLS 1.3の0-RTTを利用していた場合、この脆弱性によって大きな影響が新しく出てきます。

さっそく「GnuTLSの脆弱性(CVE-2020-13777)でTLS1.3の再接続を完全に理解する」というタイトルでブログを書こうと思いましたが、いつもの通りでは面白くない。なんか良からぬ考えが頭をよぎりました。

これ、どのぐらいの方が理解されるのでしょうか? 一度問題を作って、回答を公募してみようと思います。

3. 問題

以下のレポジトリにある pcap データを使って次の問題1,2に回答してください。
pcap データにはGnuTLS-3.6.13のサーバ(192.168.100.23:5556)に対するTLS1.3の接続データが2つ含まれています。1回目は新規TLS1.3接続、続く2回目は 0-RTT のTLS1.3再接続です。

https://github.com/shigeki/challenge_CVE-2020-13777

  1. pcap中のTLS1.3 ClientHelloデータだけ使って、CVE-2020-13777によってTLS1.3のMITMが可能であることを証明してください。
  2. pcap中の暗号化されたTLS1.3 の 0-RTTアプリケーションデータをCVE-2020-13777によって復号し、アプリケーションデータの平文を取得してください。

できるだけ純粋にTLS1.3仕様の理解を実証していただくため、GnuTLS固有で必要な情報(暗号化されたチケットの書式、チケットの中身の書式)は以下にヒントとして記しておきます。 f:id:jovi0608:20200613055805p:plain

不明な点は、直接GnuTLSのソースコードを参照してください。

4. 応募方法、期限

回答の説明と回答を得るために使ったソースコード を secret gist にあげて、そのリンクを私(twitter:@jovi0608)までDMで送ってください。

2問回答された方で、私の判断で一番見事と思う回答者1名にアマゾンギフト券(1万円)を贈呈したいと思います。

対象者が複数いた場合は、応募時間が先の方に贈呈します。

4.1 Vさん賞贈呈の追記 (6/13 13:40)

急遽Vさん賞を別途設けます。Vさんが好みそうな方を独自に選んでギフト贈呈します。

応募期限は、2020年6月18日(木) 23時59分59秒(JST) です。

5. 応募条件、免責事項

応募条件は、細かいですが以下の方でお願いします。

  • 「TLS1.3やQUICの実装していて、他者に提供している人」でない方:(実装されてる方は完全に理解されてますよねw 自己申告に任せます)。(追記6/13 11:24, ちょっと書き方が紛らわしかったので少し明確にしました。)
  • 正解の有無に関わらず、応募された twitter/githubアカウントや応募内容について、このブログで公開を許可していただける方(内容によっては文意を変えない程度に編集をさせていただきます)。
  • なにかリーガル上の理由やその他考慮不足など止む得ない理由で、予告なく Challenge の条件変更や取りやめを行う可能性がありますが、ご了承いただける方。
  • 私の一存の判断で応募内容の評価させていただくことに異論のない方。

TLS 1.2のPoCに関しては、全てのアプリケーションデータの forward secrecy を破ることになり影響が大きいので対象としません。

TLS 1.3については、現在 0-RTT を利用していると公表している中で netflix が一番の大規模サービスと思いますが、今回の脆弱性に該当するGnuTLSを利用していないことを確認済です。TLS1.3 0-RTTの機能はセキュリティ上の理由で安全に利用するのが難しく現在利用が普及していません。そのため今回のPoC公開・解説はあまり世間に影響ないものと判断しています。もし影響が大きいとわかれば、PoCの公表を取りやめます。

こういうことやるの初めてなので、いろんな不備・不測の自体が発生した場合にはお許しください。なにか不明な点があればこのブログにコメントください(moderateされています)。

応募が全然なかったら寂しいですね。贈呈するギフト券は完全に自分のポケットマネーです。これを機にTLS1.3仕様の完全理解に取り組んでくれる方がいらっしゃれば嬉しいです。

TLS1.3の再接続を完全に理解している方、応募をお待ちしています!