{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiecs5s5rrhivzklu3353hruo433l3p3j6k2mo625zgkmkjw3uesbi",
"uri": "at://did:plc:gc2nrf5j5b2po5huoyw6utr4/app.bsky.feed.post/3mmdv2nvbycs2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreidhiabaru6taj4oxnhvgbfemofe44vncemjnpqzehxw34gdzhvlbu"
},
"mimeType": "image/jpeg",
"size": 43349
},
"description": "SMARTHIRE — WALKTHROUGH\n\n\n\n\n\n\nMachine Detail\nValue\n\n\n\n\nName\nSmartHire\n\n\nDifficulty\nMedium\n\n\nOS\nLinux\n\n\nDate\n05-16-2026\n\n\n\n\n\n\n\nINTRODUCTION\n\nSmartHire 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 writa...",
"path": "/hack-the-box-htb-smarthire-writeup-medium-weekly-may-16th-2026/",
"publishedAt": "2026-05-21T07:20:59.000Z",
"site": "https://1337sheets.com",
"tags": [
"Subscribe now"
],
"textContent": "# SmartHire — Walkthrough\n\nMachine Detail | Value\n---|---\nName | SmartHire\nDifficulty | Medium\nOS | Linux\nDate | 05-16-2026\n\n## Introduction\n\nSmartHire 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.\n\n## Phase 1: Reconnaissance and Enumeration\n\n### Nmap Port Scanning\n\nInitial discovery was conducted using Rustscan to identify open ports, followed by a detailed Nmap scan for service identification.\n\nIn 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).\n\n\n Open 10.129.XX.XX:22\n Open 10.129.XX.XX:80\n [~] Starting Script(s)\n [>] Running script \"nmap -vvv -p {{port}} -{{ipversion}} {{ip}} -A -oA smarthire.txt\" on ip 10.129.XX.XX\n\n\nNmap service detection results:\n\n\n PORT STATE SERVICE REASON VERSION\n 22/tcp open ssh syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.15 (Ubuntu Linux; protocol 2.0)\n | ssh-hostkey:\n | 256 41:3c:e3:bb:88:70:99:7f:b8:96:59:48:9b:85:98:69 (ECDSA)\n |_ 256 d5:9d:fd:6b:be:d8:39:6f:3f:43:ab:0e:f6:3e:22:db (ED25519)\n 80/tcp open http syn-ack nginx 1.18.0 (Ubuntu)\n |_http-server-header: nginx/1.18.0 (Ubuntu)\n | http-methods:\n |_ Supported Methods: GET HEAD POST OPTIONS\n |_http-title: Did not follow redirect to http://smarthire.htb/\n Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel\n\n\nTwo 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/`.\n\n### Web Enumeration\n\nA direct curl request to the target IP resulted in a 302 redirect. To resolve this, the local `/etc/hosts` file was updated:\n\n\n [IP_ADDRESS] smarthire.htb\n\n\nVerify the redirect:\n\n\n curl -vv $ip\n\n\nAdd the host entry:\n\n\n sudo -- sh -c -e \"echo \\\"$ip smarthire.htb\\\" >> /etc/hosts\"\n # or\n echo \"$ip smarthire.htb\" | sudo tee -a /etc/hosts\n\n\nTo remove the last line of the file:\n\n\n sudo sed -i '$ d' /etc/hosts\n\n\nThe 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.\n\n#### Directory Fuzzing\n\nRun FFUF for additional pages:\n\n\n ffuf -u http://smarthire.htb/FUZZ -w ~/git/SecLists/Discovery/Web-Content/common.txt -ac\n\n\nResults:\n\n\n dashboard [Status: 302, Size: 199, Words: 18, Lines: 6, Duration: 98ms]\n logout [Status: 302, Size: 199, Words: 18, Lines: 6, Duration: 109ms]\n login [Status: 200, Size: 6160, Words: 1357, Lines: 128, Duration: 142ms]\n register [Status: 200, Size: 6499, Words: 1415, Lines: 132, Duration: 132ms]\n\n\n#### Sub-Domain / V-Host Enumeration\n\n\n ffuf -w /home/kali/git/SecLists/Discovery/DNS/subdomains-top1million-110000.txt \\\n -u http://smarthire.htb/ -H 'Host: FUZZ.smarthire.htb' -ac\n\n\nResult:\n\n\n models [Status: 401, Size: 137, Words: 11, Lines: 1, Duration: 147ms]\n\n\nV-Host enumeration identified a subdomain: `models.smarthire.htb`. Update `/etc/hosts` to map both:\n\n\n sudo sed -i '$ d' /etc/hosts\n echo \"$ip smarthire.htb models.smarthire.htb\" | sudo tee -a /etc/hosts\n\n\nBoth domains were mapped to the target IP to allow proper interaction with the virtual hosts.\n\n### Application Analysis\n\nThe `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.\n\n#### Register\n\nWe can register for an account and log in to see the dashboard (\"Welcome back, wind0!\"). The dashboard exposes:\n\n * **Train Model** — One-click training (upload hiring data CSV, max 2MB)\n * **Make Predictions** — Score resumes\n\n\n\nBoth pages accept CSV in a specific format.\n\n#### The models subdomain\n\nThe `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.\n\nWe'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.\n\n## Phase 2: Exploiting MLflow for Initial Access\n\n### Authentication Bypass\n\nThe 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.\n\n### Vulnerability Research and Vector Selection\n\nSeveral vulnerabilities were considered for the 2.14.1 environment:\n\n * **CVE-2025-15379** — Command injection via `python_env.yaml` (requires specific environment managers).\n * **CVE-2025-11201** — Directory traversal during model creation.\n * **CVE-2025-14287** — RCE via unsanitized container image names.\n * **CVE-2024-37055** — Deserialization of untrusted data.\n * **CVE-2024-2928** — Inapplicable (only affects versions < 2.11.2).\n\n\n\nGiven the \"Make Predictions\" feature on the main site, a **Pickle deserialization attack** was determined to be the most viable path.\n\n### Pickle Deserialization Attack (The \"Mocked Utils\" Hurdle)\n\nInitial 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`.\n\n### This post is for subscribers only\n\nBecome a member to get access to all content\n\nSubscribe now",
"title": "Hack The Box - HTB SmartHire Writeup - Medium- Weekly - May 16th, 2026",
"updatedAt": "2026-05-21T07:20:59.869Z"
}