
Outil d'audit en lecture seule pour CVE-2026-0300 (exposition du portail d'authentification User-ID de PAN-OS)
Outils d'audit en lecture seule pour CVE-2026-0300 — le débordement de tampon non authentifié dans le portail d'authentification User-ID de PAN-OS (anciennement connu sous le nom de « Captive Portal ») sur les pare-feu des séries PA et VM.
Ce dépôt accompagne l'avis de sécurité TRG-SA-2026-003 de Tailwind Resource Group et fournit :
audit_portal.py — Niveau 1 : audit d'un seul pare-feuaudit_fleet.py — Niveau 2 : balayage de flotte piloté par Panorama (concurrent)panos_audit.py — bibliothèque partagée utilisée par les deux CLILes scripts sont en lecture seule. Ils émettent des requêtes de type show contre l'API XML de PAN-OS et ne modifient jamais la configuration. La clé API est envoyée via l'en-tête HTTP X-PAN-KEY plutôt que comme paramètre de requête URL, afin qu'elle n'apparaisse pas dans les journaux d'accès du plan de gestion PAN, les journaux des proxys d'inspection TLS ou les arguments de processus de l'auditeur.
L'enregistrement CVE utilise le nom de fonctionnalité moderne « Portail d'authentification User-ID ». Le schéma XML de PAN-OS, les options CLI et les chemins de documentation utilisent toujours le vocabulaire hérité captive-portal. Les opérateurs qui auditeraient des flottes avec show config running | match authentication-portal manqueraient silencieusement chaque configuration, car cette chaîne n'apparaît jamais comme élément de configuration. Cet outillage recherche le nom d'élément correct selon le schéma, quelle que soit la date de création de la configuration.
L'analyse complète de Tailwind sur ce piège de nommage se trouve dans TRG-SA-2026-003, « L'empreinte héritée du Captive Portal ».
pip requise--insecure est fourni uniquement pour les audits de mise en service ponctuelsexport PAN_API_KEY="<clé>"
./audit_portal.py --hostname fw1.example.com
Exemple de sortie tabulaire :
vsys: vsys1
configured: True
enabled: True
redirect_host: auth-portal.internal.example.com
mode: redirect
bound: ethernet1/3(internal-trust), ethernet1/4(guest)
tls_verified: True
risk: EXPOSED_LIKELY
Autres formats de sortie : --output json ou --output csv.
Autres options : --vsys <nom> pour l'audit d'un seul vsys, --timeout/--retries pour les systèmes amont lents, --debug pour des détails d'erreur verbeux sur stderr.
export PAN_API_KEY="<clé-panorama>"
./audit_fleet.py --hostname panorama.example.com --workers 16 --output csv > fleet-audit.csv
Chaque ligne du CSV correspond à un appareil-vsys avec l'état du portail, l'hôte de redirection, le mode, les liaisons d'interface et une classification de risque. Le script utilise le paramètre API target=<serial> de Panorama, il ne se connecte donc jamais directement aux pare-feu gérés — une seule connexion à Panorama balaie toute la flotte.
Options notables :
--workers N — threads d'audit concurrents (défaut 8, max 32). Une flotte de 1000 appareils est traitée en quelques minutes plutôt que l'heure ou plus qu'un balayage séquentiel prendrait.--timeout, --retries — paramètres par appel API. Les URLError transitoires et les erreurs HTTP 5xx sont réessayés avec un backoff borné.--exclude-disconnected — par défaut, les appareils déconnectés sont inclus avec risk=DISCONNECTED afin qu'ils restent visibles pendant la fenêtre de correctif. Utilisez cette option pour les exclure.--min-expected-devices N — avertit (stderr) si Panorama renvoie moins d'appareils que N. Utile pour détecter une troncature de réponse par rapport à une taille de flotte connue.--serial-filter '0007*' — filtre par glob sur le numéro de série pour auditer un sous-ensemble.--debug — affiche les détails d'erreur verbeux par appareil sur stderr (inclut les chaînes reason amont ; désactivé par défaut pour éviter de divulguer des noms d'hôtes dans les CSV destinés aux clients).La colonne risk de la sortie est l'une des suivantes :
| Libellé | Signification |
|---|---|
INFO_NOT_CONFIGURED | Aucun bloc <captive-portal> sur l'appareil. Hors périmètre pour CVE-2026-0300. |
INFO_DISABLED | Le portail est configuré mais enabled=no. Le chemin de code vulnérable n'est pas actif. |
REVIEW_POLICY_NO_BINDINGS | Portail activé, mais aucune liaison d'interface trouvée dans la configuration. Vérifier via l'interface Web. |
EXPOSED_LIKELY | Portail activé et lié à une zone dont le nom suggère une exposition non fiable (untrust, dmz, guest, external, internet, wan, public). À examiner en premier. |
REVIEW_POLICY | Portail activé et lié à des zones à nom interne. Parcourir la politique de sécurité pour confirmer l'accessibilité. |
EXPOSED_LIKELY est un indice, pas un verdict — les noms de zones sont des conventions d'opérateur, pas une application de règles. Le script ne peut pas remplacer un parcours de politique de sécurité ; il trie la sortie de flotte pour indiquer où l'attention doit se porter en premier.
Ils font :
<captive-portal> par vsys (le nom d'élément du schéma est toujours captive-portal, quel que soit le nom dans l'interface ou la version de PAN-OS).EXPOSED_LIKELY apparaissent en premier dans la sortie de flotte.X-PAN-KEY pour qu'elle reste hors des journaux d'accès URL et des arguments de processus.Ils ne font pas :
La clé API PAN-OS hérite du rôle et des autorisations de l'utilisateur qui la génère.
Avertissement important : il n'existe pas d'autorisation XML API en lecture seule dans PAN-OS.
Les autorisations du rôle d'administrateur sur l'onglet API XML sont binaires Activer/Désactiver par catégorie — Configuration, Requêtes opérationnelles, Commit, Export, Import, Rapport, Journal, Agent User-ID. L'activation de Configuration pour l'API XML permet à la fois les actions
showetset/edit/delete/move/rename/clone. L'activation de Requêtes opérationnelles permet des opérations<request>arbitraires, y compris<request><restart>. Les onglets Interface Web et API REST offrent l'option Lecture seule ; l'onglet API XML ne l'offre pas.Un « utilisateur d'audit » créé en activant ces catégories d'API XML détient l'autorité d'écriture complète de l'API XML sur l'appareil. Traitez la clé résultante comme une information d'identification privilégiée : limitez sa durée de vie à la fenêtre d'audit, stockez-la dans un gestionnaire de secrets et désactivez l'utilisateur lorsque le travail est terminé.
Référence PAN canonique : Obtenir votre clé API (API XML PAN-OS).
Sur le pare-feu (ou Panorama, si vous utilisez audit_fleet.py) :
Créez le rôle d'administrateur. Accédez à Appareil > Rôles d'administrateur (ou Panorama > Rôles d'administrateur). Cliquez sur Ajouter.
audit-config-and-op.Créez l'utilisateur d'audit. Accédez à Appareil > Administrateurs (ou Panorama > Administrateurs). Cliquez sur Ajouter.
audit-cve-2026-0300.audit-config-and-op.Générez la clé API avec les informations d'identification du nouvel utilisateur. PAN-OS n'expose pas de bouton « générer une clé API » dans l'interface Web — le point de terminaison keygen est le chemin pris en charge. Utilisez un corps POST afin que les informations d'identification ne soient pas journalisées dans les journaux d'accès URL :
read -rs AUDIT_PW; echo
export PAN_API_KEY="$(curl -ksX POST "https://fw1.example.com/api/" \
--data-urlencode "type=keygen" \
--data-urlencode "user=audit-cve-2026-0300" \
--data-urlencode "password=$AUDIT_PW" \
| grep -oE '<key>[^<]+' | cut -c6-)"
unset AUDIT_PW
read -rs lit le mot de passe sans l'afficher dans le terminal et sans le mettre dans l'historique du shell. Le script lit la variable PAN_API_KEY résultante depuis l'environnement et l'envoie via l'en-tête HTTP X-PAN-KEY — ni le mot de passe ni la clé n'apparaissent dans les journaux d'accès URL ni dans ps auxww pendant l'exécution du script.
Désactivez l'utilisateur lorsque le travail d'audit est terminé. Accédez à Appareil > Administrateurs, localisez audit-cve-2026-0300, cliquez sur Supprimer (ou désactivez l'utilisateur). Commitez. Cela invalide toutes les clés générées pour cet utilisateur.
read -rs couvre le mot de passe. Pour la clé dans PAN_API_KEY, préférez la définir de manière interactive via l'extrait ci-dessus plutôt que de la coller depuis un fichier. Si vous devez la charger depuis un fichier, utilisez set +o history pour la session.--insecure dans les deux scripts d'audit désactive entièrement la vérification du nom d'hôte TLS et la validation du certificat. Tout attaquant sur le chemin peut intercepter la réponse d'audit et rapporter portal_enabled=False pour un appareil compromis. Le script audit_fleet.py exige --accept-mitm-risk en plus de --insecure pour les balayages de flotte, car le rayon d'explosion d'une réponse empoisonnée s'étend à toute la flotte.0 — aucun portail activé sur aucun vsys audité2 — aucun vsys trouvé (configuration transitoire ou non prise en charge)3 — portail activé sur au moins un vsys (examen requis)4 — échec de l'appel API (authentification, TLS, réseau)La sortie non nulle sur « portail activé » est intentionnelle — elle permet de brancher le script dans des pipelines CI / de balayage de flotte qui ont besoin d'un signal clair.
Sous licence Apache License, Version 2.0. Voir LICENSE pour les conditions complètes.
L'utilisation commerciale est autorisée ; l'attribution est requise (conservez l'avis de droit d'auteur et le fichier de licence dans les œuvres dérivées).
Copyright 2026 Tailwind Resource Group.