Ilustración abstracta de pintura fluida en tonos rojo, naranja y crema para la noticia: Diez fallos dan root en Control Web Panel y un backdoor vive en cwpsrv

Vulnerabilidades

Diez fallos dan root en Control Web Panel y un backdoor vive en cwpsrv

Control Web Panel acumula diez CVE que llevan de una cuenta de hosting a root y XLab describe CWPdoor, un cwpsrv troyanizado que borra sus huellas del log.

Un Control Web Panel anterior a la versión 1.12 entrega root a quien conozca el nombre de una sola cuenta de hosting, sin contraseña ni sesión. Es la conclusión de CWP2Shell, la investigación que VulnCheck publicó el 3 de noviembre de 2026 con diez CVE del panel antes conocido como CentOS Web Panel, dos días antes de que QiAnXin XLab describiera CWPdoor, una copia recompilada del servidor web cwpsrv de ese mismo panel que ejecuta órdenes firmadas como root y las borra del log de acceso.

  • Diez CVE de Control Web Panel, publicados el 2 de noviembre de 2026, permiten pasar de un nombre de cuenta de hosting a root en builds anteriores a 1.12 y de cualquier cuenta a root en builds anteriores a 1.29.
  • Ninguno está en KEV ni tiene explotación confirmada, pero el fallo de 2025 del mismo panel sí se explotó y entró en el catálogo de CISA.
  • CWPdoor es un cwpsrv recompilado con backdoor que XLab encontró en una muestra subida desde Brasil, se instala con root ya obtenido y no deja rastro en el access log.
  • Antes de actualizar a 1.30.5, comprueba el binario con los comandos de XLab y, si hay indicios, trata el servidor como comprometido y rota todas las credenciales.
Esquema de Valentin Lobstein con los cuatro pasos de CWP2Shell, de la cuenta alice al root en Control Web Panel
Fuente: Valentin Lobstein, «CWP2Shell: The Login Page That Never Says No»

El esquema de Valentin Lobstein, autor de la investigación, resume el recorrido en cuatro pasos: identificar una cuenta de hosting existente, ejecutar un módulo del panel de usuario sin sesión, reenviar la orden a la API local que corre como root y obtener uid 0. Las versiones 1.29 y posteriores cierran las diez vulnerabilidades, pero el fabricante tardó dos meses y medio en completarlas y nunca nombró un CVE en su changelog.

Un redirect que no detiene PHP, la raíz común de CWP2Shell

El panel de usuario de CWP, que escucha en el puerto 2083, despacha cada petición a un módulo PHP cuyo nombre llega como parámetro. Según el informe de VulnCheck, el filtro de ese parámetro solo buscaba XSS y permitía recorrer directorios para incluir cualquier fichero PHP del disco (CVE-2026-73695). El segundo fallo es el que convierte el anterior en un problema sin autenticación: cuando no hay sesión, el código devuelve una redirección al formulario de login pero no termina la ejecución, así que el módulo elegido se ejecuta igualmente (CVE-2026-73696). VulnCheck lo resume en una frase, «the redirect is cosmetic, the command ran before it» (la redirección es cosmética, el comando se ejecutó antes).

Diagrama del despachador PHP de Control Web Panel que devuelve un 302 y sigue ejecutando el módulo elegido por el atacante
Fuente: Valentin Lobstein, «CWP2Shell: The Login Page That Never Says No»

El diagrama de Lobstein ilustra esa secuencia: el cliente recibe un 302 y lo sigue, mientras el servidor termina de ejecutar el módulo. Dos de esos módulos confiaban en que el despachador ya había autenticado al visitante y aceptaban escrituras de ficheros y parámetros sin sanear hacia una shell, lo que permite ejecutar comandos con los privilegios de la cuenta de hosting (CVE-2026-73697 y CVE-2026-77876). El panel de administración de CWP, en cambio, maneja el mismo caso de forma correcta, con una lista blanca de módulos y una salida explícita tras el redirect.

La escalada a root viene de la API interna del panel de usuario, que escucha solo en loopback pero se ejecuta como root y con acceso root a MySQL. VulnCheck documenta rutas sin comprobación de token (CVE-2026-77877), dos inyecciones de comandos en operaciones de restauración y validación (CVE-2026-77878 y CVE-2026-104080), una inyección SQL en la comprobación del propio token que permite falsificarlo (CVE-2026-77879), otra inyección de comandos en el cambio de contraseña (CVE-2026-77880) y una inyección SQL ciega en el panel de control (CVE-2026-77881). Es una construcción parecida a la que la misma empresa decodificó en los trece fallos de Wazuh en octubre: ningún fallo es crítico por separado y la suma termina en root.

Diez CVE, tres parches silenciosos y un changelog sin la versión 1.16

Las puntuaciones merecen una aclaración. NVD muestra los diez registros, publicados el 2 de noviembre, con estado Deferred y sin análisis propio, de modo que las cifras disponibles son las de VulnCheck como CNA. En la ficha de CVE-2026-73695 ese vector incluye privilegios bajos, porque cada CVE se evalúa aislado. El informe, en cambio, puntúa el acceso inicial en 9,8 y la cadena en 10,0 porque el fallo del redirect elimina el requisito de sesión y el resultado final es root con cambio de ámbito. Las dos lecturas son coherentes, pero quien priorice por la puntuación de NVD verá una vulnerabilidad alta donde el investigador ve una crítica.

Campo

Dato

CVE

CVE-2026-73695, CVE-2026-73696, CVE-2026-73697, CVE-2026-77876, CVE-2026-77877, CVE-2026-77878, CVE-2026-77879, CVE-2026-77880, CVE-2026-77881 y CVE-2026-104080

CVSS y vector

De 5,5 a 8,8 en CVSS 3.1 por CVE, puntuados por VulnCheck como CNA (el más alto, CVE-2026-73695, con AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H), y 9,8 para el acceso inicial y 10,0 para la cadena completa según el informe

Producto

Control Web Panel (CWP7), panel de usuario en el puerto 2083 y API interna del puerto 2302

Versiones afectadas

webpanel anteriores a 1.12 para el acceso sin autenticación, anteriores a 1.29 para la escalada a root desde cualquier cuenta de hosting

Versiones corregidas

1.12 (8 de septiembre de 2026), 1.16 (29 de septiembre), 1.29 (31 de octubre), y la actual es 1.30.5, del 8 de noviembre

Explotación activa

Sin confirmar a 8 de noviembre de 2026, y ninguno de los diez CVE está en el catálogo KEV de CISA

Gravedad

Alta por CVE según el CNA, crítica para la cadena completa según VulnCheck

El calendario de la corrección es la parte menos tranquilizadora. VulnCheck asignó nueve de los CVE en agosto de 2026 y el décimo el 6 de octubre, y reconstruyó cada parche a partir del código decodificado de las builds porque el fabricante no documentó ninguno. La versión 1.9 del 21 de agosto anunciaba mejoras de seguridad y no corregía nada de la cadena. La 1.12 del 8 de septiembre cerró la entrada sin autenticación. La 1.16, una build del 29 de septiembre que no tiene entrada propia en el changelog de CWP, arregló los módulos del panel de usuario y dos de los fallos de la API. Los otros cuatro siguieron abiertos en la 1.23 del 24 de octubre y solo se cerraron entre la 1.27 del 30 de octubre y la 1.29 del día siguiente. El 2 de noviembre el investigador decodificó la 1.30 y comprobó que los diez estaban corregidos sin regresiones.

El precedente pesa. CVE-2025-48703, una inyección de comandos en el módulo de ficheros del mismo panel de usuario, entró en el catálogo KEV de CISA el 4 de noviembre de 2025 con plazo hasta el 25 de ese mes, y CVE-2022-44877 lo había hecho el 17 de enero de 2023. Según VulnCheck, el parche de 2025 añadió una comprobación a un único módulo y dejó intacto el flujo sin autenticación, de forma que la PoC pública pasó a devolver 403 mientras el resto de módulos seguía siendo alcanzable. La build 1.8 que probó el investigador ya incluía esa corrección y aun así llegaba a root.

CWPdoor, el cwpsrv recompilado que XLab encontró en un servidor de Brasil

El 5 de noviembre, con la cadena CWP2Shell publicada dos días antes, QiAnXin XLab describió un implante distinto para el mismo producto. La prueba de que hay víctimas reales llegó por VirusTotal. El 30 de septiembre de 2026 alguien subió desde Brasil un archivo llamado evidencia.tgz con dos ficheros: libkeyutils.so.1.5.2, que la mayoría de motores identifica como el backdoor Ebury, y cwpsrv.suspeito, que es CWPdoor y tenía cero detecciones. Para XLab eso demuestra que «real victims already exist in the wild» (ya existen víctimas reales). El laboratorio no sabe qué vulnerabilidad usan los atacantes para obtener el root necesario ni si Ebury y CWPdoor los plantó el mismo grupo, y no publica recuento de servidores infectados. La fórmula de la actualización falsa recuerda a la que copió credenciales root en 2.950 servidores con cPGuard la semana pasada, aunque aquí el script lo ejecuta alguien que ya está dentro. La captura de VirusTotal que incluye el informe muestra 25 motores sobre la biblioteca de Ebury y ninguno sobre cwpsrv.suspeito.

Resultado de VirusTotal del archivo evidencia.tgz subido desde Brasil con libkeyutils.so.1.5.2 y cwpsrv.suspeito
Fuente: QiAnXin XLab, «CWPdoor: The Invisible Backdoor Living Inside Control Web Panel»

Su informe sobre CWPdoor parte de un script capturado el 29 de junio de 2026 que se hace pasar por una actualización de cwpsrv, el servidor web derivado de Nginx que sirve el propio panel. El script exige root, solo acepta las versiones 1.15.10 (EL7) y 1.24.0 (EL8 y EL9) de cwpsrv, descarga el binario sustituto desde 136.0.141.71, detiene el servicio, sobrescribe /usr/local/cwpsrv/bin/cwpsrv y lo reinicia comprobando que los procesos vuelven a levantarse.

Fragmento del script cwpsrv_update.sh que restaura marcas de tiempo, borra el historial y avisa a 136.0.141.71
Fuente: QiAnXin XLab, «CWPdoor: The Invisible Backdoor Living Inside Control Web Panel»

El fragmento del script que publica XLab muestra la fase de limpieza: borra el fichero temporal y la copia de seguridad del binario original, devuelve al nuevo binario y a su directorio las marcas de tiempo originales para que ls y stat no delaten el cambio, elimina la orden del historial de la shell e informa del resultado al mismo servidor. XLab insiste en que «cwpdoor is not standalone malware» (cwpdoor no es un malware independiente), es código añadido al fuente de cwpsrv y recompilado.

Una vez instalado, el binario se comporta como un cwpsrv normal hasta que recibe una petición con tres cabeceras HTTP concretas: una marca de tiempo que debe caer en una ventana de 300 segundos, la orden cifrada con AES-256-CBC y codificada en Base64, y una firma RSA sobre ambas que se verifica contra una clave pública embebida en el binario. Solo quien tenga la clave privada puede activarlo, y cualquier petición sin firma válida se sirve como tráfico normal, así que un escaneo externo no distingue un panel infectado de uno limpio. La orden se ejecuta a través de un proceso auxiliar conectado por un socket Unix llamado ngx_http_integrity_helper, y la salida vuelve cifrada en una respuesta 200 de tipo application/octet-stream.

Salida de netstat y ss en un servidor con cwpsrv infectado donde aparece el socket ngx_http_integrity_helper
Fuente: QiAnXin XLab, «CWPdoor: The Invisible Backdoor Living Inside Control Web Panel»

La captura de XLab compara la salida de netstat, donde el servidor parece limpio con cwpsrv escuchando en sus puertos habituales, con la de ss -axp, donde aparece el socket del implante. La segunda pieza del ocultamiento está en el registro: cuando una petición activa el backdoor, el código sustituye el puntero del módulo de log de Nginx en el contexto de esa petición, de modo que no se escribe en el access log. XLab describe el conjunto como un ciclo «hidden from view and absent from the logs» (oculto a la vista y ausente de los logs). Es la misma idea de esconderse dentro del demonio legítimo que ya vimos en KeyDrift dentro de Cisco SD-WAN, aplicada ahora a un panel de hosting.

Nada en los dos informes vincula CWPdoor con CWP2Shell: VulnCheck no menciona el implante y XLab no cita los CVE. Lo que sí comparten es el producto y el resultado, un servidor de hosting con root en manos ajenas.

Entre 23.000 y 340.000 paneles CWP a la vista, sin cifra para España

Las cifras de exposición varían según quién mida y qué huella use. VulnCheck cuenta unos 210.000 hosts con la huella de CentOS WebPanel en el puerto 2083 en ZoomEye y unos 23.000 con el banner cwpsrv en Shodan, y su propia telemetría identificaba el 3 de noviembre 118.151 observaciones de servicios CWP, 19.834 de ellas en el puerto del panel de usuario. El informe pide tomar esos números como orden de magnitud, no como censo, por la cantidad de honeypots e instancias aparcadas que arrastran. XLab, con la plataforma Hunter de QiAnXin, contó más de 340.000 instancias expuestas en el último mes.

Tabla de la plataforma Hunter de QiAnXin con paneles Control Web Panel expuestos a internet por país y puerto
Fuente: QiAnXin XLab, «CWPdoor: The Invisible Backdoor Living Inside Control Web Panel»

La tabla de Hunter que publica XLab reparte esas instancias por país: Estados Unidos encabeza la lista con 91.641, seguido de Francia con 59.056 y Alemania con 34.301, y España no aparece entre los diez primeros. Cuando se escribe esta noticia ninguna fuente publica un recuento específico para España. INCIBE-CERT recoge CVE-2026-73696 en su base de vulnerabilidades, que se alimenta de NVD, pero no había publicado aviso propio sobre CWP2Shell ni sobre CWPdoor el 8 de noviembre. CWP es gratuito y habitual en VPS de pequeños proveedores y revendedores de hosting, el perfil de servidor que rara vez tiene EDR y que suele administrar una sola persona.

Ostorlab, que revisó los avisos el 2 de noviembre, recordaba que el fabricante presume de más de 35.000 servidores en producción y una comunidad de 94.000 miembros, y que no existía PoC pública ni constancia de explotación. ThreatDefence, que republicó la investigación de XLab el 6 de noviembre con sus propias consultas a VirusTotal, contaba ese día siete motores que detectaban el script instalador y ocho el binario de EL7, mientras que el binario de EL8 y EL9 no estaba en la plataforma.

Comprobar el binario cwpsrv, subir a 1.30.5 y cerrar los puertos 2083 y 2087

El orden importa, porque actualizar un servidor que ya tiene CWPdoor sustituye el binario, pero no deshace el root que lo instaló ni las credenciales que el atacante haya leído. Por eso la comprobación va antes que el parche. XLab propone tres comandos para saber si cwpsrv está troyanizado, y ThreatDefence los amplía con la lectura del tiempo de cambio del inodo, que el instalador no puede falsificar como hace con la fecha de modificación.

ss -axp | grep -i integrity
strings /usr/local/cwpsrv/bin/cwpsrv | grep -i 'X-Ngx-Integrity'
md5sum /usr/local/cwpsrv/bin/cwpsrv
stat -c 'modify=%y change=%z %n' /usr/local/cwpsrv/bin/cwpsrv
ls -la /usr/local/cwpsrv/bin/ | grep -E 'cwpsrv\.prev-|cwpsrv_'
ps -eo pid,ppid,user,lstart,args --forest | grep -B1 -A3 '[c]wpsrv'

Cualquier coincidencia en las dos primeras líneas significa infección. Un hash que coincida con los de la tabla de abajo, un fichero cwpsrv.prev o un proceso auxiliar colgando del master de cwpsrv apuntan en la misma dirección.

  1. Si hay indicios de CWPdoor, trata el servidor como comprometido con root: aísla, conserva una imagen para el análisis, reinstala desde cero y rota todas las credenciales del panel, de MySQL, de FTP, de correo y de SSH, además de las claves API de los clientes alojados. XLab recomienda restaurar la copia cwpsrv.prev si existe, pero el propio instalador la borra cuando el reemplazo sale bien.
  2. Actualiza a CWP 1.30.5, publicada el 8 de noviembre, o como mínimo a 1.29. Cualquier build anterior a 1.12 permite root sin autenticación con un nombre de cuenta, y cualquiera anterior a 1.29 permite a cualquier cuenta de hosting convertirse en root.
  3. Saca de internet el panel de usuario (2082 y 2083) y el de administración (2030, 2031, 2086 y 2087). Si los clientes necesitan el panel, ponlo detrás de una VPN o de una lista blanca de direcciones, que es la recomendación literal de VulnCheck incluso para builds corregidas.
  4. Busca en los logs de acceso de cwpsrv peticiones al panel de usuario con secuencias de recorrido de directorios en el parámetro de módulo y accesos a los módulos de edición de php.ini o de directorios protegidos sin un login previo en la misma sesión, que son las trazas que describen VulnCheck y Ostorlab. Revisa también ficheros PHP recientes en /tmp y en los directorios servidos por el panel. Un intento fallido puede no dejar rastro.
  5. Vigila la integridad de /usr/local/cwpsrv/bin/ con auditd o una herramienta de integridad de ficheros y bloquea el tráfico saliente hacia 136.0.141.71. La versión 1.30.3 añadió detección de criptomineros al panel, un síntoma frecuente en servidores de hosting comprometidos que el blog analizó en su guía sobre los riesgos del minado no autorizado.
  6. Si administras hosting para terceros en España y confirmas un compromiso, notifícalo a INCIBE-CERT, y a la AEPD en las 72 horas siguientes si hay datos personales de clientes afectados.

Los indicadores de CWPdoor que publica XLab, con las URL tal como aparecen en su informe, caben en una tabla.

Tipo

Valor

Contexto

hash MD5

e505d4ffa21cf494a5dc2d7c8f4f1236

Script instalador cwpsrv_update.sh, exige root y sustituye el binario

hash MD5

965aea67fb40de1bab5169ada993349f

cwpsrv 1.15.10 troyanizado para EL7

hash MD5

d3f4e95113d49ab3991b45e457bda75b

cwpsrv 1.24.0 troyanizado para EL8 y EL9

IP

136.0.141.71

Servidor de descarga de los binarios y de notificación del resultado, alojado en Evoxt (Países Bajos) según ThreatDefence

URL

http://136.0.141[.]71/static/cwpsrv_update.sh

Descarga del instalador

URL

http://136.0.141[.]71/static/cwpsrv_1.15.10

Descarga del binario para EL7

URL

http://136.0.141[.]71/static/cwpsrv_1.24.0

Descarga del binario para EL8 y EL9

ruta de archivo

/usr/local/cwpsrv/bin/cwpsrv

Binario sustituido por el implante

ruta de archivo

/usr/local/cwpsrv/bin/cwpsrv.prev-AAAAMMDD-HHMMSS

Copia de seguridad que crea el instalador y borra si la sustitución funciona

Las cabeceras X-Ngx-Integrity-Time, X-Ngx-Integrity-Data y X-Ngx-Integrity-Sig y el socket ngx_http_integrity_helper completan la lista, pero no aparecerán en el access log de un servidor infectado, porque el implante borra precisamente esas peticiones. ThreatDefence publica además consultas KQL para Microsoft Defender y Sentinel que buscan conexiones a la IP, sustituciones del binario y shells lanzadas por cwpsrv, con el consejo de retroceder hasta el 1 de junio de 2026.

Un parche que devolvía 403 y seguía ejecutando, la lectura del blog

De CWP2Shell nos interesa el método tanto como la cadena. VulnCheck no se fió del changelog y decodificó el código ionCube de cada build para comprobar qué se había arreglado. Esa comprobación revela que la corrección de 2025 convirtió un exploit público en un 403 y dejó el fallo de fondo intacto, que una build sin entrada en el changelog (la 1.16) llevaba la mitad de las correcciones y que durante un mes, entre el 29 de septiembre y el 31 de octubre, cualquier cliente de hosting con cuenta en un CWP al día podía hacerse root. Quien gestione servidores con este panel no tiene forma de saberlo leyendo las notas de versión, igual que los administradores de GitLab con Ruby propio no podían saber que el parche no les cubría.

CWPdoor añade la segunda lección. El implante necesita root para instalarse y XLab no sabe de dónde sale ese root. Con una vulnerabilidad en KEV desde hace un año, una cadena completa publicada el 3 de noviembre y cientos de miles de paneles expuestos, la hipótesis de que algunos de esos servidores ya estaban en manos ajenas antes del parche no necesita confirmación para cambiar lo que toca hacer hoy, que es mirar el binario antes de actualizar y no dar por limpio un panel solo porque la versión que muestra sea la última.

Queda por ver si el fabricante publica un aviso con los CVE, como hicieron QNAP o Zyxel tras semanas de silencio en casos recientes, y que algún laboratorio relacione el instalador de CWPdoor con una de las vías de entrada conocidas. Hasta entonces, la comprobación de ss -axp en cada servidor con CWP es la medida más barata que se puede tomar esta semana.

Temas

No hay comentarios todavía