Les ransomwares : ces logiciels malveillants prenant en otage vos données personnelles contre remise d'une rançon nous rendent immédiatement la vie pénible si l'on a le malheur de se faire avoir. Très actif depuis le début de l'année, le cas étudié ci-après a la particularité de se loger juste après le BIOS, empêchant alors même le système de démarrer après avoir chiffré le disque.
Introduction
Le principe de la rançon, déjà utilisé depuis des siècles est depuis l'informatisation de la société aussi mis en pratique dans le monde numérique. Ce ne sont plus des personnes qui sont prises en otage, mais des données rendues inaccessibles par l'utilisation d'un logiciel frauduleux jusqu'au paiement, généralement en Bitcoin.
Ce début d'année a déjà été prolifique pour ce type de logiciels. Appréciés par les pirates notamment dus à leurs principes de fonctionnement assez simple, et au retour sur investissement rapide qui les rendent très rentables. Dans la digne lignée des CryptoWall, CryptoLocker, TeslaCrypt, ou encore Locky pour n'en citer que quelques-uns, Petya se distingue par un côté rétro de par son interface en ASCII art, mais surtout par son habilité à agir comme un bootkit en se répliquant dans le Master Boot Record (MBR) ou dans la GUID Partition Table (GPT) suivant le type d'installation, empêchant alors le système de démarrer après avoir préalablement chiffré son contenu.
L'article va se composer de deux parties principales : la première traite de l'exécution du malware jusqu'à son implantation dans le secteur de démarrage, et la seconde du chiffrement du disque jusqu'à son éradication.
1. Userland
Une fois n'est pas coutume mon sample comporte un nom à consonance allemande Bewerbungsmappe-gepackt.exe (md5 :af2379cc4d607a45ac44d62135fb7015), pouvant se traduire par dossier de candidature compressé. Compressé, car il arbore comme icône celle d'une archive auto extractible de type SFX. Cela pourrait servir à cibler un service de ressources humaines d'une entreprise, ou n'importe quel particulier étant un peu trop curieux au vu d'un CV.
Dès son lancement, le malware contrôle s'il dispose des droits administrateurs requis pour l'accès au disque physique. Dans le cas contraire, rien ne se passe, car toutes ses opérations vont se faire à un niveau bas du système, ce qui est l'on peut dire un de ses points faibles ou plus généralement le revers de la médaille d'un bootkit. Pour disposer de tels privilèges, Petya va tout simplement les demander à l'utilisateur via l'élément trustInfo du manifeste de l'exécutable.
01 : <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
02 : <security>
03 : <requestedPrivileges>
04 : <requestedExecutionLevel level="requireAdministrator"
05 : uiAccess="false"/>
06 : </requestedPrivileges>
07 : </security>
08 : </trustInfo>
Le payload du malware est une dll obfusquée par un cryptor, pouvant usurper une archive auto extractible comme un PDF dans cet exemple, ou de n'importe quel programme suivant le packer utilisé. Son fonctionnement est tout ce qu'il y a de plus standard à savoir dissimuler la charge utile aux antivirus en modifiant le hash d'origine, et en ajoutant des mécanismes rendant plus difficile le reverse engineering ou l'analyse automatisée au sein d'une sandbox. De ce fait et en raison des nombreuses variations existantes, je ne vais pas traiter la déobfuscation et passer directement à l'analyse du payload, stage 1.
Petya cherche à gagner un accès bas niveau au disque physique. Pour ce faire, plusieurs étapes seront nécessaires. Premièrement, comme pour presque n’importe quelle opération sous Windows, un handle est requis et devra être passé aux API de contrôle du disque. Il s’obtient en appelant kernel32_CreateFileA avec comme cible la racine du disque logique, \\.\C: dans notre cas. Cela retournera un handle qui sera donné à la fonction système permettant d’envoyer des commandes à un driver spécifique, kernel32_DeviceIoControl.
Pour passer du disque logique au physique, cette API sera appelée avec IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS. Ce paramètre récupère l’emplacement physique d’un volume sur un ou plusieurs disques à savoir \\.\PhysicalDrive0. Une fois cet emplacement trouvé, l’argument IOCTL_DISK_GET_PARTITION_INFO_EX renvoie des informations étendues sur le type, la taille, et la nature d’une partition (MBR ou GPT). Précisons encore que l'échantillon étudié se concentre sur le cas d'une infection du MBR, néanmoins le fonctionnement de la variante GPT est similaire.
À ce stade, le malware connaît tout ce dont il a besoin pour accéder et altérer le contenu du disque physique à sa guise. Il commence par copier l’intégralité du MBR d’origine pour être en mesure de le restaurer une fois la rançon payée. Cette zone se trouve dans les 512 premiers bytes d’un disque, dans le secteur 0. Dès la copie faite, il l’obfusque simplement avec un XOR '7'.
Figure 1 : XOR '7' appliqué au MBR.
Le registre eax sert ici de compteur : incrémenté à chaque itération, la boucle se répète tant que sa valeur est strictement inférieure à ebp, dont la taille est celle d’un secteur de disque (512). Petya remplace ensuite le MBR par un bootloader qui lui permettra de charger la version bootkit du malware, aussi appelée stage 2.
Il génère en outre la clé de chiffrement symétrique du disque qui sera chiffrée asymétriquement en faisant appel aux courbes elliptiques via les librairies cryptsp.dll et rsaenh.dll. Cet identifiant unique permettra à l’attaquant de connaître la clé générée sur l’ordinateur de la victime.
Cette dernière sera encodée en base58 pour faciliter son envoi. Cet algorithme a notamment comme avantage de n’inclure que des caractères alphanumériques, en omettant certains caractères pouvant porter à confusion comme le zéro '0' et le o majuscule 'O', ou comme le L minuscule 'l' et le i majuscule 'I'. Ceci est à préférer lors d’une entrée manuelle de texte, comme ici où la victime devra envoyer cet identifiant à l'attaquant. Voici ce que donne la clé une fois chiffrée et encodée :
d0P2KsMyxbdqwWi8oU8mBcE2Pbd71hxqVDDLkfqNvJWEffA9g498oVAPpjcGLMc9HN4j6rYwVLKYfae9jai5M8b8R3
Illustré sur la figure ci-dessous, le malware va écrire sur le secteur 54 à 56 les informations suivantes :
- secteur 54 : la clé pour le chiffrement du disque et son identifiant, ainsi que les URLs du site de paiement ;
- secteur 55 : secteur entièrement rempli avec le caractère '7', cela servira pour la validation de la clé ;
- secteur 56 : le MBR d’origine préalablement XOR '7'.
Figure 2 : Écriture du malware parmi les premiers secteurs du disque.
Avec maintenant Petya profondément intégré sur le disque dans la zone d’amorçage et les secteurs suivants, le malware va provoquer un redémarrage du système via l'appel à SeShutdownPrivilege. L’ordinateur va alors juste s’éteindre brusquement comme lors d’un blue screen ou d’une coupure de courant.
Dans l’état actuel du système, il est encore possible de se remettre de l’infection, car les données utilisateur ne sont pas encore chiffrées à la fin du stage 1. Il est en outre possible de récupérer la clé de chiffrement symétrique présente dans le MBR en faisant une copie des premiers secteurs du disque jusqu’au secteur 57 compris pour avoir l’intégralité de l’injection.
Cela peut se faire en démarrant sur un support de donnée externe ou en copiant les données après avoir monté le disque dur depuis autre machine. Le script python ci-dessous permet ensuite de déobfusquer la clé présente sur le disque.
01 : #!/usr/bin/env python3
02 : import sys
03 :
04 : with open(sys.argv[1], 'rb') as f:
05 : plain = ''
06 : offset = 54*512+1
07 : f.seek(offset)
08 : cipher = f.read(0x20)
09 : for i in range(0, len(cipher)-1, 2):
10 : plain += chr(cipher[i+1]>>1)
11 :
12 : print(plain)
Ce qui affichera une fois exécuté :
$ ./petya_decoder.py mbr.bin
fxBdrvLeKo6aacQR
Il est aussi encore possible de remplacer le malware par le MBR d'origine, en réappliquant le même mécanisme de XOR en sens inverse.
Malheureusement si l’on ne fait rien comme cela arriverait sûrement lors d'une véritable infection, le redémarrage automatique en cas de défaillance du système étant activé par défaut, la machine va alors redémarrer normalement et exécuter le stage 2 du malware juste après le BIOS.
2. MBR
Le master boot record est le nom du premier secteur du disque de 512 bytes. Il contient entre autres la table des partitions ainsi qu’une routine d’amorçage exécutée après le BIOS dont le but est de démarrer le système d’exploitation sur la partition active, il se termine par la magic value 0x55AA.
À la fin de du BIOS, le flux d'exécution va lancer le bootloader du malware depuis le secteur 0 du disque contenant le MBR. Ce secteur d’amorçage modifié au préalable lors du stage 1 va s’occuper de charger en mémoire le malware depuis les secteurs du disque physique.
La figure 3 illustre l’exécution du contenu du MBR à l’offset 0x7C00, qui est la première adresse appelée par le BIOS pour lancer la séquence d’amorçage. Ce bout de code relativement compact qui utilise une architecture 16 bits charge les secteurs désignés en mémoire, et les exécutera par la suite. On retrouve dans eax les 32 secteurs à charger, dans ebx le secteur de départ 34, et dans cx la première adresse mémoire du code ainsi chargé.
Figure 3 : Charge les secteurs en mémoire depuis le disque.
Une fois le code du malware chargé en mémoire depuis le disque, Petya affiche intelligemment lors du premier redémarrage un faux utilitaire de réparation de disque chkdsk qui va en réalité chiffrer l'intégralité de la Master File Table, ou MFT avec la clé générée et stockée lors du stage 1.
Figure 4 : Faux check disk très bien réalisé, chiffrant la MFT avec l'algorithme « salsa ».
Cette table de fichiers est un élément principal d'une partition NTFS, il s'agit du premier fichier présent sur celle-ci, et il contient la liste de tous les fichiers stockés sur le disque. En temps normal, l'apparition d'un chkdsk après une défaillance du système peut légitimement arriver, ce qui démontre la subtilité du malware.
Dès l'opération terminée, l'ordinateur redémarre une deuxième fois pour afficher un nag screen en ASCII art comme montré en figure 5.
Figure 5 : Tête de mort affichée par le malware une fois le chiffrement terminé.
Après avoir pressé une touche du clavier, une autre page s'affiche détaillant la situation et nous demandant d'acheter un code pour déverrouiller notre ordinateur.
Intéressons-nous maintenant à la partie de vérification de cette clé. Une fois cette dernière entrée par l'utilisateur, l'algorithme s'assure que sa longueur soit bien de 16 caractères, et qu'ils soient tous compris dans le charset [a-zA-Z0-9]. Si ce n'est pas le cas, elle est directement rejetée. Dans le cas où cela concorde, la clé entrée est étendue de 16 à 32 caractères via l'algorithme reproduit ci-dessous.
01 : #!/usr/bin/env python3
02 : import sys
03 :
04 : cipher = ''
05 : for c in sys.argv[1]:
06 : cipher += hex(ord(c)+0x7A)[2:]
07 : cipher += hex(ord(c)<<1)[2:]
08 :
09 : print('0x'+cipher.upper())
Résultat de l'exécution du script python :
$ ./petya_encoder.py fxBdrvLeKo6aacQR
0xE0CCF2F0BC84DEC8ECE4F0ECC698DFCAC596E9DEB06CDBC2DBC2DDC6CBA2CCA4
Cette nouvelle clé est dérivée par le même algorithme relativement simple que lors du stage 1 du malware. Cela servira à prouver qu'elle est effectivement correcte. Pour cela, le secteur 55 du disque sera déchiffré avec cette clé. Si comme originellement le secteur se retrouve rempli uniquement de '7' comme écrit lors de la première partie du malware, cela signifie que cette dernière est bel et bien valide.
La routine illustrée sur la figure 6 montre qu'un message d'erreur s'affiche et redemande d'entrer une clé valide tant qu'une n'est pas reconnue comme telle. Si elle s'avère correcte, la boucle se termine et laisse place au déchiffrement du disque.
Figure 6 : Boucle d'entrée et de vérification de la clé de déchiffrement.
Il ne faut néanmoins pas essayer de modifier une condition ou le flux d'exécution du programme en biaisant un paramètre pour terminer cette boucle, car dans ce cas le déchiffrement s'effectuera avec une mauvaise clé et rendra par la suite les données du disque inutilisables au lieu de les déchiffrer correctement.
Figure 7 : Instructions de paiement et déchiffrement en cours du disque.
Dès l’opération de déchiffrement terminée, le malware nous ne nous affiche qu’une phrase écrite en rouge sur fond gris nous demandant de redémarrer notre machine. Suite à cela, l’ordinateur redémarre effectivement normalement avec le MBR d'origine et la MFT restaurée.
3. Quid du support ?
Il est encore intéressant de jeter un œil à la plateforme permettant à l’attaquant de recevoir de l’argent et d’envoyer la clé en retour à l’utilisateur victime de Petya. En suivant les instructions illustrées par la figure 7, nous avons la possibilité de nous rendre sur une des URLs suivantes :
- http://petya37h5tbhyvki[.]onion/a6UWjQ
- http://petya5koahtsf7sv[.]onion/a6UWjQ
Pour cette analyse, la première URL a été utilisée. En y accédant via Tor, apparaît un site web au design propre, et aux faux airs de communisme en prenant par exemple la faucille et le marteau comme logo, et petya ransomware en écriture rouge et caractères cyrilliques. Il en est de loin très professionnel, avec support multilingue et accès par captcha pour éviter les accès automatisés.
En page d'accueil prend place un compte à rebours, à la fin duquel le montant à payer se verra doubler. En dessous de celui-ci se trouve une section blog, avec des publications de sociétés antivirus comme trendmicro ou gdata censées accroître la peur et la crédibilité du malware.
La section payment du site comporte 4 étapes pour mener à bien une transaction en Bitcoins.
- Step1 : Enter your personal identifier ;
- Step2 : Purchase Bitcoins ;
- Step3 : Do a Bitcoin transaction ;
- Step4 : Wait for confirmation.
Vient ensuite un onglet FAQ, censé expliquer ce que Petya vient de faire à votre système et en quoi il est dangereux et robuste, mais est en réalité rempli de fausses informations comme les algorithmes de chiffrement prétendument RSA 4096 et AES 256, ainsi que la publication de vos données sur le darknet si le paiement n’est pas effectué. Évidemment, cette propagande est entièrement fausse et n’a que pour but de mettre la pression et inciter à céder au chantage.
La dernière section du site n’est de loin pas la moins intéressante : le support ! Ce dernier faisant partie intégral du business model des ransomwares. En effet, sans celui-ci les utilisateurs n'arriveraient pas à contacter l’attaquant en cas de soucis. En sachant que les victimes obtiennent une clé fonctionnelle après leur paiement, de nouveaux utilisateurs leur emboîteront le pas. Mais dans le cas contraire, les futurs acheteurs ne paieront pas sachant que l'opération pourrait ne pas fonctionner. C’est pour cela que le support est primordial dans ce type d’opération.
J’ai donc voulu tenter l’expérience en prétendant avoir payé la veille et n’ayant toujours pas reçu ma clé. Et voilà qu’un peu plus de 1h30 plus tard une réponse me parvient, en me démontrant preuve à l’appui que mon argent n’est pas arrivé sur l'adresse Bitcoin du pirate. Ce délai plus que raisonnable peut même être qualifié de court comparé à bon nombre de services clients.
Figure 8 : Demande de support relatif au paiement de la rançon.
Conclusion
Ce malware possède un design atypique, complexe, et sophistiqué. Le code démontre en outre l'expérience et l'habileté de son auteur. Cela amène aussi une certaine nouveauté sur le segment des ransomwares, avec un déploiement en plusieurs étapes d'abord dans l'espace utilisateur, puis dans le MBR tel un bootkit. À noter que l'utilisation du secure boot ou la désactivation du redémarrage automatique en cas de défaillance du système peut permettre de se prévenir du chiffrement du disque.
L'architecture de bas niveau impose quelques limitations, notamment la taille réduite à disposition et l'impossibilité d'utiliser des API, ce qui complique entre autres l'utilisation de la cryptographie. C'est une des raisons pour lesquelles la génération de clés se fait lors de la première étape du malware dans l'espace utilisateur. Cela est néanmoins très intéressant et inhabituel à étudier, comme notamment l'emploi d'interrupts comme interface avec le système, les librairies étant indisponibles.
Malgré tout ce professionnalisme et le design élaboré du malware, Petya tend à avoir manqué sa cible. Ce genre de bootkit pouvant être insérés discrètement au plus profond du système relève plus des APT (Advanced Persistent Threat) que des ransomwares. En effet, ces derniers en userland font potentiellement plus de dégâts, en pouvant aussi chiffrer des périphériques externes ou réseaux par exemple. Ils requièrent en outre des droits élevés pour pouvoir s'injecter dans le secteur de démarrage, en comparaison des ransomwares standards.
Notons encore l'arrivée de Mischa, une version mise à jour corrigeant quelques lacunes de Petya, notamment en terme de cryptographie, et propose une solution alternative de chiffrement des données utilisateur en userland en cas d'exécution par un utilisateur disposant de droits limités.
Finalement, relevons encore les clins d’œil à l'univers de James Bond, plus particulièrement à l'opus GoldenEye, avec entre autres Petya, Janus en bas de page sur le site de paiement, ou encore le XOR '7', du MBR.