Overview
Blocky is an Easy-rated Linux machine hosting a Minecraft community website built on WordPress 4.8. The box teaches a lesson that penetration testers encounter constantly in real engagements: custom application code is almost always a higher-value target than framework CVEs.
No WordPress vulnerability is exploited. Instead, a custom Minecraft plugin
JAR file exposed via Apache directory listing contains hardcoded MySQL
credentials in a public Java field. That password works for SSH as the
notch user, who happens to be in the sudo group. Root follows in one
command.
Reconnaissance
I start with a service scan:
nmap -sC -sV 10.129.13.88
| Port | Service | Product / Version | Notes |
|---|---|---|---|
| 21 | FTP | (unknown) | No banner grabbed |
| 22 | SSH | OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 | Ubuntu 16.04 |
| 80 | HTTP | Apache httpd 2.4.18 (Ubuntu) | Redirects to blocky.htb |
After adding blocky.htb to /etc/hosts, the site loads: a WordPress 4.8
installation with the TwentySeventeen theme, titled “BlockyCraft: Under
Construction!”. It is a Minecraft server community site.
Attack Surface Analysis
User enumeration
WordPress author enumeration via ?author=1 reveals the user notch (the
Minecraft creator’s handle). This gives us a target username for credential
testing.
Plugin discovery
A custom “Cute file browser” page at /plugins/ exposes /plugins/files/
with Apache directory listing enabled:
BlockyCore.jar 2017-07-02 883 bytes
griefprevention-1.11.2-3.1.1.298.jar 2017-07-02 520K
BlockyCore.jar is 883 bytes. That is tiny for a Java application; it is
almost certainly a configuration class with minimal logic.
Vulnerability Analysis
The WordPress installation itself has no obvious vulnerabilities. WPScan would identify the version (4.8) and theme (TwentySeventeen), but the interesting attack surface is not the CMS; it is the custom plugin.
I download and decompile the JAR:
wget http://blocky.htb/plugins/files/BlockyCore.jar
jar tf BlockyCore.jar
# META-INF/MANIFEST.MF
# com/myfirstplugin/BlockyCore.class
javap -c -p com.myfirstplugin.BlockyCore
public class com.myfirstplugin.BlockyCore {
public String sqlHost = "localhost";
public String sqlUser = "root";
public String sqlPass = "8YsqfCTnvxAUeduzjNSXe22";
}
Hardcoded MySQL credentials stored as public fields. No encryption, no
configuration file indirection, no environment variable lookup. The
onPlayerJoin() method has a TODO comment for username retrieval, confirming
this is development-quality code deployed to production.
The vulnerability here is not technical complexity; it is operational carelessness. The same pattern appears in production codebases regularly: database credentials embedded directly in application source.
Exploitation
Credential reuse: SSH as notch
The MySQL root password works for SSH as notch:
ssh [email protected]
# Password: 8YsqfCTnvxAUeduzjNSXe22
id
# uid=1000(notch) gid=1000(notch) groups=1000(notch),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)
The user flag is at /home/notch/user.txt. The group memberships are
immediately revealing: sudo (gid=27) provides direct root access, lxd
(gid=110) provides container escape, and adm (gid=4) provides log file
access for credential harvesting. Three independent escalation paths from
a single credential reuse finding.
Privilege escalation: sudo group
notch is a member of the sudo group (gid=27). Full root access:
sudo -i
# Password: 8YsqfCTnvxAUeduzjNSXe22
Root flag at /root/root.txt.
Alternative escalation paths exist but are unnecessary: lxd group membership
(container escape) and adm group (log file access for credential harvesting).
Post-Exploitation
With root access, I enumerate the system to understand the full exposure:
uname -a
# Linux Blocky 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64
cat /etc/os-release | head -2
# NAME="Ubuntu"
# VERSION="16.04.2 LTS (Xenial Xerus)"
The WordPress database contains additional user hashes that could be cracked
for credential reuse testing against other systems. The MySQL instance is
accessible locally with the same root password. WordPress configuration at
/var/www/html/wp-config.php confirms the database credentials match:
grep DB_PASSWORD /var/www/html/wp-config.php
# define('DB_PASSWORD', '8YsqfCTnvxAUeduzjNSXe22');
The lxd group membership is worth noting. LXD container escape provides an
alternative root path that does not require knowing the user’s password.
The technique involves importing an Alpine image, mounting the host filesystem
into the container, and reading files as root from within. On this box it is
unnecessary, but in engagements where sudo requires a different credential,
the lxd group is an immediate escalation vector.
What a real attacker does next
In a production network, the post-exploitation checklist would include:
- Credential harvesting: WordPress password hashes from the database,
SSH keys in
/home/*/.ssh/, any credentials in application config files - Network reconnaissance:
arp -a,netstat -tlnp, internal DNS - Persistence: SSH key injection, cron job, WordPress admin backdoor
- Pivot: Minecraft server communities often run multiple game servers; the credentials may grant access to additional hosts
Defensive Analysis
Detection opportunities
| Phase | MITRE ATT&CK | Detection |
|---|---|---|
| Reconnaissance | T1083 | Web server access logs showing requests to /plugins/files/ |
| Credential access | T1552.001 | Static analysis: hardcoded credentials in committed JAR files |
| Lateral movement | T1078.003 | SSH login with database credentials (credential reuse) |
| Priv escalation | T1078.003 | sudo -i from a user account (audit sudo usage) |
Build pipeline: A secrets scanner (truffleHog, gitleaks, Semgrep) in the CI/CD pipeline would flag the hardcoded password in the Java source before the JAR is ever deployed.
Web server: Apache directory listing on the plugins directory is the entry
point. Disabling Options Indexes in the Apache configuration prevents
directory browsing entirely.
Authentication: SSH login from an unexpected source IP with a database credential is suspicious. Correlating SSH auth logs with database access logs would identify credential reuse.
Remediation
| Priority | Action | Effort | Impact |
|---|---|---|---|
| P0 | Rotate the MySQL root password and all reused credentials | Low | Critical |
| P0 | Remove hardcoded credentials from BlockyCore.jar; use environment variables or a config file outside the webroot | Low | Critical |
| P1 | Disable Apache directory listing (Options -Indexes) | Low | High |
| P1 | Remove notch from the sudo group unless administrative access is genuinely required | Low | High |
| P2 | Add a secrets scanner to the build pipeline | Medium | Medium |
| P2 | Implement key-based SSH authentication; disable password auth | Low | Medium |
| P3 | Remove notch from the lxd group | Low | Low |
The root cause is not a software vulnerability; it is an operational failure. Hardcoded credentials, password reuse across services, and overly permissive group membership are all configuration decisions, not bugs in third-party software.
Key Takeaways
-
Custom code is higher value than framework CVEs. BlockyCore.jar (883 bytes of custom code) contained the entire attack chain. No WordPress vulnerability was needed. Always prioritise source code analysis over blind exploitation.
-
Directory listings on plugin/upload paths are common misconfigurations. The
/plugins/files/directory had Apache autoindex enabled, exposing JAR files that were not linked from the application. A single Apache directive closes this gap. -
Credential reuse remains the most reliable lateral movement technique. Database credentials worked for SSH because the developer reused the same password across services. Unique, randomly generated credentials per service, stored in a secrets manager, would have stopped this chain entirely.
-
Excessive group membership compounds the impact. The
notchuser was insudo,lxd, andadmgroups simultaneously. Even if one escalation path is blocked, two alternatives remain. User group membership should follow least-privilege: only grant group access that is operationally required.