Tabby
Reconnaissance:
NMAP:
nmap found three open TCP ports, SSH (22), HTTP Apache (80), and HTTP Tomcat (8080): Based on the OpenSSH and Apache versions, the host is likely running Ubuntu 20.04 Groovy. Tomcat isn’t surprising given the box name.
Enumeration: SSH - TCP PORT 22
OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
Enumeration: HTTP - TCP PORT 80/8080
The site is a hosting company: http://10.10.10.194/ http://10.10.10.194:8080/ http://megahosting.htb/
E-mail us : sales@megahosting.htb Bootstrap Themes
Forbidden: http://megahosting.htb/.php http://megahosting.htb/files/ http://10.10.10.194/files/ http://10.10.10.194/assets/
We can see that it is running Tomcat 9. Click on the manager webapp link.
http://10.10.10.194:8080/ http://10.10.10.194:8080/docs/ http://10.10.10.194:8080/examples/
tomcat9-admin: This package installs two web applications that can help managing this Tomcat instance. Once installed, you can access the manager webapp and the host-manager webapp.
We get prompted for credentials. At this stage we could test for default credentials. However, the Nikto scanner already does that and the default configuration of Autorecon runs a Nikto scan. Therefore, let’s view the nikto scan results.
It didn’t report any default credentials. Before we attempt a brute force attack, let’s move on to enumerating the other port.
Foothold: Shell as tomcat
We can see in the URL that a file with the name “statement” is being called and executed to present the above page. So the first thing we should test for is local file inclusion (LFI). An LFI vulnerability occurs when an application uses the path to a file as user input. If the application does not properly validate that input, an attacker can use this vulnerability to include files locally present on the server. Add the following string in the file parameter of the URL.
We get the content of the passwd file! So it is definitely vulnerable to a LFI. Let’s switch to Burp for further testing.
The next thing to test for is Remote File Inclusion (RFI). RFI is similar to LFI, except that it instead allows an attacker to include remote files. This is way more dangerous than an LFI. There are several methods you can try to turn an LFI to an RFI. For this blog, I will test it using the PHP http:// wrapper
First, start a simple python server on the attack machine.
We can see that there was no attempt to download the file.
So it’s not likely to be vulnerable to RFI. Therefore, let’s focus on the LFI vulnerability. The has a list of LFI payloads that you could try to potentially get useful information about the box the web server is running on. However, the first thing I would like to see is the source code of the news.php script to determine what caused the LFI vulnerability.
If we simply try adding “news.php” in the file parameter, we get nothing indicating that the script is not placed in the current directory. Next, let’s try the parent of the current directory.
We get the source code! Let’s do a quick code review.
Line 10: Takes in the content of the file URL parameter and saves it in the $file parameter.
Line 11: Takes in the content of the $file parameter, appends it to the directory files and attempts to open the file at that location.
Lines 12–14: Output the content of the file.
The LFI vulnerability is introduced in Line 11 since the $file parameter is a user-controlled input that is not sanitized. Discovering the reason behind the vulnerability is a bit of a detour from solving the box, however, it is important to understand why things work the way they do.
Going back, how can we use the LFI vulnerability to get code execution on the box? Well, when we visited the Tomcat server running on port 8080, it gave us the location of the tomcat-users.xml file. Depending on the configuration, this file could contain the list of user names, roles, and passwords. Let’s use the LFI vulnerability to output the content of the file.
This outputs nothing which leads us to believe that the file is in a different location. From the nmap scans, we do know that the OS is Ubuntu and the version of Tomcat installed is version 9. We also know that the Apache version is 2.4.41. So let’s try to use all that information to narrow down the exact Ubuntu release.
After guessing around and Googling a bit, I just installed Tomcat with apt install tomcat9. Then I used find to look for tomcat-users.xml, and got two results:
Use the above location to output the content of the file.
Exploitation:
I’ve got a single user, tomcat, with a password, “$3cureP4s5w0rd123!”, and the roles admin-gui and manager-script.
admin-gui: gives the user the ability to configure the Host Manager application using the graphical web interface.
manager-script: gives the user the ability to configure the Manager application using the text interface instead of the graphical web interface.
The user tomcat has admin-gui, but not manager-gui, which means I can’t access the manager webapp But I can access the host-manager webapp:
This page is for adding virtual hosts and assigning them an app. I tried a few things that all failed:
Priv: tomcat –> ash
The first thing to do when you get initial access on the box is to enumerate the filesystem to see if there are any cleartext passwords. While doing that, we find a backup file that is encrypted.
I copied 161612020_backup.zip it into /dev/shm and tried to unzip, but it needs a password. I exfiled it back to my own machine, starting nc on my machine, and then running:
I also got the hash so I could make sure I got the file without corruption. Back at my host, the file comes in, and the hashes match:
To crack the password, I’ll use zip2john to create a hash:
Then I can pass it to john with rockyou and it breaks instantly:
su:
I was a bit confused when looking through the archive. There wasn’t anything useful in it. Then it occurred to me that ash may have reused his password. I ran su, and it worked:
Priv: ash –> root
The first command I run in basically every Linux shell is id. It not only shows not only who the shell is running as, but also that users groups:
In this case, adm is interesting (it allows me to read log files), but I’m immediately drawn to lxd. This group was an unintentional (and eventually patched) path to root in both mischief and obscurity, but here is actually the intended path. Since originally solving, I came across a really slick way to do this even better, so I’ll show both the standard way and the upgrade
LXC Exploitation:
The basic idea is that I can create a container and mount the root file system on Tabby into the container, where I then have full access to it. There are currently no containers on the host:
I’ll need to bring a container to Tabby. I’ll grab the LXD Alpina Linux image builder by running git clone [path to repo]
in my /opt
directory. This tool creates an Alpine Linux container image. I could do this with an OS flavor, but Alpine is nice because it’s really stripped down and small. I’ll go into that directory and run the builder:
When it finishes, there’s a .tar.gz
package containing the files necessary to make an Alpine Linux container.
I’ll upload this to Tabby by running a Python webserver on my host (python3 -m http.server 80
) and then running wget
from Tabby:
Next I’ll import the image into lxc
:
As the message suggests, I’ll need to run lxd init
. I can just accept all the defaults:
Now I’ll create a container from the image with the following options:
init
- action to take, starting a container0xdf-image
- the image to startcontainer-0xdf
- the alias for the running container-c security.privileged=true
- by default, containers run as a non-root UID; this runs the container as root, giving it access to the host filesystem as root
I’ll also mount part of the host file system into the container. This is useful to have a shared folder between the two. I’ll abuse it by mounting the host system root:
Now the container is setup and ready, just not running:
I’ll start the container:
The following lxc exec
command returns a root shell inside the container:
Last updated