Ultratech - TryHackMe Writeup
The link for this lab is located here: https://tryhackme.com/room/ultratech1
You have been contracted by UltraTech to pentest their infrastructure. It is a grey-box kind of assessment, the only information you have is the company's name and their server's IP address. Can you hack it?
Full Walkthrough
The first step is to run a simple Nmap port scan with the following parameters:
-p- for all ports
10.10.39.55 (target IP)
-oN allports.scan(outputs to a normal Nmap format)
A quick side note: my command line may look slightly different. As is the case with the following nmap command where “nmap” is replaced with “cmap” – this is simply an alias I created that uses grc (generic colourizer) to add some colour to commands. The full command for “cmap” would simply be “grc nmap” – simple right?
The initial scan comes back with 4 ports open - FTP, SSH, something referred to as “blackice-icecap” and an unknown service. To find out more information about the higher ports, we can run a more detailed scan on the open ports via the following parameters:
-A for OS detection, version detection and some simple scripts
-T4 for the second fastest speed
-p21,22,8081,31331 to specify the 4 ports
Now we have more information, it looks like port 8081 is Node.js (possibly an API?) and port 31331 seems to be some web page running Apache through Ubuntu as indicated by the server header and banner returned by Nmap.
From here, my first step would be to visit the higher ports as typically lower ports like FTP and SSH require some credentials or are a rabbit hole in CTF-style machines. In a real-world scenario, I would recommend looking into every port and enumerate more.
The first port is port 8081.
Visiting port 8081 some simple text appears telling us it is “UltraTech API v0.1.3” - looks like it was an API. There is nothing else on this page. Before attempting directory busting, we can look at the other port - 31331.
This page is much more interesting. It seems to be a legitimate website. With this, a good first step is looking into the source code.
Sadly, not much awaits us. The only interesting thing I found is that the contact button seems to include a mailto reference to an email titled “ultratech@yopmail.com” - this could be a potential login.
Additionally, just scouring the website can reveal interesting information and pages.
Scrolling down the main page, we are able to see what looks like employees with their full names. However, what is more interesting is the second part - at a glance this looks like a username or nickname for these employees.
Nothing else of note appeared on the website, so the next logical step is to try and find additional directories.
For directory busting, my go to tool is Feroxbuster but feel free to use any tool you prefer. Feroxbuster is run with the following parameters:
—url http://10.10.39.55:31331 is the website URL to directory bust
-w /usr/share/SecLists/Discovery/Web-Content/common.txt is the wordlist to use
-d 2 limits the URL depth to 2
After a few seconds, we get some results back. A good thing to look at is - if the website has it - the robots.txt file to see if they are trying to hide any directories from end users.
Inside the robots.txt file, there is a link to another TXT file titled “utech_sitemap.txt” which could provide us with the full picture of the site and all its pages.
The sitemap includes three HTML pages - index.html which is the first page we landed on, what.html which is like an about us page and partners.html
Hmm… partners.html wasn’t linked on the main page - interesting!
The partners.html page seems to be a login area for partners. It might be possible to bruteforce the password with the potential usernames found on the main page or with the email we found earlier.
However, before jumping into bruteforcing, remember we can look at the source code.
At first glance, it doesn’t look too interesting. However, at the very bottom, there is a JavaScript file titled “api.js” which seems custom written and not part of Bootstrap or another framework.
Viewing the contents of this file reveals the following:
As a side note, I am by no means a JavaScript wizard or web developer, but one thing immediately stands out to me - it seems to be pinging something.
The “getAPIURL()” function looks like it is simply getting the windows.location.hostname and appending port 8081 to the end - remember back to the Nmap scan.
To find out what windows.location.hostname does, we can refer to JavaScript documentation.
It seems my theory was right. It simply returns the domain name of the web host. Looking back to the script, the more interesting line is the following:
This line defines a constant called url that has the value of http://10.10.39.55:8081/ping and then provides the “ip” parameter for windows.location.hostname.
In simpler terms, it seems like it pings itself using a /ping function or API through the web browser.
To test this, we can try navigating to it ourselves and providing our own parameter value for ip - in this case, I simply chose localhost (127.0.0.1):
And it works! The ping successfully went through with 1 packet transmitted and 1 packet received. This tells me that it’s effectively running a command in the back - maybe we can try command injection?
As another test, I tried to provide another Linux command to the ip parameter.
Sadly, this resulted in an error. What if there was some way to get that command to execute?
A really interesting thing I learnt in a BASH scripting course was that if you use commands inside backticks, that command gets executed before anything else - it takes priority.
What happens if we inject pwd into the parameter enclosed in backticks?
Success! We get command execution and we can see that we were in the /home/www/api directory.
Doing some more enumeration, we can run the ls command.
We see a SQLite database file which is interesting. There may be some hardcoded credentials inside the database. To check, we can cat out the contents of the file:
Immediately, I see what looks like hashes of some kind. In front of those hashes however, it seems there are usernames. Looking more closely, one of them (r00t) was a username we saw on the home page.
With these potential credentials found, we can determine what hash type they are:
This returns MD5 for the hash type. Next, I created a file with the extracted hashes.
Finally, I copied that file onto my main computer and ran Hashcat on it, utilizing the GPU to make it much faster. In about 5 seconds, it came back revealing that both of the passwords were cracked:
Knowing this, we now have two potential logins:
Immediately, I went back to the login page to see if anything was hiding after a successful login. Logging in with the username of “r00t” revealed a restricted area with a warning about the server’s configuration but not much else.
Logging in as the admin user reveals the same thing:
Remembering back to the port scan, SSH was open. It’s possible that these credentials work via SSH. I tried the admin user and it did not work. However, r00t was able to login.
Next, it’s always a good idea to look for easy wins. One of the easiest wins is looking at the SUDO permissions for the user. Unfortunately, r00t is not allowed to run sudo.
You can perform more manual enumeration, but to speed up the process, I like using automated scripts such as LinPEAS or LinEnum. To transfer the file over a web server can be started up using python3:
On the target machine, the command “wget” can be used to grab the linpeas.sh file from our machine. Once downloaded, we can give the script executable permissions and run it.
Looking through the results of LinPEAS, something near the top instantly lights up as critical - it seems that our current user is part of the docker group.
With this, a really good resource is GTFOBins. Searching GTFOBins for Docker reveals that it can be used to get a root shell if we are part of the Docker group.
With this information, we can run the following command to grab a root shell as we are part of the Docker group.
From there, you can answer the final question on TryHackMe asking for the first characters of the RSA key which is located at /root/.ssh/id_rsa.