- Discord, una app de escritorio basada en Electron, funciona internamente como una ventana de Chromium, por lo que es posible abrir las herramientas para desarrolladores web y modificar código del lado del cliente
- Algunos clientes modificados y plugins desbloquean del lado del cliente parte de las funciones que requieren una suscripción paga a Nitro
- La clave está en inyectar módulos divididos mediante code splitting de Webpack en la variable
webpackChunkdiscord_apppara explorar y reemplazar funciones internas - La función que verifica la calidad de compartir pantalla se valida solo en el cliente y puede eludirse, pero los temas premium además activan una verificación de sincronización en el servidor
- Todas las técnicas de la demo son una violación de los Términos de Servicio de Discord, con riesgo de suspensión de la cuenta y de robo de cuenta por ejecutar código no verificado
Panorama general
- Existen numerosos clientes modificados de Discord que cambian la apariencia o agregan funciones, y algunos plugins incluso desbloquean funciones que requieren una suscripción paga a Nitro
- Se explica el principio técnico que hace posible este comportamiento mediante el análisis de la estructura del cliente
Activación de las herramientas para desarrolladores
- Discord está desarrollado con el framework Electron, que permite crear apps multiplataforma con tecnologías web, por lo que es similar a un sitio web que se ejecuta dentro de un navegador web
- En esencia, es una ventana de Chromium, así que se pueden abrir las herramientas para desarrolladores, aunque vienen desactivadas de forma predeterminada
- Se bloquearon porque hubo muchos casos en los que usuarios pegaron comandos maliciosos por ingeniería social de actores de amenazas y terminaron con sus cuentas robadas
- Si se comprenden los riesgos, se puede activar agregando el valor
DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOINGcomotrueen el archivo de configuración%appdata%/discord/settings.json- Luego se abre la consola de desarrollo con
ctrl + shift + i
- Luego se abre la consola de desarrollo con
Parchar funciones de Discord
- Para optimizar la carga inicial, el código se divide en varios chunks que se cargan en paralelo o de forma diferida (lazy-loaded), usando la función de code splitting de Webpack
- Todos los chunks cargados se guardan en la variable
webpackChunkdiscord_app - Para ejecutar código que use variables y funciones de Discord, hay que inyectar (inject) código en esta variable
a.ces un objeto que contiene todos los módulos, y cada módulo tiene la formachunk_id,loaded,exportsexportscontiene las funciones, objetos y valores primitivos exportados por el módulo
- Es posible crear una función
findque recorra varios módulos JavaScript para localizar y llamar una función específica- Ejemplo: buscar y llamar la función
getCurrentUser()
- Ejemplo: buscar y llamar la función
- Se puede cambiar el comportamiento reemplazando (replace) la función original por otra, lo que permite modificar directamente el código
Desbloqueo de streaming en alta calidad
- El contenido a partir de este punto viola claramente los Términos de Servicio de Discord y puede llevar a la suspensión de la cuenta, por lo que implica asumir el riesgo
- Las dos funciones
canStreamMidQualityycanStreamHighQuality, que verifican el nivel de suscripción del usuario, se llaman justo antes de la pantalla de selección de calidad para compartir pantalla- Si se fuerza el valor de retorno de ambas funciones a
true, se puede seleccionar compartir pantalla en resolución original a 60 FPS incluso sin estar suscrito a Nitro
- Si se fuerza el valor de retorno de ambas funciones a
- Actualmente, Discord parece no verificar en el servidor si el stream transmitido realmente cumple con los límites para usuarios no suscritos
- Sin embargo, Discord todavía no usa cifrado de extremo a extremo (End-to-End encryption), por lo que existe la posibilidad de detección
- Según el artículo de referencia, Discord ya inspecciona el contenido de audio y video de los usuarios, y podría agregar en el futuro una verificación del lado del servidor antes de compartir pantalla
Desbloqueo de temas premium
- Si se cambia a
trueel valor de la funcióncanUseClientThemes, que devuelve si el usuario puede usar temas de Nitro, se desbloquea el botón para seleccionar temas premium - Sin embargo, después de aplicarse por un momento, el tema vuelve enseguida al tema predeterminado
- Esto ocurre porque el cliente intenta guardar el cambio de tema, pero el servidor verifica que no tiene permisos y, al recibir la respuesta, vuelve a aplicar el tema predeterminado
- Si se parchea la función
shouldSyncpara bloquear solo la sincronización de configuración de apariencia y hacer que devuelvafalsecuando el valor seaappearance, el cambio de tema se mantiene - Los temas se gestionan completamente del lado del cliente y siempre es posible modificar directamente el CSS, por lo que es difícil que Discord lo impida
Conclusión
- Existe código que permite aplicar fácilmente los hacks demostrados, pero es importante ser prudente antes de modificar el cliente o usar mods
- Discord puede suspender en cualquier momento cuentas que violen sus Términos de Servicio, y ejecutar código no verificado con acceso a la cuenta es muy peligroso
- Mensaje codificado en el artículo: "No pegues en la consola de desarrollo código que no entiendas — es la forma más fácil de que te roben la cuenta"
1 comentarios
Opiniones en Hacker News
Creo que si basta con ejecutar un simple blob codificado en base64 pegado al final para activar todas las funciones, podría convertirse en un vector de ataque bastante fácil.
No quería decir que sospechara del autor; lo acabo de decodificar y caí redondito.
base64 --decode, este es el resultado:// Here's a cake if you thought about inspecting the code before executing it:let css = 'font-size: 36px; font-weight: bold; color: red';console.log("%cNEVER paste code you don't understand into the development console.", css);console.log("%cThis is the best way to compromise your account.", css);“Actualmente, Discord no parece verificar en el servidor que el stream que se está transmitiendo realmente cumpla con los criterios para no suscriptores”; me pregunto quién pensó que esa era una buena implementación.
La validación del lado del cliente de verdad parece un error de principiante.
Llevo años usando Discord y es la primera vez que oigo de un intento de eludir la estructura de permisos de Nitro; si no es algo muy extendido, tampoco parece haber mucha razón para preocuparse.
Por otro lado, este mes empecé mi quinto trabajo nuevo, así que parece que simplemente no me llevo nada bien con los project managers.
Me pregunto cuánta gente entiende este tipo de hack y además estaría dispuesta a pagar Nitro. Seguramente hay miles, quizá decenas de miles, de personas usando varios mods de cliente de Discord que activan algunas o todas las funciones de Nitro, pero tengo dudas de cuánto ingreso real generaría bloquear eso.
Personalmente, si necesito o quiero esa función, es mucho menos molesto pagar 10 dólares al mes. Me parece mejor que estar siguiendo mods que se van a romper con cada actualización de Discord y esperar que el mantenedor no meta código malicioso.
Los canales solo están ocultos en el cliente. Para ser claros, aun así eso no permite ver el contenido de los mensajes de esos canales.
El servidor de voz solo confirma con la API si tienes permiso para entrar y, después de eso, funciona como un broadcaster de paquetes de uno a muchos.
Esto se acerca más al hacker clásico, en el sentido de alguien curioso y hábil.
No hay daños graves y nos recuerda que las apps no son magia y que el código es genial.
Así pueden intentar exprimirnos más dinero sin resistencia.
Recordatorio: todo lo que envías por Discord, incluidos los DM, queda registrado en texto plano en Discord y queda accesible para Discord y para quien compre la empresa.
En algún momento parecía que Microsoft la compraría, y ahora parece encaminarse a una IPO.
El simple hecho de tener una cuenta normaliza conversaciones privadas fáciles de minar para IA o de usar por Discord y por administradores de bases de datos/sistemas. La Section 702 de la FISA Amendments Act (FAA702) permite que agencias federales de investigación accedan a esos datos sin orden judicial.
Solo la posibilidad de front-running de criptomonedas podría valer decenas de millones de dólares al día.
Si eres amigo de alguien, no deberías recomendarle usar un sistema de chat sin cifrado de extremo a extremo. No seamos miel dentro de una trampa.
Es lo esperable salvo que uses uno de los pocos servicios que implementan un verdadero modelo zero trust donde el usuario gestiona sus propias claves. La razón por la que se guardan los mensajes es para que los usuarios puedan volver a acceder a ellos.
Hay servicios como Matrix que logran mensajería grupal con cifrado de extremo a extremo de una forma relativamente amigable, pero son la excepción. No es justo presentar a Discord como especialmente malicioso solo por hacer lo mismo que ha hecho el 95% de las plataformas de comunicación electrónica.
No digo que sea bueno, pero en algunas comunidades no hay alternativa salvo no participar.
Es peor que el viejo “todo el mundo usa WhatsApp”. En ese caso tenías el número de la otra persona y era fácil contactarla por otros medios, pero el atractivo de Discord no son las conversaciones privadas, sino las comunidades con espacios semipúblicos. Aquí “público” no significa abierto para todos, sino algo más cercano a que lo leen unas 100 personas.
Cuando borras un mensaje, ya no queda almacenado en la base de datos.
Hace poco OpenAI desactivó de golpe el Discord para beta testers, así que ya no podemos ver con quién hablábamos ni qué discutíamos.
Me preguntaba si habría alguna forma de exportar el chat para que los administradores del servidor no pudieran cortar la comunidad entre sí sin dejar siquiera una forma de revisar el historial.
Hay bastantes extensiones de Chrome para exportar chats de Discord, pero parece que la mayoría bloquea algunas funciones detrás de un pago.
Resultó que era muy fácil copiar el código fuente de la extensión desde la carpeta de Chrome, modificar en JavaScript una comprobación booleana como
is_proy volver a cargarla como extensión descomprimida.Es un programa independiente que usa la API de una forma no estándar, pero creo que todavía no he visto a nadie baneado por usarlo.
Aunque advierten correctamente que puedes ser baneado por usar estos trucos, ¿hay algún antecedente de que Discord haya baneado usuarios por algo así?
También bloquean el uso de clientes alternativos. Si tu cuenta es importante, mejor no meterse con Discord.
“Modificar el cliente va contra los Términos de Servicio de Discord.”
Dicho eso, a Discord parece importarle bastante poco, y no hay casos conocidos de baneos por usar mods de cliente. Así que, mientras no uses plugins que implementen abuso, en general deberías estar bien. No tienes que preocuparte: dicen que todos los plugins integrados son seguros.
Entiendo que algunos temas se activen de esta manera, pero es bastante difícil entender que hayan hecho que la calidad del streaming se decida con una comprobación del lado del cliente y no del servidor.
Ni siquiera necesitas acceder al video real; aunque esté completamente cifrado, viendo la cantidad de datos transmitidos puedes saber en qué calidad se está streameando.
La gran regla de la ingeniería frontend vuelve a cumplirse:
“Nunca, jamás confíes en el cliente”.
Desde que vi que se podía manejar solo del lado del cliente, he estado usando las herramientas de desarrollo para activar el botón de streaming 1080p60, y de hecho funciona.
No sé cuántos años van ya, pero parece que a nadie en Discord le importa.
Hace tiempo intenté seguir este camino, pero al final me rendí porque no encontré una forma consistente de parchear el cliente, especialmente después de las actualizaciones.
Pero al ver este método me vuelve la tentación de “abrirlo y pincharlo”.
¿Hay alguna forma sencilla de recorrer la API disponible de esta manera? Intenté registrarlo todo, pero era un desastre por maps, internacionalización y demás. Me pregunto si alguien ya se tomó el trabajo de hacer algo como documentación de ingeniería inversa.