** 本記事は、英語記事タイトル の翻訳です。最新の情報は英語記事をご覧ください。**
更新:新しいオープンソースのスキャンツールを追加し、オープンソケットクエリを調整しました。
更新:log4j 2.17.0 に関する情報を追加し、log4j のより多くのバージョンに対応できるように定期クエリを調整しました。
概要と背景
Log4j は、Apache Foundation によって開発されたオープンソースのロギングフレームワークです。サーバーとエンドユーザーシステムの両方で、Java ベースの多くのアプリケーションに組み込まれています。2021 年 12 月 9 日に最初に公開された脆弱性 Log4Shell (今回 Log4j に発見された脆弱性の略称) は、多くのアプリケーションや依存関係に Log4j が統合されていることから、広範囲に及ぶ問題です。認証していない第三者がリモートからコードを実行できる脆弱性であり、CVE-2021-44228 が採番されています。
この情報が公開されてから、すぐに概念実証 (PoC) コードが公開され武器化が行われました。
NIST (米国国立標準技術研究所) からの引用:
Apache Log4j2 2.0-beta9 から 2.12.1 および 2.13.0 から 2.15.0 までの全バージョンにて、構成、ログメッセージ、パラメーターで使用される JNDI は、攻撃者が制御する LDAP と他の JNDI 関連エンドポイントに対して保護されていません。ログメッセージやログメッセージのパラメーターを制御できる攻撃者は、メッセージのルックアップ置換が有効な場合、LDAP サーバーからロードされた任意のコードを実行できます。Log4j 2.15.0 以降のバージョンからは、この動作はデフォルトで無効化されています。バージョン 2.16.0 以降、この機能は完全に削除されました。この脆弱性は、Log4j-core に特有のものであり、log4net、log4cxx、その他の Apache Logging Services プロジェクトには影響しないことに注意してください。
更新: 2021 年 12 月 18 日、2.0-beta9 から 2.16.0 までの Log4j バージョンに影響するサービス拒否の脆弱性 (CVE-2021-45105) が発見されました (バージョン 2.17.0 で修正済み)。
この脆弱性の詳細な内訳は、Sophos News のコード分析: Log4Shell エクスプロイトの仕組みを暴く次の記事をご覧ください。
緩和策
識別
組織が最も重視すべきことは、Log4j が組織内に存在するかどうか、そしてどこに存在するかを判断することです。Log4j を使用する可能性があり、インターネットに接続しているアプリケーションを中心に調査することが重要です。Log4j は、アプリケーションとしてインストールされるわけではなくライブラリとしてベンダーやサードパーティのツールと統合されているため、この調査は容易ではありません。
アセットインベントリを明確にしている組織は、Java、JVM (Java Virtual Machine) 、Log4j ライブラリがインベントリ内のどこに存在するかを特定するために、インベントリを利用する必要があります。
現在、脆弱性のある既知のアプリケーションやベンダーを記した資料がいくつか公開されています。何か手をつけ始めるには最適なステップです。下記のリストを確認し、組織内にそのソフトウェアが存在するかどうかを判断してください。もし存在するならば、最新のパッチを適用していることを確認してください。
- Log4j の影響を受けるデータベース | https://github.com/cisagov/Log4j-affected-db
- Log4j 関連ソフトウェア | https://github.com/NCSC-NL/log4shell/blob/main/software/README.md#software-overview
- Log4Shell セキュリティアドバイザリ | https://gist.github.com/SwitHak/b66db3a06c2955a9cb71a8718970c592
もう一つの識別方法は、内部と外部の脆弱性スキャンを実行することです。現在、脆弱性スキャンの多くは、脆弱な Log4j のインスタンスを識別するためのシグネチャまたはプラグインを提供しています。
脆弱性のある Log4j JAR ファイルを持つデバイスを特定するためには Sophos XDR を利用できます。Log4j は他のアプリケーションや依存関係に埋め込まれている可能性があるため、このクエリは、組織内で実行されている Java のインスタンスを特定するための出発点として機能します。
まず、サーバー上でこのクエリを実行し、組織内の Java の可能な使用方法を特定することを推奨します。これらのクエリは、オペレーティングシステム (OS) に関係なく実行できます。
SELECT DISTINCT name, cwd, cmdline
FROM processes
WHERE (cmdline LIKE '%Log4j%' OR cmdline LIKE '%java%')
AND LOWER(cwd) NOT IN ('c:\windows\', 'c:\windows\system32\', '/')
上記のクエリを拡張した後、以下のクエリで Log4j ライブラリの脆弱性があるバージョンを列挙することができます。このクエリは、実行中の Java プロセスの作業ディレクトリを再帰的に検索し、「Log4j%.jar」という名前のファイルを特定します。
注:このクエリは、Log4j が他のサードパーティの JAR ファイルにバンドルされている場合や、非標準の名前の JAR ファイルである場合、インスタンスを見逃してしまうことがあります。しかし、問題を引き起こす可能性のある脆弱性の初期トリアージを行うには有効です。
WITH java_processes AS (
SELECT DISTINCT name, cwd, cmdline
FROM processes
WHERE (LOWER(cmdline) LIKE '%log4j%' OR LOWER(cmdline) LIKE '%java%')
AND LOWER(cwd) NOT IN ('c:\windows\', 'c:\windows\system32\', '/')
)
SELECT
p.name,
p.cwd,
p.cmdline,
f.path,
f.directory,
f.filename,
CASE
WHEN f.filename LIKE 'log4j-1%' THEN 'log4j 1.X is no longer maintained supported, but is not vulnerable to CVE-2021-44228'
WHEN f.filename LIKE 'log4j-%-2.17.%.jar 'THEN' Patched against CVE-2021-44228 #log4shell, CVE-2021-45046, and CVE-2021-45105 and on the latest version'
WHEN f.filename LIKE 'log4j-%-2.16.%.jar 'THEN 'Patched against CVE-2021-44228 #log4shell and CVE-2021-45046, but susceptible to CVE-2021-45105. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.15.%.jar 'THEN 'Patched against CVE-2021-44228 #log4shell, but susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.14.%.jar 'THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.13.%.jar 'THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.12.%.jar 'THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.11.%.jar 'THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.10.%.jar 'THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.9.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.8.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.7.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.6.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.5.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE 'log4j-%-2.4.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE' log4j-%-2.3.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE' log4j-%-2.2.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
WHEN f.filename LIKE' log4j-%-2.1.%.jar' THEN 'Not Patched against CVE-2021-44228 #log4shell and susceptible to CVE-2021-45046. Upgrade to log4j 2.17.0'
ELSE' Unknown version or unrecognized filename, need to investigate manually'
END AS patch_status
FROM
java_processes p
JOIN
file f
WHERE
f.path LIKE p.cwd || '%%'
AND f.filename LIKE 'log4j%.jar'
ネストされた JAR ファイルの課題を解決するために、ローカルスキャナーを使用して、ファイルシステム上に存在する脆弱な Log4j ライブラリを列挙できます。これを目的として、いくつかのオープンソースプロジェクトがリリースされています。上記で確認した、Java プロセスが動作しているすべてのシステムに対して、以下のオープンソースツールを使用して、より詳細なスキャンを実施できます。
- https://github.com/CERTCC/CVE-2021-44228_scanner
- https://github.com/fox-it/Log4j-finder
- ツールの実行方法の詳細は、こちらの「ダウンロードと実行」のセクションに記載されています。
脆弱性があるバージョンの更新
最も完璧な緩和策は、発見された脆弱な Log4j ライブラリを更新しパッチを適用することですが、当然ながら、すべてのシナリオでこれが可能なわけではありません。この記事を書いている時点では、2.16.0 が最新のバージョンです。最新の Log4j の脆弱性の修正に関する詳細な情報は、https://logging.apache.org/Log4j/2.x/security.html で確認できます。
2021 年 12 月 14 日、Log4j ライブラリに 2 つ目の CVE (CVE-2021-45046) が発見され、一部のデフォルト構成では 2.15.0 バージョンが有効でないことが判明しました。CVE-2021-44228 と CVE-2021-45046 の両方に対処するには、Log4j バージョン 2.16.0 にアップデートすることが推奨されます。アップデートが不可能な場合は、以下の章「その他の緩和策」を参照してください。
更新:現在判明している脆弱性の一覧と推奨される修正方法は以下の通りです。
- CVE-2021-44228 (CVSS スコア : 10.0) – Log4j 2.0-beta9 から 2.14.1 のバージョンに影響する、リモートコード実行の脆弱性 (バージョン 2.15.0 で修正されました
- CVE-2021-45046 (CVSS スコア : 9.0) – Log4j 2.0-beta9 から 2.15.0 (2.12.2 を除く) のバージョンに影響する、情報漏洩とリモートコード実行の脆弱性 (2.16.0 で修正されました)
- CVE-2021-45105 (CVSS スコア : 7.5) – Log4j 2.0-beta9 から 2.16.0 までのバージョンに影響する、サービス拒否の脆弱性 (バージョン 2.17.0 で修正されました)
Apache のガイダンスに従い、log4j のバージョンを 2.17.0 にアップグレードすることが推奨されます。
その他の緩和策
Log4j ライブラリの更新や識別が不可能な場合、または万が一の場合に備えて、以下の対策をご検討ください。
- この攻撃では、悪意のある Java のクラスをロードするために、感染したホストが敵の悪意のある LDAP サーバーに、最初のアウトバウンド接続を行うことが必要です。LDAP、LDAPS、および RMI の標準ポート (389、636、1099、1389) をブロックすると、ポートがランダムになる可能性があるため網羅的ではありませんが、攻撃対象領域を縮小できます。
- IPS と WAF は、この攻撃に有効な別の回避手法であるために包括的でないことが示されていますが、それでも検出と対応を手助けするために実装する必要があります。
- Log4j の脆弱なバージョンをアップグレードできない場合、2.16.0 以外のリリースでは、以下のクラスパスから JndiLookup クラスを削除できます。
zip -q -d Log4j-core-*.jar org/apache/logging/Log4j/core/lookup/JndiLookup.class
注:以前推奨されていた、「Log4j2.formatMsgNoLookups」プロパティの設定や環境変数「LOG4J_FORMAT_MSG_NO_LOOKUPS」の True への設定は、効果がないことが確認されたため、現在では推奨されていません。
モニタリングと脅威ハンティング
log4j の使用状況を完全に把握することは困難ですが、以下のデータレイククエリを使用することで、疑わしいプロセスやネットワーク接続を探索できます。
Java による不審なプロセスの生成
以下のデータレイククエリは、調査すべき Java の疑わしい子プロセスを列挙します。これらは、脆弱性のある log4 インスタンスの悪用に成功したことを示す可能性があります。疑わしいコマンドはさらに調査する必要があります。
Windows
SELECT
meta_hostname,
parent_path,
parent_sophos_pid,
path,
sophos_pid,
cmdline
FROM xdr_data
WHERE query_name = 'running_processes_windows_sophos'
AND LOWER(parent_name) = 'java.exe'
AND name IN (
'cmd.exe',
'powershell.exe',
'rundll32.exe',
'whoami.exe',
'certutil.exe',
'ipconfig.exe',
'net.exe'
)
Linux
注:親子関係を再構築する必要があるため、プロセス ID の再利用により結果に矛盾が生じる可能性があります。
SELECT DISTINCT
X3.meta_hostname AS ep_name,
X3.meta_os_platform,
replace(replace(CAST(from_unixtime(X3.time) AS VARCHAR),'.000','Z'),' ','T') Date_Time, -- add the T to help excel understand this is a date and time
X3.name,
X3.cmdline,
X3.path,
S1.Single_PID||':'||CAST(X3.time AS VARCHAR) AS sophos_pid,
S1.Single_PID pid,
X4.name Child_Name,
X4.cmdline Child_cmdline,
X4.path Child_Path,
-- WE DID NOT unnest the PIDS so are only showing FIRST PID
SPLIT_PART(X4.pids,',',1)||':'||CAST(X4.time AS VARCHAR) AS Child_Sophos_PID,
SPLIT_PART(X4.pids,',',1) Child_PID,
P1.Single_Parent||':'||CAST(X4.time AS VARCHAR) AS Child_Parent_Sophos_PID,
P1.Single_Parent Child_Parent_PID,
X3.query_name
FROM xdr_data X3 CROSS JOIN UNNEST(SPLIT(X3.pids,',')) AS S1 (Single_PID)
LEFT JOIN xdr_data X4 CROSS JOIN UNNEST(SPLIT(X4.parents,',')) AS P1 (Single_Parent) ON P1.Single_Parent = S1.Single_PID
AND X4.query_name = 'running_processes_linux_events'
AND X3.meta_boot_time = X4.meta_boot_time -- Try and avoid PID collisions
AND X4.time <= X3.time
AND LOWER(X4.name) IN ('sh', 'bash', 'dash', 'ksh', 'zsh', 'curl', 'wget')
WHERE X3.query_name = 'running_processes_linux_events'
AND LOWER(X3.name) = 'java'
予期しないアウトバウンドネットワークトラフィック
このクエリは、LDAP、RMI、および DNS 標準ポート (389、636、1099、1389、53、5353) 上の Java プロセスからの異常なトラフィックを識別するのに役立ちます。これは、プロトコルの標準ポート上の RFC1918 以外のアドレスを宛先とするトラフィックを探すものです。また Log4j の脆弱なバージョンが敵の LDAP サーバーに通信を試みているデバイスを特定するのにも役立ちます。正規のトラフィックも識別される場合あるため、結果はバリデートする必要があります。
Windows / Linux / OSX
SELECT
meta_hostname,
name,
cmdline,
pid,
parent,
path,
remote_address,
remote_port,
local_address
FROM
xdr_data
WHERE
query_name = 'open_sockets'
AND (LOWER(name) = 'java.exe' OR LOWER(name) = 'java')
AND remote_port IN (389, 636, 1099, 1389, 53, 5353)
AND remote_address NOT LIKE '10.%'
AND remote_address NOT LIKE '192.168.%.%'
AND remote_address NOT LIKE '172.16.%.%'
AND remote_address NOT LIKE '172.17.%.%'
AND remote_address NOT LIKE '172.18.%.%'
AND remote_address NOT LIKE '172.19.%.%'
AND remote_address NOT LIKE '172.20.%.%'
AND remote_address NOT LIKE '172.21.%.%'
AND remote_address NOT LIKE '172.22.%.%'
AND remote_address NOT LIKE '172.23.%.%'
AND remote_address NOT LIKE '172.24.%.%'
AND remote_address NOT LIKE '172.25.%.%'
AND remote_address NOT LIKE '172.26.%.%'
AND remote_address NOT LIKE '172.27.%.%'
AND remote_address NOT LIKE '172.28.%.%'
AND remote_address NOT LIKE '172.29.%.%'
AND remote_address NOT LIKE '172.30.%.%'
AND remote_address NOT LIKE '172.31.%.%'
--Exclude localhost
AND remote_address NOT LIKE '127.%.%.%'
--Exlude self-signed IP Addresses
AND remote_address NOT LIKE '169.254.%.%'
AND remote_address NOT LIKE '-'
AND remote_address NOT LIKE '::1'
AND remote_address NOT LIKE '%::%'
本記事の執筆にあたり、Managed Threat Response チームのメンバー (Tyler Wojcik) に協力して頂きました。
リソース
関連する CVE/strong>
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046
Apache のセキュリティログ
Sophos Central Live Discover