
Détecter en toute sécurité la contournement d'authentification de Veeam Service Provider Console CVE-2026-58073
Un détecteur sûr et non authentifié pour les vulnérabilités KB4893 de la Veeam Service Provider Console (publié le 04/08/2026). Il répond à une question par cible, avant toute authentification ou TLS : les correctifs KB4893 sont-ils présents sur cette console ?
La paire principale est une chaîne. CVE-2026-58073 (CVSS 9.5) permet à un pair réseau non authentifié d'usurper un agent de gestion connecté et de recevoir le véritable certificat de cet agent, car la poignée de main de l'agent décide de l'autorisation à partir du GUID que le pair a écrit dans son propre certificat. CVE-2026-58072 (CVSS 9.0) est une écriture de fichier arbitraire accessible une fois que vous détenez une identité d'agent. Enchaînées, elles constituent une exécution de code à distance non authentifiée sur la console qui gère les sauvegardes de chaque locataire. Le même avis corrige également CVE-2026-58071 (CVSS 8.2, API d'appliance proxyfiée en tant qu'administrateur du portail) et CVE-2026-58067 (CVSS 8.7, déni de service non authentifié par épuisement de la mémoire). CVE-2026-58073 et CVE-2026-58072 ont été signalées à Veeam via HackerOne ; l'avis ne nomme pas le rapporteur.
Ce script ne tente pas d'usurpation, ne demande pas de certificat et n'écrit aucun fichier. Il lit la génération de protocole annoncée par le routeur et rien d'autre.
Oui. Le détecteur est conçu pour une utilisation en production et en évaluation :
Connector nommant un récepteur qui n'existera pas. Aucune session TLS
n'est négociée, aucun certificat n'est présenté et SaveFiles n'est jamais appelé.ChannelHostProxy.m_multiplexers. Aucun récepteur n'est enregistré, aucun canal ou
multiplexeur n'est construit, aucun enregistrement d'agent n'est touché. Une poignée de main de type
Receiver enregistrerait un nom ; cet outil n'en envoie jamais.ConnectionHub.log, chacune portant le nom de récepteur bf-probe-<uuid4> afin qu'un défenseur
puisse distinguer un scan d'une attaque. Les lignes exactes figurent ci-dessous.VULNERABLE qu'après avoir prouvé
qu'elle est un ConnectionHub VSPC (voir ci-dessous), de sorte qu'un service TCP silencieux ne peut pas
être confondu avec une console non corrigée.Par cible, l'outil ouvre deux connexions TCP et envoie une poignée de main ConnectionHub sur chacune,
nommant un récepteur bf-probe-<uuid4> qui n'existera pas.
Avec le --transport auto par défaut, une cible dont le transport n'est pas celui impliqué par son port
coûte une connexion supplémentaire : la sonde de mauvais transport est rejetée pendant la poignée de
main, avant qu'aucun nom de récepteur ne soit lu, et le bon transport est ensuite utilisé pour les deux
véritables sondes. Épinglez --transport direct ou --transport gateway pour le maintenir à exactement
deux connexions — utile si vous avez cité un nombre de connexions dans une demande de modification.
État modifié sur le serveur : aucun. Le chemin de code Connector effectue une recherche de
dictionnaire dans ChannelHostProxy.m_multiplexers, échoue et renvoie une erreur. Aucun récepteur n'est
enregistré, aucun multiplexeur ou canal n'est créé, aucune session TLS n'est négociée, aucun enregistrement
d'agent n'est touché. Cet outil n'envoie jamais de poignée de main de type Receiver, qui est celle qui
enregistrerait un nom.
Les entrées de journal sont écrites dans
%ProgramData%\Veeam\Veeam Availability Console\Log\Server\ConnectionHub.log. Textuellement depuis un
ConnectionHub 9.2.1.33875 en direct, avec horodatages et JSON de portée tronqués :
sonde 1 (version 6), builds corrigés et non corrigés :
[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",...}
sonde 2 (version 7), builds corrigés uniquement :
les mêmes trois lignes
sonde 2 (version 7), builds non corrigés :
[INFO] ChannelHostProxy: Accept connection begin
[WARN] ChannelHostProxy: Handshake failed. Reason:Unsupported client version "7"
[INFO] ChannelHostProxy: Accept connection end
Deux connexions, six lignes, aucune autre entrée et aucun changement d'état — confirmé sur un hôte en direct.
La chaîne littérale bf-probe- dans ConnectionHub.log identifie le trafic de cet outil, de sorte
qu'un défenseur peut l'attribuer et qu'une équipe de scan peut prouver ce qu'elle a envoyé. Modifiez
RECEIVER_PREFIX dans le source si vous avez besoin d'un marqueur différent.
Le routeur d'agents de gestion ConnectionHub lit une poignée de main client avant toute authentification
ou TLS, et Request.Read valide la version de protocole annoncée par le client par rapport à une plage
codée en dur. Le correctif a élargi cette plage dans le même build qui a corrigé les CVE :
| Build | Vérification | Accepte |
|---|---|---|
<= 9.2.1.33875 (vulnérable) | (uint)(versionByte - 3) <= 3 | 3, 4, 5, 6 |
>= 9.3.0.35057 (corrigé) | (uint)(versionByte - 3) <= 4 | 3, 4, 5, 6, 7 |
Ainsi, une poignée de main annonçant la version 7 est un discriminateur binaire propre. Le détecteur envoie deux sondes par cible, dans cet ordre pour une raison précise (la détection du transport peut en ajouter une troisième — voir ci-dessous) :
| Sonde | Annonce | Objectif |
|---|---|---|
| 1 | version 6 | Doit renvoyer Requested receiver not found, prouvant que la cible est réellement un ConnectionHub VSPC |
| 2 | version 7 | Une réponse signifie PATCHED ; le silence signifie VULNERABLE |
Sans la barrière de l'étape 1, le silence de la sonde 2 correspondrait également à tout service TCP silencieux sur Internet, et les pare-feu seraient signalés comme des consoles Veeam vulnérables.
Il fonctionne sur les deux chemins qu'utilise un agent de gestion :
| Transport | Port | Exposition |
|---|---|---|
| Direct vers le ConnectionHub | 9999 | généralement interne |
| Via une passerelle Veeam Cloud Connect | 6180 | exposé à Internet par conception |
Le chemin de la passerelle nécessite un prologue de relais que le chemin direct ne doit pas avoir, donc
la sonde 1 sert également de détection de transport. Avec le --transport auto par défaut, il essaie un
transport, et si la barrière d'empreinte ne passe pas, il essaie l'autre. Celui qui passe est
verrouillé, et la sonde 2 le réutilise — un fichier de cibles mixte ne nécessite aucune annotation
par hôte.
Le verrouillage est essentiel. Si la sonde 2 pouvait réessayer sur l'autre transport, le silence ne
serait plus attribuable à la vérification de version, mais seulement à « l'un des deux chemins d'octets
n'a pas répondu », ce qui est ainsi qu'un faux VULNERABLE est fabriqué.
Le transport essayé en premier est décidé par le port, et ce n'est pas cosmétique — les deux inadéquations échouent à des vitesses très différentes :