組み込みシステムや IoT デバイスは、非常に限られた処理能力、メモリ、ストレージで動作することが多いです。OpenSSL、MbedTLS、WolfSSL などの標準ライブラリは堅牢で十分にテストされていますが、オーバーヘッドが大きくなりすぎることがあります。そのため、セキュリティ侵害や混乱を防ぐために信頼性と応答性が極めて重要なヘルスケアモニタリングや産業用制御システムなどの環境では、実用的ではありません。
Mongoose Web Server Library が提供するような軽量な TLS 実装は、特にこうしたデバイスのニーズを満たすように設計されており、限られたリソースに負担をかけずに安全な通信を可能にします。
Nozomi Networks Labs は、多くのデバイスで Mongoose が果たす重要な役割を認識し、HTTPS サーバーなどの重要な機能でこのライブラリを使用するすべての製品のセキュリティ対策を改善するために、詳細な分析を行いました。HTTPS サーバーは、データ転送のセキュリティ確保と機密情報の保護に不可欠な機能です。
私たちの調査により、モンガスの TLS 実装には、標的のデバイスに巧妙に細工された悪意のある TLS パケットを送信することで悪用できる深刻な脆弱性が 10件あることが判明しました。 攻撃者は、標的のデバイスに基本的なネットワークの可視性があるだけでも、特別に細工した TLS メッセージを送信するだけで、Mongoose のライブラリを使用しているデバイスをクラッシュさせることができます。
深刻なリスクを考慮し、Mongoose プロジェクトのベンダーである Cesanta は、Mongoose v7.15 を迅速に開発しました。この新リリースには、私たちが発見した問題に対処するためのすべてのパッチが含まれています。
このブログ記事では、Mongoose Web Server Library に関する当社の調査の主なハイライトについてご説明します。また、これらのセキュリティ脆弱性をどのように発見したか、IoT デバイスへの影響、そして IoT エコシステム全体のセキュリティにとってどのような意味を持つかについても考察します。
リサーチ範囲
Mongooseは、HTTP、WebSocket、TLS などのプロトコルを管理する、組み込みシステム用の軽量なオープンソースのネットワークライブラリです。このプロジェクトは現在、GitHubでで11,000ものスターを獲得しており、世界中で数億台のデバイスに導入されています。その人気により、Siemens, Shuneider Electric, Bosch などの大手企業や、国際宇宙ステーションでも使用している NASA からも信頼を得ています。
Mongoose を開発した Cesanta は、セキュリティを非常に重視しています。
- Mongoose のリポジトリは、GitHub 上で継続的インテグレーションシステムを使用しており、すべてのコミットに対して数百ものユニットテストを実行し、最新のアドレスサニタイザー技術を活用してセキュリティ上の脆弱性を早期に特定しています。
- Mongoose は、Google の oss-fuzz と統合されています。oss-fuzz は、潜在的な脆弱性を積極的にスキャンする継続的なファズツールであり、ライブラリが継続的に監視され、新たなセキュリティ問題が検出されるようになっています。
- Cesantaは、Cisco Talos、Microsoft Security Response Center、MITRE Corporation、Compass Security などの独立系セキュリティ組織から脆弱性に関する報告を受け取ります。
Cesanta はセキュリティのあらゆる側面を慎重に扱っていますが、当社の調査では、組み込みの TLS プロトコル実装がファズテストのパイプラインに統合されていないことが判明しました。TLS (トランスポートレイヤーセキュリティ) は、クライアントとサーバー間の安全な HTTPS 接続を確立し、データの機密性と整合性を確保する上で基本的な役割を果たすプロトコルです。TLS ライブラリに脆弱性があると、深刻な影響を及ぼす可能性があります。
TLS ネットワークプロトコルが果たす重要な役割を考慮し、この TLS 実装に依存するデバイスの安全性を低下させる可能性のあるメモリ破壊や不適切な入力処理などの潜在的な脆弱性を明らかにすることを期待して、そのセキュリティ対策を調査することにしました。
これらの脆弱性の影響
最新の Mongoose Web Server Library 7.14 バージョンを分析したところ、TLS ネットワークプロトコルコードに関連する 10件のメモリ破壊脆弱性が発見されました。この脆弱性が悪用された場合、組み込み機器や IoT デバイスに深刻なセキュリティリスクをもたらす可能性があります。
以下は、発見された脆弱性の主な影響の一部です。
- デバイスのクラッシュと不安定性:多くの脆弱性 (CVE-2024-42386など) は、攻撃者によって送信された不正な TLS パケットを読み取ることによって引き起こされる可能性があります。これにより、システムがクラッシュし、予期せぬシャットダウンや連続再起動につながる可能性があります。
- サービス拒否 (DoS):CVE-2024-42384 脆弱性を悪用することで、攻撃者は、予期しない TLS パケットを適切に処理できないデバイスの脆弱性を悪用し、デバイスに過負荷がかかり応答不能になるように仕掛けることができます。病院や工場などの重要な環境では、このような攻撃により深刻な安全上の問題が発生する可能性があります。
これらの脆弱性は、IoT 環境では特に懸念されます。IoT 環境では、デバイスがしばしば無人で稼働しており、ひとつのデバイスが侵害されるだけで、接続されたシステム全体のネットワークに混乱が生じる可能性があります。医療、スマートホーム、産業用オートメーションなどの重要な分野で信頼性と安全性の高い運用を確保するには、これらの脆弱性への対応が不可欠です。
脆弱性リストと影響を受けるバージョン
次の表は、Nozomi Networks Labs がこの脆弱性調査中に Mongoose Web Server v7.14 で発見したすべての脆弱性の一覧です。
脆弱性スポットライト
Mongoose ライブラリは Google の OSS-Fuzz プロジェクトに統合されていますが (Cハーネスコードはここから入手できます)、既存のハーネスでは TLS 関数のテストがまったく行われていないことが分かりました。この観察結果から、私たちは TLS の攻撃対象領域に注目することにしました。これは、標的へのネットワークアクセスを持つ攻撃者が悪用できる興味深いベクトルを示しています。
TLSスタックの実装をファジングするのは難しいことで知られている。TLSは本質的にステートフルであり、ハンドシェイク、キー交換、データ送信といった複数の段階を経て進行する。このようなステートフルなプロトコルをテストするための有効なテストケースを自動的に生成するには、さまざまなシナリオを効果的に評価するために、メッセージの正しいシーケンスと状態を保持する必要があります。プロトコルが各ステップで有効な状態であることを保証するのは複雑であり、特にファズテスト中に異なる入力が状態遷移に影響を与える可能性があるためです。
この複雑性を踏まえ、私たちはよりシンプルなアプローチを選択しました。まず、Mongoose TLS のソースコードを分析し、クライアントまたはサーバーが最初の TLS パケットをどこでどのように受信するかを理解することから始めました。 そして、関連する主要なデータ構造を特定し、クライアントまたはサーバーが最初の TLS パケットを処理する際の内部状態を調べました。 この理解を基に、これらのデータ構造を妥当な内部状態に初期化し、ランダムな TLS パケットを提供し、この入力データを処理する最初の TLS 関数を呼び出すテストケースジェネレータ (Cハーネス) をコーディングしました。
分析の結果、クライアントとサーバーの両方が以下のデータ構造を利用していることが判明しました。
struct tls_data
構造体 mg_connection
これらの構造体は、通信のクライアント側を表すかサーバー側を表すかによって初期化方法が異なります。どちらの TLS ピアも mg_tls_handshake
関数は、TLS 通信フロー全体を管理する機能です。この関数は、TLS ネットワークパケットを読み取ります。 rtls
のフィールドにあります。 mg_connection
構造体を作成し、受信したパケットに基づいてTLSハンドシェイクを継続します。
この情報を念頭に置いて、私たちは次のようなハーネスコードを作成した:
このコードの背景にあるコンセプトは単純で、以下のステップでまとめることができます。
- を初期化することで、模擬 TLS クライアント接続をセットアップします。
tls_data
そしてmg_connection
構造体を適切な値で再作成し、有効な TLS 初期状態を再現します。 - について
c.rtls
バッファはランダム化されたTLSパケットで感じられる。 - について
mg_tls_handshake
関数が呼び出され、ファジング入力は通常のTLSハンドシェイク時と同じように処理される。
初期パケット処理に焦点を当てることで、ファジング中に TLS ステートマシンの全状態を維持する複雑な処理をバイパスし、プロトコルシーケンス全体をシミュレートすることなく、不正な初期パケットや予期せぬ初期パケットによって引き起こされる脆弱性について、TLS 実装を効果的にテストすることができます。
fuzzer をしばらく実行した後、次のようにして障害が検出されました。 AddressSanitizer
(ASAN)。この事故は、以下のような貴重な洞察をもたらしています。
の読み取り操作によるヒープバッファオーバーフローが報告されました。 gcm_update
関数。無効な読み取りは割り当てられたバッファのすぐ先で発生しており、off-by-one エラーまたはバッファ境界の不正な計算を示唆しています。クラッシュの原因を理解するために、私たちは mg_tls_recv_record
関数で最初の復号化が行われます。関連するコードの一部を以下に示します。
この関数を分析したところ、この関数は リオ->ブフ[3:4]
バイトで計算します。 msgsz
値です。
msgsz =MG_LOAD_BE16(rio->buf + 3);
次に、クライアントまたはサーバーが復号アルゴリズムとして AES GCM を使用する場合、両者はともに mg_aes_gcm_decrypt
に 16 を引く関数です。 msgsz
値です。
mg_aes_gcm_decrypt(msg, msg, msgsz - 16, key, 16, nonce, sizeof(nonce));
しかし、ここで問題があります。 msgsz
が 16 より小さい場合、16 を引くと整数のアンダーフローが発生し、折り返しによって正数が大量に発生します。このエラーの結果は mg_aes_gcm_decrypt
関数は input_length
よりも大きな値です。 リオ→ブフ
TLSバッファ。そして gcm_update
関数が全バイトを反復処理すると、out-of-bound read がトリガーされ、バイナリアプリケーションのセグメンテーションフォールトが発生します。
クラッシュの理由を確認した後、このバグにつながる悪意のある TLS パケットについてさらに調査することにしました。以下の証拠が示すように、TLS Client Hello パケットの「長さ」フィールドのどれも、以前に発見した整数アンダーフロー脆弱性を引き起こす必要条件である 16より低い値を持っていません。 mg_tls_recv_record
関数である。
しかし、よく見ると mg_tls_recv_record
を設定していることがわかります。 リオ→ブフ
TLS バッファは、TLS Client Hello パケットの先頭ではなく、その TLS Hello パケットの先頭である ext
フィールドにあります。
このフィールドの 5バイト目を読み取ることで、この関数はこのフィールドを初期化に使用します。 msgsz
変数を 0x5 に変換します。この動作により、この変数に 16 を引いた後、整数のアンダーフローが発生します。
修復
このブログでは、Mongoose Web Server Library v7.14に組み込まれた TLS スタックに影響を与える 10件のメモリ破壊脆弱性の開示を発表します。これらの脆弱性が悪用された場合、DoS 攻撃などの深刻なセキュリティリスクが、組み込みデバイスや IoT デバイスにおよぶ可能性があります。当社の調査結果を受け、Cesanta は迅速に Mongoose v7.15 ライブラリを開発し、リリースしました。このライブラリには、当社の調査で特定したすべての脆弱性に対するパッチが含まれています。これらの問題の影響が深刻であるため、Mongoose ライブラリを使用しているすべての開発者および組織は、バージョン 7.15 以降にアップグレードし、これらのセキュリティ問題から保護することを強くお勧めします。