クラウドコンピューティングが必要ですか? 今すぐ始める

OpenSSL 3.x の脆弱性に効果的に備えるために

この記事では、そうした雑音を排し、憶測なしで、脅威を検知して緩和するための背景とヒントを提供できればと考えています。
この記事では、そうした雑音を排し、憶測なしで、脅威を検知して緩和するための背景とヒントを提供できればと考えています。

2022 年 11 月 1 日更新:HTTP および HTTPS 経由で配信される Akamai コンテンツは、この脆弱性による影響を受けません。サーバーが使用している OpenSSL はこの脆弱性の対象外です。さらに、Akamai システムは、説明されている攻撃ベクトルを緩和する業界標準のスタック保護メカニズムを採用しています。Akamai は、影響が出ると想定されるあらゆる内部システムにパッチを適用していますが、こうした対策がお客様のダウンタイムにつながるとは考えていません。

OpenSSL プロジェクトチームは、10 月 25 日の 発表 で、OpenSSL version 3.x の重大な脆弱性に対するセキュリティ修正を公開しました。パッチのリリースは 2022 年 11 月 1 日の午後 1 時~午後 5 時(UTC)に予定されています。

OpenSSL が広い範囲で使用されていることもあり、この発表は多くの物議を醸しました。この記事では、そうした雑音を排し、憶測なしで、脅威を検知して緩和するための背景とヒントを提供できればと考えています。 前半では、OpenSSL の概要と脆弱性の範囲について説明します。後半では、OpenSSL がアプリケーションでどのように使用されているか解説し、脆弱性のあるアセットを検知するためのツールを紹介します。必要であれば、 スキップしてこれらのユーティリティに直接アクセスすることができます。

注: このブログ投稿は進行中のインシデントが対象となります。情報の収集と修正のリリースに合わせて内容を更新していきます。

この脆弱性の範囲とは?

この脆弱性により、セキュリティコミュニティに懸念が広がっています。OpenSSL チームが脆弱性を重大と評価するのは稀なケースだからです(その後、"高"レベルにダウングレードされています)。このような脆弱性ラベルは、Heartbleed(メモリーの流出と重要な開示の可能性に発展する脆弱性)に付けられて以降、 CVE-2016-6309 (「重大」に分類)しかありませんでした。"

OpenSSL チームが重大と評価する場合、その脆弱性は一般的な設定に影響し、攻撃者による悪用の可能性があることになります。そうした脆弱性の例としては、「サーバーメモリーの内容の大規模な開示(ユーザー詳細の流出に発展する可能性)を伴う脆弱性、リモートで容易に悪用されてサーバーの秘密鍵が侵害される脆弱性、リモートコード実行が一般的な状況で発生すると考えられる脆弱性」などがあります。 

OpenSSL ライブラリの普及状況を考えると、この脆弱性は有害だと考えられます。ただし、そうした脆弱性を認識しておく必要はありますが、パニックになる理由はありません。OpenSSL は非常に一般的ですが、最も普及しているバージョンは 1.X.X であり、 この脆弱性は OpenSSL バージョン 3.0.0 以降 (2021 年 9 月のみのリリース)だけに影響します。そのため、この脆弱性は、OpenSSL ライブラリ自体の普及と比べると 発生頻度は低い と言えます。

私たちは、マネージド型ネットワークの一部で検知ツールを実行し、以下の事実を確認しました。

  • 監視対象の環境の約 50% には、脆弱性のある OpenSSL バージョンに少なくとも 1 つのプロセスが 依存しているマシンが、少なくとも 1 台あります。

  • これらのネットワークのうち、脆弱性のある OpenSSL バージョンに何らかの形で依存しているネットワーク内のマシンの割合は、 0.2% から 33%となります。

    • 中央値は 6.1% で、平均値は 11.3% 、標準偏差は 11.6%です。

これらの統計データは脆弱性のない OpenSSL の使用を考慮していません。唯一の指標は、脆弱性のある OpenSSL バージョン(3.0~3.6)に依存する少なくとも 1 つのプロセスを持つマシンの割合です。同じマシンで稼働する他のプロセスは考慮されていません。 

OpenSSL とは?

OpenSSL は、オープンソース・ソフトウェア・ツールキットです。そのため、OpenSSL のリリースは基本的にソース・コード・リリースとなります。 しかし、検知しようとすると、アプリケーションの読み込みや OpenSSL への依存形態が無数に存在するため、脆弱性の重大度もさまざまです。

まずは、OpenSSL の 3 つの構成要素を定義する必要があります。

  1. libcrypto — 多くのプロトコル(AES、RSA、ChaCha など)の実装を伴う暗号ライブラリ

  2. libssl — すべての TLS プロトコルを TLSv1.3 まで実装するライブラリ

  3. openssl — さまざまなオペレーション(証明書の生成など)を実行するコマンド・ライン・ユーティリティ

アプリケーションが OpenSSL に依存するためには、 libcrypto または libssl のいくつかのコードロジックを呼び出す必要があります(openssl 自体はこれら 2 つの要素に依存するアプリケーションです)。

OpenSSL の脆弱性の緩和

OpenSSL の脅威を緩和する第 1 歩は、脆弱性のあるアセットを検知することです。当たり前だと思われるかもしれませんが、実用的な手法ではほぼ検知できません。既知の脆弱性アプリケーションのリストと、ネットワークで脆弱性のあるアプリケーションを発見する一般的な手法を以下にまとめます。

セグメンテーション — パッチ適用前および適用後の緩和

OpenSSL に対するほとんどの依存性はベンダーのソフトウェアに起因している(ベンダーが独自に修正を適用する必要がある)ため、パッチ修正の即時適用は不可能かもしれませんが、検知から得られる可視性を有効活用することは可能です。セグメンテーションとルーティングを使用することで、攻撃者が脆弱性を利用して拡散するリスクを抑えることができます。

  • (より厳格な)DMZ という形で、インターネットに面したアセットにさらなる制限を加えることもできます。

  • ドメイン全体にさらに多くのセグメンテーションを作成することで、侵害した内部マシンを足がかりに攻撃者がネットワーク全体に被害を広げようとするのを阻止できます。この手法により、脆弱性のあるマシンのアタックサーフェスを縮小し、実際に通信が必要なネットワークの一部に制限することもできます。

さらに、この可視性と検知を利用してパッチ修正のアクションプランを作成し、漏れのない確実な対策を実施できます。パッチがリリースされ、パッチプロセスを完了したら、検知ロジックを再実行して結果を比較できます。脆弱性のあるマシンを 1 台も残さないのが理想です。

脆弱性のある既知のアプリケーションとは?

BoringSSL(Google Chrome で使用)と LibreSSL は、OpenSSL コードをベースとするライブラリであり、今後の脆弱性による影響をまだ受けていません。

通常、Linux の各種ディストリビューションは OpenSSL ライブラリを搭載しています。Linux 環境を実行している場合は、脆弱性のある OpenSSL を搭載している以下のいずれかのバージョンを使用しているかどうか確認することをお勧めします。

  • Red Hat Enterprise Linux 9

  • Ubuntu 22.04+

  • CentOS Stream9

  • Kali 2022.3

  • Debian 12

  • Fedora 36

このリスト以外の Linux ディストリビューションを使用したとしても、脆弱性に対する安全が保証されるわけではありません。ライブラリを頻繁に更新している場合でも(パッケージマネージャーのアップグレードコマンドの一環としてなど)、脆弱性にさらされる可能性があります。端末に「openssl version」と入力すると、ライブラリのバージョンが出力されます。

Docker も、今後のリリースに関するアドバイザリーを 公開 しており、さまざまな Docker 公式イメージと Docker 認定パブリッシャーイメージで約 1,000 個のイメージリポジトリが影響を受けると予想しています。それらのイメージには、上記の Linux ディストリビューションのバリエーションをベースとするものも含まれます。

また、一部のフレームワークも影響を受ける可能性があります。Node.js v18.x および v19.x は OpenSSL 3 を使用しているため、脆弱性の影響を受けると考えられます。新たな更新内容は、こちらの ブログ記事で公開していきます。

開発者を不安にさせるもう 1 つのプログラミング言語が、Golang です。Go バイナリのライブラリは静的にリンクされているため、Go 開発者によるソフトウェアの再コンパイルが必要になる可能性があります。セキュリティ修正を含む新しいマイナーリリースを Golang チームが発表した同じ日に、今後の OpenSSL パッチが発表されたため、人々はこれらを結びつけて認識してしまい、関連していると思い込みました。 しかし、ご安心ください。その思い込みは間違いです。 Golang のリリースは、今後の脆弱性とは無関係です

脆弱性のあるアプリケーションのリストは今後数日でさらに拡大すると予想され、この投稿もそれに応じて更新する予定です。次のセクションでは、自分の環境内のどのアプリケーションが OpenSSL 3 を使用しているのか、つまり脆弱性があるのかを確認するための検知メカニズムとツールについて解説します。必要な場合は、 検知メカニズムに直接お進みください

OpenSSL 3 を使用しているアプリケーションの一般的な検知方法

注: このセクションでは、OpenSSL を使用するアプリケーションの内部メカニズムを詳しく解説します。 単に検知方法が知りたい場合は、 YARA ルール または OSQuery クエリーに直接お進みください

OpenSSL は、静的よび動的にアプリケーションにリンクできます。静的リンクでは、OpenSSL のソースコードはアプリケーションコードの一部として含まれており、同じバイナリとしてまとめてコンパイルされます。動的リンクでは、OpenSSL は個別に共有ライブラリにコンパイルされます(Windows では libssl.dll と libcrypto.dll、Linux では libssl.so と libcrypto.so)。その後、アプリケーションコードに共有ライブラリへのリファレンスが格納され、アプリケーションの読み込み時にオペレーティングシステムによって解決されます。

これらを踏まえて、どのように検知するのでしょうか? 実際には、静的にコンパイルされたバイナリを検知するだけで十分です。その理由は、実行中のアプリケーションが OpenSSL を動的に読み込むか、ライブラリを動的に読み込んでから OpenSSL を動的に読み込む場合(そしてこのプロセスを繰り返す場合)、最終的に静的にコンパイルされた OpenSSL ライブラリがいくつか読み込まれるからです。すべての動的読み込みは同じプロセスで発生するため、各プロセスで読み込まれたライブラリのリストを確認し、静的にコンパイルされたライブラリを見つけるだけで検知できます。

ここで必要になるのが、静的にコンパイルされた OpenSSL を確認する方法です。これについては、一目瞭然です。静的にコンパイルされたすべての OpenSSL には、 OpenSSL 3.0.6 11 Oct 2022のようにバージョン文字列が格納されます。ここでは 3.0.6 がバージョン番号です。この文字列を検知するのは非常に簡単であり、Regex または YARA を使用して検知できます。

ただし、完全に一致しない場合もあります。OpenSSL はオープンソースコードなので、ユーザーはニーズに応じてバージョン管理ロジックを容易に変更できます(その結果、検知基準と一致しなくなります)。こうした不一致は一度しか経験していませんが(Cisco では CiscoSSL 1.1.1k.7.2.225 という文字列を使用していました)、他のベンダーでも同様に発生する可能性はあります。

今すぐできることは?

修正がリリースされるまで詳細は不明ですが、パッチに備えてできることはいくつかあります。私たちのチームは、可視性を得て容易に緩和できるように、それぞれの環境で実行できるいくつかのユーティリティを構築しました。 Akamai Guardicore Segmentation を導入し、Insight 機能を有効にしているお客様は、このロジックを自身の環境で簡単に実行できます。

YARA

私たちが定義できるメインルールは、前述の文字列の検知用です。説明を簡潔にするために、ここではリリースの影響を受ける OpenSSL の実際のバージョンに検知の範囲を限定しますが、この基準は容易に変更できます。

  rule openssl_version {
	strings:
		$re1 = /OpenSSL\s3\.[0-6]{1}\.[0-9]{1}[a-z]{,1}/
	
	condition:
		$re1
}

文字列に頼らない場合、OpenSSL に依存しているメインアプリケーションも検索できますが、実行可能ファイルのインポートの解析が必要になります。これは、より確実性が低い方法であり、そのように認識して使用する必要があります。

  import "elf"
import "pe"

rule elf_import_openssl {
    condition:
        (elf.type == elf.ET_EXEC or elf.type == elf.ET_DYN) and
        (
            for any i in (0..elf.symtab_entries):
            (
                elf.symtab[i].name contains "@OPENSSL_3"
            )
        )

}

rule pe_import_openssl {
    condition:
        pe.is_pe and
        (
            for any i in (0..pe.number_of_imports):
            (
                pe.import_details[i].library_name contains "libcrypto-3" or pe.import_details[i].library_name contains "libssl-3"
            )
        )
}

osquery

上記のクエリーを使用し、osquery の YARA テーブルも利用して、実行中のすべてのプロセスでこれらのルールを適用できます。

  WITH FIRST_QUERY AS (SELECT DISTINCT
    proc.pid,
    proc.path,
    proc.cmdline,
    proc.cwd,
    mmap.path AS mmap_path
FROM process_memory_map AS mmap
LEFT JOIN processes AS proc USING(pid))
SELECT *
FROM FIRST_QUERY
JOIN yara ON yara.path = FIRST_QUERY.mmap_path
WHERE sigrule = 'rule openssl_3 {
	strings:
		$re1 = /OpenSSL\s3\.[0-6]{1}\.[0-9]{1}[a-z]{,1}/

	condition:
		$re1
}
'
AND yara.count > 0

もちろん、前述のように別の YARA ルールを適用したり、フィルターを調整してチェック対象となるファイルの範囲を広げたり、絞り込むこともできます。

まとめ

OpenSSL チームは、セキュリティチームに今後の修正リリースを通知するという興味深いアプローチを導入しました。この発表により、備える時間が与えられ、パッチ対象となる重大なアセットをマッピングする時間的余裕が生まれます。このブログ投稿は、パッチ公開日に対処すべきアプリケーションとアセットの正確な特定をサポートするために作成しています。 

これは進行中の取り組みです。新たな情報のリリースとともに、このブログ投稿も更新します。この投稿の更新情報を今後もご確認ください。 X(旧 Twitter)をフォローすると、更新をよりリアルタイムに把握できます。