Resumen
Un desbordamiento de pila clásico, de manual… en 2018, y en un cliente que tienen instalado decenas de millones de personas. El navegador de servidores de Steam (y de otros juegos de Valve) consulta la información de las partidas con un protocolo UDP llamado server queries. Al responder a una petición A2S_PLAYER con un nombre de jugador desmesuradamente largo, el cliente de Steam desbordaba un búfer en la pila dentro de la librería serverbrowser: el nombre se convertía a Unicode sin comprobar límites y, sin protección de canary en Windows, se podía sobrescribir la dirección de retorno y ejecutar código.
Nota del editor: por responsabilidad, aquí se explica la técnica pero no se reproduce el exploit completo (shellcode y cadena ROP) que sí incluye el reporte original. Está enlazado al final para quien quiera el detalle.
Pasos de reproducción
A grandes rasgos, el escenario de ataque era:
- Un servidor UDP malicioso responde a
A2S_PLAYERcon un nombre de jugador manipulado, mucho más largo de lo previsto. - La víctima abre "Ver información del servidor" en el navegador de servidores… o, más inquietante, visita una web que dispara un enlace
steam://connect/1.2.3.4desde uniframeoculto. - Al procesar la respuesta, la pila se desborda y el flujo de ejecución se desvía.
Los puntos técnicos que hacían el salto posible, sin entrar en el arma:
- La conversión a wide char transformaba un nombre como
A*1100en un patrón0x00410041en la pila; eligiendo bien los caracteres Unicode se lograba el patrón0x41414141y, con él, control de los registros. - Como el estado se corrompía antes de retornar, los autores montaron una cadena ROP usando solo gadgets del propio
Steam.exepara llamar aVirtualProtecty saltar a su código, con la dificultad añadida de que cada valor tenía que ser un carácter Unicode válido. - Sobre ASLR: en Windows solo se aleatorizaban 9 bits, así que distribuyendo el ataque en masa se acertaba con una probabilidad de ~1/512; encadenándolo con una fuga de memoria, la fiabilidad subía al 100 %.
Impacto
Ejecución de código en el ordenador de cualquier usuario que simplemente mirara la info del servidor malicioso. Y el vector web es lo que lo vuelve especialmente feo: a través del Steam browser protocol bastaba con visitar una página —sin más clics— para disparar el exploit, que incluso arrancaba Steam si no estaba abierto. A partir de ahí, lo de siempre: robo de cuenta, robo de los objetos del inventario, instalación de más malware, exfiltración de ficheros…
Remediación
El arreglo directo es comprobar los límites al copiar el nombre del jugador y añadir las protecciones de memoria que faltaban (canary, mitigaciones contra ROP). Pero hay una segunda lección igual de importante: los protocolos que dejan que una web abra una aplicación de escritorio (steam://…) amplían enormemente la superficie de ataque, porque convierten un fallo "de red local" en uno alcanzable desde cualquier navegador.