Understanding Log4Shell -A Log4J Zero-Day Exploit

I am sure If you’re interested enough to read this blog, you are familiar with the zero-day exploit discovered recently in the log4j library which allows remote code execution. I believe we can agree that it is the most dangerous type of vulnerability. In this post, we’ll examine which applications are vulnerable, how this exploit works (with a demo application), and what actions you can take to protect yourself.

Who is vulnerable?

  • Applications using java versions older than 8u191, 7u201, 6u211, and 11.01.
  • Tries to log an input field with log4j.
  • trustURLCodebase is set to true for either ldap or rmi. (or have Tomcat 8+ or SpringBoot 1.2.x+ in classpath)
  • Using Log4j2 versions >= 2.0-beta9 and <= 2.14.1.

How does it work?

This exploit works by taking advantage of the JNDI (Java Naming and Directory Interface). JNDI is an API that provides naming and directory functionality for Java applications. It can work with registry services like RMI or directory services like LDAP. You can learn more about JNDI from the official oracle docs.

  1. As the first step, the attacker has to serve or mimic an LDAP or RMI server from a location that the target application server can reach and trust.
  2. After running the fake LDAP server with the malicious class in it, the attacker will find an endpoint that logs the input with a vulnerable version of Log4j and send a request to that endpoint which requires access to the attacker’s fake LDAP server. (e.g. “http://attacker.com/Malicious.class)
  3. After retrieving the request from the victim server, the attacker’s LDAP will serve a malicious class.
  4. After loading the Malicious.class, the victim server will execute it and enable the attacker to run any type of command on the server. Hence the name Remote Code Execution.

As soon as this exploit went public, people started to come up with different ideas and ways to take advantage of the situation. Some people are trying to use this vulnerability to run crypto miners on servers. It is not hard to imagine that this will also allow attackers to upload and run a reverse TCP payload to your server and use it to gain higher privileges. Now let’s take look at how it works in a demo project.

Demo Project

First things first, we need a server that we can direct our target. Luckily GitHub user welk1n created a simple server project that serves both RMI and LDAP endpoints. We can download, INSPECT, compile and run the source from here. We’ll set the command that we want to run as the parameter -C in quotation marks. You can see the example below.

Running the application that will server malicious class.

When you run this project, it will print out multiple endpoints for different kinds of servers. 
After we set our server, I’ll go ahead and create a basic application with a simple endpoint that logs the given input with log4j.

Application class with the system properties set for trustURLCodebase.
Example controller that logs the inputs retrieved from the request.

So, the issue begins when we run this server and call some of the example endpoints. It doesn’t have to be in the body or the header both can work. It doesn’t matter how you get your string into some logging method if you can achieve that this will work.

Calling a post request with a jndi request in the body.
Calling a GET request with jndi request in the header.

As you can see in both examples very clearly, when a request is sent to these endpoints after accessing the LDAP or RMI server, the retrieved piece of code ran on the server. This was an innocent touch command but in the wrong hands, it can be very dangerous.

Solution

The best and safest way to protect yourself from this is to upgrade your log4j library to 2.15.0-rc1. For those who can’t do that at the moment, there are some workaround fixes.

  • You can modify all logging patterns you’re using with %m{nolookups}.
  • You can pass ‐Dlog4j2.formatMsgNoLookups=True in the startup JVM command. This will prevent the whole project from using look-ups within Log4j.
  • You can create an empty or modified implementation of org.apache.logging.log4j.core.lookup.JndiLookup and modify your project to use your empty implementation instead of the default one.

Conclusion

This is a nasty vulnerability we’re facing today because of the widespread use of the log4j in the industry, discovering a vulnerability that allows RCE for the latest version on a popular library is pretty scary if you ask me. Fortunately, the community that builds these libraries and solutions is also supporting and responsive during these types of crises.

I hope everyone will quickly respond to the issue and update their projects so we can exterminate this pandemic.

Sources & Projects

You can get the test project source codes from here:

GitHub – cagdasalagoz/SpringBoot-log4shell
This is a vulnerable application for log4shell vulnerability. You can use these curl requests to test it. curl…github.com

GitHub – welk1n/JNDI-Injection-Exploit: JNDI注入测试工具(A tool which generates JNDI links can start…
Materials about JNDI Injection JNDI-Injection-Exploit is a tool for generating workable JNDI links and provide…github.com

Digging deeper into Log4Shell – 0Day RCE exploit found in Log4j
This vulnerability is actively being exploited in the wild, allows remote code execution, and is trivial to exploit…www.fastly.com

Log4Shell: RCE 0-day exploit found in log4j2, a popular Java logging package | LunaSec
· 7 min read Updated @ December 10th, 10am PST A few hours ago, a 0-day exploit in the popular Java logging library…www.lunasec.io

Leave a Reply