Hack The Box - HTB SmartHire Writeup - Medium- Weekly - May 16th, 2026

Hack The Box -  HTB SmartHire  Writeup - Medium- Weekly - May 16th, 2026

SmartHire — Walkthrough

Machine Detail Value
Name SmartHire
Difficulty Medium
OS Linux
Date 05-16-2026

Introduction

SmartHire is a Linux-based target that demonstrates the risks of outdated MLOps infrastructure and insecure plugin architectures. The attack vector involves bypassing authentication on an outdated MLflow instance (version 2.14.1), achieving Remote Code Execution (RCE) via a tailored Pickle deserialization payload, and escalating privileges through a writable Python plugin directory used by a high-privilege management script.

Phase 1: Reconnaissance and Enumeration

Nmap Port Scanning

Initial discovery was conducted using Rustscan to identify open ports, followed by a detailed Nmap scan for service identification.

In professional penetration testing, controlling packet frequency is vital. The flags --min-rate and --max-rate were utilized to manage Packets Per Second (PPS). This ensures the scan remains efficient without overwhelming the target's network stack or triggering rate-limiting thresholds on Intrusion Detection Systems (IDS).

Open 10.129.XX.XX:22
Open 10.129.XX.XX:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} -{{ipversion}} {{ip}} -A -oA smarthire.txt" on ip 10.129.XX.XX

Nmap service detection results:

PORT    STATE SERVICE REASON  VERSION
22/tcp  open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.15 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 41:3c:e3:bb:88:70:99:7f:b8:96:59:48:9b:85:98:69 (ECDSA)
|_  256 d5:9d:fd:6b:be:d8:39:6f:3f:43:ab:0e:f6:3e:22:db (ED25519)
80/tcp  open  http    syn-ack nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://smarthire.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Two services were exposed: SSH (OpenSSH 8.9p1) on port 22 and HTTP (nginx 1.18.0) on port 80. The web server redirected to http://smarthire.htb/.

Web Enumeration

A direct curl request to the target IP resulted in a 302 redirect. To resolve this, the local /etc/hosts file was updated:

[IP_ADDRESS] smarthire.htb

Verify the redirect:

curl -vv $ip

Add the host entry:

sudo -- sh -c -e "echo \"$ip smarthire.htb\" >> /etc/hosts"
# or
echo "$ip smarthire.htb" | sudo tee -a /etc/hosts

To remove the last line of the file:

sudo sed -i '$ d' /etc/hosts

The landing page is the SmartHIRE site — an "AI-first evaluation platform powering high-trust hiring at scale," with About, Products, Testimonials, and Sign in navigation.

Directory Fuzzing

Run FFUF for additional pages:

ffuf -u http://smarthire.htb/FUZZ -w ~/git/SecLists/Discovery/Web-Content/common.txt -ac

Results:

dashboard [Status: 302, Size: 199, Words: 18, Lines: 6, Duration: 98ms]
logout    [Status: 302, Size: 199, Words: 18, Lines: 6, Duration: 109ms]
login     [Status: 200, Size: 6160, Words: 1357, Lines: 128, Duration: 142ms]
register  [Status: 200, Size: 6499, Words: 1415, Lines: 132, Duration: 132ms]

Sub-Domain / V-Host Enumeration

ffuf -w /home/kali/git/SecLists/Discovery/DNS/subdomains-top1million-110000.txt \
  -u http://smarthire.htb/ -H 'Host: FUZZ.smarthire.htb' -ac

Result:

models [Status: 401, Size: 137, Words: 11, Lines: 1, Duration: 147ms]

V-Host enumeration identified a subdomain: models.smarthire.htb. Update /etc/hosts to map both:

sudo sed -i '$ d' /etc/hosts
echo "$ip smarthire.htb models.smarthire.htb" | sudo tee -a /etc/hosts

Both domains were mapped to the target IP to allow proper interaction with the virtual hosts.

Application Analysis

The smarthire.htb dashboard provides "Train Model" and "Make Predictions" functionalities. These features utilize CSV uploads for processing. The models.smarthire.htb subdomain was identified as an instance of MLflow, a platform for the machine learning lifecycle.

Register

We can register for an account and log in to see the dashboard ("Welcome back, wind0!"). The dashboard exposes:

  • Train Model — One-click training (upload hiring data CSV, max 2MB)
  • Make Predictions — Score resumes

Both pages accept CSV in a specific format.

The models subdomain

The http://models.smarthire.htb subdomain is running MLflow. Some searching turns up CVE-2026-2635, an authentication bypass exploitable with the default credentials admin:password. This works, granting access.

We're running version 2.14.1, which is quite old (current version is 3.12). The next step is to search for known remote code execution vulnerabilities.

Phase 2: Exploiting MLflow for Initial Access

Authentication Bypass

The MLflow instance was identified as version 2.14.1, significantly outdated compared to current releases (e.g., 3.12). Research identified CVE-2026-2635, an authentication bypass vulnerability. Using the default credentials admin:password successfully granted access to the MLflow dashboard.

Vulnerability Research and Vector Selection

Several vulnerabilities were considered for the 2.14.1 environment:

  • CVE-2025-15379 — Command injection via python_env.yaml (requires specific environment managers).
  • CVE-2025-11201 — Directory traversal during model creation.
  • CVE-2025-14287 — RCE via unsanitized container image names.
  • CVE-2024-37055 — Deserialization of untrusted data.
  • CVE-2024-2928 — Inapplicable (only affects versions < 2.11.2).

Given the "Make Predictions" feature on the main site, a Pickle deserialization attack was determined to be the most viable path.

Pickle Deserialization Attack (The "Mocked Utils" Hurdle)

Initial attempts to trigger RCE failed due to Python version mismatches and missing dependencies. Analysis of a legitimate python_model.pkl using unpickle.py and pickletools revealed that the model relied on a specific local structure: utils/simplehiringmodel.py.