
Herramienta de auditoría de solo lectura para CVE-2026-0300 (exposición del Portal de Autenticación User-ID de PAN-OS)
Herramientas de auditoría de solo lectura para CVE-2026-0300 — el desbordamiento de búfer no autenticado en el Portal de Autenticación de User-ID de PAN-OS (anteriormente conocido como "Portal Cautivo") en firewalls de las series PA y VM.
Este repositorio acompaña al aviso de seguridad de Tailwind Resource Group TRG-SA-2026-003 y proporciona:
audit_portal.py — Nivel 1: auditoría de un solo firewallaudit_fleet.py — Nivel 2: barrido de flota impulsado por Panorama (concurrente)panos_audit.py — biblioteca compartida utilizada por ambas CLILos scripts son de solo lectura. Emiten consultas de tipo show contra la API XML de PAN-OS y nunca modifican la configuración. La clave de API se envía mediante el encabezado HTTP X-PAN-KEY en lugar de como parámetro de consulta en la URL, por lo que no aparece en los registros de acceso del plano de gestión de PAN, en los registros de proxies con inspección TLS ni en los argumentos de proceso del auditor.
El registro CVE utiliza el nombre de función moderno "Portal de Autenticación de User-ID". El esquema XML de PAN-OS, las opciones de CLI y las rutas de URL de documentación aún utilizan el vocabulario heredado captive-portal. Los operadores que auditan flotas con show config running | match authentication-portal pasarán por alto silenciosamente toda configuración porque esa cadena nunca aparece como elemento de configuración. Esta herramienta busca el nombre de elemento correcto según el esquema, independientemente de cuándo se creó la configuración.
El análisis completo de Tailwind sobre este detalle de nomenclatura se encuentra en TRG-SA-2026-003, "La huella heredada del Portal Cautivo".
pip install--insecure solo para auditorías de puesta en marcha puntualesexport PAN_API_KEY="<key>"
./audit_portal.py --hostname fw1.example.com
Ejemplo de salida en tabla:
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
Otros formatos de salida: --output json o --output csv.
Otras opciones: --vsys <nombre> para auditoría de un solo vsys, --timeout/--retries para upstreams lentos, --debug para detalles de error detallados en stderr.
export PAN_API_KEY="<panorama-key>"
./audit_fleet.py --hostname panorama.example.com --workers 16 --output csv > fleet-audit.csv
Cada fila del CSV es un dispositivo-vsys con estado del portal, host de redirección, modo, enlaces de interfaz y una clasificación de riesgo. El script utiliza el parámetro de API target=<serial> de Panorama, por lo que nunca se conecta directamente a los firewalls gestionados: una sola conexión a Panorama barre toda la flota.
Opciones destacadas:
--workers N — hilos de auditoría concurrentes (predeterminado 8, máximo 32). Una flota de 1000 dispositivos se completa en minutos en lugar de la hora o más que tomaría un barrido en serie.--timeout, --retries — ajustes por llamada a la API. Los URLError transitorios y los HTTP 5xx se reintentan con retroceso acotado.--exclude-disconnected — de forma predeterminada, los dispositivos desconectados se incluyen con risk=DISCONNECTED para que sigan siendo visibles durante la ventana de parcheo. Use esta opción para eliminarlos.--min-expected-devices N — advierte (stderr) si Panorama devuelve menos dispositivos que N. Útil para detectar truncamiento de respuesta frente a un tamaño de flota conocido.--serial-filter '0007*' — filtra por glob según el número de serie para auditar un subconjunto.--debug — imprime detalles de error detallados por dispositivo en stderr (incluye cadenas reason del upstream; desactivado por defecto para evitar filtrar nombres de host en CSV orientados al cliente).La columna risk en la salida es una de las siguientes:
| Etiqueta | Significado |
|---|---|
INFO_NOT_CONFIGURED | Sin bloque <captive-portal> en el dispositivo. Fuera del alcance de CVE-2026-0300. |
INFO_DISABLED | El portal está configurado pero enabled=no. La ruta de código vulnerable no está activa. |
REVIEW_POLICY_NO_BINDINGS | Portal habilitado, pero no se encontraron enlaces de interfaz en la configuración. Verificar mediante la WebUI. |
EXPOSED_LIKELY | Portal habilitado y vinculado a una zona cuyo nombre sugiere exposición no confiable (untrust, dmz, guest, external, internet, wan, public). Investigar primero. |
REVIEW_POLICY | Portal habilitado y vinculado a zonas con nombres internos. Revisar la política de seguridad para confirmar la accesibilidad. |
EXPOSED_LIKELY es una pista, no un veredicto: los nombres de zona son convenciones del operador, no una aplicación de seguridad. El script no puede reemplazar una revisión de política de seguridad; ordena la salida de la flota para indicar dónde debe centrarse la atención primero.
Sí hacen:
<captive-portal> por vsys (el nombre del elemento de esquema es siempre captive-portal, independientemente del nombre en la interfaz o la versión de PAN-OS).EXPOSED_LIKELY aparezcan primero en la salida de la flota.X-PAN-KEY para que no aparezca en los registros de acceso de URL ni en los argumentos de proceso.No hacen:
La clave de API de PAN-OS hereda el rol y los permisos del usuario que la genera.
Advertencia importante: no existe una concesión de API XML de solo lectura en PAN-OS.
Los permisos de Rol de Administrador en la pestaña API XML son binarios Habilitar/Deshabilitar por categoría: Configuración, Solicitudes Operativas, Commit, Exportar, Importar, Informe, Registro, Agente User-ID. Habilitar Configuración para la API XML permite tanto
showcomo accionesset/edit/delete/move/rename/clone. Habilitar Solicitudes Operativas permite operaciones<request>arbitrarias, incluido<request><restart>. Las pestañas de Web UI y API REST ofrecen Solo Lectura como opción; la pestaña de API XML no.Un "usuario de auditoría" creado al habilitar estas categorías de API XML posee autoridad completa de escritura de API XML en el dispositivo. Trate la clave resultante como una credencial privilegiada: limite su vigencia a la ventana de auditoría, guárdela en un gestor de secretos y deshabilite al usuario cuando el trabajo esté completo.
Referencia canónica de PAN: Obtenga su clave de API (API XML de PAN-OS).
En el firewall (o Panorama, si está usando audit_fleet.py):
Cree el Rol de Administrador. Navegue a Dispositivo > Roles de Administrador (o Panorama > Roles de Administrador). Haga clic en Agregar.
audit-config-and-op.Cree el usuario de auditoría. Navegue a Dispositivo > Administradores (o Panorama > Administradores). Haga clic en Agregar.
audit-cve-2026-0300.audit-config-and-op.Genere la clave de API con las credenciales del nuevo usuario. PAN-OS no expone un botón de "generar clave de API" en la WebUI: el endpoint de keygen es la ruta compatible. Use un cuerpo POST para que las credenciales no queden registradas en los registros de acceso de 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 lee la contraseña sin mostrarla en la terminal y sin incluirla en el historial del shell. El script lee la PAN_API_KEY resultante del entorno y la envía mediante el encabezado HTTP X-PAN-KEY: ni la contraseña ni la clave aparecen en los registros de acceso de URL ni en ps auxww mientras el script se ejecuta.
Deshabilite al usuario cuando el trabajo de auditoría esté completo. Navegue a Dispositivo > Administradores, localice audit-cve-2026-0300, haga clic en Eliminar (o deshabilite al usuario). Haga Commit. Esto invalida cualquier clave generada para ese usuario.
read -rs cubre la contraseña. Para la clave en PAN_API_KEY, prefiera configurarla de forma interactiva mediante el fragmento anterior en lugar de pegarla desde un archivo. Si debe cargarla desde un archivo, use set +o history para la sesión.--insecure en ambos scripts de auditoría deshabilita por completo la verificación del nombre de host TLS y la validación de certificados. Cualquier atacante en la ruta puede hacer MITM en la respuesta de auditoría e informar portal_enabled=False para un dispositivo comprometido. El script audit_fleet.py requiere --accept-mitm-risk junto con --insecure para barridos de flota porque el radio de explosión de una respuesta envenenada es de toda la flota.0 — ningún portal habilitado en ningún vsys auditado2 — no se encontró ningún vsys (configuración transitoria o no compatible)3 — portal habilitado en al menos un vsys (se requiere revisión)4 — falló la llamada a la API (autenticación, TLS, red)La salida no cero en "portal habilitado" es intencional: le permite conectar el script a canalizaciones de CI/barrido de flota que necesitan una señal clara.
Licenciado bajo la Licencia Apache, Versión 2.0. Consulte LICENSE para conocer los términos completos.
Se permite el uso comercial; se requiere atribución (conservar el aviso de copyright y el archivo de licencia en obras derivadas).
Copyright 2026 Tailwind Resource Group.