Aikido

O MECCHA CHAMELEON não consegue esconder-se da RCE

Escrito por
Robbe Van Roey

TL;DR: Encontrámos outra RCE com atraso no MECCHA CHAMELEON. Ao jogar no mapa de um atacante, este pode explorar uma função exposta para escrever ficheiros arbitrariamente no sistema da vítima. Isto pode levar à execução remota de código no sistema da vítima após um reinício. Reportámos o problema aos responsáveis pelo jogo, que corrigiram a vulnerabilidade na atualização 4.0.0. Esta atualização é instalada automaticamente antes de iniciar o jogo.

Se é jogador, provavelmente já ouviu falar do MECCHA CHAMELEON. O jogo online de esconde-esconde tornou-se numa obsessão global, vendendo 15 milhões de cópias no primeiro mês!

Enquanto jogador, tem uma tarefa muito simples: encontrar um bom esconderijo e pintar uma personagem totalmente branca para condizer com o cenário. Depois, um dos seus amigos virá à sua procura. Ganha se o caçador não o conseguir encontrar. É assim tão simples!

Página inicial do Meccha Chameleon

Os mapas criados pela comunidade são uma parte importante do atrativo. Qualquer pessoa pode criar um novo mapa para os jogadores se esconderem e publicá-lo através do Steam Workshop. Estes novos mapas podem ser uma galeria de arte, áreas nostálgicas de outros jogos, entre outros.

Loja Meccha Chameleon, com vários mapas jogáveis

Uma funcionalidade específica chamou-nos a atenção: quando joga num servidor, o anfitrião do lobby escolhe o mapa e todos os jogadores desse lobby são instados a descarregar esse mapa (o ecrã avisa-o se ainda não tiver feito o download e estiver a atrasar o jogo!). Isto é muito conveniente, mas também significa que entrar numa partida pode implicar carregar um mapa feito por alguém que nunca viu. Queria perceber o que esse mapa descarregado podia realmente fazer.

No passado, o MECCHA CHAMELEON já tinha sofrido de uma RCE ao carregar mapas, conforme detalhado nesta publicação de blog. Esse erro específico já foi corrigido, mas será que isso eliminou todas as vias possíveis para uma RCE?

O que é, na verdade, um mapa de MECCHA CHAMELEON?

Poderá assumir que um mapa são apenas alguns recursos: modelos para o cenário e texturas para garantir o aspeto visual correto. É assim que um mapa funciona em muitos jogos, onde o ficheiro descarregado descreve o nível, enquanto o próprio jogo controla a lógica.

Os mapas de MECCHA CHAMELEON oferecem um controlo superior. O jogo foi desenvolvido com o Unreal Engine 5.6.1 e os seus mapas podem conter Blueprints. O Blueprint é o sistema de programação visual do Unreal. É possível ligar nós para desencadear ações quando um jogadorprime um botão, entra numa área ou simplesmente carrega o mapa.


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

Naturalmente, um mapa não pode chamar todas as funções do Unreal ou do MECCHA CHAMELEON. Primeiro, uma função nativa tem de ser disponibilizada ao Blueprint. Quando o mapa é iniciado, os respetivos gráficos são executados no âmbito do processo do MECCHA CHAMELEON. Se um gráfico invocar uma função exposta, o jogo executa essa ação utilizando a conta e as permissões do jogador.

Isto significa que os mapas personalizados constituem uma superfície de ataque interessante:

  • Um anfitrião de lobby pode solicitar a todos os outros jogadores que descarreguem e executem um mapa.
  • Esse mapa pode, posteriormente, executar gráficos Blueprint dentro do jogo.

Assim, comecei a prestar atenção às funções do motor que conseguia alcançar.

Encontrar funções invocáveis

Felizmente, não precisamos de adivinhar quais as funções que o Unreal expõe. Podemos abrir um gráfico Blueprint e clicar com o botão direito do rato numa área vazia. O Unreal apresenta agora um menu de nós pesquisável que podem ser adicionados a esse gráfico.

Do ponto de vista da segurança, eu estava sobretudo interessado em funções que interagissem de alguma forma com o sistema operativo. Por isso, procurei aquelas que continham guardar, exportar, escrever, gravar, open, iniciar, e load. Passámos de uma lista imensa de APIs para uma lista gerível que consegui analisar.

Assim, investiguei estas funções uma a uma até me deparar com Concluir a Gravação de Saída. Esta destacou-se porque conseguia criar um ficheiro no sistema de ficheiros com um caminho que pode ser absoluto ou relativo. Também armazena a saída de áudio, a qual podemos provavelmente controlar de alguma forma.

Escrever ficheiros em qualquer local

Portanto, para utilizar a função Concluir a Gravação de Saída , o criador de um mapa deve iniciar uma gravação, reproduzir um som e, em seguida, parar a gravação. De seguida, fornecemos um nome e um caminho para guardar o ficheiro. A função encontra-se documentada mais detalhadamente aqui.

Então, este é um caso bem claro de «Basta indicar qualquer diretório e qualquer nome de ficheiro, e podemos guardar esses ficheiros em qualquer lugar do sistema», certo?

Pois sim. Pode simplesmente fornecer C:\Users\Public\ como o caminho do ficheiro e escrever ficheiros aí, ou pode fornecer um caminho relativo. O diretório predefinido utilizado é C:\Users\<user>\AppData\Local\Chameleon\Saved\BouncedWavFiles, portanto, ao fornecer um caminho que começa com ../../../../../, poderíamos aceder à pasta pessoal do utilizador sem precisarmos de saber o seu nome de utilizador.

Assim, agora podíamos escrever ficheiros em qualquer local do sistema de ficheiros. A forma mais fácil de escalar isto para uma execução remota de código atrasada é escrever um executável em C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup. Sempre que o seu dispositivo arrancar, executará automaticamente todos os ficheiros nesta pasta.

Portanto, fornecemos este valor como o nome da gravação:

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

E quando empacotámos e executámos o nosso mapa, reparámos que...

Funcionou, mais ou menos? De facto, escrevemos um ficheiro na pasta de arranque. Mas a nossa extensão .exe não se manteve. O Unreal Engine está a adicionar a extensão .wav a qualquer nome de ficheiro que forneçamos e, por conseguinte, o Windows continua a tratar o ficheiro como um WAV em vez de um executável.

Remover o sufixo .wav

Refleti um pouco sobre como poderíamos contornar isto. O que temos aqui é um caso clássico de 2 sistemas diferentes a fazerem pressuposições. O Unreal Engine tem a sua forma de processar um caminho e o Windows tem a sua forma de interpretar um caminho. Só tive de encontrar uma discrepância entre ambos.

Para o Unreal Engine, é incrivelmente simples: ele vê apenas uma string e acrescenta .wav a mesma. O Windows é um pouco mais complexo. O Windows tem comprimentos máximos de nome de ficheiro e carateres que não são permitidos num caminho, tal como o carater nulo (U+0000).

Mas o que acontece quando tentamos criar um ficheiro com um carater nulo no seu nome? Bem, na maior parte das vezes, obtém um erro:

Mas nem todas as APIs geram um erro. Algumas APIs de nível inferior vão efetivamente ver os bytes nulos como um terminador e descartar tudo o que se segue:

Portanto, e se tentarmos utilizar o nosso mapa malicioso para guardar uma gravação em:

POC.exe\u0000IGNORED

Podemos ver que funcionou! Agora podemos guardar ficheiros com nomes arbitrários em localizações arbitrárias no sistema de ficheiros!

Mas continua a existir um grande problema. Estamos apenas a escrever os bytes de uma gravação de áudio WAV num ficheiro com uma extensão .exe . Precisamos de conseguir controlar também o conteúdo desse ficheiro para o tornar executável!

A janela pop-up indica: «Esta aplicação não pode ser executada no seu PC»

Bytes maliciosos numa gravação de áudio

Tínhamos agora um novo desafio pela frente. Estávamos a guardar uma gravação de áudio real como um ficheiro WAV numa localização arbitrária. Mas para este exploit funcionar, também precisamos de conseguir controlar o que está escrito nesse ficheiro.

Para o conseguir fazer, vamos utilizar um ficheiro WAV PCM não comprimido. O WAV é o container do ficheiro, que contém alguns metadados seguidos de dados de áudio. Os ficheiros WAV podem armazenar áudio em vários formatos, por isso o .wav a extensão por si só não nos diz como as amostras estão codificadas.

PCM significa Pulse-Code Modulation (Modulação por Código de Pulsos). Com o PCM, cada medição da onda sonora é armazenada diretamente como um número. A nossa prova de conceito utilizou PCM de 16 bits, pelo que cada amostra ocupava exatamente dois bytes. "Não comprimido" significa que esses números foram gravados sem passar por um codec como o MP3.

Um ficheiro WAV PCM não comprimido consiste em valores de amostras de áudio. Se controlarmos esses números com precisão, também controlamos os bytes utilizados para os armazenar.

Isto é muito importante porque a compressão de áudio normal tenta preservar a forma como um som é percecionado, e não os bytes exatos de cada amostra. Assim, uma versão comprimida pode soar de forma idêntica enquanto contém bytes muito diferentes.

Um ficheiro WAV simplificado tem o seguinte aspeto:

+-------------------------------+
| Cabeçalho RIFF/WAVE            |  Criado pelo Unreal
| Formato, canais, taxa de amostragem |
| Tamanho da secção de dados        |
+-------------------------------+
| Amostra PCM 0                 |  Controlado através da onda sonora
| Amostra PCM 1                 |
| Amostra PCM 2                 |
| ...                           |

O Unreal controla o cabeçalho, incluindo os RIFF e WAVE identificadores. Não podemos modificá-los porque o nosso controlo do ficheiro só começa na secção de dados PCM. Isso elimina uma grande quantidade de executáveis para o nosso exploit. Não podemos carregar um ficheiro .exe ou .dllnormal, uma vez que ambos precisam de um cabeçalho PE válido para ser executado.

Portanto, precisávamos de um tipo de ficheiro cujo analisador (parser) não insistisse em encontrar o seu cabeçalho no primeiro byte. As Aplicações HTML do Windows revelaram-se a opção perfeita.

Um HTML Application é um formato antigo do Windows com a extensão .hta . O ficheiro é muito semelhante a uma página web: pode conter HTML, CSS e JScript ou VBScript. O Windows abre-o com mshta.exe (Microsoft HTML Application Host).

A diferença importante em relação a uma página web normal é o local onde esse script é executado. Um HTA é tratado como uma aplicação de ambiente de trabalho em vez de uma página dentro da sandbox do browser. O seu script pode criar objetos COM do Windows, incluindo WScript.Shell, que pode iniciar outro processo.

Uma versão simplificada da nossa payload de prova de conceito tem o seguinte aspeto:

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

Quando este ficheiro é aberto, mshta.exe ignora os metadados WAV no topo e executa o script. Depois WScript.Shell inicia a Calculadora.

O desafio restante consistia em colocar esse HTML e script dentro das amostras PCM do 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

Ao agrupá-los em pares, obtemos três valores de amostra de 16 bits:

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

Quando essas amostras são gravadas novamente num WAV little-endian, os bytes originais reaparecem. Na realidade, foi preciso muito trabalho de ajuste para funcionar, mas no fim conseguimos criar um ficheiro WAV real que continha o nosso hta payload.

Um ficheiro de texto com muitos símbolos aleatórios, uma vez que se trata de um ficheiro WAV

Montar o mapa

A esta altura, cada parte funcionava isoladamente. O trabalho que restava era juntar tudo num mapa que pudesse executar o ataque completo de uma só vez quando o nível fosse carregado.

Portanto, ligamo-nos a BeginPlay e fazemos o seguinte:

  1. StartRecordingOutput num submix privado (para evitar interferência do áudio habitual do jogo)
  2. PlaySound2D com o nosso PCM não comprimido preparado
  3. StopRecordingOutput usando ../../../../Roaming/Microsoft/Windows/Start Menu/Programs/Startup/poc.exe\u0000IGNORED como o nome do ficheiro
Gráfico do Blueprint do Unreal Engine que mostra a cadeia de ataque: o evento «BeginPlay» liga-se aos nós «Start Recording Output», «Play Sound 2D» e a um «Delay»; em seguida, um nó «Finish Recording Output» grava um ficheiro WAV num caminho malicioso da pasta de arranque.

Construímos o mapa e carregamo-lo (de forma privada!) para o Steam.

Mapa do POC, com um meme do Borat como descrição

E foi assim que chegámos a este vídeo de prova de conceito:

Portanto, o MECCHA CHAMELEON está seguro agora?

A vulnerabilidade que reportámos foi corrigida e já não pode ser explorada. A StopRecordingOutput função já não cria quaisquer ficheiros (nem mesmo os pretendidos).

Também verificámos todos os mapas do Steam Workshop para ver se algum já estava a explorar este problema, mas não encontrámos nenhum.

No entanto, enquanto trabalhávamos neste PoC, várias pessoas contactaram-nos para nos informar de que poderão existir outras vulnerabilidades no MECCHA CHAMELEON. Não forneceram detalhes e estas não foram comprovadas nem verificadas por nós.

Por conseguinte, apelamos a que seja cauteloso e vigilante ao jogar o jogo com mapas personalizados. Recomendamos que jogue apenas nos mapas oficiais disponibilizados pelo MECCHA CHAMELEON.

Cronologia da divulgação

  • 11 de agosto de 2026: Tentativa de contacto através do Twitter
  • 12 de agosto de 2026: Tentativa de contacto através do Discord
  • 13 de agosto de 2026: Tentativa de contacto com o suporte do Steam e através do endereço de e-mail do programador
  • 17 de agosto de 2026: Foi possível restabelecer o contacto através do Twitter. O programador respondeu que iria corrigir o problema.
  • 20 de agosto de 2026: Foi lançada a versão 4.0.0 do MECCHA CHAMELEON com uma correção para esta vulnerabilidade
Compartilhar:

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

Verificar por malware

Comece Gratuitamente
4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes

Torne-se seguro hoje,
de forma rápida e gratuita.

Proteja o seu código, a cloud e o runtime num sistema central.
Conecte um repositório para descobrir o que os agentes de raciocínio encontram na sua base de código.

Não é necessário cartão de crédito | Resultados do teste em 32 segundos.
Confiado por mais de 150 mil orgs