Le piratage de 700 millions de comptes Electronic Arts
(battleda.sh)- La combinaison d’une documentation Swagger exposée pour les API d’authentification et de passerelle d’EA et d’un défaut de vérification des droits lors de la mise à jour des personas pouvait affecter les données de compte d’autres utilisateurs, ainsi que les flux de connexion
- Le point central était que la requête PUT sur
/identity/pids/{pidId}/personas/{personaId}était accessible avec le scopedp.client.defaultdu client OAuth EA Desktop standard, et que les contrôles de propriété entre le pidId du corps de requête et le personaId du chemin étaient insuffisants - Un attaquant pouvait combiner le changement de nom d’utilisateur d’un persona, le passage au statut
BANNED, le déplacement de personas, la recherche d’ID de personas de comptes masqués et le contournement de connexion basé sur un persona Xbox pour parvenir jusqu’à la connexion web au compte - L’impact allait du vol de noms d’utilisateur et de certaines données de jeu au blocage de l’accès aux jeux en ligne, en passant par le contournement de bannissements de jeu et la connexion à un compte EA via Xbox ; la sévérité a été évaluée à CVSS 10.0
- La vulnérabilité a été signalée à EA le 16 juin 2024 ; EA l’a classée critical le 25 juin, puis a déployé des correctifs du 8 juillet au 8 octobre, incluant des vérifications de propriété des personas et la suppression de la documentation
Une exposition de documentation API partie de l’environnement d’authentification EA
- Le point de départ a été un environnement de test integration découvert dans EA Desktop
- L’API d’authentification de production est
accounts.ea.com - L’hôte d’authentification integration est
accounts.int.ea.com
- L’API d’authentification de production est
- Dans l’environnement integration, il était possible d’obtenir un access token autorisé ; la recherche de documentation exposée a alors commencé afin d’identifier les API accessibles avec ce jeton
- Les endpoints d’authentification se trouvaient derrière un reverse proxy ; les formats de réponse 404 différaient entre le chemin
/connectet le chemin/général, et l’en-têteserverindiquaitistio-envoy /connect/api-docsrenvoyait une 404 vide, contrairement aux autres chemins/connect, ce qui suggérait un routage vers un service distinct ; une documentation Swagger 1.1 a été trouvée à/connect/api-docs/index.json- La documentation Swagger pointait vers
/api-docs/connect; elle a été convertie en spécification OpenAPI 3.0 avecswagger-codegen-cli, puis consultée dans une Swagger UI locale
La liste des API internes révélée dans Gateway
- EA Desktop utilise une API GraphQL appelée « Service Aggregation Layer », mais le SAL de l’environnement integration était derrière un pare-feu
- L’API gateway de
gateway.ea.com, qui semblait être une version plus ancienne, utilisait des endpoints au formatproxy/{service}/{route} gateway.int.ea.com/proxy/api-docs/index.jsonrenvoyait une liste de plus de 80 documentations de services- Plusieurs services y figuraient, notamment
addresses,agerequirements,billing,commerce
- Plusieurs services y figuraient, notamment
- Chaque documentation d’API a été téléchargée, convertie vers une spécification OpenAPI récente, puis les fonctionnalités accessibles ont été examinées
- Certains endpoints renvoyaient des données « projects » liées aux équipes de jeux EA, nécessitaient le scope
basic.domaindata, et un client disposant de ce scope a également été trouvé en production- Les exemples de données contenaient notamment un jeu Star Wars annulé et Apex Legends affiché avec un nom de groupe lié à
Titanfall3
- Les exemples de données contenaient notamment un jeu Star Wars annulé et Apex Legends affiché avec un nom de groupe lié à
- Dans l’environnement integration, une méthode pour accorder des entitlements de jeux personnalisés était également documentée, mais son intérêt pratique était limité, car les services integration nécessaires au téléchargement et au jeu se trouvaient derrière un pare-feu
- Un endpoint renvoyait aussi un Xbox Live Server Token, mais comme le sandbox ID n’était pas
RETAIL, l’exploration n’a pas été poussée plus loin
Informations de comptes en production et structure des personas
- Chaque endpoint de la documentation indiquait les scopes d’authentification requis, et les vérifications se sont concentrées sur les endpoints accessibles avec des clients OAuth de production
/identity/pids/merenvoie les informations générales du compte- Cela inclut notamment une valeur d’e-mail masquée, l’état de l’e-mail, une partie de la date de naissance, le pays, la langue, l’état du compte, la version des conditions d’utilisation, les dates de création, de modification et de dernière authentification, ainsi que l’activation ou non de la 2FA
/identity/pids/me/personasrenvoie la liste des personas liés au compte- Le compte EA de base utilise le namespace
cem_ea_id - Les comptes externes liés, comme Steam ou Xbox, apparaissent eux aussi chacun comme un persona
- Le compte EA de base utilise le namespace
- Les jeux peuvent généralement stocker sous un persona des données comme des statistiques ou l’inventaire, ce qui peut séparer les données par plateforme
- Par la suite, le persona du namespace
cem_ea_idest désigné comme persona « Origin »
Vulnérabilité principale : échec de vérification des droits lors de la mise à jour d’un persona
- L’endpoint
/identity/pids/{pidId}/personas/{personaId}accepte les requêtes GET, PUT et DELETE - La requête PUT autorisait les scopes
dp.client.defaultetdp.server.default, et le client d’authentification EA Desktop standard disposait dedp.client.default - Le corps de requête pouvait contenir
displayName,namespaceName,status,statusReasonCode,lastAuthenticated,nickName,pidId, entre autres - Une requête PUT modifiant le
displayNamede son propre persona Origin réussissait, et le nom d’utilisateur était modifié sur le site du compte EA- Cette requête contournait le cooldown de changement de nom d’utilisateur ainsi que la vérification par e-mail liée au changement de nom
- La modification de
namespaceNamen’avait pas d’effet - Les valeurs possibles de
statusétaientACTIVE,DISABLED,PENDING,DELETEDetBANNED; en passant son propre persona Origin à l’étatBANNED, EA Desktop restait utilisable, mais la connexion aux jeux était bloquée - Le problème le plus grave était qu’il était possible de remplacer le pidId du corps de requête par l’ID d’un autre compte
- Une requête déplaçant son propre persona Steam vers le compte EA d’un ami a réussi
- Il était ensuite aussi possible de le remettre sur son propre compte
Vérification de connexion et tentative de XSS
- Après avoir déplacé son persona Steam vers le compte d’un ami, une tentative de connexion au site EA via Steam a déclenché une vérification par e-mail fondée sur le nouvel emplacement et l’appareil non approuvé
- Une partie de l’e-mail affiché n’était pas la sienne, ce qui montrait que le flux de connexion au compte de l’ami avait été atteint, mais il a été bloqué à l’étape de 2FA basée sur la localisation
- Une requête changeant le nom d’utilisateur du persona en
BattleDash <script>alert(1)</script>a également réussi - Une alerte s’exécutait sur la page de liaison de compte, rendant une XSS possible
- Si un utilisateur connecté à son compte EA était amené vers cette page de liaison, il devenait possible d’exécuter du code dans son navigateur et d’extraire la session
Manipulation directe des personas d’autres comptes
- Pour vérifier si le
personaIddans le chemin manquait lui aussi de contrôle de propriété, une tentative de changement de nom d’utilisateur a été effectuée avec l’ID d’un persona qui ne lui appartenait pas - Après avoir obtenu l’ID de persona d’un nouveau compte de test, une requête a réussi à changer le nom d’utilisateur de ce compte sans authentification du compte victime
- De la même manière, il était possible de passer son
statusàBANNED, empêchant ce compte de se connecter aux jeux /identity/personaspermet de rechercher un persona pardisplayNameet renvoie l’ID du persona, l’ID du compte, la date de création et l’heure de dernière connexion- En revanche, les utilisateurs ayant masqué leur compte ne sont pas affichés
/identity/namespaces/{namespace}/personaseffectue une recherche dans un namespace donné ; il ne renvoie que le nom d’utilisateur et l’ID du persona, mais inclut aussi les comptes masqués- Cet endpoint suffisait à lui seul à obtenir l’ID de persona nécessaire
Contraintes de déplacement des personas et prise de contrôle partielle de comptes
- Une tentative de déplacement du persona Origin d’un autre utilisateur vers son propre compte a entraîné l’erreur
TOO_MANY_PERSONAS_FOR_NAMESPACE- Son propre compte possédait déjà un persona Origin
- En partant de l’idée qu’un compte créé sur console pouvait n’avoir que le persona de cette plateforme et aucun persona Origin, un compte console a été utilisé pour éviter le conflit de namespace
- Il était possible de déplacer le persona Origin d’un compte de test vers le compte console, puis de déplacer le persona Origin de la victime vers son propre compte
- Dans cet état, la connexion affichait le nom d’utilisateur de la victime, les statistiques de jeux non cross-platform et quelques autres détails de compte
- En se connectant au compte victime, un flux « Finish setting up my account » apparaissait et demandait de choisir un nom d’utilisateur, comme lors de la création d’un nouveau compte
- Les entitlements, amis et données de sauvegarde de jeux cross-platform récents comme Battlefield 2042 étaient stockés sur le compte EA lui-même, et non sur le persona, et n’étaient donc pas transférés
- Malgré cela, un attaquant pouvait bannir un utilisateur, contourner un bannissement de jeu, voler un nom d’utilisateur ou prendre en otage des données de compte
Contournement de connexion à l’aide d’un persona Xbox
- À ce stade, les actions possibles étaient de déplacer son propre persona de compte lié vers n’importe quel compte EA, de déplacer n’importe quel persona vers son propre compte, et de bannir un persona ou de modifier son nom d’utilisateur
- Le déplacement de son propre persona pour se connecter au compte d’un autre utilisateur déclenchait une vérification par e-mail
- En s’appuyant sur le fait qu’aucune invite 2FA n’avait été observée lors de l’utilisation de jeux EA sur console, les connexions basées sur des jetons Xbox/PSN ont été examinées
- La documentation de l’API Nexus Connect décrivait la transmission de jetons Xbox/PSN, et l’identifiant client PSN a été obtenu dans le flux de connexion PSN du site EA pour tenter une connexion par jeton PSN
- La connexion par jeton PSN créait un persona du namespace
ps3et permettait de se connecter au compte sans 2FA, mais les clients disposant dedp.client.defaultne pouvaient pas manipuler le namespaceps3 - L’ajout de l’en-tête
X-Include-Namespaceà/connect/tokeninfoa révélé qu’il existait, selon le client OAuth, des listes de namespaces de personas manipulables- Par exemple,
JUNO_PC_CLIENTincluait les namespacescem_ea_id,steam,epicetxbox
- Par exemple,
- Le namespace Xbox était autorisé, mais faute de pouvoir fabriquer manuellement un jeton Microsoft XSTS valide pour les jeux, le test a été réalisé sur une vraie Xbox
- Un nouveau compte Microsoft a été créé, puis le persona Xbox a été lié à un compte EA de test avant d’être déplacé vers le compte victime
- Sur le site EA, la connexion avec le compte Xbox déclenchait une vérification par e-mail liée au nouvel emplacement ; mais après avoir installé Battlefield 2042 sur Xbox et s’être connecté au jeu, l’accès s’effectuait bien au compte victime
- Ensuite, une connexion au site EA avec le même compte Xbox a réussi jusqu’à l’accès web au compte victime, sans vérification par e-mail
Impact et sévérité
- Les principaux chemins exploitables par un attaquant étaient au nombre de deux
- Déplacer les données de persona d’une autre personne hors de son compte pour voler son nom d’utilisateur et ses données de jeu
- Déplacer son propre persona Xbox vers le compte victime, se connecter à un jeu EA sur Xbox, puis, une fois le réseau considéré comme fiable, se connecter au site EA avec le compte Xbox
- Les impacts supplémentaires étaient importants
- Il était possible de bannir le persona d’une autre personne et ainsi de bloquer la plupart des jeux en ligne
- Il était possible de changer le nom d’utilisateur d’une autre personne, puis de se l’approprier
- Comme un bannissement de jeu est traité par la désactivation des entitlements de jeu à l’échelle du compte, il était possible de contourner un bannissement de jeu en déplaçant le persona vers un nouveau compte
- Ce flux était possible sans interaction utilisateur, principalement via un seul endpoint API
- La sévérité a été évaluée à CVSS 10.0 avec le vecteur
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Calendrier de correction et remarques ultérieures
- La vulnérabilité a été signalée à EA le 16 juin 2024
- EA a envoyé un accusé de réception le 25 juin 2024 et lui a attribué une sévérité critical
- Le calendrier des correctifs a été le suivant
- 8 juillet 2024 : déploiement du Patch 1, vérification de propriété des personas
- 18 juillet 2024 : déploiement du Patch 2, détails inconnus
- 6 septembre 2024 : déploiement du Patch 3, détails inconnus
- 10 septembre 2024 : déploiement du Patch 4, suppression de la documentation
- 8 octobre 2024 : déploiement du Patch 5, détails inconnus
- L’estimation initiale d’EA était que la correction pourrait prendre jusqu’à la fin de l’année, et l’évaluation est qu’un correctif temporaire plus rapide aurait été préférable dans un cas où les éléments clés étaient une documentation exposée et un unique endpoint non sécurisé
- EA ne dispose toujours pas de programme de bug bounty, et l’absence de récompense concrète pour les signalements laisse craindre que certaines personnes conservent des vulnérabilités de manière privée
- Le compte d’ami utilisé pour les premiers tests l’a été avec son consentement
1 commentaires
Avis sur Hacker News
EA aime utiliser un système commun pour plusieurs jeux. En fouillant dans Madden, quelqu’un a découvert un backend commun appelé
blaze, avec des endpoints web/TCP génériquesIl a créé un outil pour appeler cet endpoint, qui demandait d’uploader du XML, puis a découvert plus tard que les serveurs d’EA plantaient à chaque appel
Comme une nouvelle instance de serveur était lancée pour chaque requête, il faisait planter un à un tous les serveurs Madden, et EA a fini par créer une API pour empêcher les gens de fouiller
De mémoire, il fallait environ une instance Blaze pour 5 000 à 10 000 joueurs
Ils semblaient assez confortablement installés dans l’usage de formats propriétaires et d’une sécurité reposant sur le fait que personne ne découvrirait le fonctionnement de l’interface, autrement dit une sécurité par l’obscurité
J’aimerais y revenir un jour, et il y a au moins pas mal de choses intéressantes à raconter
Un bon conseil pour faire de la rétro-ingénierie d’API de services connus : utiliser la recherche de code GitHub. Si on y met un nom d’endpoint unique, on tombe souvent sur des gens qui ont bricolé eux-mêmes un petit client API, ce qui aide parfois mes recherches d’une manière inattendue
namespacenameissue des données personnelles est renvoyée. Les informations de jeton 2FA devraient être hachées par l’endpoint/tokeninfo/récupéré depuis JUNOLors de tentatives d’intégration a posteriori, l’infrastructure pour l’API C++ renvoyait parfois l’ID utilisateur PSN
N’importe qui de normal aurait évidemment fait pareil : commander une Xbox en livraison pour le lendemain, installer Battlefield 2042, attendre le moment décisif, et réussir à entrer
les hackers sont vraiment formidables <3
Le déroulé détaillé de la progression d’un point à l’autre était intéressant. Je doute que cela ait été aussi propre et linéaire qu’un billet de blog
Pour montrer le temps et les efforts réels que ce type d’attaque demande, il doit sûrement exister une montagne de notes, et ce serait intéressant à voir aussi
Le plus étrange dans toute cette histoire, c’est qu’EA affirme depuis des années qu’il est techniquement impossible de dissocier un compte Xbox déjà lié puis de le relier à un nouveau compte. Il suffit de voir des posts comme https://www.reddit.com/r/XboxGamePass/comments/12gsy4i/ea_xb... et les innombrables messages sur les forums EA
J’ai moi-même buté sur ce mur, et après plusieurs heures au téléphone avec le support EA, ils n’ont pas réussi à relier mon très ancien compte Xbox. Résultat : impossible de me connecter à n’importe quel jeu EA sur Xbox, ce qui m’a empêché de jouer à la plupart d’entre eux sur la plateforme
Pourtant ici, on voit que c’est tout à fait possible
Curieusement, mon compte prenait énormément de temps, et pendant 1 à 2 ans j’ai écrit plusieurs fois au support, qui me répondait toujours qu’ils mettaient à niveau les comptes aussi vite que possible, mais que l’opération était si vaste qu’elle prendrait des années
Plus tard, j’ai vu sur un forum une astuce consistant à fermer temporairement le compte puis à le rouvrir, ce qui permettait de passer à 25 Mo, mais pas aux 250 Mo promis
Avec des comptes existants à 2~4 Mo, de nouveaux comptes à 25 Mo, et un déploiement sur plusieurs années jusqu’à 250 Mo, on avait l’impression que Microsoft peinait énormément à trouver de l’espace disque disponible. Puis, quelques mois plus tard, il a fallu rivaliser avec Gmail, et ils ont décidé de donner 2 Go à tout le monde, déployés d’un coup sur tous les comptes Hotmail, y compris le mien. Des extraterrestres ont forcément livré un OVNI rempli de disques durs
[1] Exemple d’un ancien message de forum sur cette astuce, avec aussi des réponses vantant le tout nouveau GMail : https://bimmersport.co.nz/topic/5232-hotmail-upgrade-2mb-to-...
Le changement de lien pourrait invalider des données stockées dans le système de facturation, casser les rapports mensuels envoyés à la division Xbox de Microsoft, ou faire planter une page d’administration interne pendant son chargement
Je ne cherche pas à défendre EA, mais quand on a beaucoup travaillé avec des systèmes complexes de microservices, modifier la structure des données à un endroit n’est pas toujours simple
Bannir tous les comptes en espérant qu’il n’y ait pas de sauvegarde de la base de données, ça aurait sans doute été amusant aussi
En tant que client payant, j’attends une meilleure attitude de la part de ces entreprises, et si elles n’ont pas de programme, personnellement je ne blâmerais pas des hackers qui exploiteraient ce qu’ils ont découvert
Personne ne stocke 400 millions d’enregistrements sur une seule machine, et au final ça ne ferait que mettre le service hors ligne tout un après-midi avant de vous valoir 15 ans de prison fédérale
La première réaction — et apparemment le commentaire le mieux noté en ce moment — c’est de se dire que ce serait « amusant » de nuire à des millions de personnes pour donner une leçon à l’entreprise avec laquelle elles faisaient affaire
Il y a ce passage dans l’article :
I had found a way to obtain a privileged access token within the environment (a story for another day, but a certain game's executable had hardcoded credentials!), but I wasn't sure what I could do with it.Quelqu’un peut expliquer un peu plus cette partie ? Je pensais qu’on ne devait pas pouvoir lire facilement ce genre d’identifiants dans un binaire exécutable, et si un exécutable de jeu doit s’authentifier lui-même auprès d’un serveur distant, je ne vois pas très bien ce que les développeurs sont censés faire autrement
Dans une architecture client-serveur, le client n’est jamais digne de confiance. Un exécutable ne devrait pas avoir besoin de s’authentifier lui-même auprès du serveur. Il devrait s’authentifier en tant qu’utilisateur ou compte avec des informations fournies par l’utilisateur
Pour des choses comme la télémétrie, ce type de point de terminaison reçoit généralement des données sans authentification ou avec une authentification faible, puis applique plusieurs niveaux de validation pour éviter les abus. C’est souvent en écriture/ajout uniquement
Il faudrait un système où l’exécutable est chiffré et où une zone sécurisée dans le die du CPU gère le déchiffrement avec une clé privée, mais même là ce ne serait probablement qu’une question de temps avant que quelqu’un ne décapsule la puce pour récupérer la clé
Même si vous chiffrez la chose et mettez la clé dans un HSM, sur une machine cliente arbitraire ce n’est probablement pas faisable, et à un moment ou à un autre le jeu devra déchiffrer cette chaîne et la charger en mémoire. Et cette mémoire peut être lue
Ce que le développeur du jeu doit faire, c’est avoir un système de comptes côté backend et demander au joueur de saisir ses propres identifiants dans le jeu. Le jeu peut alors s’identifier auprès du serveur backend comme ce joueur
Cela permet d’attribuer les actions côté backend à un joueur précis et fournit une bonne base pour prendre des décisions de sécurité
Il existe des outils comme IDA, donc ce n’est pas comme s’il fallait repérer à l’œil nu des identifiants au milieu de tout ce qui ressemble à une chaîne
Le problème n’est pas tant qu’il y ait des identifiants codés en dur dans le binaire, mais que ces identifiants aient des privilèges élevés
En tant qu’ingénieur dans ce genre d’entreprise, je me demande parfois ce que ça fait de voir des API internes, des bugs bizarres et des saletés d’architecture interne exposés dans un rapport public d’intrusion
Cela dit, dans un cas comme celui-ci, il est peu probable qu’une seule personne soit responsable de la vulnérabilité. Cinq ou six équipes possédaient probablement différentes parties exploitées, ce qui explique justement pourquoi l’exploit a pu exister. C’est un système énorme et complexe où chacun ne comprend que son petit bout
Dans une entreprise de la taille d’EA, il est presque certain que cette affaire sera utilisée dans des luttes politiques internes, et que certains s’en serviront pour obtenir davantage de contrôle sur une organisation réduite, même si cela nuit à l’entreprise dans son ensemble
Tout le monde est une ressource remplaçable, alors pourquoi s’investir émotionnellement dans le travail ?
À l’époque, l’équipe s’appelait Nucleus, ce qui explique qu’une des réponses de l’article ait
refTypeàNUCLEUS. Cette équipe créait et maintenait les API backend pour les autorisations, les comptes et les paiementsC’était un stage d’été, puis j’ai reçu une offre de cette équipe et j’ai commencé à y travailler un an plus tard. À ce moment-là, l’équipe avait été renommée EADP et fusionnait lentement avec Origin. Je ne me souviens plus très bien si le DP signifiait Data Platform, mais c’est pour ça qu’un des endpoints commence par
dp.À l’époque, il n’y avait pas de base de données GraphQL ; c’était uniquement de l’Enterprise Java, OCI, Spring, Hibernate, etc., et avant mon départ il y avait aussi un peu de Groovy/SpringBoot plus récent. Ça tournait sur des serveurs en datacenter, pas dans le cloud
Malgré tout, c’était un travail intéressant, et même si je suis parti deux ou trois ans après une grosse panne, j’y ai beaucoup appris sur le développement backend auprès de très bons ingénieurs
Je n’ai aucune idée de l’état actuel de l’équipe, de qui sont les ingénieurs ni de ce qui se passe, mais ça m’attriste de voir ça. À l’époque, nous étions très attentifs à la sécurité et nous avions aussi travaillé sur des systèmes pour détecter et traiter les tentatives de brute force sur la page de connexion
Je ne sais pas si c’est encore actif ni même en fonctionnement, mais les vérifications/revues de sécurité visant à réduire le risque d’intrusion et la surface d’attaque faisaient partie du travail de sprint
Si vous avez trouvé cet article intéressant, vous pouvez en voir davantage sur des plateformes de bug bounty comme Hacktivity de HackerOne : https://hackerone.com/hacktivity
Mis à jour toutes les quelques semaines ou tous les quelques mois
Existe-t-il quelque part un guide des bonnes pratiques pour mettre en place un programme de bug bounty ?
Il suffit d’indiquer quelque part sur le site web qu’il est permis de tester la sécurité technique à condition de suivre une procédure coordonnée de divulgation de vulnérabilités, et de préciser pour quels bugs, dans quel périmètre, quelle récompense sera versée. Bien sûr, il faut être un peu plus précis que cette seule phrase
Il vaut aussi mieux préciser à l’avance les exceptions pour éviter les frustrations plus tard, par exemple si vous ne payez pas les personnes trop jeunes ou trop âgées, ou si elles sont nées dans un pays soumis à des sanctions
S’il y a des questions précises, je peux y répondre ou chercher de bonnes ressources de référence
Quand on lit ce passage de l’article :
It's also disappointing that EA has yet to start a bug bounty program. Without any real incentive to report vulnerabilities, I know people who have instead chosen to keep them to themselves. I would love to see EA follow the rest of the industry's lead here.cela veut-il dire que l’auteur a signalé ça et n’a rien reçu du tout ?
Le signalement comporte un risque juridique, et le fait que, techniquement, l’entreprise puisse engager une procédure jusqu’au bout n’aide pas non plus. Je parle ici du cadre UE/Royaume-Uni