Retroingénierie .NET: extraction de clés de chiffrement

Retroingénierie .NET: extraction de clés de chiffrement

Les travaux présentés ici décrivent l’analyse d’une application .NET éditeur rencontrée dans le cadre de nos tests d’intrusion. Toutes les informations permettant d’identifier ce dernier ont été supprimées.

Sommaire

  1. Analyse en boîte noire
  2. Rappel sur l’environnement d’exécution .NET
  3. Analyse en boîte blanche
  4. Extraction des clés
  5. Conclusion

1. Analyse en boîte noire

Avant toute chose, il est utile de préciser le contexte. Dans le cadre d’une campagne de tests d’intrusion réalisée pour un client, nous avons récupéré une application .NET.

Cette application dispose d’une authentification afin de se connecter au backend. Lorsque l’utilisateur s’identifie, l’application télécharge des données à partir du serveur backend.

 

00 - dotnet_application

Authentification de l’application

00 - dotnet_application_data_transfer

 Récupération de données à partir du serveur

 

La particularité intéressante qui nous a incitée à pousser plus loin nos investigations est que la validité du couple login / mot de passe fourni par l ‘utilisateur est vérifiée sans échange avec le serveur… et cela même pour d’autres comptes utilisateurs ne s’étant jamais connectés !
Ce comportement ayant été observé à partir du moment où l’utilisateur s’est connecté une première fois à l’application et a récupéré des données à partir du serveur, on peut légitimement se demander si des informations sensibles ne seraient pas stockées localement.

Naturellement, c’est donc à l’intérieur de ces données que nous sommes allés chercher des informations.

Après un petit tour sur le système de fichiers, il s’avère que les données téléchargées sont stockées dans un seul et même fichier XML de plusieurs Mo.

00 - Fichier chiffre

Vue du fichier XML

 

Malheureusement, ce fichier ne semble pas contenir d’information utile et semble totalement illisible au premier abord.
Une mesure du taux d’apparition des octets révèle que l’entropie du fichier est élevée.

graph_strip

Représentation de l’entropie du fichier

Lorsqu’un fichier potentiellement sensible présente une entropie élevée, cela indique généralement que ce dernier est chiffré.
Notre approche en boîte noire atteint là ses limites. Pour valider l’hypothèse précédente, il faut regarder le fonctionnement interne de l’application et continuer notre analyse en boîte blanche.

2. Rappel concernant l’environnement d’éxécution .NET

L’éxécution des applications .NET s’effectue conformément à la spécification Common Language Infrastructure (CLI)

Le principe est analogue à Java et sa machine virtuelle: l’objectif est de rendre les applications portables.
Les applications sont compilées en Common Intermediate Language (CIL).

 

Overview_of_the_Common_Language_Infrastructure

Architecture CLI

 

Les fichiers obtenus après la compilation sont au format exécutable natif du système et ne présentent à première vue pas de dissimilitude avec les .EXE et .DLL traditionnels.
Dans la terminologie Microsoft .NET, le terme utilisé pour désigner ces exécutables est assembly.
Ces fichiers embarquent le bytecode CIL ainsi que des metadatas contenant toutes les informations de haut-niveau traditionnellement perdues à la compilation: structures des classes, variables membres, méthodes, noms des variables, …

 

dotnet_assembly

Structure d’un fichier .NET assembly

 

En utilisant des outils de décompilation de .NET type .NET Reflector ou ILSpy, il est ainsi possible d’afficher le code-source originel de l’application. Cette démarche est appelée analyse en boîte blanche.

3. Analyse en boîte blanche

.NET Reflector s’étant métamorphosé en un vulgaire shareware (et accessoirement n’étant pas capable de décompiler notre application sans crasher), nous avons choisi d’utiliser ILSpy.

 01 - ilspy_static_analysis

 Ouverture des fichiers .NET dans ILSpy

 

Les informations techniques sont très fournies: on dispose à peu de choses prêts de la même vision que le développeur originel ! C’est un luxe incommensurable quand on sait le peu d’informations complémentaires dont on dispose quand on introspecte les fichiers .EXE classiques.

Désormais, il suffit simplement de parcourir le code pour obtenir plus de détails sur le fichier XML de départ.

On tombe rapidement sur des zones de code intéressantes:

 

05 - xmlencryptor

 Classe interne XmlManager::XMLEncryptor

 

Le nom de la classe XMLEncryptor a tendance à confirmer que de la cryptographie est utilisée pour chiffrer le XML…

 

02 - generate_iv_key

 Code d’initialisation des clés + vecteurs d’initialisation

 

this.password ET this.username sont utilisés pour initialiser le couple clé/IV. Dans le constructeur de la classe XmlManaged::XMLEncryptor, ces variables sont affectés avec le nom de l’éditeur et de la solution respectivement.

 

03 - algorithm_encryption

Le chiffrement utilisé  est RijndaelManaged (autrement dit de AES-128 en mode CBC d’après la terminologie .NET)

 

Toutes les informations nécessaires au déchiffrement du fichier XML sont maintenant connues: algorithmes d’initialisation de la clé + IV ainsi que le type du chiffrement utilisé. Il ne reste plus qu’à extraire les clés et à ré-implémenter la fonction de déchiffrement réciproque.

4. Extraction des clés

Pour connaître les valeurs des clés + IV à la sortie des méthodes GenerateKey() et GenerateIV(), le plus simple est de copier-coller le code précédent dans Visual Studio puis d’afficher les valeurs après leur initialisation.

 

08 - key and iv

 Ré-implémentation dans Visual Studio et affichage du couple (clés + IV)

 

Essayons à présent de déchiffrer  le fichier en utilisant la clé  et le vecteur d’initialisation précédent.

 

09 - unencrypted_xml

Extrait du fichier XML déchiffré

 

Bingo ! le résultat est un gros fichier XML de plusieurs mégas qui contient l’ensemble des utilisateurs et administrateurs de l’application avec de nombreuses informations personnelles parmi lesquelles les hashs ! Ces derniers peuvent à présent être attaqués en local afin d’obtenir des comptes supplémentaires sur l’application.

 

5. Conclusion

L’hypothèse de départ, à savoir que le fichier XML contenait des informations sensibles et qu’il était chiffré, s’est finalement avérée être la bonne.

C’est monnaie courante, dans le cadre de tests d’intrusions réalisés sur des clients lourds, de retrouver des informations compromettantes cachées dans les applications.

La parade est pourtant simple: il suffit d’appliquer un certain nombre de principes élémentaires que l’on pourrait qualifier de bonnes pratiques de sécurité:

  • N’accorder aucune confiance aux données émanant du côté client: vérifier l’ensemble des informations côté serveur.
  • Ne stocker aucune information sensible côté client.
  • Sécuriser, authentifier et assurer l’intégrité de l’ensemble des communications réseaux.

 

G.O.

Remerciements: F.B.