
Detectar de forma segura la omisión de autenticación de Veeam Service Provider Console CVE-2026-58073
Un detector seguro y no autenticado para las vulnerabilidades KB4893 en Veeam Service Provider Console (publicado el 2026-08-04). Responde una pregunta por objetivo, antes de cualquier autenticación o TLS: ¿están presentes las correcciones de KB4893 en esta consola?
El par principal es una cadena. CVE-2026-58073 (CVSS 9.5) permite que un par de red no autenticado suplante a un agente de gestión conectado y reciba el certificado real de ese agente, porque el handshake del agente decide la autorización a partir del GUID que el par escribió en su propio certificado. CVE-2026-58072 (CVSS 9.0) es una escritura arbitraria de archivos alcanzable una vez que tienes una identidad de agente. Encadenadas, son ejecución remota de código no autenticada en la consola que gestiona las copias de seguridad de cada inquilino. El mismo aviso también corrige CVE-2026-58071 (CVSS 8.2, API de appliance proxy como Portal Administrator) y CVE-2026-58067 (CVSS 8.7, DoS no autenticado por agotamiento de memoria). CVE-2026-58073 y CVE-2026-58072 fueron reportados a Veeam a través de HackerOne; el aviso no menciona al reportero.
Este script no intenta suplantación, no solicita un certificado ni escribe archivos. Lee la generación de protocolo anunciada por el router y nada más.
Sí. El detector está diseñado para uso en producción y evaluación:
Connector que nombra un receptor que no existirá. No se negocia ninguna sesión TLS, no se
presenta ningún certificado y SaveFiles nunca se llama.ChannelHostProxy.m_multiplexers. No se registra ningún receptor, no se construye
ningún canal o multiplexor, no se toca ningún registro de agente. Un handshake de tipo Receiver
sí registraría un nombre; esta herramienta nunca envía uno.ConnectionHub.log, cada una con el nombre de receptor bf-probe-<uuid4> para que un defensor pueda
distinguir un escaneo de un ataque. Las líneas exactas están abajo.VULNERABLE después de
demostrar que es un VSPC ConnectionHub (ver abajo), por lo que un servicio TCP silencioso no puede
confundirse con una consola sin parchear.Por objetivo, la herramienta abre dos conexiones TCP y envía un handshake de ConnectionHub en cada una,
nombrando un receptor bf-probe-<uuid4> que no existirá.
Con el --transport auto predeterminado, un objetivo cuyo transporte no es el implicado por su puerto
cuesta una conexión extra: la sonda de transporte incorrecto se rechaza durante el handshake, antes de
que se lea cualquier nombre de receptor, y luego se usa el transporte correcto para ambas sondas reales.
Fija --transport direct o --transport gateway para mantenerlo en exactamente dos conexiones — vale la
pena si has cotizado un número de conexiones en una solicitud de cambio.
Estado cambiado en el servidor: ninguno. La ruta de código Connector realiza una búsqueda en el
diccionario de ChannelHostProxy.m_multiplexers, falla y devuelve un error. No se registra ningún
receptor, no se crea ningún multiplexor o canal, no se negocia ninguna sesión TLS, no se toca ningún
registro de agente. Esta herramienta nunca envía un handshake de tipo Receiver, que es el que
registraría un nombre.
Las entradas de registro se escriben en
%ProgramData%\Veeam\Veeam Availability Console\Log\Server\ConnectionHub.log. Textualmente de un
ConnectionHub 9.2.1.33875 en vivo, con marcas de tiempo y JSON de alcance recortados:
sonda 1 (versión 6), tanto builds parcheados como sin parchear:
[INFO] ChannelHostProxy: Accept connection begin {"RemoteEndPoint":"<ip>:<port>","Line":"1"}
[INFO] ChannelHostProxy: Accept connection end {"RemoteEndPoint":"<ip>:<port>","Line":"2",...}
[WARN] ChannelHostProxy: Cannot connect transmitter. Requested receiver not found
(receiver name:bf-probe-<uuid>) {"RemoteEndPoint":"<ip>:<port>","Line":"3",...}
sonda 2 (versión 7), solo builds parcheados:
las mismas tres líneas
sonda 2 (versión 7), builds sin parchear:
[INFO] ChannelHostProxy: Accept connection begin
[WARN] ChannelHostProxy: Handshake failed. Reason:Unsupported client version "7"
[INFO] ChannelHostProxy: Accept connection end
Dos conexiones, seis líneas, sin otras entradas y sin cambio de estado — confirmado en un host en vivo.
La cadena literal bf-probe- en ConnectionHub.log identifica el tráfico de esta herramienta, por lo
que un defensor puede atribuirlo y un equipo de escaneo puede demostrar lo que envió. Cambia
RECEIVER_PREFIX en el código fuente si necesitas un marcador diferente.
El router de agentes de gestión de ConnectionHub lee un handshake de cliente antes de cualquier
autenticación o TLS, y Request.Read valida la versión de protocolo anunciada por el cliente contra un
rango codificado. La corrección amplió ese rango en el mismo build que corrigió los CVE:
| Build | Comprobación | Acepta |
|---|---|---|
<= 9.2.1.33875 (vulnerable) | (uint)(versionByte - 3) <= 3 | 3, 4, 5, 6 |
>= 9.3.0.35057 (parcheado) | (uint)(versionByte - 3) <= 4 | 3, 4, 5, 6, 7 |
Así que un handshake que anuncia la versión 7 es un discriminador binario limpio. El detector envía dos sondas por objetivo, en este orden por una razón (la detección de transporte puede añadir una tercera — ver abajo):
| Sonda | Anuncia | Propósito |
|---|---|---|
| 1 | versión 6 | Debe devolver Requested receiver not found, demostrando que el objetivo realmente es un VSPC ConnectionHub |
| 2 | versión 7 | Una respuesta significa PATCHED; el silencio significa VULNERABLE |
Sin la compuerta de la etapa uno, el silencio en la sonda 2 también coincide con cualquier servicio TCP silencioso en internet, y los firewalls se reportarían como consolas Veeam vulnerables.
Funciona sobre ambas rutas que usa un agente de gestión:
| Transporte | Puerto | Exposición |
|---|---|---|
| Directo al ConnectionHub | 9999 | normalmente interno |
| A través de un gateway de Veeam Cloud Connect | 6180 | expuesto a internet por diseño |
La ruta del gateway necesita un prólogo de relay que la ruta directa no debe tener, por lo que la sonda 1
sirve también como detección de transporte. Con el --transport auto predeterminado, prueba un
transporte y, si la compuerta de huella no pasa, prueba el otro. El que pase queda fijado, y la sonda
2 lo reutiliza — un archivo de objetivos mixto no necesita anotación por host.
El fijado es esencial. Si la sonda 2 pudiera reintentar en el otro transporte, el silencio ya no sería
atribuible a la comprobación de versión, solo a "una de dos rutas de bytes no respondió", que es cómo se
fabrica un VULNERABLE falso.
Qué transporte se prueba primero lo decide el puerto, y eso no es cosmético — los dos desajustes fallan a velocidades muy diferentes:
| Desajuste | Cómo lo lee el extremo remoto | Coste |
|---|---|---|
| Prólogo de relay → hub directo | meta int16 de hostType 44 / versionByte 0, falla la comprobación de rango de Request.Read | descartado en un round trip |
| Handshake directo → gateway | longitud de frame int32 de 1,012,729,346 | el gateway espera bytes que nunca llegan; agota el timeout completo |