Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
log4j-jndi-be-gone — Byte Buddy Javaエージェントベースの修正、CVE-2021-44228(log4j 2.xの「JNDI LDAP」脆弱性)向け。 | Kitploit
ツール/GitHubGitHub/nccgroup/log4j-jndi-be-gone
防御ツール脆弱性分析コード分析エクスプロイトサプライチェーンセキュリティ
GitHubnccgroup/log4j-jndi-be-gone

log4j-jndi-be-gone

Byte Buddy Javaエージェントベースの修正、CVE-2021-44228(log4j 2.xの「JNDI LDAP」脆弱性)向け。

リポジトリを見る
721654年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
ウェブサイト

log4j-jndi-be-gone

Byte Buddy ベースのJavaエージェントによるCVE-2021-44228(log4j 2.xの「JNDI LDAP」脆弱性)の修正です。

次の3つのことを行います:

  • jndi: フォーマット文字列(ルックアップ)の内部メソッドハンドラを無効にします。
  • log4j JNDIの試行が行われたことを示すメッセージを System.err(stderr)に記録します(試行されたフォーマット文字列を含み、 ${} 文字はサニタイズされて転送インジェクションを防止します)。
  • ログメッセージ内でフォーマット文字列を "(log4j jndi disabled)" に解決します(転送インジェクションを防止するため)。

使用方法

-javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar を java コマンドに追加してください。

注意: 既にクラスパスにByte Buddyがある場合は、log4j-jndi-be-gone-1.0.0.jar を使用してみてください。

root@kitploit:~
$ java -javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar -jar path/to/some.jar

バージョン1.1.0以降、log4j-jndi-be-goneはデフォルトで、アプリケーションの依存関係と依存関係自身の依存関係との間の衝突を防ぐために、別のパッケージ名でJAR内に埋め込まれている可能性がある、リパッケージ(シェーディング)されたlog4jのバージョンを処理しようとします。ただし、log4jは、静的なクラス名や埋め込み設定ファイルからのクラス名を使ったリフレクションの使用により、別のパッケージ名/プレフィックスの下で簡単にリパッケージできないことに注意する必要があります。

この動作は、-javaagent: 引数のエージェントJARパスの後に =structureMatch=0 を置くことで無効にできます。例:

root@kitploit:~
-javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar=structureMatch=0

これにより、1.0.0と同じマッチング動作、つまりクラス名に対する単純な完全文字列比較が行われます。

log4j-jndi-be-goneの入手

JARは ./gradlew でビルドするか(build/libs/log4j-jndi-be-gone-1.0.0(-standalone).jar)、リリースページから入手できます。

互換性

log4j-jndi-be-goneエージェントJARはJava 6~17以上をサポートしています。

クラスマッチング

実装はまず、org.apache.logging.log4j.core.lookup.JndiLookup の最も内側のサブパッケージとクラス名に一致するサフィックスを持つクラス、つまり lookup.JndiLookup とのマッチングから開始します。これは、org.apache.logging.log4j.core がパッケージ名を保持しないリパッケージルールによって改変されている可能性が合理的に考えられるためです。さらに、他のすべての予想されるlog4jタイプに対して単に同様のチェックを実行するだけでなく、それらが同じベースパッケージの下に存在することも確認します。

次に実装は、特定された可能性のあるlog4jの lookup.JndiLookup クラスの構造を調べ、以下に対して検証を試みます:

  • クラス自体の修飾子
  • クラスの親クラスおよび/または実装されたインターフェース(これらはlog4jのバージョンによって異なります)
  • すべての2.xバージョンで期待される org.apache.logging.log4j.core.config.plugins.Plugin アノテーション(アノテーションパラメータとその値を含む)
  • メソッド lookup() (その修飾子と型シグネチャと照合し、2.0の1引数バージョンは無視)
  • メソッド convertJndiName() (その修飾子と型シグネチャと照合)
  • フィールド CONTAINER_JNDI_RESOURCE_PATH_PREFIX (その修飾子と照合)

注意事項

  • log4jライブラリが難読化されている場合、または基本的なリパッケージ(シェーディング)以外でクラスパッケージ/名前が変更されている場合、log4j-jndi-be-goneは動作しません。

    • ちなみに、log4j 2.xはリパッケージに関してかなり柔軟性が低いため、そのような慣行がどの程度一般的かは不明です。
  • log4j-jndi-be-gone-1.0.0-standalone.jar はByte Buddyをバンドルしています。すでにByte Buddyを使用している場合、問題が発生する可能性があります。代わりに log4j-jndi-be-gone-1.0.0.jar を使用してみてください。ただし、log4j-jndi-be-goneはByte Buddy 1.12.xを期待していることに注意してください。 バージョン1.1.0以降、log4j-jndi-be-goneのスタンドアロンJARは、独自のパッケージプレフィックスの下にリパッケージされたByte Buddyをバンドルしています。これにより、競合を防ぐことができます。

  • JndiLookup クラスをハニーポットや lookup() 呼び出しのログ記録を試みる実装に置き換えた場合、log4j-jndi-be-goneはそれらの lookup メソッドを無効にして動作しなくなる可能性があります。

使用例

tests/jnditest ディレクトリには、log4jのログ呼び出しがJNDI LDAPフォーマット文字列を渡す簡単なテストケースがあります。また、log4jによって接続試行が行われたかどうかを判断するために独自のポートリスナーを設定し、接続を受信した場合にテストを失敗とします。

root@kitploit:~
$ ./tests/jnditest/test-uninstrumented.sh

BUILD SUCCESSFUL in 1s
6 actionable tasks: 5 executed, 1 up-to-date

BUILD SUCCESSFUL in 1s
3 actionable tasks: 3 up-to-date
JUnit version 4.12
.16:08:49.547 [main] ERROR trust.nccgroup.jnditest.test.JndiTest - Hello, _${jndi:ldap://127.0.0.1:8899/evil}_!
E
Time: 0.929
There was 1 failure:
1) logging(trust.nccgroup.jnditest.test.JndiTest)
java.lang.AssertionError: jndi ldap connection received
	at org.junit.Assert.fail(Assert.java:88)
	at trust.nccgroup.jnditest.test.JndiTest.logging(JndiTest.java:55)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
	at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
	at trust.nccgroup.jnditest.Main.main(Main.java:24)

FAILURES!!!
Tests run: 1,  Failures: 1

$ ./tests/jnditest/test-instrumented.sh

BUILD SUCCESSFUL in 1s
6 actionable tasks: 5 executed, 1 up-to-date

BUILD SUCCESSFUL in 1s
3 actionable tasks: 3 up-to-date
JUnit version 4.12
.log4j jndi lookup attempted: (sanitized) ldap://127.0.0.1:8899/evil
16:09:06.064 [main] ERROR trust.nccgroup.jnditest.test.JndiTest - Hello, _(log4j jndi disabled)_!

Time: 1.362

OK (1 test)

ライセンス

Apache 2ライセンスの下でライセンスされています。

互換性

テスト済みJavaバージョン

log4j-jndi-be-goneは、OpenJDK 6、8、11、17、およびHotSpotおよびOpenJ9 JVMでテストされています。

テスト済みLog4jバージョン

  • 2.0
  • 2.0.1
  • 2.0.2
  • 2.1
  • 2.2
  • 2.3
  • 2.4
  • 2.4.1
  • 2.5
  • 2.6
  • 2.6.1
  • 2.6.2
  • 2.7
  • 2.8
  • 2.8.1
  • 2.8.2
  • 2.9.0
  • 2.9.1
  • 2.10.0
  • 2.11.0
  • 2.11.1
  • 2.11.2
  • 2.12.0
  • 2.12.1
  • 2.12.2
  • 2.13.0
  • 2.13.1
  • 2.13.2
  • 2.13.3
  • 2.14.0
  • 2.14.1
  • 2.15.0
  • 2.16.0
  • 2.17.0
ツールをダウンロード