2 pontos por GN⁺ 2025-01-10 | 1 comentários | Compartilhar no WhatsApp

WorstFit: Revelando transformadores ocultos no Windows ANSI

TL;DR

  • Descobriu-se uma nova superfície de ataque explorando o recurso interno de conversão de conjunto de caracteres do Windows chamado Best-Fit.
  • Esse recurso foi convertido em ataques práticos, como path traversal, injeção de argumentos e execução remota de código (RCE).
  • As causas raiz estão no comportamento do compilador, no runtime de C/C++ e em erros dos desenvolvedores.
  • Também discute-se a dificuldade de inserir correções no ecossistema de código aberto.

Decodificando codificação do Windows

Inicial: ANSI e code pages

  • No início, o Windows usava codificação ANSI, que era eficaz para idiomas específicos, mas não conseguia lidar com conjuntos de caracteres mistos.
  • Existem diversas code pages, e cada uma suporta idiomas específicos.

Era Unicode: UTF-16

  • O Windows migrou para Unicode em meados da década de 1990, permitindo representar praticamente todos os caracteres de praticamente todos os idiomas em um único padrão.
  • Inicialmente ele usava UCS-2, mas logo foi atualizado para UTF-16.

Era de codificação dupla

  • Para manter compatibilidade com as code pages ANSI antigas, o Windows implementou duas versões de API.
  • API ANSI e API Unicode, e os desenvolvedores podem obter facilmente o formato de dados desejado.

Vantagens do Best-Fit

  • A conversão de caracteres "Best-Fit" do Windows é uma forma de tratar caracteres ausentes na code page de destino durante a conversão de UTF-16 para ANSI.
  • Por exemplo, como o símbolo não existe na code page Windows-1252, a Microsoft o mapeia para 8.

WorstFit: nova superfície de ataque no Windows

🔥 O pesadelo do Leste Asiático - CVE-2024-4577

  • CVE-2024-4577 é uma vulnerabilidade que pode comprometer um servidor PHP-CGI configurado com code pages chinesas ou japonesas por meio de uma requisição simples ?%ADs.
  • Devido ao comportamento do Best-Fit, U+00AD (hífen suave) é mapeado para hífen (-), permitindo bypass.

🔥 Smuggling de nome de arquivo

  • É possível abusar do WorstFit no tratamento de nomes de arquivos e transformá-los em payloads de path traversal.
  • Por exemplo, o Developer Shell do Chrome V8 (d8.exe) obtém o diretório de trabalho atual usando a API ANSI.

🔥 Divisão de argumentos

  • É possível manipular a saída de GetCommandLineA e explorar o comportamento do WorstFit no parsing da linha de comando.
  • Por exemplo, a entrada " --use-askpass=calc " pode fazer o sistema executar calc.exe.

Conclusão

  • O comportamento do Best-Fit oferece uma superfície de ataque no processo de conversão em nível de sistema, o que pode causar vulnerabilidades em diversas ferramentas.
  • Nem funções de bibliotecas padrão nem funções de linguagens de programação conseguem bloquear completamente esse tipo de ataque.

1 comentários

 
GN⁺ 2025-01-10
Opinião do Hacker News
  • A Microsoft sabia desse problema há pelo menos um ano. Pela regra de análise de código específica CA2101, ela já não recomenda o uso de mapeamento best-fit. A vulnerabilidade de segurança foi mencionada, mas os detalhes ficaram vagos.

  • Isso é sistêmico. A Microsoft fornece o mapeamento de código "best fit" para converter Unicode para ASCII. Esse mapeamento é usado em muitos lugares, e como a Microsoft prioriza compatibilidade com versões anteriores, precisa continuar incluído. Está fundamentalmente acoplado em todo lugar por padrão.

    • É explorado principalmente convertendo pontos de código anormais em slash, hífen, aspas etc. Em linguagens de programação modernas isso é avaliado corretamente, mas gera problemas ao ser passado para comandos de shell ou para a API Win32.

    • O mantenedor do curl diz que "o curl é a vítima", mas a causa do problema está em outro lugar. Ele ocorre quando a entrada do usuário é validada de uma maneira e o sistema é aplicado de outra forma na biblioteca do sistema.

    • Desativar seletivamente a conversão "best fit" no espaço Win32 pode ser uma solução. Provedores de código aberto podem adicionar isso como uma boa prática.

  • O Windows pode ser como um jogo de cartas Munchkin: recursos se combinam de forma inadvertida e criam uma vulnerabilidade poderosa. Converter a subsistema ANSI para UTF-8 pode mitigar esse problema.

  • A Microsoft vinha descontinuando o ANSI gradualmente desde o NT 3.5 e incentivando o uso da API de caracteres largos. No entanto, a forma de implementação da runtime da biblioteca C/C++ da Microsoft é um obstáculo importante.

    • As funções padrão usam funções A e empregam a abordagem best-fit, em vez de relatar falha de conversão de Unicode.
  • É improvável que a Microsoft ative UTF-8 por padrão em todas as edições do Windows. Isso porque aplicativos antigos dependem de certas páginas de código ou de caracteres de 1 byte.

    • Remover a lógica Best-Fit em APIs win32 xxxA causaria menos problemas.
  • Existem duas maneiras de forçar a página de código "Ansi" para UTF-8 em uma aplicação: usar um arquivo Manifest ou usar a ferramenta "App Locale".

  • Em uma máquina Windows pessoal, fiquei seguro contra esse bug ao configurar o modo UTF-8. Ativei isso porque um jogo antigo estrangeiro exibia texto quebrado.

  • Resolver o problema não é algo que se arranja trocando simplesmente main() pela versão wide-character. Seria preciso converter todas as variáveis para wchar_t *, o que é doloroso e propenso a erros.

    • Em vez disso, é possível converter os wide characters recebidos para UTF-8 e continuar usando char. Tome cuidado para não misturar strings ANSI ou OEMCP com strings UTF-8.
  • Eu sabia que a API do Windows fornece conversão best-fit, mas não sabia que esse é o comportamento padrão. Esse recurso deveria ser proibido.

  • Eu tinha curiosidade se a caixa de seleção Beta fazia o mesmo que definir o ActiveCodePage como UTF-8. O GDI não segue a página de códigos por processo, e sim apenas a página de códigos global. É uma pena não poder escolher UTF-8 totalmente.