Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
log4j-jndi-be-gone — 一个基于 Byte Buddy Java agent 的修复方案,用于修复 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 agent 的修复方案,用于修复 CVE-2021-44228,即 log4j 2.x 的"JNDI LDAP"漏洞。

查看仓库
721654年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

log4j-jndi-be-gone

一个基于 Byte Buddy Java agent 的修复方案,用于 CVE-2021-44228,即 log4j 2.x 的 "JNDI LDAP" 漏洞。

它做三件事:

  • 禁用 jndi: 格式字符串("lookups")的内部方法处理器。
  • 向 System.err(即 stderr)记录一条消息,表明发生了 log4j JNDI 尝试(包括尝试的格式字符串,其中任何 ${} 字符均被清理以防止传递注入)。
  • 将格式字符串解析为日志消息中的 "(log4j jndi disabled)"(以防止传递注入)。

使用方法

将 -javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar 添加到你的 java 命令中。

注意: 如果你的 classpath 中已有 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 中的重新打包(即 "shaded")版本的 log4j,以避免应用程序的依赖版本与某个依赖自身的相同依赖版本之间发生冲突。但需要注意的是,由于使用了带有静态类名和/或来自嵌入式配置文件的类名的反射,log4j 似乎不容易在备用包名/前缀下重新打包。

可以通过在 -javaagent: 参数中的 agent 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

你可以使用 ./gradlew 构建 JAR(build/libs/log4j-jndi-be-gone-1.0.0(-standalone).jar),或者从 releases 页面 获取。

兼容性

log4j-jndi-be-gone agent 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 中的单参数版本)
  • 方法 convertJndiName(),匹配其修饰符和类型签名
  • 字段 CONTAINER_JNDI_RESOURCE_PATH_PREFIX,匹配其修饰符

注意事项

  • 如果 log4j 库已被混淆,或者其类包/名称除基本重新打包(即 "shading")之外被修改,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 standalone 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
下载工具