
Une procédure forensic pratique de CVE-2025-59359, une vulnérabilité critique d'injection de commandes OS dans Chaos-Mesh. Apprenez comment les attaquants détournent des clusters Kubernetes via des mutations GraphQL, et comment détecter, analyser et signaler la brèche en utilisant ELK.
Une procédure pas à pas médico-légale pratique de CVE-2025-59359, une faille critique d'injection de commandes OS dans Chaos-Mesh. Apprenez comment les attaquants détournent les clusters Kubernetes via des mutations GraphQL, et comment détecter, analyser et signaler la brèche en utilisant ELK.
Par Mark Mallia
CVE-2025-59359 expose une faille critique d'injection de commandes OS dans le Controller Manager de Chaos-Mesh. Cette vulnérabilité permet aux attaquants d'exécuter des commandes shell arbitraires à travers les pods Kubernetes, pouvant mener à une compromission complète du cluster. Cet article simule l'exploit, cartographie son empreinte médico-légale et décrit les stratégies de détection et d'atténuation pertinentes pour les équipes techniques et les parties prenantes exécutives.
Dans le monde en constante évolution de la sécurité Kubernetes, CVE-2025-59359 se distingue comme un rappel frappant de la façon dont une seule entrée négligée peut défaire un cluster entier. Cette vulnérabilité critique (CVSS 9.8) affecte le Controller Manager de Chaos-Mesh, où les paramètres fournis par l'utilisateur sont imprudemment concaténés dans des commandes shell sans aucune vérification ni assainissement. Le résultat ? Un attaquant non authentifié à l'intérieur du cluster peut exécuter des commandes arbitraires sur les pods, obtenant un contrôle complet avec une facilité alarmante. C'est un cas d'école d'escalade de privilèges via l'injection de commandes, et un puissant exemple de pourquoi les commandements de codage sécurisé dans les environnements cloud-native sont importants.
La faille existe dans la mutation cleanTcs. Cette mutation nettoie les paramètres de contrôle de trafic Linux (TC) après les expériences de chaos, et elle accepte des paramètres fournis par l'utilisateur à partir des spécifications d'expérience.
Lorsqu'un attaquant fournit une valeur modifiée pour ces paramètres, la commande shell résultante est construite par concaténation de chaînes. Aucune vérification défensive n'est effectuée avant que cette commande ne soit exécutée avec les privilèges du Controller Manager—ce qui signifie qu'un utilisateur non authentifié peut injecter des commandes arbitraires dans n'importe quel pod ou namespace contrôlé par le cluster.
Voici un extrait du code source de la mutation (montré dans le contexte de son implémentation Go).
// cleanTcsMutation.go
func executeCleanTcs(ctx context.Context, payload Payload) error {
// Build command string using user input directly
cmd := fmt.Sprintf(
"tc qdisc add dev %s root handle 1: htb rate %s ceil %s",
payload.Device,
payload.Rate,
payload.Ceil,
)
log.Debugf("Running command: %s", cmd)
if err := ctx.RunCommand(cmd); err != nil {
return fmt.Errorf("tc clean mutation failed: %w", err)
}
return nil
}
Device, Rate et Ceil.Imaginez un cluster Kubernetes exécutant Chaos-Mesh, où un attaquant conçoit une spécification d'expérience apparemment innocente. Mais au lieu de régler le contrôle de trafic, il glisse une charge utile comme ; rm -rf /tmp dans des champs comme Device, Rate ou Ceil. Une fois soumise via l'interface utilisateur ou l'API, la mutation construit et exécute aveuglément la commande—aucun assainissement, aucune barrière de sécurité. Et parce qu'elle s'exécute avec les privilèges du controller-manager, le code injecté se propage à travers les pods comme une traînée de poudre. Pire encore, si l'attaquant utilise également CVE-2025-59358 pour accéder au point de terminaison GraphQL sans authentification, il n'a même pas besoin d'identifiants.
Si elle est exploitée en production, CVE-2025-59359 pourrait permettre aux attaquants de perturber les services, d'accéder à des charges de travail sensibles et de pivoter entre les namespaces—posant un risque matériel pour la continuité des affaires et la conformité réglementaire. Les organisations utilisant Chaos-Mesh devraient prioriser le patching, l'application de RBAC et l'audit des points de terminaison GraphQL.
| Tactique | Technique |
|---|---|
| Execution | T1059 – Interpréteur de commandes et de scripts |
| Élévation de privilèges | T1068 – Exploitation pour l'élévation de privilèges |
| Mouvement latéral | T1021 – Services distants |
| Impact | T1499 – Déni de service sur les points de terminaison |
cleanTcs.Créez un fichier logstash-tcs.conf dans votre répertoire de configuration Logstash.
input {
beats {
port => 5044
codec => "json"
}
}
filter {
# The Python script will be referenced here.
python {
code => "/opt/elk/python/process_tcs.py"
add_field => { "[tcs]" => "%{[message][device]}-%{[message][rate]}-%{[message][ceil]}" }
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "chaos-tcs"
document_type => "experiment"
codec => "json"
}
}
process_tcs.py#!/usr/bin/python3
def process(event):
"""
Transforms the raw event from Logstash into a JSON document suitable for Elasticsearch.
Expected input format (example):
{
"message": {
"device": "eth0",
"rate": "100mbit/s",
"ceil": "200mbit/s",
"timestamp": "2025‑09‑18T14:33:00Z"
}
}
The script extracts the three key values, normalises them and returns a dictionary.
"""
# 1. Grab nested fields
device = event.get("message", {}).get("device", "")
rate = event.get("message", {}).get("rate", "")
ceil = event.get("message", {}).get("ceil", "")
# 2. Normalise numeric values – remove unit suffixes and cast to float.
def strip_unit(val, unit):
return float(val.replace(unit, "").strip())
rate_val = strip_unit(rate, "mbit/s")
ceil_val = strip_unit(ceil, "mbit/s")
# 3. Build output dict
result = {
"device": device,
"rate_mbit_s": rate_val,
"ceil_mbit_s": ceil_val,
"ts": event.get("message", {}).get("timestamp", ""),
"tcs_id": f"{device}-{rate_val}-{ceil_val}"
}
# 4. Return the dict
return result
Créez un fichier de mapping chaos-tcs-mapping.json:
{
"mappings": {
"_doc": {
"properties": {
"device": { "type": "keyword" },
"rate_mbit_s":{ "type":"float" },
"ceil_mbit_s":{ "type":"float" },
"ts": { "type":"date", "format":"yyyy-MM-dd'T'HH:mm:ssZ"},
"tcs_id": { "type":"keyword" }
}
}
}
}