HTB - Dyplesher

Zweilosec's write-up of the Insane difficulty Linux machine from https://hackthebox.eu

Overview

Dyplesher was an insane difficulty Linux machine that tested both web enumeration skills, and code review and writing skills. Multiple Git repositories containing source code, the Memcache service, and a Minecraft server were all exploited to gain access to this machine. I learned quite a bit about the inner workings of a Minecraft server and how their plugins work during the course of this challenge!

Useful Skills and Tools

Recreating a git repository from a GitLab export .bundle file

Gitlab exports a tar.gz archive which contains .bundle files for each project. You can convert these files into a normal git repository using the following steps:

  • From releases page download the export archive containing .bundle files

  • Extract each .bundle file

  • Restore the .bundle to a git repository

    • Make a new directory and clone the repository into it

    • Change directories to repository folder, then initialize and checkout the repository

  • Check the contents of your restored repository

Initial credit to https://gist.github.com/maxivak/513191447d15c4d30953006d99928658. https://gist.github.com/paulgregg/181779ad186221aaa35d5a96c8abdea7 for updated instructions to recreate repository

Enumeration

Nmap scan

I started my enumeration with an nmap scan of 10.10.10.190. The options I regularly use are: -p-, which is a shortcut which tells nmap to scan all ports, -sC is the equivalent to --script=default and runs a collection of nmap enumeration scripts against the target, -sV does a service scan, and -oA <name> saves the output with a filename of <name>.

My scan showed that there were lots of ports open. The table below shows the information that I pulled out that seemed the most relevant.

Port

Description

22

OpenSSH 8.0p1 Ubuntu 6build1 (Ubuntu Linux; protocol 2.0)

80

Apache httpd 2.4.41 ((Ubuntu))

http-title: Dyplesher

3000

"Gogs is a painless self-hosted Git service"

4369

Erlang Port Mapper Daemon

nodes: rabbit: 25672

5672

amqp RabbitMQ 3.7.8 (0-9)

See http://www.rabbitmq.com/

| platform: Erlang/OTP 22.0.7

| product: RabbitMQ

| version: 3.7.8

| mechanisms: PLAIN AMQPLAIN

11211

memcached default port

25565

Minecraft default port

25672

Erlang Port Mapper above reveals this to be RabbitMQ related

There were also two unknown ports: 25562 and 25572. I was quite curious about the Erlang Port Mapper and RabbitMQ since I had never dealt with those before, but I decided to enumerate the HTTP service on port 80 first.

Port 80 - HTTP

On port 80 there was a Minecraft server hosted called the "Worst Minecraft Server". There was not much information on the page itself, other than a virtual host notated at test.dyplesher.htb, which I added to my hosts file and navigated to.

At test.dyplesher.htb there was a page where I could enter a key/value pair which would be inserted into the local memcache, and the page would tell me whether the key and value were equal to each other. After playing around with adding different pairs I decided to move on.

I found a link to the website staff, which led to a page with 3 potential users. There was a link under each username which pointed to http://dyplesher.htb:8080/. I added dyplesher.htb to my hosts file and tried to navigate to the first one http://dyplesher.htb:8080/arrexel but port 8080 was not open.

In the source code of the page I found an app.js; at the bottom of the code found a path C:\Users\felamos\Documents\tekkro\resources\js\app.js which looks like a Windows path (I thought this was a linux machine?) I figured that this pointed towards this machine requiring cross-compilation of code later on. The path also referenced the username felamos which I had seen earlier. It looks like this may be the site's developer.

Searching for tekkro led to https://tekkitserverlist.com/server/0fOnRygu/tekkro-tekkit-classic, which refers to a mod pack for Minecraft called Tekkit Classic which seems to possibly be quite outdated since it was last updated in May of 2018.

https://tekkitclassic.fandom.com/wiki/The_Tekkit_Wiki

Created by the Technic team, Tekkit Classic is a modpack for the record breaking sandbox construction game Minecraft. It brings together some of the best mods from the Minecraft community for automating, industrializing and powering your worlds and bundles them into one easy download!

Tekkit Classic runs on a base of Minecraft 1.2.5 and has Bukkit inbuilt, so the full range of Bukkit Pluggins are available for server owners.

This potentially reveals the version of this Minecraft server as 1.2.5.

The .git repository

While scanning with dirbuster, I found a .git folder. Browsing to this folder resulted in getting denied, so next I tried using git-dumper.py like I did in the Hack the Box machine Travel.

Using git-dumper.py I was able to dump the contents of the git repository, and started searching through the source code.

In the file index.php there were credentials for felamos:zxcvbnm and access information for a memcached server. I did some research to see if there was a way to access this remotely and found https://techleader.pro/a/90-Accessing-Memcached-from-the-command-line, which describes how to access memcache through the command line.

This is source code for the page I saw hosted at test.dyplesher.htb, and it did exactly what I thought.

Enumerating memcached

Unfortunately telnet did not work as described in the article. Next I tried a tool I found on GitHub called memclient from https://github.com/jorisroovers/memclient.

The memclient tool also failed to work properly because I was unable to figure out how to send credentials with my connection. (among other random tests! For some reason I forgot to save this output, but I found these commands in my .history file)

I tried one last tool from GitHub called bmemcached-cli from https://github.com/RedisLabs/bmemcached-cli since it supported remote login. Unfortunately this bmemcached-cli tool was written in python2 so I had to go through and fix it up so it ran in python3...but after fixing it up it ran just fine and connected me to the memcached server using the credentials I found.

I did some research on enumerating memcached and found two useful sites:

Using this information I began enumerating the memcached service.

It seems like there are a lot of items stored in this service (2588).

There were four active slabs, however the command stats cachedump caused the program to crash, and I didn't find much that looked useful using the other methods I knew, so I tried to guess possible keys.

I got some results back when trying to get values for the keys 'username' and 'password'. I was able to collect three usernames and three password hashes.

I identified the hashes as bcrypt by the $2a$ before the salt and used hashcat's help to get the right hashtype code. Next I fired up hashcat to attempt to crack the hashes using rockyou.txt.

One of the password hashes was cracked fairly quickly, however only two of the hashes were recognized by hashcat (one seemed to be the wrong length). mommy1 was the password.

Port 3000 - the Gogs git service

I tried logging into SSH and the login page on the dyplesher.htb site with this password and the four usernames I found but I had no luck there.

Looking back at the nmap report, I saw that port 3000 was running another HTTP service hosting Gogs. Searching for Gogs and git led to https://gogs.io/, which gave me some information about this self-hosted git service. I navigated to the local Gogs repo page to check it out.

I created an account to see what would happen, but then changed my mind and went back and tried to see if I already had credentials for an active account.

I used burp intruder to brute force the login page with the usernames and passwords I had collected. The username felamos and the password mommy1 logged me in to a dashboard where I could see that felamos had created two git repositories.

I noted the email addresses on the /explore/users page (and my test account!).

There was nothing of use in any of the profile pages. I got hopeful when I saw the SSH keys page, but there wasn't anything there.

I found a git repository with the code for the memcached page were I got the credentials for felamos. This looks to be the repository I retrieved earlier with gitdump.py.

l also found backup of a gitlab page, but there was only a basic README.md file.

The /releases page for the gitlab repo held a few downloads. The Source code links just contained a README.md with no useful information, however the repo.zip was more interesting.

Recreating a git repository from a .bundle file

I downloaded and extracted repo.zip and found that it contained a repositories folder which had several .bundle files in nested folders.

I did some research on gitlab .bundle files and found https://gist.github.com/paulgregg/181779ad186221aaa35d5a96c8abdea7 which contained instructions on how to recreate a git repository from these files.

I followed the instructions and was able to successfully recreate the git repository for the first .bundle file.

The first .bundle file turned into a repo for votelistener.py which seemed to be a plugin for taking in-game user votes.

There did not seem to be anything that was actually useful other than a potential database to check out.

The next repository contained many more files, and looked to be the main code for this Minecraft server.

This repository contained a lot of files. I started with checking out craftbukkit.jar which turned out to be code for hosting a Minecraft server. https://getbukkit.org/

GetBukkit The most reliable and secure Minecraft server mirror.

Get Bukkit strives to be available 24 hours a day and 7 days a week for server owners, hosts, and the general public, providing the safest and most trusted third-party Minecraft server mirror.

I found some potential database login information in bukkit.yml but couldn't figure out how to connect to it.

The file server.properties had a flag in the motd field but nothing else useful was to be found.

In the plugins folder there was a LoginSecurity.jar and related files, including a users.db which looked interesting.

The file config.yml had more database credentials, this time for a MySQL database.

The users database

I opened up users.db in the DB browser for SQLite an started looking through it. There was not a lot of information stored in this database.

The users table contained only one record, but it held another bcrypt password hash.

I decrypted the hash with hashcat and found another password: alexis1. Once more I tried SSH login and failed, so again I tried using burp's Intruder on the main site's (http://dyplesher.htb) login page.

First, I captured a login request to the site, and configured Intruder to only brute force the name portion of the email field. I went under the assumption that the email address would end in @dyplesher.htb since that was what I found on the internal Gogs site.

I set the payload to only contain the list of names I had found on the site.

After running Intruder, I got a redirect to the /home page after logging in using felamos@dyplesher.htband alexis1.

The Minecraft server site

After logging in I was greeted by a fancy dashboard with all sorts of statistics that made it look like this was a pretty successful game server (contrary to the headline of 'Worst Minecraft server').

The console tab showed a running activity log for the game server.

On the players tab I found a page with a potential list of more usernames.

There was also a plugin upload page, which looked very interesting since it seemed I had permissions to upload files. Next I did some research on creating malicious Minecraft plugins to see if I could get code execution on the server through uploading my own plugin.

Crafting a malicious Minecraft plugin

At https://www.spigotmc.org/resources/spigot-anti-malware-detects-over-200-malicious-plugins.64982/ I came across information about an addon for detecting malicious plugins which I had seen mention of in the source somewhere. I was worried about potentially having to do encoding/obfuscation on my file uploads (It didn't end up being an issue).

On the site https://www.instructables.com/Creating-a-Minecraft-Plugin/ I found instructions on making a Minecraft plugin.

Creating a Minecraft Plugin

Important Info

  1. You need to be proficient in Java

  2. You need to know about general programming concepts

Steps

· Download the necessary files.

· Create an eclipse Java project.

· Create a plugin.yml.

· Learn some bukkit basics.

· Learn some bukkit advanced topics.

I did a lot of research on writing Minecraft plugins and coding in Java. I have used Eclipse for writing simple Java programs in the past but...well it's definitely not my favorite IDE or language.

  • How to write bukkit plugins from:

    • https://bukkit.gamepedia.com/Plugin_Tutorial

    • https://hypixel.net/threads/guide-start-coding-minecraft-bukkit-plugins.1084267/

    • https://stackoverflow.com/questions/22359193/bukkit-getting-a-response-from-a-php-file

  • how to write to files in Java:

    • https://www.w3schools.com/java/java_files_create.asp

    • https://stackoverflow.com/questions/3984185/how-to-write-a-java-desktop-app-that-can-interact-with-my-websites-api

  • Bukkit plugin code example from:

    • https://github.com/Bukkit/SamplePlugin

First I fired up the Eclipse IDE and loaded the Bukkit sample plugin. Next I added a package to the project.

While adding the new package I added the different .jar files I had found in the source code as libraries to the project since they seemed to all be dependencies for this plugin.

One of the required files I had to create was called plugin.yml, and contained some basic configuration information about the plugin.

Another required file for the plugin was pom.xml. This one contained basic information about the plugin such as the name, version, and the dependencies.

I created a new SSH key to use to try to log in to each user on the machine.

For the main Java program I wrote my plugin to write the public key I generated to the authorized_keys file of each user, to the default folder such as /home/MinatoTW/.ssh. After uploading my plugin on the site and reloading the page I tried to log in through SSH.

The final list of files included in my project before compiling. After I built my dyplesher-plugin.jar file I uploaded it through the portal and hoped that it would pass inspection and be loaded.

Initial Foothold

Enumeration as MinatoTW

After uploading my plugin I waited a short time, then tried to login to my first victim, MinatoTW. I was pleasantly surprised to get logged in immediately. I was a little sad after all that work, however, to find that this user did not have user.txt.

Reading local traffic with Tshark/Wireshark

My first bit of enumeration I always do when logging in as a new user is find out who I am and what privileges and permission I have. Immediately I noticed that this user was in the Wireshark group, which sounded quite interesting as it meant that I could probably capture traffic on the local host.

Since I didn't have a GUI I decided to try running tshark to see if there was interesting traffic on the host. I wrote the captured packets to a .pcapng file and exfiltrated it to my computer after capturing for a few minutes.

I noticed pretty quickly the Erlang Port Mapper traffic identifying port 25672 as a RabbitMQ node.

Next I identified some traffic that contained the memcache information I had pulled from that service earlier. It looked like there was a backup.sh shell script running that was either reading to or writing an email, username, and password key to memcache.

My next find in the packet capture was a jackpot. There was a full list of user information being sent through AMQP that contained names, emails, and passwords for a list of users, amongst other information.

Finding user creds

There was a login username and password for AMQPLAIN, which turned out to be the AAA controls for RabbitMQ (Which I saw open on port 5672 earlier in my nmap output).

The Advanced Message Queuing Protocol (AMQP) is an open standard for passing business messages between applications or organizations. It connects systems, feeds business processes with the information they need and reliably transmits onward the instructions that achieve their goals.

AMQP enables applications send and receive messages. In this regard it is like instant messaging or email.

I tried adding a user but got an error. I guess I need to find a user in the rabbitmq group?

Again I seem to have either failed to take notes, or something got deleted or overwritten in Joplin. What I had done was: I tried using rabbitmgctl to add a user account for myself but got back the error message above.

The first set of users from the packet capture all had the same password,

However the last three names seemed familiar and each had unique passwords.

Path to Power (Gaining Administrator Access)

Further enumeration as MinatoTW

Before trying to login as another user, I decided to look around a bit as MinatoTW first.

This user's folder contained a few folders, and a lot of standard Linux user files that contained nothing useful.

The /Cuberite folder contained a lot of files which looked to again be related to the Minecraft server. After spending a lot of time looking through them, I concluded there was nothing interesting here.

The next folder contained the backup.sh script I had noticed in my Wireshark packet capture.

In the /backup folder I found the script and files that had given me information earlier through memcached.

The /paper folder contained even more plugin and configuration info for the Minecraft server, but again, nothing useful was there.

Lastly, I tried checking if MinatoTW was able to run any commands as sudo, but despite the password I had found working for the user, I was unable to run any superuser commands.

Enumeration as felamos

Next I tried using felamos password to switch users, and was successful.

felamos was also unable to run sudo commands.

User.txt

However, I was happy to find the user.txt file under this user's home directory.

in the /yuntao folder there was a file calledsend.sh with a note to yuntao regarding user created plugins and using the plugin_data Exchange and Queue. It also says to send the URL of new plugins and the server wil automatically add them. This looks like a good privilege escalation route if I could figure out how to publish a cuberite plugin.

While checking out running processes I noticed screen was running so I attached to each of the two sessions,

but unfortunately neither had anything useful, and looked like it was all running gameworld information.

after checking /etc/passwd I noticed something a bit strange...is git usually able to login with a shell?

Enumeration as yuntao

Since I hadn't found much useful information as felamos besides the hint about cuberite plugins, I decided to try switching to the third user, yuntao.

Now I confirmed that I had three users that I could freely su between, but I was still missing something. yuntao was also unable to use sudo, and I still hadn't found a way to interact with the RabbitMQ service or upload cuberite plugins. Next I searched for privilege escalation and RabbitMQ led to https://book.hacktricks.xyz/pentesting/15672-pentesting-rabbitmq-management. I also found a way to interact with RabbitMQ through python at https://www.rabbitmq.com/tutorials/tutorial-one-python.html.

I created a test script using the information in the article to see if I could send messages through rabbit... but unfortunately there was no pika module installed on dyplesher. I installed the pika module on my machine and looked up how to connect remotely.

I found a few articles that gave me some good information, including one that specifically dealt with using RabbitMQ to communicate with Minecraft.

Using the message I had found in the yuntao folder in felamos home folder I set the Queue and routing_key to be plugin_data, however it setting the Queue caused an error.

Next I tried running a python3 http.server on the local machine since the note in the yuntao folder had mentioned entering a URL for plugins. After doing some troubleshooting, I found that commenting out the queue.declare line allowed me to connect to the service. I ran my script again and was able to see it connect to my test server on the dyplesher machine.

I wrote a python reverse shell back to my machine and tried to get my script to execute it.

My script worked, connected to the http server, and retreived my python script, but the python reverse shell didnt work...and neither did writing to root's authorized_keys file after modifying the local script. I decided to do some more enumeration of the files in MinatoTW's folder to see if there was anything that I missed that could give me any clues as how to proceed.

Side Note: Python3's http.server exits much cleaner than the verbose error messages SimpleHTTPServer from python2 gives! Sometimes it's the little things that make us happy :)

I went back and looked closer into the Minecraft related files in MinatoTW's user folder. In the webadmin folder I found some files related to generating keys and a script that would generate self-signed keys for the server.

The template.lua file included code for loading plugins and running code for the webadmin site. I did some research on lua and cRoot, which led me to pages related to Cuberite, which made me sure I was on the right track.

https://api.cuberite.org/cRoot.html

cRoot class

This class represents the root of Cuberite's object hierarchy. There is always only one cRoot object. It manages and allows querying all the other objects, such as cServer, cPluginManager, individual worlds etc.

If this server will execute Lua scripts as code then perhaps I could use one to either send me a shell or write an SSH key...unfortunately I had never written anything in Lua, so I had some more reading to do. I found a good resource which showed me that writing to a file was just as easy as in python.

https://www.tutorialspoint.com/lua/lua_file_io.htm

I tested my Lua script by using it to append my SSH key (again) to MinatoTW's authorized_keys file, and was successful!

Getting a shell

Next I tried running the script against root through my remote RabbitMQ connection.

My first try was unsuccessful, but after some troubleshooting, I realized that for some reason the file was not being opened for appending. Changing the file open mode to write made everything work~

Root.txt

After writing my public key to root it was simple to login using SSH and collect my hard-earned proof!

Thanks to felamos & yuntao for creating this very challenging, yet very fun and interesting machine! I learned a lot more about Minecraft plugins than I ever thought I would want to!

If you like this content and would like to see more, please consider buying me a coffee!

Last updated

Was this helpful?