- Una documentación Swagger expuesta de la API de autenticación y gateway de EA, combinada con una falla en la validación de permisos para actualizar personas, podía afectar tanto los datos de cuentas de otros usuarios como el flujo de inicio de sesión
- El punto clave era que la solicitud PUT a
/identity/pids/{pidId}/personas/{personaId}podía accederse con el alcancedp.client.defaultde un cliente OAuth común de EA Desktop, y faltaban verificaciones de propiedad tanto del pidId en el cuerpo como del personaId en la ruta - Un atacante podía combinar cambio de nombre de usuario de la persona, asignación del estado
BANNED, movimiento de personas, búsqueda del ID de persona de cuentas ocultas y bypass de login usando una persona de Xbox para llegar incluso al inicio de sesión web de la cuenta - El impacto incluía robo de nombres de usuario y algunos datos de juego, bloqueo de acceso a juegos en línea, evasión de bans en juegos e inicio de sesión en cuentas de EA mediante Xbox, con una gravedad evaluada en CVSS 10.0
- La vulnerabilidad fue reportada a EA el 16 de junio de 2024; EA la clasificó como crítica el 25 de junio y desplegó parches entre el 8 de julio y el 8 de octubre, incluyendo verificación de propiedad de personas y eliminación de la documentación
Exposición de documentación API en el entorno de autenticación de EA
- El punto de partida fue una prueba del entorno de desarrollo integration encontrada en EA Desktop
- La API de autenticación de producción era
accounts.ea.com - El host de autenticación de integration era
accounts.int.ea.com
- La API de autenticación de producción era
- En el entorno integration se podía obtener un access token con permisos, así que comenzó la búsqueda de documentación expuesta para identificar qué APIs eran accesibles con ese token
- Los endpoints de autenticación estaban detrás de un reverse proxy; el formato de la respuesta 404 en la ruta
/connectdifería del de la ruta general/, y el headerservereraistio-envoy /connect/api-docsdevolvía un 404 vacío, distinto a otras rutas bajo/connect, lo que sugería un posible enrutamiento a otro servicio; en/connect/api-docs/index.jsonse encontró documentación Swagger 1.1- La documentación Swagger apuntaba a
/api-docs/connect, y se convirtió a especificación OpenAPI 3.0 conswagger-codegen-clipara revisarla localmente en Swagger UI
Lista de APIs internas expuestas por Gateway
- EA Desktop usa una API GraphQL llamada “Service Aggregation Layer”, pero la SAL del entorno integration estaba detrás de un firewall
- La API gateway de
gateway.ea.com, aparentemente de una versión anterior, usaba endpoints con formatoproxy/{service}/{route} gateway.int.ea.com/proxy/api-docs/index.jsondevolvía una lista con documentación de más de 80 servicios- Incluía servicios como
addresses,agerequirements,billing,commercey otros
- Incluía servicios como
- Se descargó la documentación de cada API, se convirtió a especificaciones OpenAPI más recientes y luego se revisaron las funciones accesibles
- Algunos endpoints devolvían datos de “projects” relacionados con equipos de juegos de EA y requerían el alcance
basic.domaindata; también se encontraron clientes en producción con ese alcance- Entre los datos de ejemplo había entradas sobre un juego cancelado de Star Wars y Apex Legends mostrado con un nombre de grupo relacionado con
Titanfall3
- Entre los datos de ejemplo había entradas sobre un juego cancelado de Star Wars y Apex Legends mostrado con un nombre de grupo relacionado con
- En el entorno integration también estaba documentada la forma de otorgar entitlements personalizados de juegos, pero como los servicios necesarios para descarga y juego estaban detrás de un firewall, su utilidad práctica era baja
- También había un endpoint que devolvía un Xbox Live Server Token, pero como el sandbox ID no era
RETAIL, no se investigó más a fondo
Información de cuentas en producción y estructura de personas
- Cada endpoint en la documentación indicaba los alcances de autenticación requeridos, y la revisión se centró en endpoints accesibles mediante clientes OAuth de producción
/identity/pids/medevolvía información general de la cuenta- Incluía correo enmascarado, estado del correo, parte de la fecha de nacimiento, país, idioma, estado de la cuenta, versión de términos, fechas de creación, modificación y última autenticación, y si 2FA estaba activado
/identity/pids/me/personasdevolvía la lista de personas vinculadas a la cuenta- La cuenta base de EA usa el namespace
cem_ea_id - Cuentas externas vinculadas, como Steam o Xbox, también aparecen cada una como una persona
- La cuenta base de EA usa el namespace
- Los juegos normalmente pueden guardar datos como estadísticas o inventario bajo una persona, por lo que los datos pueden quedar separados por plataforma
- A partir de ahí, la persona del namespace
cem_ea_idse denomina “persona Origin”
Vulnerabilidad principal: falla en la validación de permisos al actualizar personas
- El endpoint
/identity/pids/{pidId}/personas/{personaId}aceptaba solicitudes GET, PUT y DELETE - La solicitud PUT permitía los alcances
dp.client.defaultydp.server.default, y un cliente de autenticación normal de EA Desktop teníadp.client.default - El cuerpo de la solicitud podía aceptar
displayName,namespaceName,status,statusReasonCode,lastAuthenticated,nickName,pidIdy otros campos - Una solicitud PUT para cambiar
displayNamede la propia persona Origin funcionó, y el nombre de usuario del sitio web de la cuenta EA cambió- Esa solicitud evadía tanto el cooldown de cambio de nombre como la verificación por correo para cambio de nombre de usuario
- Cambiar
namespaceNameno tuvo efecto - Los valores posibles de
statuseranACTIVE,DISABLED,PENDING,DELETED,BANNED; al cambiar el estado de la propia persona Origin aBANNED, EA Desktop seguía funcionando pero el inicio de sesión en juegos quedaba bloqueado - El problema mayor era que el pidId del cuerpo podía cambiarse por el ID de otra cuenta
- Una solicitud para mover la persona de Steam propia a la cuenta EA de un amigo se ejecutó con éxito
- Después también fue posible devolverla a la cuenta original
Verificación de login e intento de XSS
- Después de mover la propia persona de Steam a la cuenta de un amigo, se intentó iniciar sesión en el sitio web de EA con Steam, y apareció una verificación por correo basada en nueva ubicación o dispositivo no confiable
- Parte del correo mostrado no era propio, lo que indicaba que el flujo ya había llegado al intento de inicio de sesión en la cuenta del amigo, aunque quedó bloqueado en la etapa de 2FA basada en ubicación
- También funcionó una solicitud para cambiar el nombre de usuario de la persona a algo como
BattleDash <script>alert(1)</script> - En la página de vinculación de cuenta se ejecutaba el alert, por lo que era posible XSS
- Si se lograba llevar a un usuario que ya tuviera sesión iniciada en su cuenta EA a esa página de vinculación, se podía ejecutar código en el navegador y extraer la sesión
Manipulación directa de personas de otras cuentas
- Para comprobar si también faltaba validación de propiedad sobre el
personaIden la ruta, se intentó cambiar el nombre de usuario usando un persona ID que no pertenecía al atacante - Tras obtener el persona ID de una cuenta de prueba nueva, la solicitud para cambiar el nombre de usuario de esa cuenta funcionó sin autenticación de la víctima
- Del mismo modo, también se podía cambiar
statusaBANNED, dejando esa cuenta sin posibilidad de iniciar sesión en juegos /identity/personaspermitía buscar personas pordisplayNamey devolvía persona ID, account ID, fecha de creación y fecha del último login- Sin embargo, no mostraba cuentas ocultas
/identity/namespaces/{namespace}/personaspermitía buscar dentro de un namespace específico y devolvía solo nombre de usuario y persona ID, pero sí incluía cuentas ocultas- Solo con este endpoint ya se podía obtener el persona ID necesario
Restricciones al mover personas y toma parcial de cuentas
- Al intentar mover la persona Origin de otro usuario a la propia cuenta, aparecía el error
TOO_MANY_PERSONAS_FOR_NAMESPACE- Eso ocurría porque la cuenta del atacante ya tenía una persona Origin
- Se observó que las cuentas creadas desde consola podían tener solo la persona de esa plataforma y no una persona Origin, así que se usaron cuentas de consola para evitar el conflicto de namespace
- Fue posible mover la persona Origin de una cuenta de prueba a una cuenta de consola y luego mover la persona Origin de la víctima a la cuenta del atacante
- En ese estado, al iniciar sesión se mostraban el nombre de usuario de la víctima, estadísticas de juegos no cross-platform y algunos otros detalles de la cuenta
- Al iniciar sesión en la cuenta de la víctima aparecía el flujo “Finish setting up my account”, como si se estuviera creando una cuenta nueva y hubiera que elegir nombre de usuario
- Entitlements, amigos y datos guardados de juegos cross-platform modernos como Battlefield 2042 no se transferían, porque se almacenaban en la cuenta EA misma y no en la persona
- Aun así, el atacante podía banear usuarios, evadir bans en juegos, robar nombres de usuario y secuestrar datos de cuenta
Bypass de login usando una persona de Xbox
- En ese estado, las acciones posibles incluían mover una linked account persona propia a cualquier cuenta EA, mover cualquier persona a la cuenta propia y banear o cambiar el nombre de usuario de una persona
- Al intentar iniciar sesión en la cuenta de otro usuario moviendo una persona propia, seguía apareciendo la verificación por correo
- Como al jugar títulos de EA en consola no se había visto nunca un prompt de 2FA, se revisó el login basado en tokens de Xbox/PSN
- La documentación de la API Nexus Connect mostraba cómo enviar tokens de Xbox/PSN, y usando el flujo de login de PSN en el sitio de EA se obtuvo un client ID de PSN para probar el inicio de sesión con token PSN
- El login con token PSN creaba una persona en el namespace
ps3y permitía iniciar sesión en la cuenta sin 2FA, pero los clientes condp.client.defaultno podían manejar el namespaceps3 - Al agregar el header
X-Include-Namespacea/connect/tokeninfo, se confirmó que cada cliente OAuth tenía una lista de namespaces de personas que podía manipular- Por ejemplo,
JUNO_PC_CLIENTincluía los namespacescem_ea_id,steam,epic,xbox
- Por ejemplo,
- El namespace de Xbox estaba permitido, pero como no fue posible generar manualmente un Microsoft XSTS token válido para juegos, la prueba se hizo en una Xbox real
- Se creó una nueva cuenta Microsoft, se vinculó su persona de Xbox a una cuenta EA de prueba y luego esa persona de Xbox se movió a la cuenta de la víctima
- Al iniciar sesión en el sitio web de EA con la cuenta de Xbox aparecía verificación por correo por nueva ubicación, pero al instalar Battlefield 2042 en la Xbox e iniciar sesión en el juego, se accedía a la cuenta de la víctima
- Después, al iniciar sesión otra vez en el sitio web de EA con esa misma cuenta de Xbox, se logró el login web a la cuenta de la víctima sin verificación por correo
Alcance del impacto y gravedad
- Había dos rutas principales que un atacante podía explotar
- Mover los datos de la persona de otra persona fuera de su cuenta para robar nombres de usuario y datos de juego
- Mover su propia persona de Xbox a la cuenta de la víctima, iniciar sesión en un juego de EA desde Xbox y, una vez que la red quedaba en estado confiable, iniciar sesión en el sitio web de EA con la cuenta de Xbox
- El impacto adicional también era considerable
- Se podía banear la persona de otra persona y bloquear la mayoría de sus juegos en línea
- Se podía cambiar el nombre de usuario de otra persona y luego quedarse con él
- Como los bans de juego se gestionaban desactivando los entitlements de juego de toda la cuenta, se podía evadir un ban moviendo la persona a una cuenta nueva
- Todo este flujo era posible principalmente mediante un solo endpoint de API y sin interacción del usuario
- La gravedad se evaluó como CVSS 10.0 bajo
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Cronograma de corrección y observaciones posteriores
- La vulnerabilidad fue reportada a EA el 16 de junio de 2024
- EA confirmó el hallazgo el 25 de junio de 2024 y le asignó gravedad crítica
- El cronograma de parches fue el siguiente
- 8 de julio de 2024: despliegue de Patch 1,
persona ownership check - 18 de julio de 2024: despliegue de Patch 2, detalles no especificados
- 6 de septiembre de 2024: despliegue de Patch 3, detalles no especificados
- 10 de septiembre de 2024: despliegue de Patch 4, eliminación de la documentación
- 8 de octubre de 2024: despliegue de Patch 5, detalles no especificados
- 8 de julio de 2024: despliegue de Patch 1,
- La estimación inicial de EA era que la corrección podía tardar hasta fin de año, y se consideró que en un caso centrado en documentación expuesta y un solo endpoint inseguro habría sido deseable una mitigación temporal más rápida
- EA todavía no tiene un programa de bug bounty, y sigue existiendo la preocupación de que, sin una recompensa real por reportar, algunas personas prefieran conservar estas vulnerabilidades en privado
- La cuenta de un amigo usada en las pruebas iniciales era una cuenta con consentimiento
1 comentarios
Opiniones en Hacker News
A EA le gusta usar sistemas comunes en varios juegos. Revisando Madden, descubrí que había un backend común llamado
blazey endpoints genéricos web/TCP.Hice una herramienta para llamar a ese endpoint, pero había que subir XML, y después me enteré de que cada vez que lo llamaba estaba tirando los servidores de EA.
Como en cada solicitud tomaba un servidor nuevo, estaba haciendo crashear uno por uno todos los servidores de Madden, y al final EA creó una API para que la gente dejara de hurgar.
Si no recuerdo mal, hacía falta más o menos una instancia de Blaze por cada 5.000 a 10.000 jugadores.
Parece que estaban bastante cómodos usando un formato propietario y asumiendo que nadie iba a descubrir cómo interactuar con la interfaz; es decir, confiaban en seguridad por oscuridad.
Algún día me gustaría volver a ese artículo; como mínimo, tiene contenido bastante interesante.
Un tip para hacer ingeniería inversa de APIs de servicios conocidos como este es usar la búsqueda de código de GitHub. Si pones un nombre de endpoint único, suelen aparecer personas que hicieron algo parecido hackeando su propio pequeño cliente de API, y eso termina ayudando a tu investigación de formas inesperadas.
namespacenametomado de datos personales. La información del token 2FA debería hashearse en el endpoint/tokeninfo/tomado de JUNO.Al intentar una integración posterior, la infraestructura para la API de C++ solía devolver el ID de usuario de PSN.
Como haría cualquier persona normal, pedí una Xbox con entrega al día siguiente, instalé Battlefield 2042, esperé el momento decisivo y pude entrar.
Me encantan los hackers <3
Me pareció interesante el flujo detallado de cómo pasaron de un punto al siguiente. Supongo que en la práctica no fue tan limpio y lineal como en el post del blog.
Para mostrar el tiempo y el esfuerzo reales que requiere un ataque así, probablemente habría una montaña de notas; también sería interesante verlas.
Lo más extraño de todo esto es que EA lleva años afirmando que desvincular una cuenta de Xbox existente y volver a vincularla con una cuenta nueva era técnicamente imposible. Basta ver publicaciones como https://www.reddit.com/r/XboxGamePass/comments/12gsy4i/ea_xb... y montones de posts en los foros de EA.
Yo también me topé con ese muro, y pasé horas hablando con soporte de EA, pero no pudieron vincular mi cuenta de Xbox muy antigua. Por eso no puedo iniciar sesión en ningún juego de EA en Xbox y quedé sin poder jugar a la mayoría en esa plataforma.
Pero aquí resulta que sí era perfectamente posible.
Curiosamente, mi cuenta tardaba demasiado, y durante uno o dos años escribí varias veces a soporte, pero siempre me respondían que estaban actualizando las cuentas lo más rápido posible, aunque como la tarea era enorme tomaría años.
Más tarde vi en un foro un truco que consistía en cerrar la cuenta por un momento y volver a abrirla para aumentarla a 25 MB, pero no eran los 250 MB prometidos.
La situación —cuentas existentes con 2-4 MB, cuentas nuevas con 25 MB y un despliegue de varios años para llegar a 250 MB— daba la impresión de que Microsoft estaba teniendo enormes dificultades para encontrar almacenamiento sobrante. Pero unos meses después, cuando tuvieron que competir con Gmail, decidieron dar 2 GB a todos, y se desplegó de una vez para todas las cuentas de Hotmail, incluida la mía. Seguro que unos extraterrestres trajeron un ovni lleno de discos duros.
[1] Un ejemplo de un viejo post de foro sobre ese truco, con una respuesta elogiando el recién lanzado GMail: https://bimmersport.co.nz/topic/5232-hotmail-upgrade-2mb-to-...
Cambiar la vinculación podría invalidar datos guardados en el sistema de facturación, arruinar reportes mensuales enviados a la división Xbox de Microsoft o hacer que una página interna de administración crashee mientras carga.
No intento defender a EA, pero si has trabajado mucho con sistemas complejos de microservicios, cambiar una estructura de datos en un lugar no siempre es sencillo.
También habría sido divertido banear todas las cuentas y esperar que no hubiera backups de la DB
Como cliente que paga, espero una mejor actitud de estas empresas, y si no tienen un programa, personalmente no culparía a los hackers por explotar lo que encuentren.
Nadie guarda 400 millones de registros en una sola máquina, y al final lo único que lograrías sería tumbar el servicio toda la tarde y pasar 15 años en una prisión federal.
Que la primera reacción —o al menos el comentario mejor votado ahora mismo— sea pensar que sería "divertido" perjudicar a millones de personas para darle una lección a la empresa con la que hacían negocios.
En el texto aparece este pasaje:
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.¿Alguien puede explicar un poco más esta parte? Pensaba que no debería ser fácil leer esas credenciales desde el binario ejecutable, y tampoco tengo muy claro qué otra cosa debería hacer un desarrollador si el ejecutable del juego tiene que autenticarse ante un servidor remoto.
En una arquitectura cliente-servidor, el cliente nunca es confiable. El ejecutable no debería necesitar autenticarse a sí mismo ante el servidor. El ejecutable debería autenticarse como usuario o cuenta usando la información proporcionada por el usuario.
Para cosas como telemetría, esos endpoints normalmente aceptan datos sin autenticación o con autenticación débil, y aplican varias capas de validación para evitar abusos. Por lo general también son solo de escritura/agregado.
Necesitarías un sistema que cifre el ejecutable y en el que una zona segura del die de la CPU se encargue de descifrarlo con una clave privada, y aun así probablemente sería cuestión de tiempo hasta que alguien haga delid del chip y obtenga la clave.
Aunque lo cifres y pongas la clave de cifrado en un HSM, en una máquina cliente arbitraria probablemente ni siquiera sea posible; y en algún momento el juego tiene que descifrar esa cadena y cargarla en memoria. Y esa memoria se puede leer.
Lo que deberían hacer los desarrolladores del juego es tener un sistema de cuentas en el backend y pedirle al jugador que ingrese sus propias credenciales dentro del juego. Entonces el juego puede identificarse ante el servidor backend como ese jugador.
Así se pueden atribuir las acciones en el backend a un jugador específico y se obtiene una buena base para tomar decisiones de seguridad.
Existen herramientas como IDA, así que tampoco es que tengas que buscar a simple vista entre todo lo que parezca una cadena.
El problema no es tanto que haya credenciales hardcodeadas en el binario, sino que esas credenciales tengan privilegios elevados.
Como ingeniero en una empresa así, a veces me pregunto cómo se sentirá que tus API privadas, bugs raros y trapos sucios internos queden expuestos en un reporte público de intrusión.
Aunque en un caso así es poco probable que una sola persona haya sido responsable de la vulnerabilidad. Probablemente 5 o 6 equipos eran dueños de distintas partes explotadas, y por eso el exploit existía en primer lugar. Es un sistema enorme y complejo donde cada quien solo entiende su pequeña parte.
En una empresa del tamaño de EA, esto casi seguro se usará para política interna, y aunque perjudique a la empresa en su conjunto, la gente lo aprovechará para obtener más control sobre una empresa más pequeña.
Todos son recursos reemplazables, ¿por qué alguien se involucraría emocionalmente con el trabajo?
En ese entonces el equipo se llamaba Nucleus, por eso en una de las respuestas del artículo
refTypeeraNUCLEUS. Ese equipo creaba y mantenía las API de backend para autorizaciones, cuentas y pagos.Fue una pasantía de verano, y un año después recibí una oferta de ese equipo y empecé a trabajar ahí. Para entonces el equipo había cambiado de nombre a EADP y se estaba fusionando lentamente con Origin. Recuerdo vagamente que DP quizá era Data Platform, y por eso uno de los endpoints empieza con
dp..En ese momento no había una base de datos GraphQL; todo era Enterprise Java, OCI, Spring, Hibernate y cosas por el estilo, y antes de irme también había algo más nuevo con Groovy/SpringBoot. Corría en servidores de data center, no en la nube.
Aun así hice trabajos interesantes y, aunque me fui 2 o 3 años después de que ocurriera un incidente grande, aprendí mucho desarrollo backend de buenos ingenieros.
No tengo idea de cómo es el equipo ahora, quiénes son los ingenieros ni qué está pasando, pero me da pena ver esto. En ese entonces éramos muy conscientes de la seguridad, e incluso trabajamos en sistemas para detectar y manejar intentos de fuerza bruta contra la página de login.
No sé si todavía están activos o funcionando, pero las revisiones de seguridad para reducir la posibilidad de intrusiones y la superficie de ataque formaban parte del trabajo de los sprints.
Si este artículo te pareció interesante, puedes ver más en plataformas de bug bounty como Hacktivity de HackerOne: https://hackerone.com/hacktivity
Se actualiza cada pocas semanas o meses
¿Existe en algún lado una guía de mejores prácticas para configurar un programa de bug bounty?
Basta con publicar en algún lugar del sitio web que se permite revisar la seguridad técnica siempre que se siga un proceso de divulgación coordinada de vulnerabilidades, e indicar qué recompensas se darán por qué tipos de bugs y dentro de qué alcance. Claro, habría que especificarlo un poco más que en esta sola oración.
También conviene dejar por escrito de antemano las excepciones, para evitar malos ratos después, como que no se pagará si la persona es demasiado joven o demasiado mayor, o si nació en un país equivocado y está sujeta a sanciones.
Si tienes preguntas concretas, puedo responderlas o buscar buenas referencias.
Viendo esta parte del artículo:
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.Entonces, ¿el autor reportó esto y no recibió nada?
Reportarlas implica riesgos legales, y tampoco ayuda que, técnicamente, la empresa pueda llevar el litigio hasta el final. Hablo desde el contexto de la UE/Reino Unido.