2 points par GN⁺ 2025-01-10 | 1 commentaires | Partager sur WhatsApp

WorstFit : dévoilement des convertisseurs cachés de l’ANSI de Windows

TL;DR

  • Une nouvelle surface d'attaque a été découverte en exploitant le mécanisme interne de conversion de jeux de caractères de Windows, le Best-Fit.
  • Cette fonctionnalité peut être transformée en attaques concrètes, notamment en traversée de répertoires, injection d'arguments et exécution de code à distance (RCE).
  • La cause principale se trouve dans le comportement du compilateur, du runtime C/C++ et des erreurs de développement.
  • L’article aborde également la difficulté d'introduire des correctifs dans l'écosystème open source.

Décodage des encodages Windows

Initial : ANSI et pages de code

  • Windows utilisait initialement l'encodage ANSI, qui était efficace pour certaines langues mais ne pouvait pas gérer de jeux de caractères mélangés.
  • Il existe plusieurs pages de code, et chaque page prend en charge une langue spécifique.

L'ère Unicode : UTF-16

  • Windows est passé à Unicode au milieu des années 1990, ce qui a permis d'exprimer les caractères de presque toutes les langues dans un standard unique.
  • Au départ, il utilisait UCS-2, mais il a rapidement été mis à niveau vers UTF-16.

L'ère du double encodage

  • Pour conserver la compatibilité avec les anciennes pages de code ANSI, Windows a implémenté deux versions d'API.
  • Il existe des API ANSI et des API Unicode, permettant aux développeurs d'obtenir facilement le format de données souhaité.

Les avantages de Best-Fit

  • La conversion de caractères Best-Fit de Windows est une façon de gérer les caractères qui n'existent pas dans la page de code cible lors d'une conversion de UTF-16 vers ANSI.
  • Par exemple, comme le symbole n'existe pas dans la page de codes Windows-1252, Microsoft le mappe vers 8.

WorstFit : une nouvelle surface d'attaque de Windows

🔥 Cauchemar en Asie de l'Est - CVE-2024-4577

  • CVE-2024-4577 est une vulnérabilité qui permet de compromettre un serveur PHP-CGI utilisant des pages de code chinoises ou japonaises via une simple requête ?%ADs.
  • Grâce au comportement Best-Fit, U+00AD (tiret doux) est mappé sur le tiret -, ce qui permet un contournement.

🔥 Détournement de noms de fichiers

  • En exploitant WorstFit lors du traitement des noms de fichiers, il est possible de le transformer en charge utile de traversée de répertoires.
  • Par exemple, le Developer Shell (d8.exe) de Chrome V8 utilise l'API ANSI pour récupérer le répertoire de travail actuel.

🔥 Division d'arguments

  • On peut manipuler la sortie de GetCommandLineA pour exploiter le comportement WorstFit dans l'analyse de la ligne de commande.
  • Par exemple, l'entrée " --use-askpass=calc " peut permettre d'exécuter calc.exe sur le système.

Conclusion

  • Le comportement Best-Fit introduit une surface d'attaque au niveau du processus de conversion au niveau système, pouvant causer des vulnérabilités dans de nombreux outils.
  • Ces attaques ne peuvent être entièrement évitées par les fonctions des bibliothèques standard ou des langages de programmation.

1 commentaires

 
GN⁺ 2025-01-10
Commentaires Hacker News
  • Microsoft connaissait ce problème depuis au moins un an. Via la règle d’analyse de code dédiée CA2101, l’utilisation du mappage best-fit est déconseillée. Une vulnérabilité de sécurité avait été mentionnée, mais les détails restaient flous.

  • Il s’agit d’un problème structurel. Microsoft propose un mappage de code « best-fit » pour convertir l’Unicode en ASCII. Ce mappage est utilisé à de nombreux endroits et, comme Microsoft accorde beaucoup d’importance à la rétrocompatibilité, il doit continuer à être inclus. Il est connecté partout par défaut.

    • Il est surtout exploité pour convertir des points de code anormaux en slash, tiret, guillemets, etc. Cela s’évalue correctement dans les langages de programmation modernes, mais pose problème lorsqu’il est transmis à une commande shell ou à l’API Win32.

    • Le mainteneur de curl dit que « curl est la victime », mais la cause se situe ailleurs. Si une entrée utilisateur est validée d’une manière par le serveur et d’une autre via la bibliothèque système, un problème apparaît.

  • Dans l’environnement Win32, désactiver sélectivement la conversion best-fit pourrait être la solution. Les fournisseurs open source peuvent l’ajouter comme bonne pratique.

  • Windows peut, comme dans un jeu de cartes Munchkin, combiner plusieurs fonctionnalités de manière imprévue et créer une vulnérabilité puissante. Convertir le sous-système ANSI vers UTF-8 pourrait atténuer ce problème.

  • Microsoft a progressivement supprimé ANSI depuis NT 3.5 et encouragé l’usage des API wide character. La mise en œuvre de la runtime C/C++ de Microsoft reste toutefois l’obstacle principal.

    • Les fonctions standard utilisent les fonctions A sans signaler l’échec de conversion Unicode et recourent à l’approche best-fit.
  • Il est peu probable que Microsoft active par défaut UTF-8 sur toutes les éditions de Windows, car des applications anciennes dépendent de certaines pages de codes ou de caractères sur 1 octet.

    • Retirer la logique best-fit des API win32 xxxA provoquerait probablement moins de perturbations.
  • Il y a deux façons de forcer la page de codes « Ansi » d’une application vers UTF-8 : l’une via un fichier Manifest, l’autre via l’outil « App Locale ».

  • J’ai sécurisé un PC Windows personnel contre ce bug en activant le mode UTF-8, à cause de texte cassé affiché par un vieux jeu étranger.

  • Remplacer simplement main() par sa version wide-character ne suffit pas à résoudre le problème. Il faut convertir toutes les variables en wchar_t *, ce qui est pénible et sujet aux erreurs.

    • Il suffit plutôt de convertir les wide characters reçus en UTF-8 et de continuer à utiliser « char ». Il faut juste veiller à ne pas mélanger des chaînes ANSI ou OEMCP avec des chaînes UTF-8.
  • Je savais que l’API Windows proposait une conversion best-fit, mais je ne savais pas que c’était le comportement par défaut. Cette fonctionnalité devrait être interdite.

  • Je me demandais si la case Beta correspondait à définir ActiveCodePage sur UTF-8. Le GDI suit uniquement la page de codes globale, pas la page de code propre au processus. C’est dommage qu’on ne puisse pas choisir entièrement UTF-8.