OpenSSL の DoS 脆弱性、認証不要の攻撃者が大規模なメモリ割り当てを引き起こす

新たに公表されたOpenSSLの重大な脆弱性により、攻撃者はハンドシェイクを完了させることも身元を証明することもなく、サーバーをクラッシュさせられることが分かりました。

Oktaのレッドチームによって文書化され、「HollowByte」と名付けられたこの脆弱性は、TLS接続の最初期段階でOpenSSLがメモリを確保する仕組みを悪用するもので、わずか11バイトのペイロードで、実際のリクエスト内容をはるかに超える量のメモリをターゲットに割り当てさせることができます。

TLSハンドシェイクは、レコードにラップされたClientHelloメッセージから始まります。各ハンドシェイクメッセージには、受信予定のメッセージ本体のサイズを示す4バイトのヘッダーが付いています。

古いバージョンのOpenSSLは、実際にデータが到着する前に、この攻撃者が申告した長さに基づいて受信バッファを確保します。

悪意ある11バイトのペイロードが到着すると、TLSステートマシンはヘッダーを読み取り、この長さフィールドに基づいて検証なしの事前割り当てを引き起こします。

ヘッダー読み取り → grow_init_buf() → OPENSSL_clear_realloc() → malloc(attacker_size)

この段階ではペイロードの検証が一切行われないため、malloc()はパケットの申告内容のみに基づいて最大131KBを割り当ててしまいます。ワーカースレッドはその後、決して届かないデータを無期限に待ち続けることになります。

スレッドを枯渇させるために接続を開いたまま保持する手法は、Slowlorisに似た古典的な手口です。HollowByteは、glibcのメモリ管理方式に結び付いた、より厄介な複合的効果を加えています。

接続が切断されるとOpenSSLはバッファを解放しますが、glibcは中小規模の割り当てを即座にOSへ返却せず、再利用のために保持し続けます。

攻撃者が申告サイズをランダムに変えながら大量の接続を仕掛けることで、アロケータが解放済みチャンクを再利用できなくなります。ヒープは激しく断片化し、サーバーの常駐セットサイズ(RSS)は増加し続けます。

攻撃者が切断した後も、サーバーは肥大化したまま元に戻りません。唯一の対処法はプロセスを強制終了することです。パッチ適用前後のOpenSSLをNGINX上でテストした結果、この問題の深刻さが明らかになりました。

OpenSSLはエコシステム全体に組み込まれているため、この脆弱性はWebサーバー(Apache、NGINX)、言語ランタイム(Node.js、Python、Ruby、PHP)、データベース(MySQL、PostgreSQL)に影響を及ぼします。

OpenSSLはこの問題を解決し、バッファを段階的に拡張する方式に切り替えました。この修正はPR #30792、#30793、#30794としてマージされています。修正はOpenSSL v4.0.1で静かに配布され、3.6.3、3.5.7、3.4.6、3.0.21にもバックポートされました。

ヘッダーの内容をそのまま信頼するのではなく、OpenSSLは実際に回線上でバイトが届いた分だけバッファを拡張するようになったため、空の申告ではサーバーに一切コストがかかりません。注目すべきは、OpenSSLがこれを正式なCVEセキュリティアドバイザリではなく、堅牢化のための修正として扱った点です。

とはいえ、管理者は各ディストリビューションのOpenSSLパッケージを直ちにアップグレードすべきです。特に、認証不要でアクセスできるためこの脆弱性が大規模かつ容易に悪用されかねない、インターネットに公開されたTLSエンドポイントでは注意が必要です。

より強力な予防的防御で重大インシデントと金銭的損失を防ぎましょう。15,000のSOCが利用するライブ脅威フィードを統合する

翻訳元: https://cyberpress.org/openssl-dos-flaw/

ソース: cyberpress.org