Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
log4j-check — log4j 2025/2026 年 7 条「配置静默失效」CVE 自查:按 CVE×模块 判定 4 个模块,结构化解析 log4j2 配置做 applicability 降噪,并算出该升到哪个版本才一次到位(6 条写 2.25.4,但有一条要 2.25.5,而它 Dependabot 报不出来) CVE-2026-49844 / CVE-2026-34477 | Kitploit
Tools/GitHubGitHub/xiaoqimikko/log4j-check
Vulnerability ScannersVulnerability AnalysisConfiguration AuditingDevSecOpsSupply Chain Security
GitHubxiaoqimikko/log4j-check

log4j-check

log4j 2025/2026 年 7 条「配置静默失效」CVE 自查:按 CVE×模块 判定 4 个模块,结构化解析 log4j2 配置做 applicability 降噪,并算出该升到哪个版本才一次到位(6 条写 2.25.4,但有一条要 2.25.5,而它 Dependabot 报不出来) CVE-2026-49844 / CVE-2026-34477

View Repository
1 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
Content not available in the requested language. Showing English version.

log4j-check

log4j 2025/2026 年这批「配置静默失效」公告的自查工具。 零运行时依赖,单个 jar,不联网。

⚠️ 先把口径说清楚:这批全是 medium,一条 RCE 都没有,不是 Log4Shell 那种。 它们的共同点是 配置在没有任何报错的情况下失效了 —— 属性被静默忽略、 属性被静默改名、日志被静默丢掉。所以光看版本号看不出你到底中没中,要读配置。 如果你在找 CVE-2021-44228(Log4Shell),这个工具帮不了你。

java -jar log4j-check.jar app.jar          # fat jar 里带配置,一步到位
java -jar log4j-check.jar ./target ./src   # 构建产物 + 源码
java -jar log4j-check.jar ~/.m2/repository --no-config

它回答什么问题

Dependabot 告诉你「log4j 有 N 个漏洞」。这个工具回答三个它不回答的:

  1. 你到底该升到哪个版本? —— 不是照抄某一条 advisory,是把命中的条目逐条求交集。
  2. 这 7 条里你真中几条? —— 每条都要求你用了某个特定的 layout / appender, 而那些东西写在 log4j2.xml 里,能读,而且能读准。
  3. 你是不是属于「已经升过级、以为修完了」的那批人? —— 这批里有两条补丁缺口链。

三个承重结论(都可以自己复核)

一、🔥 升到 2.25.4 的人没升到位(漏掉的那条,曾经 Dependabot 也报不出来)

这批 7 条里,6 条的修复版都 ≤ 2.25.4。于是绝大多数人会得出「升到 2.25.4」这个答案。

但 CVE-2026-49844 要 2.25.5(2.26 线上要 2.26.1)。它的 advisory 原文写着自己是 CVE-2026-34481 的不完整修复:

The fix released in version 2.25.4 did not cover all affected code paths. CVE-2026-49844 was assigned to the remaining issue …

📌 更正(2026-08-16)

本节原本写着「而这一条恰好是 Dependabot 结构性报不出来的那一条」—— 那句话现在只对一半。

GHSA-qv9r-c865-cp47 已于 2026-08-13 被 GitHub 转为 reviewed 并补齐包信息, 补上的两个区间是 >= 2.13.1, < 2.25.5 和 >= 2.26.0, < 2.26.1:

  • ✅ 跑 2.x 的人,现在收得到 Dependabot 告警了。
  • 🔴 但 3.x 预览线(3.0.0-alpha1 ~ 3.0.0-beta2)至今没有对应区间,那条线仍然报不出来。

升级结论完全没变 —— log4j-api 仍然要 2.25.5(2.26 线要 2.26.1)。 变的只是「机器看不看得见它」。本工具的判定表已按版本线逐条更新,报告里印的数字由表算出,不再硬编码。

🔑 这件事本身比原来那个例子更值得记:advisory 的形态会随时间被上游补齐, 而你上一次扫描的结论不会自己更新,也不会有人通知你。 「当时扫过了」和「现在是安全的」,是两件事。

它的 GitHub advisory(GHSA-qv9r-c865-cp47)在 2026-08-13 之前是 unreviewed, 且 vulnerabilities 数组为空 —— 没有包名、没有版本区间、没有修复版, 那段时间 Dependabot 拿不到任何可以跟你的依赖树比对的数据。

在 OSV.dev 上当时同样如此:另外 6 条都能通过 GHSA alias 拿到 Maven 坐标,只有它拿不到 (它在 OSV 里连 GHSA alias 都没有)。这是第三个源上的独立佐证, tools/recheck_before_publish.py 每次重跑都会重新核实 (该脚本现在也会把「已经补齐」这件事本身报出来)。

🔴 这一条别读成「Dependabot 不好用」。 它是「这条数据当时不存在」,不是「这个工具有 bug」。 unreviewed 是 GitHub 的正常流程状态,而 08-13 的补齐正是那个流程在正常走完。

另一条链是 CVE-2025-68161(2.25.3)→ CVE-2026-34477(2.25.4): verifyHostName 属性自 2.12.0 引入,却一路到 2.25.3 都被静默忽略, 配了等于没配。照 68161 升到 2.25.3、且用属性(而不是 system property)配主机名校验的人,仍然中招。

二、判定粒度是 CVE × 模块,共 4 个模块

模块命中条目该升到
log4j-core34477 / 34478 / 34480 / 681612.25.4
log4j-api498442.25.5(2.26 线:2.26.1)
log4j-1.2-api344792.25.4
log4j-layout-template-json344812.25.4

目标版本不是同一个数字。 而绝大多数项目的 pom 里只写 log4j-core —— 按那一个坐标反查只查得到 4 条,另外 3 条对他们来说根本不存在。

这个工具把四个模块分别扫出版本并分别判定。四个模块版本错开时(BOM 覆盖、 手工排除、老 WAR 里塞着两代 jar)它会明确报出来。

三、降噪:每条都要求特定的 layout / appender,而那写在配置里

CVE触发条件(取自官方原文)
CVE-2026-34477<Ssl> 的 verifyHostName 属性 + Socket / Syslog / SMTP appender
CVE-2025-68161SocketAppender + TLS
CVE-2026-34478直接配 Rfc5424Layout(用 SyslogAppender 的不受影响)
CVE-2026-34480log4j-core 的 XmlLayout
CVE-2026-34479桥的 Log4j1XmlLayout,或 log4j 1 兼容层 + org.apache.log4j.xml.XMLLayout
CVE-2026-34481JsonTemplateLayout + MapMessage/ObjectMessage 里的浮点值
CVE-2026-49844JsonTemplateLayout 的 message resolver,或 MapMessage.asJson()

实测(真实构件,见下):同一套装了受影响版本的四个模块,

  • 配置是最常见的那种(Console + RollingFile + PatternLayout)→ 版本层报 7 条,真中 0 条
  • 配置里有 Socket+<Ssl verifyHostName>+Rfc5424Layout+XmlLayout → 报 7 条,真中 4 条

两个负判据是官方原文明说的,单独成档: 用 SyslogAppender 的不中 34478;只用 HTTP appender 的 verifyHostname 的不中 34477。 这一档和「我没找到」的可靠程度完全不同 —— 前者有原文背书,后者只是我们没看见。

🔴 verifyHostName(大写 N,<Ssl>,中招)与 verifyHostname(小写 n,HTTP appender, 官方写明不受影响**)只差一个字母的大小写,结论完全相反。** 同理 XmlLayout(34480,log4j-core)是 Log4j1XmlLayout(34479,桥)的子串。 只 grep 名字会让人额外背上不属于他的 CVE。所以配置层做结构化解析而不是文本匹配。

它怎么读你的配置

格式怎么读能不能判准属性归属
log4j2*.xml(含 strict 模式 <Appender type="…">)DOM 解析,XXE 已关✅
log4j2*.properties按 xxx.type = Foo 建前缀→插件映射✅
log4j2*.yaml / .json文本匹配(JDK 无 YAML 解析器,而本工具坚持零依赖)❌ 标为「文本依据」
.java文本匹配(已剥注释,认字符串)❌

配置在归档内部也扫(BOOT-INF/classes/、WEB-INF/classes/), 所以只丢一个 Spring Boot fat jar 给它,降噪也做得成 —— 不需要源码树。

log4j-spring.xml / log4j2-test.xml / log4j.xml(1 兼容层)都认。

🔴 这个报告不能证明什么

「没找到触发条件」不等于安全,至少四种情况会让它变成假的安心:

  1. 配置是代码里构建的(ConfigurationBuilder / Configurator.initialize);
  2. 配置运行时才注入(log4j2.configurationFile 指别处、容器里挂进来);
  3. 第三方库自带一份 log4j2 配置而没被扫到;
  4. 你压根没把配置传进来 —— 这种情况报告会单独标成「本次没看到配置」, 而不是「不适用」。这两句话该导致完全不同的动作。

「触发条件全部成立」也不等于确认中招:多数条目还要求「攻击者能控制被记进日志的那个值」, 这一点工具判不了。所以结论只够用来排优先级,不够用来宣布事故。

本工具不覆盖 log4j 1.x(log4j:log4j)。扫到会告警,但不判定 —— 它是另一套代码。

判定表是生成的,不是手抄的

python tools/gen_rules.py          # 从两个一手源重建 CveTable.java + Triggers.java
  • 源 A = Apache 官方 CycloneDX VDR(logging.apache.org/cyclonedx/vdr.xml)—— 条目全集 + 逐模块精确区间 + 描述原文。

    🔴 /repos/apache/logging-log4j2/security-advisories 实测返回 0 条 —— Apache 不走 GitHub Security Advisories。只查那个端点会得到「log4j 很太平」,而且不报错。

  • 源 B = GitHub advisory DB 按坐标反查(= Dependabot 实际用的索引),四个模块各查一次。

17 条断言,任一不满足就中止不写文件。其中几条是承重的:

断言钉住的事
ASSERT2双源盲区:官方 7 条 vs 单坐标 4 条 vs 四坐标 6 条,三个数字都要量出来
ASSERT13那 1 条结构性盲区必须能给出可复核的理由,不许写死在文案里
ASSERT7每个修复版去 Central 实测 + 负对照(证明探测器真会说「拿不到」)
ASSERT8修复版是从区间上界推导的 → 必须逐字出现在官方 recommendation 原文里
ASSERT9两条补丁缺口链的原文措辞 + 后一环修复版必须真的更高
ASSERT10照最常见的修复版升级必须仍有漏 —— 否则「求交集」没价值
ASSERT14XmlLayout≠Log4j1XmlLayout、verifyHostName≠verifyHostname,正反样本各测一次
ASSERT17描述原文必须是完整句子,不是被 asciidoc 硬换行折断的残句

验证做到哪一步

  • 93 个单测,含报告渲染层的测试(不只测内部返回值,测印出来的字)
  • 12 个真实构件场景:14 个从 Maven Central 下的真 jar 拼成 Spring Boot fat jar / WAR / 裸 m2 目录 / 源码树,端到端跑
  • 发文前独立口径复核(tools/recheck_before_publish.py): 不读生成脚本的任何输出,换三个源(OSV.dev / 官方安全网页 / Maven Central)重新算一遍

真实构件复验抓到 3 个单测测不出的问题,都已修 + 加回归:

  1. 真 log4j-api jar 里自带 Log4j-charsets.properties,被当成了用户的 log4j2 配置 → 「本次没看到配置」被翻译成「看过了,没找到」,而只要 classpath 上有 log4j-api, 这个翻译就一直在发生。
  2. 一个标着「触发条件成立的:N 条」的数字把部分成立也算了进去 —— 而这个数字是本工具唯一的卖点。现在拆成两个。
  3. 纯 YAML 配置的命中被印成「结构化解析,依据最硬」—— 那份配置从头到尾没有被结构化解析过一次。

退出码

码含义
0版本没中,并且每个文件都真的读进去了
2版本中,但配置里没找到触发条件(或本次没看到配置)
3触发条件也成立
4有文件读不动 —— 不是 zip、内容截断、或读取失败

🔴 4 是 2026-09-09 加的。 在此之前,读不动的文件只在输出里留一行提示,而退出码照旧是 0 —— 留痕是给人看的,CI 和脚本看的是退出码,于是「我没能读它」在自动化里等于「通过」。 「我读不动它」和「你是安全的」必须是两句话。

⚠️ 合法的空 jar 不算读不动(一条 22 字节的 EOCD 记录是一个真的空 zip),不会触发 4。 ⚠️ 4 只在版本没中时出现:真判出问题(2 / 3)比读不动更要紧,不会被它盖掉。

构建

JDK 17+,mvn package。运行时零依赖 —— 尤其不依赖 log4j 本身: 一个排查 log4j 配置问题的工具自己带着一份 log4j,会在扫自己的目录时把自己报出来。

一手来源

  • Apache Log4j 安全公告:https://logging.apache.org/log4j/2.x/security.html
  • CycloneDX VDR:https://logging.apache.org/cyclonedx/vdr.xml
  • CVE-2026-34477 https://github.com/advisories/GHSA-6hg6-v5c8-fphq
  • CVE-2026-34478 https://github.com/advisories/GHSA-445c-vh5m-36rj
  • CVE-2026-34479 https://github.com/advisories/GHSA-h383-gmxw-35v2
  • CVE-2026-34480 https://github.com/advisories/GHSA-3pxv-7cmr-fjr4
  • CVE-2026-34481 https://github.com/advisories/GHSA-w35j-pv5h-q9q9
  • CVE-2026-49844 https://github.com/advisories/GHSA-qv9r-c865-cp47 ← 2026-08-13 已转 reviewed 并补齐 2.x 区间;3.x 线仍无覆盖
  • CVE-2025-68161 https://github.com/advisories/GHSA-vc5p-v9hr-52mj

Apache License 2.0


需要更进一步的排查?

这个工具回答的是「我中没中」。下面这些它答不了,可以找我做:

  • 依赖被 shade / relocate 过,或者构建产物根本拿不到
  • 要判的是「这条 CVE 在我们的调用链上到底会不会触发」,而不只是版本命中
  • 要按你们自己的构建流程或内网环境做定制、接进现有流水线
  • 手上是另一个组件的同类问题,还没有现成工具

📮 [email protected] —— 说清情况,我 24 小时内给你一页书面答复: 能不能做、难在哪、大概多久。这一步免费,也不用你先承诺什么。

Download Tool