Nouveaux outils, anciennes méthodes. Nous inversons l'ingénierie et découvrons la faille fatale de 1Password.Tout le monde aime les gestionnaires de mots de passe. Ils sont parfaits pour de nombreuses raisons. Personnellement, j'ai plus de 200 entrées dans le manager. Avec autant de données confidentielles en un seul endroit, il est important de comprendre l'étendue des dommages si votre dossier est compromis, qu'il s'agisse de logiciels malveillants, d'exploits ou simplement d'un ordinateur laissé sans surveillance pendant plusieurs minutes.
Le Washington Post a récemment publié un article basé sur notre
étude . Cet article permet de faire comprendre aux gens que tous les gestionnaires de mots de passe ne sont pas identiques.
Je croyais fermement qu'un gestionnaire de mots de passe verrouillé était bien protégé. Si quelqu'un a accès à mon ordinateur, le maximum peut compter sur un tas d'octets aléatoires, car les informations sont effacées de manière fiable de la mémoire.
Cela est vrai pour 1Password 4 (notez que la dernière version est la septième aujourd'hui). Avant de passer à celui-ci il y a quelques années, j'ai vérifié qu'il n'y avait vraiment pas de mot de passe en clair lorsque le manager était verrouillé. Ainsi, en cas de compromis, l'attaquant devra faire face à un stockage chiffré.
Le coffre-fort est verrouillé!Dans cet état, il n'y a aucune entrée de mot de passe ou mot de passe principal. Très raisonnable et correct, et 1Password 4 a réussi ce test. Ou pas?
Pour me débarrasser des détails ennuyeux, je dirai tout de suite: nous avons pu restaurer le mot de passe principal à partir d'une instance verrouillée dans 1Password 4, comme indiqué ci-dessous.
Déverrouillez 1Password 4 et récupérez votre mot de passe principalL'animation montre que 1Password 4 est d'abord déverrouillé de manière normale, puis verrouillé. Après cela, nous
exécutons notre utilitaire
multipass , qui récupère avec succès le mot de passe. L'utilitaire exploite un traitement incorrect du champ de saisie de mot de passe dans 1Password 4 pour restaurer le tampon de mot de passe maître obscurci, le désobfusquer, déverrouiller automatiquement 1Password 4 et enfin afficher le mot de passe principal dans la console.
Détails ennuyeux
La première étape de l'évaluation d'un gestionnaire de mots de passe consiste à rechercher un mot de passe maître clair en mémoire. Ceci est possible dans n'importe quel éditeur hexadécimal capable d'interagir avec l'espace mémoire du processus. Par exemple, l'éditeur
HxD gratuit. Utilisez-le pour ouvrir l'espace mémoire de 1Password 4.
Nous tombons immédiatement dans la première zone lisible de l'espace mémoire de 1Password 4.
Exemple de représentation de la mémoire HxDRien de spécial pour le moment. Mais vous pouvez faire une recherche. Par exemple, à quoi ressemble la situation si vous tapez le mot de passe dans la fenêtre de déverrouillage de 1Password 4, mais ne cliquez pas sur le bouton "Déverrouiller":
Coffre-fort verrouillé 1 Mot de passe 4 avec le mot de passe principal entré dans le champLe mot de passe est sûrement quelque part dans la mémoire?
Nous ouvrons HxD, mais la recherche d'une ligne avec notre mot de passe principal («Z3Superpass #») ne produit aucun résultat.
Il semble que 1Password chiffre ou obscurcit en quelque sorte le formulaire lors de sa saisie. Si la procédure fonctionne correctement, tout va bien.
Plonger plus profondément
Pour savoir pourquoi le mot de passe principal est introuvable dans la mémoire alors qu'il est clairement présent dans la boîte de dialogue de déverrouillage, vous devez trouver le code qui interagit avec lui. Il y a plusieurs façons. Vous pouvez suivre le traitement des événements du clavier et de la souris en localisant «GetMessage», «PeekMessage», «GetWindowText» ou d'autres API Windows qui gèrent généralement les entrées utilisateur. Nous trouvons donc le tampon où les frappes sont enregistrées, et à travers eux, nous passons à la routine de cryptage / obscurcissement. Mais c'est un processus long et sujet aux erreurs, en particulier avec les grands cadres qui gèrent parfois la mémoire de manière très étrange, vous devez donc effectuer de nombreuses copies et conversions pour suivre le tampon.
Au lieu de cela, nous utilisons notre propre outil Thread Imager, conçu pour rétroconcevoir des protocoles propriétaires «étranges» au niveau de l'application. Il vous aidera à déterminer où en mémoire 1Password 4 interagit avec notre mot de passe principal. L'outil identifie "automatiquement" les zones de code dans 1Password 4 qui interagissent avec un mot de passe obscurci (il met simplement en évidence les instructions qui interagissent avec les données d'intérêt pour une analyse plus approfondie). Le résultat ressemble à ceci:
Thread Imager trouve le code 1Password 4 qui interagit avec un mot de passe maître non focaliséÉtant donné que le mot de passe principal est stocké en mémoire sous une forme obscurcie, l'outil doit d'abord indiquer où l'obfuscation se produit.
Un fragment du premier résultat montre que la première apparition du mot de passe principal est accompagnée d'une transition de code de l'adresse 0x7707A75D à 0x701CFA10.
Une entrée détaillée dans Thread Imager met en évidence la transition de code de 0x7707A75D à 0x701CFA10, tandis que les registres EAX et ECX se réfèrent au tampon avec le mot de passe principalL'examen de cet endroit 0x7707A75D dans le débogueur (x64dbg) confirme notre théorie. En effet, pour la première fois, la chaîne «Z3superpass #» apparaît lorsque la fonction de décodage «RtlRunDecodeUnicodeString» de la bibliothèque ntdll.dll se termine.

Après une petite analyse, il est clair que ces deux fonctions sont utilisées pour masquer le mot de passe: «RtlRunEncodeUnicodeString» et «RtlRunDecodeUnicodeString». Ainsi, le mot de passe principal est caché de la copie primitive de la mémoire, c'est pourquoi auparavant nous ne pouvions pas le trouver dans l'éditeur hexadécimal.
Si vous étudiez le tampon codé à la fin de la fonction RtlRunEncodeUnicodeString, la ligne chiffrée avec le mot de passe principal ressemble à ceci:
Mot de passe principal cryptéAprès RtlRunDecodeUnicodeString ', il est décodé:
Mot de passe principal déchiffréFait intéressant, cette zone est enregistrée à la même adresse 0x00DFA790 et nous pouvons littéralement observer son changement lors de la saisie d'un mot de passe dans la fenêtre de déverrouillage de 1Password 4:
Vulnérabilité
'RtlRunEncodeUnicodeString' et 'RtlRunDecodeUnicodeString' sont des fonctions simples qui modifient une chaîne avec une simple opération XOR. Ce n'est pas si mal: il semble que ce soit la méthode standard pour masquer tous les contrôles d'édition natifs de Windows avec le jeu d'indicateurs 'ES_PASSWORD'.
Le problème est qu'après le déverrouillage de 1Password 4, le mot de passe principal chiffré n'est pas effacé de la mémoire.
Pire, il reste en mémoire même après le verrouillage de 1Password 4. Autrement dit, nous avons un magasin de mots de passe verrouillé, mais avec un mot de passe maître chiffré en mémoire.
Et pire encore, puisque nous interagissons avec la boîte de dialogue de saisie du mot de passe principal, la même zone de mémoire est réutilisée avec la même valeur XOR, ce qui nous donne un accès facile au tampon codé pour créer un exploit.
Défi
Pour créer un exploit fiable pour 1Password 4, vous devez obtenir une image plus claire de la façon dont le mot de passe principal est traité par les flux de travail du programme. En utilisant les outils susmentionnés, nous avons construit un diagramme de données de sortie (voir la figure ci-dessous).

Ce diagramme permet de mieux comprendre où et quelles bibliothèques sont impliquées afin d'identifier de manière fiable les zones de la mémoire où vous pouvez récupérer le mot de passe principal.
Exploiter
Qu'avons-nous en ce moment? Nous avons un stockage verrouillé, et quelque part dans la mémoire, un mot de passe masqué est stocké, car le programme n'a pas nettoyé la mémoire correctement.
Pour le récupérer, vous devez appeler la procédure dans 1Password 4, qui lance les «RtlRunEncodeUnicodeString» et «RtlRunDecodeUnicodeString». Ainsi, il montrera l'emplacement de la mémoire tampon avec le mot de passe principal codé.
Zone de mémoire avec un mot de passe maître masquéSans ce tampon, il faudrait plonger dans l'abîme des procédures internes et des contrôles Windows et des mécanismes de gestion de la mémoire associés. Peut-être que cette analyse permet de trouver facilement un tampon, mais nous ne sommes pas allés de cette façon.
Il semble que la seule façon d'appeler «RtlRunEncodeUnicodeString» et «RtlRunDecodeUnicodeString» est d'entrer le mot de passe principal dans le caractère de la boîte de dialogue. Nous obtenons donc le tampon souhaité. Mais nous ne connaissons pas la longueur du mot de passe.
Nous avons résolu ce problème en interceptant du code qui accède au premier caractère de notre tampon, bloquant une tentative de modification. Cette routine se trouve dans la boucle des messages de contrôle dans comctl32, qui gère le contrôle du tampon des éléments correspondants. L'appel de 'memmove' avec l'offset 0x70191731 écrase le tampon avec le caractère entré:
(Effet secondaire: la ligne en surbrillance (jaune) met à jour toute la ligne de mot de passe)Maintenant, nous avons enfin tout ce dont nous avons besoin pour créer un exploit. Les étapes suivantes nous permettront d'extraire le mot de passe principal:
- Accrochez «memmove» pour éviter d'écraser le premier octet du mot de passe principal.
- Accrochez «RtlRunEncodeUnicodeString» pour obtenir l'emplacement du tampon de mot de passe maître masqué.
- Accrochez «RtlRunDecodeUnicodeString» pour accéder au tampon obscurci obtenu à l'étape précédente.
- Entrer un caractère dans le champ de saisie du mot de passe et refuser l'étape 1 (enregistrer le mot de passe maître entier), rediriger l'étape 2 vers l'étape 3 pour décoder le mot de passe maître masqué.
Pour effectuer toutes ces actions, créez une DLL avec le code du gestionnaire pour tous ces hooks. La bibliothèque est intégrée dans le processus 1Password 4, envoie un caractère à la boîte de dialogue de mot de passe principal, en lançant les étapes memmove, RtlRunEncodeUnicodeString et RtlRunDecodeUnicodeString que nous pouvons intercepter - et faisant notre magie pour récupérer le mot de passe principal masqué. La plupart de la magie se produit dans le DetourRtlRunEncodeUnicodeString, c'est le crochet pour la fonction 'RtlRunEncodeUnicodeString', illustrée ci-dessous:
Ce qui nous amène au résultat final: déverrouiller le référentiel verrouillé 1Password 4 de n'importe quelle version en utilisant la procédure de buggy utilisée par l'API Windows:

Résumé
Lorsque nous avons exploré pour la première fois l'intérieur de 1Password 4, nous nous attendions à rencontrer une sorte de système de sécurité complexe et nous nous attendions à ce que toutes les informations sensibles soient effacées de la mémoire, comme cela se produit dans les procédures PBKDF2 et dans d'autres domaines où le mot de passe principal est utilisé. Les entrées correspondantes sont également effacées. Cependant, en raison d'un oubli, le champ de saisie du mot de passe est considéré comme un contrôle API Windows standard avec un mot de passe caché, ce qui compromet la sécurité de 1Password 4.