- Les requêtes HTTP du réseau domestique ont été rejouées à l’identique environ 10 secondes plus tard depuis une IP DigitalOcean, révélant des signes d’exposition vers l’extérieur du trafic de plusieurs appareils derrière une passerelle Cox Panoramic Wifi
- Le suivi via VirusTotal et URLscan a montré que cette IP avait déjà été liée à des domaines de phishing et à des vagues de domaines du type
mot+6 chiffres+TLD, ce qui a soulevé l’hypothèse d’un algorithme de génération de domaines pour du C&C - Lors de l’analyse du portail Cox Business en 2024, une API basée sur Spring ainsi que sa documentation Swagger ont été exposées derrière
/api/cbma/, et de simples requêtes répétées permettaient de contourner la vérification d’autorisation - L’API exposée permettait la recherche de clients, la consultation de PII de comptes, la récupération d’adresses MAC d’équipements et même la modification des paramètres WiFi, tandis que la logique de génération de
encryptedValuepouvait aussi être appelée depuis le JavaScript frontend - Après le signalement, Cox a retiré l’API exposée en 6 heures, mais le service avait démarré en 2023, si bien que la cause de la compromission initiale du modem en 2021 reste distincte
Rejeu de requêtes HTTP observé sur le réseau domestique
- Pour tester une faille blind XXE, un serveur HTTP Python a été lancé sur une instance AWS, puis une requête
/test123a été envoyée depuis l’ordinateur de la maison- La requête d’origine est arrivée depuis l’IP domestique
98.161.24.100 - Environ 10 secondes plus tard, une IP inconnue
159.65.76.209a renvoyé la même requête vers le même chemin
- La requête d’origine est arrivée depuis l’IP domestique
- En demandant la même URL depuis Safari sur iPhone, la même IP a de nouveau rejoué la requête
- Le même phénomène s’est reproduit non seulement depuis l’ordinateur de la maison, mais aussi depuis d’autres appareils du réseau domestique
- Le même rejeu depuis cette IP a également été observé avec une nouvelle instance AWS sous Nginx et une instance GCP, ce qui rendait peu probable un problème propre à AWS
- Les hypothèses restantes étaient donc l’ISP, le modem ou une compromission sur le chemin réseau
- La recherche sur le propriétaire de l’IP a montré que
159.65.76.209appartenait à DigitalOcean, et non à l’ISP
Ancienne infrastructure malveillante liée à l’IP DigitalOcean
- Une recherche VirusTotal a permis de voir quels domaines avaient déjà été résolus vers cette IP
- Parmi les 5 domaines les plus récents, 3 étaient des sites de phishing et 2 ressemblaient à des serveurs mail
- Exemples de domaines :
regional.adidas.com.pyisglatam.onlineisglatam.tkmx12.limit742921.tokyomx12.jingoism44769.xyz
isglatam.onlineetisglatam.tkétaient des sites de phishing visantisglatam.com, une entreprise de cybersécurité sud-américaine- Le site réel d’ISG Latam indiquait qu’il s’agissait d’une société basée au Paraguay, partenaire de Crowdstrike, AppGate, Acunetix, DarkTrace et ForcePoint
- URLscan conservait des traces montrant que les deux domaines avaient hébergé des sites de phishing BeEF classiques
- Enregistrement associé : résultat URLscan
- La même IP était liée à la fois à des domaines liés à Adidas, au phishing d’ISG Latam et à ce qui ressemblait au rejeu du trafic du modem
- Il restait possible que l’IP ait tourné entre plusieurs propriétaires, mais l’intervalle entre les activités semblait trop long pour une réattribution immédiate à un autre utilisateur malveillant
Remplacement du modem et nouvelle enquête trois ans plus tard
- L’équipement utilisé était une passerelle Cox Panoramic Wifi, remplacée par un nouveau modem dans une boutique Cox
- L’ancien équipement devait être restitué car il était loué à l’ISP
- Aucun dump du firmware ni rétro-ingénierie n’a pu être réalisé
- Après l’installation du nouveau modem, le phénomène de rejeu des requêtes HTTP a complètement cessé
- Aucune autre IP n’est ensuite apparue dans les logs
- À l’époque, il était difficile d’aller plus loin au-delà de la conclusion que l’ancien modem avait été compromis
- Début 2024, environ trois ans plus tard, l’enquête a repris avec des contacts du secteur de la sécurité en se concentrant sur des formats de domaines comme
limit742921.tokyoetjingoism44769.xyz- Une recherche reverse IP a révélé plus de 1 000 domaines suivant le même motif pour l’IP concernée
- Tous les domaines suivaient la structure
mot+6 chiffres+TLD- En raison de l’enregistrement en masse et de cette structure algorithmique, cela ressemblait à un algorithme de génération de domaines utilisé par un opérateur malveillant pour dissimuler l’adresse de serveurs C&C
- Le dernier domaine observé avait été enregistré le 17 mars 2023, et plus aucun hôte résolu n’est apparu ensuite
- Le nouveau modem de remplacement était du même modèle, mais aucune vulnérabilité publique n’a été trouvée pour ce modèle via Google
Hypothèse autour des outils de support ISP et de TR-069
- En déplaçant le modem Cox vers un autre lieu, il a été confirmé qu’un agent du support ISP pouvait modifier à distance la configuration de l’équipement
- L’agent pouvait mettre à jour la configuration, changer le mot de passe WiFi et voir les appareils connectés
- Cette administration à distance repose sur le protocole TR-069, mis en œuvre en 2004
- L’ISP gère ainsi les équipements de son propre réseau via le port
7547 - Le protocole a déjà été évoqué dans des conférences DEF CON, mais il ne constituait pas une surface directement exposée à Internet
- L’ISP gère ainsi les équipements de son propre réseau via le port
- L’enquête s’est alors déplacée du protocole lui-même vers le site web interne d’administration des équipements utilisé par les agents, ainsi que vers l’API derrière celui-ci
- Si une telle API permettait de consulter ou de modifier la configuration des équipements clients, voire d’exécuter des commandes, elle pouvait constituer une voie de compromission du modem
Structure de l’API du portail Cox Business
- Le portail Cox Business fournit des fonctions d’administration distante des équipements, de configuration de règles de pare-feu et de surveillance du trafic réseau
- Les routes ont été extraites du fichier JavaScript frontend de la page de connexion,
main.36624ed36fb0ff5b.js- Plus de 100 appels API basés sur
/api/cbma/ont été identifiés - Exemples :
/api/cbma/voicemail/services/voicemail/inbox/transcribeMessage//api/cbma/profile/services/profile/userroles//api/cbma/accountequipment/services/accountequipment/equipments/eligibleRebootDevice
- Plus de 100 appels API basés sur
/api/cbma/renvoyait des réponses différentes du frontend classique, ce qui faisait penser à un reverse proxy pointant vers un backend séparé- Une requête
/api/anything_else/examplerenvoyait une redirection 301 - Une requête
/api/cbma/examplerenvoyait une erreur 500 Internal Server Error
- Une requête
- Les requêtes d’inscription incluaient plusieurs en-têtes liés à l’authentification
Clientid: cbmauserApikey: 5d228662-aaa1-4a18-be1c-fb84db78cf13Cb_session: unauthenticateduserAuthorization: Bearer undefined
- En changeant la méthode HTTP, une réponse d’erreur au format Spring a été renvoyée, confirmant que le backend reposait sur Spring
Documentation Swagger et contournement des ressources statiques
- Aucun chemin Spring Actuator n’a été trouvé, mais certaines routes Swagger UI restaient accessibles
- Le chemin
/api/cbma/userauthorization/swagger-ui/index.htmlrépondait
- Le chemin
- La page Swagger chargée au départ était vide
- Les ressources statiques comme
.png,.jset.cssétaient routées vers le chemin de l’hôte d’origine au lieu du proxy API, provoquant des redirections infinies
- Les ressources statiques comme
- Un test avec Burp Intruder en ajoutant
%00à%FFà la fin de l’URL a montré qu’en ajoutant%2f, c’est-à-dire un/encodé en URL, après un fichier.js, on obtenait un 200 OK- Exemple :
/swagger-initializer.js%2f
- Exemple :
- En utilisant la fonction match-and-replace de Burp pour ajouter
%2fà toutes les ressources statiques, la documentation Swagger s’est chargée correctement - Au total, environ 700 appels API ont été identifiés
account: 115voiceutilities: 73user: 70datainternetgateway: 57accountequipment: 55billing: 53ticket: 52- ainsi que
profile,voicecallmanagement,voicemail,userauthorization,csr, etc.
- Les API semblant les plus importantes pour les équipements et les comptes clients étaient
accountequipment,datainternetgatewayetaccount
Contournement de l’autorisation par simple répétition de requêtes
- Une vérification des endpoints GET pour savoir s’ils étaient accessibles sans authentification a montré que certains renvoyaient une erreur d’authentification, tandis que d’autres répondaient en 200 OK
- L’endpoint
profilesearchrenvoyait d’abord une réponse réussie contenant un résultat de recherche vide- La même requête pouvait parfois renvoyer
Authorization Error-Invalid User Token, puis réussir à nouveau si elle était renvoyée
- La même requête pouvait parfois renvoyer
- En renvoyant plusieurs fois la même requête, l’erreur d’autorisation finissait par disparaître et des résultats de recherche client étaient renvoyés
- Une recherche sur
coxrenvoyait10000+ hits - Une recherche sur
fbirenvoyait des résultats contenant les adresses physiques de bureaux locaux du FBI, clients de Cox Business
- Une recherche sur
- Le simple fait de répéter des requêtes API permettait donc un contournement d’autorisation, et le même problème semblait affecter plus de 700 API
Accès aux équipements clients et consultation des comptes
- Pour vérifier si l’API Cox Business pouvait aussi accéder à des équipements de réseau résidentiel, une API simple recevant une adresse MAC a été testée
- Endpoint :
/api/cbma/accountequipment/services/accountequipment/ipAddress?macAddress=:mac
- Endpoint :
- Après avoir récupéré l’adresse MAC sur son propre compte Cox puis répété la requête, l’adresse IPv4 du modem personnel a été renvoyée
- Cela a confirmé que cette API pouvait réellement communiquer avec les équipements Cox
- Une API listant les équipements à partir d’un ID de compte fonctionnait également
- Endpoint :
/api/cbma/accountequipment/services/accountequipment/v1/equipments/{accountId} - La réponse contenait des informations sur l’équipement Internet, vocal et TV
- Le modèle, le type d’équipement, l’adresse MAC, la liste des ports et le numéro de série étaient renvoyés
- Endpoint :
- Une API de consultation d’utilisateur basée sur l’e-mail renvoyait aussi des informations de comptes business
- Exemple de requête :
/api/cbma/user/services/user/admin@cox.net - Elle contenait l’e-mail, le nom, le numéro de téléphone, le statut, les permissions, le statut de propriétaire du profil et d’autres e-mails
- Exemple de requête :
- Une requête POST similaire de mise à jour de compte fonctionnait également, confirmant des capacités de lecture et d’écriture sur des comptes business
encryptedValue et modification de la configuration d’équipements
- Les requêtes de modification de la configuration matérielle exigeaient un paramètre
encryptedValue- Par exemple pour changer le mot de passe d’un équipement ou les paramètres WiFi
- La logique de génération et de déchiffrement de
encryptedValuea été retracée dans le JavaScript frontendencryptWithSaltandPaddingdecryptWithSaltandPadding
- Le PIN à 4 chiffres défini lors de la création d’un compte était lui aussi chiffré avec la même fonction ; il a donc été possible de poser un point d’arrêt dans le débogueur du navigateur à l’endroit où la fonction était appelée, puis de l’invoquer directement depuis la console
- En déchiffrant un
encryptedValuerécupéré dans une vraie réponse de compte, le format suivant a été observé- Numéro de compte Cox
- Nom de l’équipement
- ID de l’équipement
- Valeur inconnue
- Adresse MAC
- Libellé
- Même en remplissant arbitrairement la plupart des champs comme le numéro de compte et en mettant uniquement une adresse MAC valide pour générer un nouveau
encryptedValue, la requête réussissait- Le serveur ne vérifiait pas que l’ID de compte correspondait bien à l’adresse MAC
Possibilité de modifier arbitrairement la configuration de modems
- Une requête POST a été envoyée sur le propre équipement de l’auteur pour changer le SSID WiFi en
Curry- Endpoint :
/api/cbma/accountequipment/services/accountequipment/gatewaydevice/wifisettings - Le corps de la requête contenait
wifiSettings,additionalPropertiesetencryptedValue
- Endpoint :
- La réponse était
{"message": "Success"}; ensuite, le réseau a été brièvement coupé avant que l’équipement redémarre environ 5 minutes plus tard- Le SSID a bien été modifié en
Curry
- Le SSID a bien été modifié en
- Ce comportement montrait que les changements de configuration via l’API s’appliquaient réellement à l’équipement
- Un attaquant pouvait obtenir l’UUID d’un compte via la recherche client
- récupérer l’adresse MAC de l’équipement connecté
- puis lire ou modifier la configuration de l’équipement à partir de cette adresse MAC
- Ce niveau de privilège était comparable à celui de l’équipe support de l’ISP, avec un impact potentiel sur des millions d’équipements Cox
Portée de l’impact et scénarios d’attaque
- La combinaison des vulnérabilités montrait qu’un attaquant externe pouvait, sans prérequis, effectuer les actions suivantes
- exécuter des commandes et modifier la configuration de millions de modems
- accéder aux PII de clients Cox Business
- obtenir des privilèges comparables à ceux du support ISP
- Cox est le plus grand fournisseur privé de haut débit des États-Unis, le troisième fournisseur de télévision par câble, le septième opérateur téléphonique, et l’ISP le plus populaire dans 10 États
- Exemple de chaîne d’attaque :
- rechercher des cibles Cox Business par nom, numéro de téléphone, e-mail ou numéro de compte
- utiliser l’UUID renvoyé pour récupérer l’ensemble des PII du compte ainsi que les adresses MAC des équipements, e-mails, numéros de téléphone et adresses
- utiliser l’adresse MAC matérielle pour consulter le mot de passe WiFi et les appareils connectés
- exécuter des commandes arbitraires, modifier les propriétés des équipements et compromettre les comptes des victimes
- Parmi les plus de 700 API exposées, beaucoup offraient des fonctions d’administration, et le même problème d’autorisation apparaissait lors de la répétition des requêtes
Signalement à Cox et correctif
- La vulnérabilité a été signalée via le programme de responsible disclosure de Cox
- Cox a retiré les appels API exposés dans les 6 heures suivant le signalement et a commencé à corriger le problème d’autorisation
- Le lendemain, il n’était plus possible de reproduire la vulnérabilité
- Chronologie publique :
- 2024-03-04 : signalement de la vulnérabilité à Cox
- 2024-03-05 : application d’un hotfix ; les endpoints business non essentiels renvoient 403 et cessent de fonctionner
- 2024-03-06 : e-mail à Cox indiquant qu’il n’est plus possible de reproduire la faille
- 2024-03-07 : réponse de Cox annonçant le lancement d’un examen de sécurité complet
- 2024-04-10 : information transmise à Cox sur l’intention de divulguer après 90 jours
- 2024-04-29 : partage avec Cox d’un lien vers un brouillon de billet de blog
Questions en suspens
- Cox a enquêté sur une éventuelle exploitation passée de cette voie de vulnérabilité spécifique et a indiqué n’avoir trouvé aucun antécédent d’exploitation
- Le service avait commencé à fonctionner en 2023
- La compromission initiale du modem datant de 2021, la vulnérabilité exposée dans l’API Cox Business n’en était donc pas la cause à l’époque
- Cox a indiqué n’avoir aucun lien avec l’IP DigitalOcean
- L’équipement avait bien été réellement piraté, mais par une autre méthode que la vulnérabilité API révélée
- Le modem n’avait pas été configuré pour être accessible de l’extérieur, et aucune connexion à l’équipement n’avait été effectuée depuis le réseau domestique
- Parmi les autres pistes possibles figurait par exemple une 0day allant d’un CSRF local à du RCE
- La plus grande question reste de savoir pourquoi l’attaquant rejouait les requêtes HTTP
- S’il était déjà présent dans le réseau, il aurait pu y accéder discrètement ; la raison du rejeu systématique de toutes les requêtes HTTP reste inconnue
1 commentaires
Avis de Hacker News
Bon article, facile à suivre. J’ai particulièrement apprécié que Cox n’attaque pas la personne à l’origine du signalement ni ne nie le problème, et qu’ils se soient comportés comme un exemple de réponse de sécurité responsable dans ce genre de situation.
J’aimerais lire un article de suivi sur le bug qui autorisait par intermittence l’accès non autorisé à l’API. Ce type d’erreur peut facilement passer au travers de tests superficiels, ou même ne pas être reproductible du tout en environnement de test selon sa cause.
Il y a quelque temps, j’ai découvert par hasard une vulnérabilité grave chez un opérateur télécom traditionnel ; avec les seuls canaux de support client grand public, il a fallu près d’une semaine pour atteindre la bonne personne, et l’organisation de support n’a absolument pas su escalader le sujet. Chez Cox aussi, un spécialiste en sécurité de l’information s’est présenté directement avec un équipement infecté, mais l’organisation de support n’a pas su le traiter correctement.
Ce qui est pénible dans ce genre de situation, c’est quand les FAI vous imposent d’utiliser leur modem ou leur routeur. Par exemple, AT&T fiber utilise une authentification 802.1X basée sur certificats pour l’accès au réseau ; sans cela, on pourrait brancher n’importe quel équipement sur l’ONT.
Il existe ou existait des contournements, mais je n’ai pas envie de passer par ce genre de procédure juste pour avoir Internet ; j’ai donc désactivé toutes les fonctions du routeur AT&T et placé derrière mon propre routeur, que je maintiens à jour. Si le routeur AT&T est piraté, je pourrais ne pas m’en rendre compte tant que le service n’est pas affecté. Heureusement qu’aujourd’hui la plupart du trafic passe en HTTPS.
Si l’ONT redémarre, il faudra très probablement recommencer, mais dans mon cas AT&T m’a fourni un onduleur pour l’ONT, donc les redémarrages devraient être rares. Personnellement, j’ai mis en place une configuration complexe à base de NIC de contournement : quand mon pare-feu est éteint ou en cours de redémarrage, le trafic passe par le modem AT&T ; quand il est allumé, mon pare-feu reçoit le trafic et le relaie sélectivement via le modem. Mais en réalité, un simple switch non administrable suffit.
Mais mes compliments à Cox s’arrêtent là. Je subis des pertes de paquets intermittentes depuis deux ans ; même en collectant des données montrant qu’un nœud précis est probablement surabonné, il ne semble exister aucun chemin d’escalade du support permettant d’atteindre quelqu’un capable de comprendre le problème.
En pratique, l’état 802.1X n’est pas vérifié côté serveur. La norme dit que si le 802.1X est requis mais non effectué, le modem ne doit pas transmettre le trafic, mais la plupart le transmettent quand même, ou peuvent être modifiés pour le faire. Côté AT&T, il n’y a pas de vérification et le trafic passe toujours ; en interne, c’est bien ce qui se produit.
Article agréable à lire et excellente enquête. C’est aussi appréciable de voir un cas où une grande entreprise ne largue pas une bombe nucléaire sur un chercheur en sécurité.
Je n’en suis pas certain, mais je doute que les requêtes vers l’interface locale d’administration de ce routeur Nokia soient correctement authentifiées. J’ai récemment reçu le même équipement, et certains paramètres n’étaient pas modifiables avec les droits administrateur standard ; le FAI ne fournissait pas de compte super administrateur. Pourtant, en réactivant avec l’inspecteur de page les champs désactivés puis en modifiant les valeurs, l’API les acceptait telles quelles. Dans ces conditions, si une application peut s’exécuter à l’intérieur du réseau local, il ne serait pas très difficile de prendre le contrôle du routeur de cette façon, même si cela semble reposer sur des conditions assez spécifiques.
Cox est clairement une cible attractive, et comme dans l’exemple de l’article, une seule vulnérabilité pourrait mettre en danger jusqu’à des bureaux locaux du FBI. Il aurait sans doute été plus juste d’écrire « Cox a affirmé avoir enquêté » plutôt que « Cox a enquêté sur d’éventuelles exploitations passées et n’a trouvé aucune trace ».
Peut-on croire l’affirmation selon laquelle il n’y a eu « aucun historique d’exploitation passée » ? L’ensemble du réseau ressemble à du gruyère.
De nombreux routeurs doivent être mis à jour manuellement côté firmware. Les routeurs GL.iNet ont connu plusieurs vulnérabilités d’exécution de code à distance ces six derniers mois ; mieux vaut donc vérifier rapidement que son routeur n’a pas été piraté et, si possible, mettre à jour le firmware
Du point de vue d’un utilisateur ordinaire, les symptômes observés étaient un ralentissement de la connexion Internet, des coupures du signal Wi‑Fi et des échecs de connexion des appareils, ainsi qu’une page d’administration interne (192.168.8.1) qui ne répondait pas alors que le routeur lui-même était bien connecté à Internet. Dans mon cas, l’attaquant avait installé l’application Pawns d’IPRoyal pour transformer le routeur en serveur proxy et gagner de l’argent ; il avait aussi volé les journaux système indiquant les périodes d’utilisation et la présence d’une connexion au NAS, et disposait également d’un reverse shell. La bonne séquence de correction semble être : mise à jour du firmware, réinitialisation du routeur pour supprimer le malware, désactivation de SSH, puis coupure des accès distants comme le DNS dynamique. Si un accès distant est nécessaire, on peut envisager Cloudflare Tunnel, Zero Trust, GoodCloud, ZeroTier ou Tailscale, mais je ne sais pas vraiment lequel serait le plus adapté. GL.iNet ne respecte pas le principe du moindre privilège, exécute par défaut les processus en root, et SSH est aussi activé par défaut avec un accès root ; il me semble donc préférable de l’éviter
Dire qu’« il n’y avait pas d’historique d’exploitation » peut simplement vouloir dire qu’il n’y avait pas assez de logs ou de données d’audit dès le départ, ou que les logs n’étaient plus présents après le piratage
Quel système d’authentification laisse parfois passer des appels au hasard ? Ça a vraiment l’air incompétent
L’ont-ils payé ? Cette personne a pratiquement sauvé Cox, en leur signalant une prise de contrôle complète de leur infrastructure de sécurité qui n’était pas facile à découvrir
Il semble n’avoir rien reçu pour avoir fait « ce qu’il fallait », ce qui est assez insultant. La manière dont l’entreprise a dû percevoir quelqu’un arrivant jusqu’aux bureaux avec des informations critiques était sans doute très différente de l’image qu’il avait de lui-même. Ce cas illustre bien pourquoi il ne faut jamais signaler un 0day
Une question reste ouverte : comment les attaquants ont-ils capturé son trafic HTTP ?
Certains CPE disposent d’une sorte de fonction cloud façon Wireshark pour le débogage. Je ne sais pas si une telle fonction est présente dans les images firmware de production de Cox. En général, les firmwares de production et de test sont séparés, ce qui rend les problèmes en environnement de production plus difficiles à tester. Cox devrait pouvoir vérifier quelles versions de firmware sont déployées sur le terrain ; un ISP peut mettre à jour automatiquement un firmware qui ne correspond pas à une version donnée, et comme il s’agit d’un modem Cox, il est très probable qu’ils disposent aussi du firmware. Si c’était un firmware de debug, je me demande comment il a été installé et comment il a pu rester en place
Il suffit d’intercepter toutes les données du port 80, de parser les en-têtes HTTP et d’effectuer les actions nécessaires. En revanche, je ne sais pas bien pourquoi quelqu’un aurait rejoué les requêtes
C’est l’une des raisons pour lesquelles il ne faut pas se réjouir des modems câble fournis par l’ISP avec Wi‑Fi intégré, et pour lesquelles il faut bien sécuriser les endpoints et services dans son LAN. Au minimum, il faut du TLS et du DNS over TLS entre le modem et l’ISP
Pour ma part, je le laisse simplement en mode bridge, je coupe le Wi‑Fi, puis je confie toutes les fonctions réseau à mon propre matériel. Le dernier modem loué à mon ISP n’avait pas reçu de mise à jour de firmware pendant près de dix ans ; cela dit, il était du coup très stable
Free, où je travaille, est un ISP français et fournit aussi des passerelles domestiques en Italie via Iliad ; nous mettons encore à jour du matériel lancé en 2011. Il fait tourner un Linux 6.4 récent, propose des fonctions modernes comme l’airtime QoS, des mises à jour de l’application mobile et plusieurs fonctions logicielles
J’ai acheté un routeur plutôt correct, installé OpenWrt dessus, puis je l’ai relié au réseau en bridge via l’équipement de l’ISP, et ça fonctionne bien. Désormais, j’utilise HTTPS même à l’intérieur du LAN