Aikido

MECCHA CHAMELEON no puede esconderse de la RCE

Escrito por
Robbe Van Roey

Resumen: Hemos encontrado otra RCE con retardo en MECCHA CHAMELEON. Al jugar en el mapa de un atacante, este puede explotar una función expuesta para escribir archivos de forma arbitraria en el sistema de la víctima. Esto puede provocar la ejecución remota de código en el sistema de la víctima después de un reinicio. Informamos del problema a los desarrolladores del juego y corrigieron la vulnerabilidad en la actualización 4.0.0. Esta actualización se instala automáticamente antes de iniciar el juego.

Si eres gamer, es probable que hayas oído hablar de MECCHA CHAMELEON. El juego online de el escondite se ha convertido en una obsesión global, ¡con 15 millones de copias vendidas en su primer mes!

Como jugador, tienes un cometido muy sencillo: encontrar un buen escondite y pintar un personaje blanco en blanco para que coincida con el escenario. Después, uno de tus amigos vendrá a buscarte. Ganas si el cazador no te encuentra. ¡Así de simple!

Página de inicio de Meccha Chameleon

Los mapas creados por la comunidad son una parte fundamental de su atractivo. Cualquiera puede crear un nuevo mapa para que los jugadores se escondan y publicarlo a través de Steam Workshop. Estos nuevos mapas pueden ser una galería de arte, zonas nostálgicas de otros juegos, etc.

Tienda «Meccha Chameleon», con diferentes mapas en los que se puede jugar

Una característica específica nos llamó la atención: cuando juegas en un servidor, el host del lobby elige el mapa y todos los jugadores de ese lobby reciben el aviso para descargarlo (¡la pantalla te avisa si aún no lo has descargado y estás retrasando la partida!). Esto es muy cómodo, pero también significa que unirse a una partida puede implicar cargar un mapa hecho por alguien a quien no conoces de nada. Quisimos averiguar qué se le permitía hacer realmente a ese mapa descargado.

En el pasado, MECCHA CHAMELEON ya había sufrido una RCE al cargar mapas, tal como se detalla en esta publicación del blog. Dicho error específico ya se ha solucionado, pero ¿eliminó eso todas las vías posibles hacia una RCE?

¿Qué es realmente un mapa de MECCHA CHAMELEON?

Puedes suponer que un mapa es solo un conjunto de recursos: modelos para el escenario y texturas para que todo se vea bien. Así es como funciona un mapa en muchos juegos, donde el archivo descargado describe el nivel, mientras que el juego en sí controla la lógica.

Los mapas de MECCHA CHAMELEON tienen un control mucho mayor. El juego está desarrollado con Unreal Engine 5.6.1, y sus mapas pueden contener Blueprints. Blueprint es el sistema de programación visual de Unreal. Puedes conectar nodos para que ocurra algo cuando un jugador pulsa un botón, entra en un área o simplemente carga el mapa.


https://dev.epicgames.com/documentation/unreal-engine/introduction-to-blueprints-visual-scripting-in-unreal-engine

Por supuesto, un mapa no puede llamar a cualquier función dentro de Unreal o MECCHA CHAMELEON. Primero es necesario exponer una función nativa a Blueprint. Cuando el mapa se inicia, sus gráficos se ejecutan dentro del proceso de MECCHA CHAMELEON. Si un gráfico llama a una función expuesta, el juego realiza dicha acción utilizando la cuenta y los permisos del jugador.

Esto significa que los mapas personalizados constituyen una superficie de ataque interesante:

  • El host de un lobby puede incitar al resto de jugadores a descargar y ejecutar un mapa.
  • A continuación, ese mapa puede ejecutar gráficos de Blueprint dentro del juego.

Así que empecé a prestar atención a las funciones del motor a las que podía acceder.

Búsqueda de funciones ejecutables

Por suerte, no tenemos que adivinar qué funciones expone Unreal. Podemos abrir un gráfico de Blueprint y hacer clic derecho en un área vacía. Ahora Unreal muestra un menú de nodos searchable que se pueden añadir a dicho gráfico.

Desde una perspectiva de seguridad, me interesaban principalmente las funciones que interactuaban de alguna manera con el sistema operativo. Así que busqué aquellas que contenían guardar, exportar, escribir, grabar, open, lanzar, y cargar. Pasamos de una lista enorme de APIs a una lista manejable que pude analizar.

Así que, una por una, investigué estas funciones hasta que di con Finalizar grabación de salida. Esta destacó porque podía crear un archivo en el sistema de archivos con una ruta que puede ser absoluta o relativa. También almacena la salida de audio, la cual probablemente podamos controlar de alguna forma.

Escritura de archivos en cualquier ubicación

Por lo tanto, para usar la función Finalizar grabación de salida , un creador de mapas debe iniciar una grabación, reproducir un sonido y luego detener la grabación. A continuación, proporcionamos un nombre y una ruta donde guardar el archivo. La función está documentada con más detalle en aquí.

Así que este es un caso claro de "simplemente proporciona cualquier directorio y cualquier nombre de archivo, y podremos guardar estos archivos en cualquier parte del sistema", ¿verdad?

Pues sí. Puedes simplemente proporcionar C:\Users\Public\ como la ruta del archivo y escribir archivos ahí, o puedes proporcionar una ruta relativa. El directorio predeterminado que se utiliza es C:\Users\<user>\AppData\Local\Chameleon\Saved\BouncedWavFiles, por lo que al proporcionar una ruta que empieza con ../../../../../, podríamos acceder a la carpeta de inicio del usuario sin necesidad de conocer su nombre de usuario.

Así que ahora podíamos escribir archivos en cualquier parte del sistema de archivos. La forma más sencilla de escalar esto hacia una ejecución remota de código diferida es escribir un archivo ejecutable en C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup. Cada vez que tu dispositivo se inicie, ejecutará automáticamente todos los archivos de esta carpeta.

Por lo tanto, proporcionamos este valor como el nombre de la grabación:

..\..\..\..\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\poc.exe

Y cuando empaquetamos y ejecutamos nuestro mapa, notamos que...

¿Funcionó, más o menos? De hecho, escribimos un archivo en la carpeta de inicio. Pero nuestra extensión .exe no se mantuvo. Unreal Engine añade la extensión .wav a cualquier nombre de archivo que le proporcionemos y, por lo tanto, Windows sigue tratando el archivo como un WAV en lugar de un ejecutable.

Eliminación del sufijo .wav

Estuve dándole vueltas a cómo podríamos eludir esto. Lo que tenemos aquí es un caso clásico de dos sistemas diferentes que hacen suposiciones. Unreal Engine tiene su propia manera de gestionar una ruta y Windows tiene la suya de interpretarla. Solo tenía que encontrar una discrepancia entre ambos.

Para Unreal Engine es increíblemente sencillo: simplemente ve una cadena y le añade .wav Windows es un poco más complejo. Windows tiene longitudes máximas de nombres de archivo y caracteres que no están permitidos en una ruta, como el carácter nulo (U+0000).

¿Pero qué pasa cuando intentamos crear un archivo con un carácter nulo en su nombre? Bueno, la mayor parte del tiempo, obtienes un error:

Pero no todas las API generan un error. Algunas API de más bajo nivel ven en realidad los bytes nulos como un terminador y descartan cualquier cosa que les siga:

¿Y si intentamos usar nuestro mapa malicioso para guardar una grabación en:

POC.exe\u0000IGNORED

¡Podemos ver que funcionó! ¡Ahora podemos guardar archivos con nombres arbitrarios en ubicaciones arbitrarias del sistema de archivos!

Pero queda un gran problema. Simplemente estamos escribiendo los bytes de una grabación de audio WAV en un archivo con una extensión .exe ¡Necesitamos controlar de alguna manera también el contenido de ese archivo para hacerlo ejecutable!

Aparece un mensaje emergente que dice: «Esta aplicación no se puede ejecutar en tu ordenador».

Bytes maliciosos en una grabación de audio

Ahora teníamos un nuevo desafío por delante. Estábamos guardando una grabación de audio real como un archivo WAV en una ubicación arbitraria. Pero para que este exploit funcione, también necesitamos poder controlar lo que se escribe en ese archivo.

Para hacer eso, vamos a utilizar un archivo WAV PCM sin comprimir. WAV es el contenedor de archivos, que contiene algunos metadatos seguidos de datos de audio. Los archivos WAV pueden almacenar audio en varios formatos, por lo que la .wav extensión por sí sola no nos indica cómo están codificadas las muestras.

PCM significa Modulación por Impulsos Codificados (Pulse-Code Modulation). Con PCM, cada medición de la onda sonora se almacena directamente como un número. Nuestra prueba de concepto utilizaba PCM de 16 bits, por lo que cada muestra ocupaba exactamente dos bytes. «Sin comprimir» significa que esos números se escribían sin pasar por un códec como MP3.

Un archivo WAV PCM sin comprimir consta de valores de muestras de audio. Si controlamos esos números con precisión, también controlamos los bytes utilizados para almacenarlos.

Esto es muy importante porque la compresión de audio normal intenta preservar cómo se percibe un sonido, no los bytes exactos de cada muestra. Por lo tanto, una versión comprimida puede sonar idéntica al tiempo que contiene bytes muy diferentes.

Un archivo WAV simplificado tiene este aspecto:

+-------------------------------+
| Cabecera RIFF/WAVE            |  Creado por Unreal
| Formato, canales, frecuencia  |
| Tamaño de la sección de datos   |
+-------------------------------+
| Muestra PCM 0               |  Controlado a través de la onda sonora
| Muestra PCM 1               |
| Muestra PCM 2               |
| ...                           |

Unreal controla la cabecera, incluyendo los RIFF y WAVE identificadores. No podemos modificarlos porque nuestro control del archivo solo comienza en la sección de datos PCM. Eso descarta una gran cantidad de ejecutables para nuestro exploit. No podemos subir un archivo .exe o .dllnormal, ya que ambos necesitan una cabecera PE válida para ejecutarse.

Por lo tanto, necesitábamos un tipo de archivo cuyo analizador sintáctico no exigiera encontrar su cabecera en el primer byte. Las aplicaciones HTML de Windows resultaron ser ideales.

Un Aplicación HTML es un formato antiguo de Windows con la extensión .hta . El archivo se parece mucho a una página web: puede contener HTML, CSS y JScript o VBScript. Windows lo abre con mshta.exe (Host de aplicaciones HTML de Microsoft).

La diferencia importante con respecto a una página web normal es dónde se ejecuta ese script. Una HTA se trata como una aplicación de escritorio en lugar de una página dentro del sandbox del navegador. Su script puede crear objetos COM de Windows, incluyendo WScript.Shell, que pueden iniciar otro proceso.

Una versión simplificada de nuestro payload de prueba de concepto tiene este aspecto:

[RIFF/WAVE header ...]
<html>
  <head>
    <hta:application />
    <script>
      new ActiveXObject("WScript.Shell").Run("calc.exe");
    </script>
  </head>
</html>

Cuando se abre este archivo, mshta.exe ignora los metadatos WAV al principio y ejecuta el script. A continuación, WScript.Shell ejecuta la Calculadora.

El desafío restante era colocar ese HTML y script dentro de las muestras PCM del archivo WAV.

Our payload used 16-bit PCM. Each sample is a 16-bit number stored in little-endian order, meaning the least significant byte is written first. Take the sample value 0x683C: it appears in the WAV as 3C 68, which also happens to be the ASCII text <h.

The same conversion works for a longer string. The text <html> has these ASCII bytes:

3C 68 74 6D 6C 3E

Agruparlos en parejas nos da tres valores de muestra de 16 bits:

Bytes:    3C 68 | 74 6D | 6C 3E
Muestras:  0x683C  0x6D74  0x3E6C

Cuando esas muestras se vuelven a escribir en un WAV little-endian, los bytes originales vuelven a aparecer. En realidad, costó muchos ajustes hacer que funcionara, pero al final logramos crear un archivo WAV real que contenía nuestro hta payload.

Un archivo de texto con un montón de símbolos aleatorios, ya que se trata de un archivo WAV

Uniendo el mapa

Llegados a este punto, cada parte funcionaba por sí sola. La tarea restante consistía en integrarlo todo en un mapa capaz de ejecutar el ataque al completo de una vez al cargar el nivel.

Así que nos conectamos a BeginPlay y realizamos lo siguiente:

  1. StartRecordingOutput en un submix privado (para evitar interferencias con el audio habitual del juego)
  2. PlaySound2D con nuestro audio PCM sin comprimir preparado
  3. StopRecordingOutput utilizando ..\..\..\..\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\poc.exe\u0000IGNORED como nombre de archivo
Gráfico de Blueprint de Unreal Engine que muestra la cadena de ataque: el evento «BeginPlay» se conecta a la salida «Start Recording», a «Play Sound 2D» y a un nodo «Delay»; a continuación, un nodo de salida «Finish Recording» escribe un archivo WAV en una ruta maliciosa de la carpeta de inicio.

Compilamos el mapa y lo subimos (¡de forma privada!) a Steam.

Mapa de POC, con un meme de Borat como descripción

Y así es como llegamos a este vídeo de prueba de concepto:

¿Es seguro MECCHA CHAMELEON ahora?

La vulnerabilidad que informamos ha sido parcheada y ya no puede ser explotada. La StopRecordingOutput función ya no crea ningún archivo (ni siquiera los previstos).

También revisamos todos los mapas de Steam Workshop para comprobar si alguno ya estaba explotando este problema, pero no encontramos ninguno.

Sin embargo, mientras trabajábamos en esta PoC, varias personas se pusieron en contacto con nosotros para avisarnos de que podría haber otras vulnerabilidades en MECCHA CHAMELEON. No proporcionaron detalles y estas no han sido verificadas ni comprobadas por nosotros.

Por lo tanto, le instamos a que sea cauto y vigilante al jugar utilizando mapas personalizados. Recomendamos jugar únicamente en los mapas oficiales proporcionados por MECCHA CHAMELEON.

Cronología de divulgación

  • 11 de agosto de 2026: Se intentó establecer contacto a través de Twitter
  • 12 de agosto de 2026: Se intentó establecer contacto a través de Discord
  • 13 de agosto de 2026: Se intentó establecer contacto con el soporte de Steam y la dirección de correo electrónico del desarrollador
  • 17 de agosto de 2026: Se pudo contactar de nuevo a través de Twitter. El desarrollador respondió que solucionaría el problema.
  • 20 de agosto de 2026: Se lanzó MECCHA CHAMELEON 4.0.0 con un parche para esta vulnerabilidad
Compartir:

https://www.aikido.dev/blog/meccha-chameleon-rce

Escanear en busca de malware

Empieza gratis
4.7/5
¿Cansado de los falsos positivos?

Prueba Aikido como otros 100k.
Empiece ahora
Obtenga un recorrido personalizado

Con la confianza de más de 100k equipos

Reservar ahora
Escanee su aplicación en busca de IDORs y rutas de ataque reales

Con la confianza de más de 100k equipos

Empezar a escanear
Vea cómo el pentesting de IA prueba su aplicación

Con la confianza de más de 100k equipos

Empezar a probar

Consigue seguridad hoy mismo,
de forma rápida y gratuita.

Protege tu código, cloud y runtime en un sistema centralizado.
Conecta un repositorio para descubrir qué encuentran los agentes de razonamiento en tu base de código.

No se requiere tarjeta de crédito | Resultados del análisis en 32 segundos.
Con la confianza de más de 150k organizaciones