Petya or Not Petya

Depuis le 27 mai, le grand public a un bel exemple pour mesurer notre dépendance aux sytèmes d’information et comprendre la relative fragilité de ces derniers.

Mais essayons d’y voir un peu plus clair dans cette affaire. Nous ne ferons pas ici d’analyses techniques mais reprendrons ce qui a été déjà largement traité par des personnes qui maitrisent leurs sujets.

En effet un logiciel malveillant que nous nommerons ici NotPetya a ravagé plusieurs entreprises dans un grand nombre de pays. Et afin d’éviter toute confusion sur les faits avérés et les suppositions nous allons découpé notre article en 2 parties, la première reprendra ce qui a pu être démontré et la seconde laisse plus de place à l’interprétation et aux suppositions.

Les Faits :

Mardi après midi, la température est montée d’un cran en Ukraine tout d’abord, avec plusieurs entreprises qui se sont faites défoncées (le terme nous parait assez approprié) par un logiciel malveillant s’apparantant à un rançongiciel de type Petya.

Pour les profanes, Petya est un rançongiciel : Vous savez un petit logiciel qui va chiffrer les informations sur votre disque dur et demander le paiement d’une certaine somme d’argent pour que vous puissez retrouver vos si précieuses données. Mais bon pour vous, pas de menace, car vous faites des sauvegardes régulièrement, n’est-ce pas ?

La famille Petya a cependant une particularité par rapport aux autres rançongiciels (Locky et consort). En effet a contrario d’un locky par exemple qui chiffre certains fichiers mais vous permet encore d’utiliser votre PC (naviguer le net pour aller payer la rançon), Petya chiffre vos données et en plus replace le MBR de votre disque. Précisons et ce sera important pour la suite que le MBR ou Master Boot Record est ce qui permet à votre ordinateur au démarrage de savoir où trouver votre système d’exploitation sur le disque dur. En clair, Petya bloque complétement l’utilisation de votre machine. Mais gardons en tête que les auteurs sont des businessmen qui veulent avoir bonne réputation afin d’inciter les victimes à payer : Toutes ces opérations sont parfaitement réversibles et la machine revient en état de fonctionnement dès lors que la rançon est payée… Enfin ça c’est si tout se passe bien. La revue MISC a consacré un article sur cette famille de rançongiciel.

Petya n’a rien d’un nouveau dans le petit monde des rançongiciels puisque depuis début 2015, ces auteurs lancent régulièrement des campagnes d’hameçonnage et rafinent régulièrement leur logiciel.

Le virus NotPetya qui s’est repandu cette semaine reprend effectivement la même logique pour le chiffrement :

– On écrase le MBR
– On chiffre les fichiers utilisateurs
– On planifie un reboot pour l’heure suivante

L’ANSSI détaille précisement la succession de logiciel malveillant dans son bulletin.

Et c’est ce qui lui a valu d’être confondu avec Petya. Mais il y a quelques différences.

Le chiffrement :

Tout d’abord, l’écrasement du MBR qui permet d’avoir la belle image ci-dessous contient des erreurs empéchant la récupération du disque.

petya-ransomware-attack-1
La fonction de génération de l’ID unique, permettant à l’utilisateur de s’authentifier auprès de pirate est également bancale.

Egalement, le logiciel peut chiffrer plusieurs fois les données utilisateurs. Au fur et à mesure des analyses, la liste des erreurs se rallongent.
Bref, au niveau de la qualité, les auteurs de cette campagne ont un peu baclé de le travail.

Le vecteur de propagation :

Habituellement (i.e dans l’énorme majorité des cas), ces attaques ne sont pas ciblés et se font à travers des campagnes de phishing avec des mots clés classiques dans l’objet des messages (INVOICE, PAIEMENT, ORDER, …). Ces messages prétextant donc un sujet d’ordre financier à ouvrir un pièce jointe qui ira elle même télécharger le rançongiciel sur le net et l’executera. Les types de pièce jointe varient d’une campagne à l’autre : fichier pdf contenant du JS, Document Word ou Excel avec des macros, zip de JS, RTF avec CVE-2017-0199. Si ce dernier vous ne le comprenez pas c’est pas grave, l’idée étant que tout ce fait via pièce jointe qui est un format assez générique pour l’ouvrir sur des PCs quelconques afin de toucher un maximum de victime (Les pirates sont là pour faire du chiffre).

Dans le cas de cette campagne, il n’y a pour l’instant (n’en déplaisent à certains) que 2 vecteurs de propagations avérés : Le premier vecteur de contamination à utiliser le processus de mise à jour d’un logiciel de compatibilité fiscale ukrainien MeDOC et le second est un point d’eau sur le site d’une banque ukrainienne également un seul et unique vecteur de contamination, le processus de mise à jour d’un logiciel ukrainien de comptabilité fiscale. Autrement dit, les pirates n’ont pas choisi la technique la plus simple pour distribuer leur petit gadget… Et cela semble tout de même très centré sur l’Ukraine. Mais comme dirait Bigard « …Admettons !! »

Et pour que cela soit bien clair : il n’y a à ce jour aucun cas avéré de campagne de phishing utilisant la faille CVE-2017-0199 qui soit lié à NotPetya (Ceci si vous avez des preuves, on est preneur).

« Please Insert Coin »

Le mode de paiement de la rançon est aussi un peu surprenant, une grande partie des acteurs du milieu préfére l’utilisation de portails sur le darknet pour échanger avec les victimes : preuve de paiement de la rançon contre procédure de déchiffrement. Ici, le choix s’est porté sur une adresse mail publique . Méthode plus fragile car celle-ci a rapidement été désactivée pour le fournisseur : rendant impossible le contact avec les auteurs de l’attaque.

Les mouvements latéraux :

Dans la tradition des rançongiciels, ils ne sont pas très complexes en terme de fonctionnalité qui se résument en générale aux actions suivantes : Ils sont lancés par l’utilisateur, ils communiquent avec leur tour de contrôles, ils chiffrent, ils affichent leur message et puis voilà c’est fini. Au pire, afin d’obtenir un mouvement latéral pas trop technique, les pirates proposent aux personnes infectés d’infecter leurs amis pour obtenir la clé de déchiffrement gratuitement…

Dans ce cas-ci, il y a une spécifité qui rappelle WannaCry. En effet tous les deux sont équipés d’un fonctionnalité dites de « Vers » : ils vont chercher à contaminer tous ce qu’ils peuvent dans leurs alentours. Mais a contrario de WannaCry qui scannait à tout azimut à l’aide d’une vulnérabilité Microsoft MS17-010 de son petit nom « Eternal Blue », NotPetya utilise EternalBlue, Eternal Romance, PSExec, MimiKatz-like pour se propager sur le réseau interne de la machine.

Détaillons un peu : la véritable force de NotPetya (oui à un moment faut bien que le truc fasse quelque chose correctement pour qu’on parle de lui :)) est sa faculté à se répliquer.

  • EternalBlue et EternalRomance sont des bouts de codes exploitant des vulnérabilités du service de partage réseau de Windows
  • MimiKatz est un logiciel qui permet de scanner la mémoire vive d’une machine et d’y extraire des informations tels que les mots de passe ou jetons d’authentification
  • PSExec et WMI sont des outils légitimes de microsoft pour executer des commandes à distance sur une machine

Les deux derniers et MimiKatz s’utilisent ensemble : le mimikatz-like recherche en mémoire des identifiants de comptes ayants des droits administrateurs sur plusieurs machines et ensuite utilisent ces identifiants avec psexec pour contaminer les machines voisines.

Officiellement, il est aujourd’hui impossible de dire qu’est ce qui a permis de faire le plus dégat entre les exploits EternalBlue/EternalRomance et le combo Mimikatz/PsExec…

Donc bref, mettez tous cela ensemble, secouer bien et balancer cela une vieille de jour férié en Ukraine… Et voilà c’est la catastrophe pour un grand nombre d’entreprises de ce pays.

Oui mais cela n’a pas touché que l’Ukraine, cela s’est aussi répendu dans plusieurs pays provoquant une belle pagaille sur le globe.

Une question reste en suspend : Comment cela est-il sorti du pays ? Officiellement le mystère reste entier, peu d’entreprise ont abordé le sujet (il faudra surement attendre le SSTIC 2020 pour avoir les Retex de Saint Gobain). Mais le logiciel malveillant ne se propageant que sur les réseaux internes et si aucun autre vecteur n’a été utilisé, une pièce serait à mettre sur les réseaux privés virtuels (aka VPN). Mais nous tombons dans la supposition, il est temps de passer à notre seconde partie…

Supputations et Interprétations subjectives

Soyons clairs et transparents, tous ce qui est écrit ci-dessous est probablement invérifiable, mais pas impossible.

Rançongiciel ou logiciel destructeur ?

Les nombreuses erreurs dans la modification du MBR et la faiblesse du système retenu pour offrir le déchiffrement contre le paiement de la rançon laissent penser que ce n’était pas pour l’attaquant la motivation première. Cette dernière serait de bloquer les système distant en détruisant les partitions des machines et rendant la récupération des données complexes.

Cependant pourquoi se donner tant de mal en incluant un code de rançongiciel incomplet dans la charge, si au final elle ne sert pas. Par exemple, les attaques de Shamoon ont fait pas mal de dégat en Arabie Saoudite et cela était plutot efficace en termes d’impact sur les infrastructures industrielles du pays.

Une théorie viable est de dire que NotPetya devait être les deux à la fois, mais que pris de cours par la pandémie WannaCry qui avait largement exploitée la faille MS17-010 (beaucoup de systèmes ont été patchés depuis) et probablement d’autres événements non publics, les auteurs ont choisis de balancer leur vermine un peu précipitament, sans prendre le temps/ le soin de finaliser la partie rançongiciel.

Alors pourquoi le coupler avec un rançongiciel ?

Très certainement pour assurer une certaine « Plausible deniability » en se faisant à moitié passer pour une organisation criminelle.

Qui a fait ça ? Mafia ou Etat ?

Comme expliqué plus haut, les organisations criminels n’auraient probablement pas autant baclé le travail sur leur gagne-pains et n’ont que peu d’intérêt à cibler sur des populations ou pays particuliers. De plus, la cible principal semble être des organismes ou entreprises qui pour la plus part doivent avoir des sauvegardes et/ou des plans de continuité (enfin on l’espère), autrement dit pour qui payer la rançon n’est pas une nécessité pour récuper leurs données). A l’opposé, un état a plus d’intérêt à paralyser un état rival afin de l’affaiblir et lui faire comprendre que bon maintenant va falloir être gentil. L’effort dans le code a avant tout été porté sur la viralité du logiciel et non sa fonction final.

Du coup, le regard se tourne assez rapidement vers une attaque d’origine étatique.

Du coup, quel pays ?

On peut penser aux blagueurs de la république démocratique et populaire de Corée. Ces derniers sont probablement les auteurs de la campagne WannaCry. Mais le gap technique entre ces 2 campagnes est important, là où WannaCry tirait tout azimut ( à l’image de la Corée du Nord qui n’a pas beaucoup d’amis dans la communauté internationale), NotPetya semble bien viser les camarades ukrainiens et si on regarde un peu la carte du monde et le contexte géopolitique. On trouve assez rapidement un coupable potentiel. En effet, depuis quelques temps, les Russes ne raffolent pas des Ukrainiens (et inversement) et Petya est un rançongiciel d’origine Russe.

Et mettons cela dans une fresque chronologique :

Décembre 2015 : Première attaque majeure sur le réseau électrique de la capitale ukrainienne.
Décembre 2016 : Nouvelle Attaque sur le réseau électrique de Kiev (capital de l’Ukraine)
Janvier 2016 : The Shadow Broker met aux enchères « Eternal Blue » et « Eternal Romance » issue d’un probable pirate de ressources de la NSA
Février 2017 : Panique chez Microsoft (pas de Patch Tuesday : c’est du jamais vu) qui s’active pour corriger ces failles (probalement averti par la NSA des risques)
Février 2017 : Le développement du module de propagation de NotPetya est en cours probablement avec des infos de premier main venant de « Shadow Broker »
Avril 2017 : « The Shadow Broker » publie son arsenal
Mai 2017 : WannaCry utilise massivement « Eternal Blue » et déclenche une prise de conscience du monde sur les risques de SMB : il faut patché et vite. L’équipe de NotPetya est prise de cours et termine rapidement les développements de son programme.
30 Mai 2017 : Le renseignement ukrainien a perquisitionné l’hébergeur WNet sous l’hypothèse que c’était une antenne du FSB (espionnage russe) : WNet est l’hébergeur du serveur de mise à jour de MeDOC.
23 Juin 2017 : Il est rendu public qu’Obama a autorisé les agences américaines à s’attaquer aux infrastructures russes à la fin de son manda
27 Juin 08h15 : le Colonel Maksim Shapoval du renseigment militaire ukrainien est tué dans sa voiture piégée : il enquétait sur les implications russes dans l’Est du Pays
27 Juin 10H30 : NotPetya frappe de plein fouet l’Ukraine avec comme vecteur zéro la mise un jour d’un logiciel de comptabilité ukrainien très largement utilisé
28 Juin : Jour férié en Ukraine, compliqué de faire rester des gens au boulot.

Bref, cette chronologie n’est pas forcément cohérente mais il y a quand même une idée qui se dégage, ne croyez vous pas ?

Certes les Russes ont aussi été touchés, nous direz vous. Et c’est vrai, mais on peut assez solidement pencher pour des dommages collatéraux.

La morale de cette histoire :

Nous n’allons pas vous refaire la liste des bonnes pratiques sur les droits, les mises à jours de votre parc.

Néanmoins, cette fois c’est le processus de mis à jour de logiciel MeDOC qui pour nous est très exotique. Mais sans parler des applications spécifiques et métiers, avez vous déjà vérifié la légitimité des patchs reçus sur votre serveur WSUS ?

L’attribution dans le monde numérique est déjà une chose relativement compliquée et il semble que des réponses à ces actions de cyberterrorisme soient encore plus compliquées, n’en déplaisent à nos amis européens.

Egalement, dans des cas de crises de ce type, il est appréciable et apprécié de se limiter au fait en ne confondant pas vitesse et précipitation. Notamment sur les vecteurs de contamination dans les premières 24h certains experts ou CSIRTs (parfois nationaux) se sont un peu emballés sur telles ou telles capacités de logiciels et/ou des attaquants. Certains voient ces attaques comme du pain bénit pour vendre plus de sécu, certes, mais soyons raisonables et ne racontons pas n’importe quoi non plus.

Et revient encore la question, y-a-t-il des experts cyber en France ? On pose la question parce qu’on a vu la vidéo du figaro… Du coup on se demande si c’était vraiment nécessaire de demander à des Russes ce genre d’infos alors que des boites de Sécu française et même l’ANSSI (si si ils parlent à la presse) pourraient faire de même et cela vous ferait économiser des frais de traduction…

Dans la catégorie troll, pour ceux qui en société pensent que c’est de bon ton de balancer : « Oh vous avez vu, c’est encore une vulnérabilité de la NSA, c’est pas bien, c’est la faute de la NSA, c’est à eux de payer ! » Du coup avec ce genre de logique débile, doit-on aussi s’insurger contre les travaux de @gentilKiwi ? Dites le vite au parquet (non pas celui-là, le judiciaire) car une enquête est en cours… Curieux de voir sur quoi cela aboutira.

Allez pour la fin, une petite touche de légereté :
Pour ceux qui ont besoin de se convaincre que le groupe « The Shadow Broker » est bien d’origine russe, nous vous invitons à lire un de leurs textes avec l’accent russe… Vous allez voir c’est radical !

Publicités
Publié dans Analyse, Malware, Sensibilisation | Tagué , , , | Laisser un commentaire

Base de clé

Nous avons trouvé (enfin reçu dans notre boite) une menace qui nous change des désormais fades rançongiciels : Dans ce cas, l’habituelle macro dropper n’existe pas : le fichier Microsoft Word est le dropper.

Ceci se veut être le résumé de notre présentation lors du premier rendez-vous SecParis mi décembre.

Sans plus tarder, regardons tout cela de façon progressive :

Et commençons par le message en lui même : Toujours basé sur un prétexte fallacieux, nous sommes invités à ouvrir une pièce jointe au nom évocateur.

mail

La pièce jointe est un fichier Word banale sans métadata intéressante, la taille fait un peu sourciller.  Dans le contexte actuel, le contenu du fichier ne choque pas plus que cela : Une image indiquant qu’il est nécessaire d’activer les macros pour accéder au « vrai » contenu :

doc

On remarque cependant que le fichier est anormalement long : Plus de neuf cents pages (qui par ailleurs semblent blanches) et la langue par défaut est le polonais.

Pour notre plus grand bonheur (ou pas), l’accès aux macros n’est pas protégé par mot de passe : nous n’aurons pas besoin cette fois d’avoir recours à OleDump et OleTools. Un simple Alt-F8 nous conduit à pouvoir accéder au code. Là, nous constatons de l’obfuscation avec des noms de variables barbares et un lot de fonctions inutiles.  Nous faisons un rapide tri et nous nous rendons rapidement compte que les 900 pages blanches ne sont pas si vides qu’elles laissent à penser : simplement le texte est en blanc sur fond blanc. Le rôle de la fonction principale est d’extraire de ce texte en le « xorant », un premier binaire et de l’exécuter dans l’environnement utilisateur.

macro

La charge extraite est alors renommer en ID.exe. Une fois ce premier binaire extrait, il est bien évidemment exécuté. Cacher le binaire dans le corps du fichier texte n’est pas nouveau, nous avions déjà rencontré ce mode de dissimulation en début d’année lors d’une campagne « Petya ».

Essayons maintenant de voir ce qu’on peut y trouver en analyse statique. Nous commençons par les habituels file, strings et hexdump -C.

idfile
Le strings ne donne rien d’intéressant. A contrario lors du parcours rapide du fichier avec le hexdump, nous remarquons ce qui semblent être des caractères encodés sur 16 bits : « strings -e l » vous connaissez ? Cela peut être utile parfois…

iddump

Directement dans le code hexadécimal, nous remarquons un marqueur MSCF, ce qui ressemble fort au numéro magique des fichiers cabinets de Microsoft : Et si nos attaquants avaient utilisés ce format pour dissimuler leur charge ?

Nous pouvons essayer d’extraire ce cabinet file à l’aide de la technique du « File Carving » (technique qui consiste à rechercher des structures de formats connus pour extraire/reconstruire des fichiers à partir de données brutes (une copie de disque dur par exemple) : c’est typiquement ce qui est utilisé pour récupérer les fichiers effacés d’un disque). Nous utilisons l’outil foremost disponible sur la majorité des grandes distributions Linux.

Cependant, petit problème : par défaut foremost ne recherche pas les fichiers CAB, mais bon comme on vient de l’écrire, c’est un « petit » problème : on édite rapidement le fichier /etc/foremost pour y rajouter la ligne suivante et le tour est joué.

foremost_conf

Voici alors le résultat de notre recherche :

foremost

Nous avons bien récupéré un fichier png et cab. Reste à vérifier que ce dernier est bien un fichier Microsoft Cabinet valide :

cabextract

Cela semble tout à fait correct : Nous pouvons donc poursuivre notre analyse avec ce fichier fraichement extrait. Pour ce nouveau binaire nous adoptons la même stratégie : file, strings et hexdump.

mefile
Nous avons bien un fichier PE32 valide. Mais le plus intéressant vient du résultat de la commande strings. En effet le fichier contient une chaîne très longue (plus d’un million de caractères) et qui ressemble fortement à du base64. En particulier, on note en fin de la chaîne la présence de bourrage XPADDINGX. Après un rapide petit nettoyage, on décode la chaîne et on récupère non pas un mais deux fichiers.

Le premier est un fichier binaire et en consultant les propriétés du fichier, nous apprenons que  c’est un interpréteur du langage de script autoIT (Lien vers autoIT) et il semble tout à fait légitime : Les recherches de son condensat sur VirusTotal n’indiquent rien de malveillant. Nous avons donc affaire à l’interpréteur officiel du langage AutoIT.

clll
Le second est un fichier texte et n’est autre que le script qui sera exécuté grâce à cette interpréteur.

script

Vous noterez au passage la concordance des temps (de modification) entre ces deux fichiers.

Le binaire étant légitime, concentrons-nous sur le script !

En aparté, sachez qu’AutoIT est très puissant et visiblement les auteurs de logiciel malveillant l’apprecient comme en témoigne ce lien.

Ce script est particulièrement intéressant et c’est d’ailleurs sur ce dernier que nous avons passé la plus longue partie de notre analyse, d’abord parce qu’il utilise un langage qui nous était certes inconnu, mais ça reste du langage scripté donc pas de décompilation. Ensuite il fait des choses assez originales : Comprendre que c’est la première fois que dans notre très jeune expérience d’analyse de virus, nous rencontrons un truc autant tiré par les cheveux.

L’avantage d’un script est qu’on peut le lire sans décompilation. Mais cela se révèle sensiblement plus compliqué que prévu : Les attaquants redoublent d’effort pour rendre le code le moins intelligible possible et ralentir l’analyse.

Tout d’abord nous constatons quelques petites mesures de détection d’antivirus et de sandboxing

testav_vm

Notons tout de même que les trois derniers tests ne sont jamais vrais : la $var1 est initialisée à 0.
Ensuite, le virus cherche à passer sous le radar des antivirus et autres possibilités de détection fortuite en créant un sous-répertoire dans le répertoire utilisateur et en s’y copiant lui-même ainsi que cLLL.exe (l’interpréteur).

hide_files

L’option « +SH » donne les attributs System et Hidden au répertoire et ses fichiers : permettant de rendre ce sous-répertoire quasi-invisible. Notons que dans ces conditions, ce répertoire n’est par exemple plus scanné par défaut par Avast. Les éditeurs d’antivirus n’aiment pas trop scanner les fichiers systèmes : cela garantit un certain niveau de persistance sur le poste.

Ensuite, le code est truffé de tests conditionnels sur des variables statiques : cela rend la lecture difficile mais des CTRL-F et autre chercher/remplacer nous permettent rapidement de faire le ménage dans le code.

Nous tombons sur des morceaux de code comme celui-ci que nous pourrions qualifier de « Third layer of Inception » :

inception

On vous laisse apprécier : Avez vous noté le « TVq » en base64 ?

Bref au final, nous découvrons que le script contient encore un binaire caché dans les commentaires : le 3eme depuis le début, ça commence à devenir une habitude.

Ce binaire que nous appellerons pudiquement charge.exe est un executable PE32 valide, mais il n’est jamais exécuté directement par le script. Et c’est là que ça devient un peu ésotérique pour nous. En effet, au lieu d’extraire charge.exe et de l’exécuter directement, le script préfère se lancer dans une entreprise beaucoup plus complexe :

Notons l’utilisation de code compilé directement dans le script :

"0xC81000005356578365F800E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFF00FFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132338F45F08B7D0C8B5D0831D2E9910000008365FC00837DFC047D548A034384C0750383EA033C3D75094A803B3D75014AB00084C0751A837DFC047D0D8B75FCC64435F400FF45FCEBED6A018F45F8EB1F3C2B72193C7A77150FB6F083EE2B0375F08A068B75FC884435F4FF45FCEBA68D75F4668B06C0E002C0EC0408E08807668B4601C0E004C0EC0208E08847018A4602C0E00624C00A46038847028D7F038D5203837DF8000F8465FFFFFF89D05F5E5BC9C21000"

Une fois la chaîne décompilée en assembleur, cela ressemble à un « base64 -d »  qui permettra de décoder le commentaire/charge en mémoire.

Parser le contenu du binaire pour en extraire les différentes fonctions et les charger via des appels à des DLL  (entre autre kernel32.dll, user32.dll, avdapi32.dll) et  ainsi les injecter dans un process qui semble légitime : RegSvcs.exe est ici visé en priorité.

Ainsi, alors que les premières variables ont des noms très aléatoires, ici on observe une certaine « rigueur » dans le nommage des variables

dllstruct

Ces noms de variables ne sont pas sans rappeler les sections d’un fichier exécutable.

Résultat des courses : ce code est injecté en mémoire et se lance alors dans l’espionnage de l’activité sur le poste.

Lorsque nous nous penchons plus attentivement sur cette charge, nous nous apercevons qu’elle n’est pas packé et est semble-t-il codé en « Microsoft Visual C# / Basic .Net » si on en croit PEiD. Le résultat de la commande file nous met aussi sur la piste d’un fichier .NET.

charge

Aussi pour une fois, le code binaire ne sonne pas le glas de notre analyse. Nous pouvons utiliser l’outil de RedGate Reflector pour décompiler. Nous découvrons alors le coeur du logiciel malveillant.

Il y a quelques fonctions au nom plus qu’évocateur:

functionnames

On retrouve aussi des informations intéressantes :

Il communique avec un CC via des requêtes HTTP : les communications ne sont pas chiffrées, le canal de communication passe sur de l’http simple (sans surcouche SSL/TLS) et les requêtes HTTP sont globalement explicites.

L’objectif de ce malware semble surtout de voler des identifiants de messageries et de comptes internet ; il se concentre en effet sur les navigateurs et les clients lourds de messagerie.

Nous remarquons enfin qu’il contient encore trois blops binaires. A la lecture du code, on se rend compte que ces données sont chiffrées en AES mais avec une fonction assez simple.

Outre son nom étrange « RSMDecrypt », elle utilise la fonction de dérivation Rfc2898DeriveBytes avec une itération au lieu des mille recommandées.

public static byte[] RSMDecrypt(byte[] ƈƖƻƨÔ, byte[] ƄƏƵÉ)
{
    Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(ƄƏƵÉ, new byte[8], 1);
    RijndaelManaged managed = new RijndaelManaged {
        Key = bytes.GetBytes(0x10),
        IV = bytes.GetBytes(0x10)
    };
    byte[] src = managed.CreateDecryptor().TransformFinalBlock(ƈƖƻƨÔ, 0, ƈƖƻƨÔ.Length);
    byte[] dst = new byte[(src.Length - 0x11) + 1];
    Buffer.BlockCopy(src, 0x10, dst, 0, src.Length - 0x10);
    return dst;
}

Bref, une fois déchiffrés, les blops se révelent être des nouveaux binaires ; Ils confirment notre première analyse de code. Ainsi le premier n’est autre que « WebBrowserPassView » et le second se revèle être « Email Password-Recovery ».

webrecover

Enfin le dernier blop binaire n’est semble-t-il jamais utilisé dans le code et ressemble à ce qui pourrait être du chinois… Un début d’attribution ?

Et voici un petit schéma qui récapitule tout cela à regarder en écoutant Fred Kal (qui a inspiré le nom d’une des charges.)

resume

Mais prenons un peu de recul par rapport à ce démontage et concentrons nous sur ce que nous avons pu apprendre des attaquants :

Tout d’abords les technologies utilisées : on remarque pour quasiment toutes les étapes une forte adhérence à l’écosystème Microsoft : Macro, Cabinet Files, Script AutoIT et binaire .Net.

Ensuite, il n’y a pas de métadonnées intéressantes dans les différents niveaux excepté dans la charge finale où nous trouvons des métadonnés probablement forgées par les attaquants mais qui donnent une idée de l’origine géographique.

Sur l’origine géographique des attaquants, on remarque la présence récurrente d’encode en UTF-16. De plus bien que la langue par défaut du binaire final ait été écrasée (langID=0), certains noms de variable ou fonction paraissent très abscons en alphabet latin.

Un troisième point aiguise notre curiosité : la fameuse fonction RSMDecrypt. Ce nom de fonction semble sortir de nulle part et ne fait pas référence a priori à un chiffrement particulier. Après avoir creusé le sujet sur internet, on se rend compte qu’il y a 3 types de ref à cette fonction :

  • Des dumps de la fonctions sur divers forums et blogs
  • PasteBin avec du code malveillant
  • Des sites d’analyse de code malveillant

Il est par contre intéressant de regarder la chronologie de ces diverses apparitions : la première d’entre elle date de 2012 sur un forum francophone.

Nous sommes dans un cul de sac : on appelle alors un ami qui nous parle d’une protection contre les attaques par canaux cachés : Rotating S-box Masking. Bref, il semble bien que les attaquants s’inspirent de truc qu’ils ne comprennent pas forcément.

Enfin, une autre fonction de chiffrement (cette fois-ci un simple XOR) est présente dans le code. Mais c’est la clé qui pour ainsi dire nous donnera la clé pour avancer.

xor.png

Ainsi déchiffrés nous obtenons :

  • CreateProcessA             ‘ĈőŘĝŏŒįķŎŖġŎŠĠz’
  • GetThreadContext         ‘ŝƕƸšƔưƕŷƔƇżƚƲƕƎƤË’
  • GetThreadContext        ‘ķůƒĻŮƊůőŮšŖŴƌůŨž¥’
  • SetThreadContext         ‘ńŰƓļůƋŰŒůŢŗŵƍŰũſ¦’
  • Wow64SetThreadContext     ‘ŨƚƶľśƌƐƅſƧźƌƚƏŔƚƭżƌƱƟÆ’
  • ReadProcessMemory         ‘ĴšűĽňżūŅšƃŌŅůũőŮƉ\x97’
  • WriteProcessMemory         ‘ŇżƇśūŨżşŭƃŚŹťůŝŹƐŠ¥’
  • NtUnmapViewOfSection     ‘ıűŦňŦŬŭĹŦŶőňűŐňŠƅŃŨŹ\x98’
  • VirtualAllocEx             ‘ńűƎřŹŷŴįŴƈŔŧśƀ£’
  • ResumeThread             ‘ŵƢDŽƏƦưƑƋƯƶŻƝØ’

La clé de chiffrement est « KeyBase » et cela nous fait vite faire le lien avec cette mire d’authentification trouvée sur le site compromis :

mire.png

A partir de là, nous obtenons beaucoup d’information sur notre logiciel malveillant. Notamment Palo Alto a fait une analyse très intéressante sur le sujet

Publié dans Analyse, Malware, Sensibilisation | Tagué , , , | Laisser un commentaire

Certains ne devraient pas dire ça

Annonce préalable : Il y a un peu de mauvaise foi dans ce qui suit !

Ca y est : nous sommes le deuxième mardi du mois et autrement dit le jour où Microsoft sort ses correctifs mensuels. Un de ces correctifs a une saveur particulière. Techniquement, l’affaire n’a rien d’exceptionnel. Mais c’est plutôt sur la forme.

En effet la semaine passée, les équipes sécurité de Google ont publié des informations techniques et très précises sur cette vulnérabilité. Normalement, Google donne une période de 90 jours à l’éditeur pour corriger la vulnérabilité avant de la rendre publique. Cependant ici ce ne fut pas le cas : sous prétexte que la faille est « activement exploitée », ils ont décidé unilatéralement de rendre publique la vulnérabilité avant que l’éditeur ne soit en mesure de sortir un correctif 7 jours après la notification.

Sans vouloir tomber dans le manichéisme primaire, il y a de quoi trouver la démarche cavalière :

  • L’équipe sécurité de Google semble en vouloir à Microsoft : c’est au moins la troisième fois que Google publie un avis avant la sortie d’un patch : On notera qu’il semble y avoir deux vitesses en fonction d’où se trouve la vulnérabilité : Pas plus tard que le mois dernier, ils ont étendu la période des 90 jours pour une vulnérabilité Apple.
  • Dans un article de blog ironiquement appelé « disclosing vulnerabilities to protect users », rendre publique une faille aussi critique n’est pas si bénéfique. Cela est à nos yeux d’autant plus contre-productif que les pirates sont d’excellents techniciens et s’approprient très vite ces nouvelles attaques alors que la majorité des défenseurs sont à la traine. A titre d’illustration, prenons par exemple un des domaines utilisés pour l’envoi massif de spam implémente SPF et DKIM, quand la majorité des serveurs légitimes ne proposent pas encore de StartTLS : Voyez-vous le problème ?

On ne veut pas jouer les vierges effarouchées : mais à un moment donné, il faut prendre du recul et avoir une vision globale du problème. Tout le monde n’est pas un expert en détection d’intrusion ni même un utilisateur averti : Google le premier devrait être au courant : c’est bien eux qui ont rencontrés des utilisateurs qui confondaient le symbole du cadena des pages en HTTPs avec un sac à main.

En effet jusqu’il y a encore quelques années, il était encore permis de prendre les attaques informatiques avec une certaine philosophie : « Y a pas mort d’hommes » avons-nous entendu maintes et maintes fois lorsqu’un utilisateur cliquait sur une pièce jointe ou un lien malveillant.

Aujourd’hui nous ne pouvons plus l’ignorer : l’informatique gère de plus en plus de systèmes critiques et un simple rançongiciel (ie: attaque non-ciblée) peut rapidement avoir des conséquences sur des vies humaines en témoigne l’incident dans cet hôpital britannique.

Quels bénéfices peuvent en tirer les majorités des équipes informatiques des révélations de Google ? Notez que nous n’osons même pas parler des équipes de sécurité, elles sont parfois  inexistantes ou mal dimensionnées : Prenons le cas de l’ANTS. Vous savez l’agence qui gère en autre l’édition des passeports français (un truc que d’aucun pourrait qualifier de sensible) et aussi le fameux fichier sur les soixante millions de compatriotes au sujet duquel tout le monde s’écharpe : l’équipe de sécurité se résume à un gars.  On veut bien parler de démarche de sécurité intégré mais bon y a un minimum ! Pour mémoire on a déjà vu ce que ça pouvait donner de n’avoir qu’un seul membre dans une équipe sécurité.

Avant d’aller plus loin, on attire l’attention sur l’absence totale de réactions des états souverains sur le sujet mise à part l’alerte du CERT-FR.  D’ailleurs à la lecture des recommandations laconiques (i.e: ne surfez plus en attendant la mise à jour), on sent bien que l’ANSSI est plus qu’impuissante sur le sujet.

A contrario, on se rappelle de la réplique administrative à la publication d’un post sur la sécurité du Wifi et plus récemment si un petit jeune en panne d’inspiration renomme son réseau Wifi : le mec passe au tribunal directement. Mais dans le cas de Google qui potentiellement balance une arme d’infiltration massive sur tous les postes utilisant Windows : Silence radio ! On rappelle que jusque très récemment la divulgation de vulnérabilités était passible de poursuite en France. M. Poupard, où est notre souveraineté face aux géants du net ?

Fin de l’aparté. Le problème principal est que la sécurité est encore et toujours perçue par beaucoup comme une source de contrainte mais aussi et surtout de coût. « Emprunter de l’argent coute aussi de l’argent » disent-ils dans le slogan. Nous avons un scoop pour vous les gars : Avec la sécurité  qu’elle soit incendie, routière, informatique : même combat ! Cela va couter du pognon : pour recruter, pour former, pour sensibiliser, pour implémenter, pour auditer, pour analyser, pour investiguer … Et oui cela va empiéter sur la si précieuse rentabilité de vos équipes et vos bénefs et cela risque de contrarier le comité de direction : L’argent reste encore le nerf de la guerre !

Mais n’oubliez pas : c’est aussi ce qui pourrait permettre de sauver votre boite. Et ce n’est pas qu’un fantasme des paranos de la sécurité :  60% des PME mettent la clé sous la porte après une attaque.

L’histoire de TV5 Monde est assez éloquente en la matière : Malheureusement tout le monde n’a pas la chance d’avoir l’ANSSI à son chevet et des subventions en perfusion !  De son coté,  le FBI le résume aussi assez bien dans sa campagne de sensibilisation.

Alors une grande partie des entreprises commencent à intégrer ces risques et comprennent qu’il est préférable d’anticiper que de subir et recrutent ardemment des RSSIs (il parait que cela a la côte). Parfois, cela fait suite à un incident parfois, cela est anticipé, voir dans certain cas imposé…  Mais malheureusement, on finit par tomber sur des articles comme celui-ci. Avec ce genre de discours, il ne faut s’étonner que les budgets soient en bernes.

Rappelons qu’il y a deux types de RSSI : ceux dont l’entreprise a été piratée et ceux qui savent que leur entreprise a été piratée.

Il y a fort à parier que les équipes des RSSIs interviewés dans cette étude sont confortés dans leur idée d’invincibilité par les cohortes de firewalls, HIPS et SIEM déployés sur leurs systèmes. Rappelez vous comment la DSI d’Areva était fière de ses systèmes et de sa certification ISO 27001.  On ne va pas revenir aux fondamentaux mais Bruce le dit très bien : “If you think technology can solve your security problems, then you don’t understand the problems and you don’t understand the technology.”

Et parions que ce sont probablement les même RSSI qui accusent l’ANSSI de piller le marché des compétences sécurités…

En effet, n’oublions pas qu’avant tout il faut des femmes et des hommes pour mettre en place de la sécurité et faire évoluer les mesures organisationnelles et techniques. Ces compétences ne s’inventent pas : l’ANSSI propose pléthores de postes et ce de façon continue. Nous invitons d’ailleurs tout le monde à aller faire un tour sur cette page afin de bien mesurer l’étendu et la diversité des métiers de la sécurité de l’information.

Donc arrêtons avec la politique de l’autruche, arrêtons avec les fiches de poste couteau suisse « Expert en Reverse, en Gestion Incident, en Analyse de Risque, en Aspect juridique et en Architecture », arrêtons avec les « j’ai une équipe de sécurité : bon c’est 1 gars mais je vous assure il est balaise ! » (cf l’incident TV5Monde et bientôt peut-être celui de l’ANTS ?). Parce que oui, dire qu’on fait aussi bien que le voisin revient à dire qu’on fait les choses aussi mal que lui.

« Wake up, Neo » comme dirait l’autre !

Allez une soupe et au lit : en espérant que cela aille mieux demain… ou pas !

Publié dans Sensibilisation | Tagué , | 4 commentaires

Anodin Odin

Depuis quelques jours, les serveurs de messageries sont sous le joux d’une campagne massive de messages malveillants.

Encore un nouveau rançongiciel ! Décidément, ils sont à la mode : cela fait plus d’un an qu’on se prend vague sur vague des Locky et consort. Le principe est quasiment toujours le même : un message avec une pièce jointe qui va téléchargé une charge qui chiffre les données sur votre poste et ses partages réseaux…

Cependant la dernière campagne est intéressante pour deux raisons :

Premièrement,  même si le vecteur de contamination reste le même : fichier office avec des macro. Le code de ces dernières n’est pas aussi obfusqué que d’habitude. Preuve que les pirates se lassent peut-être : en tous les cas, la puissance olevba ou oledump peut s’exprimer pleinement pour en extraire rapidement des informations pertinentes à l’analyse et la recherche d’IOC.

 | IOC        | http://juyinggroup.c | URL                                     |
 |            | om/g76ub76           |                                         |
 | IOC        | ll32.exe             | Executable file name                    |
 | IOC        | P.dll                | Executable file name                    |
 | IOC        | rundll32.exe         | Executable file name (obfuscation: VBA  |
 |            |                      | expression)

Le code VBA des macros laisse aussi paraitre que les auteurs seraient hispaniques. En effet, bon nombre de variables et noms de fonction sont directement pris de l’Espagnol. Voici quelques exemples :

For i = 1 To Len(permiso)
 letra = Mid(permiso, i, 1)
 If letra = "A" Then
  Alta = True
 End If

 If letra = "B" Then
  Baja = True
 End If

 If letra = "M" Then
  modi = True
 End If

 If letra = "C" Then
  Consu = True
 End If
Next i
If Len(permiso) = 0 Then
 Consu = False
 modi = False
 Alta = False
 Baja = False
End If

Info ou intox de la part des attaquants ?

La seconde nouveauté concerne l’exécution de la charge:
Notons que le code de la macro ne télécharge plus directement un exécutable mais un blop binaire qui est par la suite déchiffré (XOR avec une clé de 32 caractères). Ce stratagème permet à la charge de passer inaperçue même au travers d’un proxy HTTP. Une fois déchiffrée cette charge est toujours un fichier PE mais ce n’est pas un exécutable EXE mais une bibliothèque de liens dynamiques (ie : une DLL).

jshmendes@cb:~$ file charge.bin
 charge.bin: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows

Cette DLL est alors exécutée à l’aide de rundll32.exe avec la commande suivante :

Call Shell("rund" & "ll32.exe " & moyaMANUNAUUUKA & ",qwerty", vbHide)

Cet appel à travers rundll32.exe présente l’avantage de contourner les éventuelles restrictions AppLocker présentes sur le poste ciblé : Non seulement la charge s’exécute même s’il y a un filtrage sur les fichiers DLL, mais en plus les journaux d’événements ne voient rien, rendant l’investigation moins triviale.

Notons qu’il s’agit ici d’une limitation connue d’AppLocker (Et non ce n’est pas une vulnérabilité d’après Microsoft). Rajoutons que ce n’est pas la seule technique pour contourner une politique de restriction d’exécution sous Windows, mais que c’est probablement la plus efficace et la plus simple à mettre en oeuvre.

Cette limitation laisse donc les postes vulnérables à cette nouvelle campagne de rançongiciel qui prend le doux nom d’Odin (en référence à l’extension utilisée pour renommer les fichiers chiffrés). Après Locky, voici donc une autre divinité de la mythologie nordique qui met à mal la sécurité des données.

Publié dans Outils, Uncategorized | Tagué , , , , | Laisser un commentaire

Un challenge pour un boulot

Comme vous le savez sûrement l’édition 2016 du challenge SSTIC est sortie (et de ce que nous avons pu en voir la forme ressemble étrangement au Holidays Hack Challenge du gars de la SANS SEC560). Bref, les lapins en chocolat ne nous ont pas encore permis de nous lancer sur le sujet, mais cela ne serait tarder… Mais comme d’habitude la retro-ingéniérie est au programme.

N’ayant pas eu de préchauffe officielle cette année, nous en avons débusqué une. En effet, une grande organisation a récemment publié une fiche de poste avec un challenge à résoudre (le recrutement est terminé depuis le 6 avril).

On dispose de deux fichiers :
– o-hsucrpt-e : binaire qui chiffre des données
– crypt.bin : un message chiffré

Objectif : Retrouver le message en clair !
Donc un bon exercice pour monter un peu en compétence sur l’ingénierie inverse,

Nous présentons ici notre méthode de résolution :

Tout d’abord on commence sans trop réfléchir :

jshmendes@vima:~/omc$ hexdump -C crypt.bin
00000000  45 84 85 b8 a1 dc 4b e0  5b 2e 0f 55 07 a2 77 8e  |E.....K.[..U..w.|
00000010  4e b7 35                                          |N.5|
00000013
jshmendes@vima:~/omc$ cat crypt.bin | ./o-hsucrpt-e | hexdump -C
00000000  57 fc c0 90 e1 fd 50 06  77 d9 21 c1 a8 e0 46 43  |W.....P.w.!...FC|
00000010  69 0f d9                                          |i..|
00000013
jshmendes@vima:~/omc$ printf "EW" | ./o-hsucrpt-e | hexdump -C
00000000  57 2f                                             |W/|
00000002
jshmendes@vima:~/omc$ printf "W/" | ./o-hsucrpt-e | hexdump -C
00000000  45 c3                                             |E.|
00000002
jshmendes@vima:~/omc$ printf "EWW" | ./o-hsucrpt-e | hexdump -C
00000000  57 2f 2d                                          |W/-|
00000003
jshmendes@vima:~/omc$ printf "EWWW" | ./o-hsucrpt-e | hexdump -C
00000000  57 2f 2d 36                                       |W/-6|
00000004
jshmendes@vima:~/omc$ printf "EWWWW" | ./o-hsucrpt-e | hexdump -C
00000000  57 2f 2d 36 9a                                    |W/-6.|
00000005
jshmendes@vima:~/omc$ printf "W/-6" | ./o-hsucrpt-e | hexdump -C
00000000  45 c3 8f 6b                                       |E..k|
00000004
jshmendes@vima:~/omc$ printf "F" | ./o-hsucrpt-e | hexdump -C
00000000  54                                                |T|
00000001
jshmendes@vm:~/omc$ printf "T" | ./o-hsucrpt-e | hexdump -C
00000000  46                                                |F|
00000001
jshmendes@vima:~/omc$ printf "W" | ./o-hsucrpt-e | ./o-hsucrpt-e ; echo ""
W
jshmendes@vima:~/omc$ printf "M" | ./o-hsucrpt-e | ./o-hsucrpt-e ; echo ""
M

Ainsi peut-on supposer les choses suivantes :

  1. Le clair et le chiffré ont toujours la même longueur : ça ressemble à un chiffrement par flot
  2. Les caractères sont chiffrés les uns après les autres : ça ressemble encore plus à un chiffrement par flot
  3. Le premier caractère en clair est toujours le chiffré de son chiffré, ie E(E(M)) = M : cela laisse penser qu’une fonction XOR est utilisée

Nous avons déjà grâce à l’assertion 3, le premier caractère. Et la longueur du chiffré étant de 0x13 (19) octects, cela ne devrait pas être très long de déchiffrer ce message par force brute. Nous passons donc en mode cryptobourrin.

jshmendes@vima:~/omc$ printf "E" | ./o-hsucrpt-e ; echo ""
W

Notre message commence donc par W. On essaie donc « WTO » pour World Trade Organisation, nom anglais de l’OMC :

jshmendes@vima:~/omc$ printf "WTO" | ./o-hsucrpt-e | hexdump -C
00000000  45 b8 48                                          |E.H|
00000003

Pas de chance, ça ne colle pas. A tâtons, nous tentons plusieurs valeurs et finissons rapidement par trouver :

jshmendes@vima:~/omc$ printf "What a" | ./o-hsucrpt-e | hexdump -C
00000000  45 84 85 b8 a1 dc                                 |E.....|
00000006

Du coup, n’ayant pas que cela à faire, on va faire les petits bourrins :
(Que les puristes du serpent constrictor nous pardonnent, nous balbutions)

from subprocess import Popen, PIPE

def encrypt(message):
        p1 = Popen(["cat", message], stdout=PIPE)
        p2 = Popen(["./o-hsucrpt-e"], stdin=p1.stdout, stdout=PIPE)
        output = p2.communicate()[0]
        return output

fi = open("crypt.bin", "rb")

ok = 1
ind = 5
message = "What "
for line in fi:
        while True:
                for i in range(256):
                        ok = 1
                        message+= str(chr(i)) + '\n'
                        fo = open("foo.txt", "wb")
                        fo.write( message)
                        fo.close()
                        output = encrypt("foo.txt")
                        for j in range(len(str(output))-1):
                                if str(output)[j] != str(line)[j]:
                                        ok = 0
                                        break
                        if ok == 1:
                                ind+=1
                                message = message[:ind]
                                break
                        message = message[:ind]
                if (ind == len(str(line))):
                        print message
                        break

Et quasi instantanément, nous avons notre sésame :

jshmendes@vima:~/omc$ python craker.py
 What a lovely day!

Voilà c’est fait mais on reste un peu sur notre faim : comment fonctionne ce petit programme ?

Tout d’abord, essayons d’en savoir un peu plus :

jshmendes@vima:~/omc$ file o-hsucrpt-e
o-hsucrpt-e: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=d100acad15a7f26eb019e597d48a3e04c86fc950, not stripped
jshmendes@vima:~/omc$ ldd o-hsucrpt-e
        linux-vdso.so.1 =>  (0x00007ffe8759a000)
        libmcrypt.so.4 => /usr/lib/libmcrypt.so.4 (0x00007fcaf07ae000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcaf03e9000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fcaf09e2000)

On remarque que le binaire est pour une architecture 64 bits et est dynamiquement lié avec la bibliothèque mcrypt, il doit donc utiliser des fonctions de chiffrement standard (ou du moins implémentée dans cette bibliothèque). On y reviendra mais continuons :

Un coup de strings :

jshmendes@vima:~/omc$ strings  o-hsucrpt-e | grep -v _ | grep -v '\.'
strcpy
stdin
calloc
strlen
stdout
rand
malloc
fwrite
fread
memmove
code = lH
ib man pH
goto fail;
twofish
;*3$"
main

Ah on commence à voir des choses intéressantes ; enfin surtout une chaîne « twofish ». Cherchons maintenant un mode de chiffrement. Par défaut, strings ne cherche que les chaînes de 4 caractères et plus, or les modes les plus communs sont abréviés en 3 lettres (ECB, CBC, OFB, …). Utilisons donc l’option -n :

jshmendes@vima:~/omc$ strings  -n 3 o-hsucrpt-e | grep -C 2 twofish
ff.
goto fail;
twofish
cfb
;*3$"

Bingo ! La chaine cfb est présente et correspond à un mode de chiffrement le Cipher FeedBack. Ce qui ne nous étonne guère car le mode CFB a la particularité de pouvoir transformer un chiffrement par bloc en chiffrement par bloc de taille arbitraire inférieure à celle de l’algorithme utilisée. Ce n’est pas très claire plus d’info ici ou

Nous supposons fortement que le programme utilise twofish en mode CFB. Reste à savoir dans quelle fonction ces deux paramètres sont utilisés, et ainsi retrouver la clé et le vecteur d’initialisation. Un petit coup de ‘nm’ devrait nous mettre sur la voie :

jshmendes@vima:~/omc$ nm o-hsucrpt-e | grep mcrypt
                 U mcrypt_enc_get_iv_size //Donne la taille de l'IV pour le mode et l'algo choisis
                 U mcrypt_generic // Chiffre un blop de donné
                 U mcrypt_generic_end // Finalize le chiffrement
                 U mcrypt_generic_init // Créer un contexte de chiffrement (IV + Key)
                 U mcrypt_module_open // Définit une struct algo+mode
                 U mcrypt_perror

Plus d’information sur les fonctions peuvent être trouvées ici.

Maintenant que nous avons tous ces éléments, nous pouvons utiliser gdb

(gdb) break mcrypt_module_open
Breakpoint 1 at 0x4008d0
(gdb) run
Starting program: /home/owner/omc/o-hsucrpt-e

Breakpoint 1, 0x00007ffff7bad110 in mcrypt_module_open () from /usr/lib/libmcrypt.so.4
(gdb) info frame
Stack level 0, frame at 0x7fffffffe3b0:
 rip = 0x7ffff7bad110 in mcrypt_module_open; saved rip = 0x400bcb
 called by frame at 0x7fffffffe490
 Arglist at 0x7fffffffe3a0, args:
 Locals at 0x7fffffffe3a0, Previous frame's sp is 0x7fffffffe3b0
 Saved registers:
  rip at 0x7fffffffe3a8
(gdb) x /96xh 0x7fffffffe3a0
0x7fffffffe3a0: 0x0001  0x0000  0x0000  0x0000  0x0bcb  0x0040  0x0000  0x0000
0x7fffffffe3b0: 0x0001  0x0000  0x7fff  0x0000  0xe1c8  0xf7ff  0x7fff  0x0000
0x7fffffffe3c0: 0x0013  0x0000  0x0010  0x0000  0x3010  0x0060  0x0000  0x0000
0x7fffffffe3d0: 0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000
0x7fffffffe3e0: 0x6f67  0x6f74  0x6620  0x6961  0x3b6c  0xf700  0x7fff  0x0000
0x7fffffffe3f0: 0xe420  0xffff  0x7fff  0x0000  0xe410  0xffff  0x7fff  0x0000
0x7fffffffe400: 0x6f63  0x6564  0x3d20  0x6c20  0x6269  0x6d20  0x6e61  0x7020
0x7fffffffe410: 0x6761  0x0065  0x0000  0x0000  0xe578  0xffff  0x7fff  0x0000
0x7fffffffe420: 0x7774  0x666f  0x7369  0x0068  0x9990  0xf7ff  0x7fff  0x0000
0x7fffffffe430: 0xe1c8  0xf7ff  0x7fff  0x0000  0x0000  0x0000  0x0000  0x0000
0x7fffffffe440: 0x6663  0x0062  0x0000  0x0000  0x0d8d  0x0040  0x0000  0x0000
0x7fffffffe450: 0xe480  0xffff  0x7fff  0x0000  0x0000  0x0000  0x0000  0x0000

Nous retrouvons notre « twofish » et « cfb ». Rajoutons un breakpoint sur la seconde fonction intéressante :

(gdb) break mcrypt_generic_init
Breakpoint 2 at 0x7ffff7babc80
(gdb) c
Continuing.
Breakpoint 2, 0x00007ffff7babc80 in mcrypt_generic_init () from /usr/lib/libmcrypt.so.4
(gdb) info frame
Stack level 0, frame at 0x7fffffffe3b0:
 rip = 0x7ffff7babc80 in mcrypt_generic_init; saved rip = 0x400c6e
 called by frame at 0x7fffffffe490
 Arglist at 0x7fffffffe3a0, args:
 Locals at 0x7fffffffe3a0, Previous frame's sp is 0x7fffffffe3b0
 Saved registers:
  rip at 0x7fffffffe3a8

Comme vu plus haut, d’après la documentation cette fonction prend bien 4 paramètres. De plus rappelons que les paramètres d’une fonction lorsque peu nombreux sont placé dans les registres par ordre inverse (le dernier paramètre sera donc le registre le « plus petit » ici rcx)

(gdb) info registers
rax            0x603030 6303792
rbx            0x60311f 6304031
rcx            0x603110 6304016   # VI
rdx            0x10     16        # Taille du Bloc
rsi            0x603010 6303760   # Clé
rdi            0x603030 6303792   # Mcrypt_Struct
rbp            0x7fffffffe480   0x7fffffffe480
rsp            0x7fffffffe3a8   0x7fffffffe3a8
r8             0xff     255
r9             0xffffffffff000000       -16777216
r10            0x7fffffffe170   140737488347504
r11            0x7ffff7babc80   140737349598336
r12            0x4009d0 4196816
r13            0x7fffffffe560   140737488348512
r14            0x0      0
r15            0x0      0
rip            0x7ffff7babc80   0x7ffff7babc80 
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) x /48xh 0x603030
0x603030:       0xffff  0xffff  0xffff  0xffff  0x7774  0x666f  0x7369  0x0068
0x603040:       0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000
0x603050:       0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000
0x603060:       0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000
0x603070:       0x0000  0x0000  0x0000  0x0000  0xffff  0xffff  0xffff  0xffff
0x603080:       0x6663  0x0062  0x0000  0x0000  0x0000  0x0000  0x0000  0x0000
(gdb) x /8xh 0x603110
0x603110:       0xc667  0x7369  0xff51  0xec4a  0xcd29  0xabba  0xfbf2  0x46e3
(gdb) x /8xh 0x603010
0x603010:       0x6f67  0x6f74  0x6620  0x6961  0x3b6c  0x0000  0x0000  0x0000
(gdb)

Nous avons donc ici des sérieux candidats pour la clé et le vecteur d’initialisation.

Enfin par acquis de conscience, nous pouvons aller « pièger » la bibliothèque :

apt-get  source libmcrypt-dev

Nous modififions la fonction mcrypt_generic_init dans lib/mcrypt.c comme suit :

int mcrypt_generic_init(const MCRYPT td, const void *key, int lenofkey, const void *IV)
{
        int i = 0 ;
        fprintf(stdout,"Captain on the bridge : The key is :");
        for( i =0 ; i<16; i++)
                fprintf(stdout,"%02x", ((unsigned char *)key)[i] );
        printf("\nThis is the IV you are looking for :");

        for( i =0 ; i<16; i++)
                fprintf(stdout,"%02x", ((unsigned char *) IV)[i]);
        printf("\n");

        return internal_init_mcrypt(td, key, lenofkey, IV);
}

On recompile, on met à jour le lien symbolique :

jshmendes@vima:~/omc/libmcrypt-2.5.8$ ./configure ; make
jshmendes@vima:~/omc/libmcrypt-2.5.8$ sudo ln -sf  /home/jshmendes/omc/libmcrypt-2.5.8/lib/.libs/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4
jshmendes@vima:~/omc$ printf "blabla" | ./o-hsucrpt-e ; echo ""
Captain on the bridge : The key is 676f746f206661696c3b000000000000
This is the IV you are looking for :67c6697351ff4aec29cdbaabf2fbe346
pspq

Et voilà ! Cela confirme notre analyse précédente. Notons ici qu’utiliser la librairie permet aussi d’avoir plus informations dans gdb :

jshmendes@vima:~/omc$ gdb ./o-hsucrpt-e
[...]
(gdb) break mcrypt_generic_init
Breakpoint 1 at 0x400900
(gdb) run
Starting program: /home/owner/omc/o-hsucrpt-e

Breakpoint 1, mcrypt_generic_init (td=0x603030, key=0x603010, lenofkey=16, IV=0x603110) at mcrypt.c:156
156     {
(gdb) info args
td = 0x603030
key = 0x603010
lenofkey = 16
IV = 0x603110

Bon c’est bien, mais d’où sortent cette clé et ce vecteur ?

La clé n’est autre qu’une chaine ASCII qui nous avions sous les yeux depuis le début : « goto fail; »

Mais le vecteur est lui plus abscons, une recherche dans le binaire ne donne rien. Il doit être généré par le code. Allez on y retourne : on va voir l’assembleur :

jshmendes@vima:~/omc/$ objdump -d o-huscrpt-e >  output.asm
 400bc6:       e8 05 fd ff ff          callq  4008d0 
 400bcb:       48 89 85 50 ff ff ff    mov    %rax,-0xb0(%rbp)
 400bd2:       48 83 bd 50 ff ff ff    cmpq   $0x0,-0xb0(%rbp)
 400bd9:       00
 400bda:       75 0a                   jne    400be6 
 400bdc:       b8 01 00 00 00          mov    $0x1,%eax
 400be1:       e9 2e 01 00 00          jmpq   400d14 
 400be6:       48 8b 85 50 ff ff ff    mov    -0xb0(%rbp),%rax
 400bed:       48 89 c7                mov    %rax,%rdi
 400bf0:       e8 bb fd ff ff          callq  4009b0 
 400bf5:       48 98                   cltq
 400bf7:       48 89 c7                mov    %rax,%rdi
 400bfa:       e8 61 fd ff ff          callq  400960 
 400bff:       48 89 85 58 ff ff ff    mov    %rax,-0xa8(%rbp)
 400c06:       c7 85 40 ff ff ff 00    movl   $0x0,-0xc0(%rbp)
 400c0d:       00 00 00
 400c10:       eb 22                   jmp    400c34 
 400c12:       8b 85 40 ff ff ff       mov    -0xc0(%rbp),%eax   // Début de boucle
 400c18:       48 63 d0                movslq %eax,%rdx
 400c1b:       48 8b 85 58 ff ff ff    mov    -0xa8(%rbp),%rax
 400c22:       48 8d 1c 02             lea    (%rdx,%rax,1),%rbx
 400c26:       e8 95 fd ff ff          callq  4009c0 
 400c2b:       88 03                   mov    %al,(%rbx)
 400c2d:       83 85 40 ff ff ff 01    addl   $0x1,-0xc0(%rbp)
 400c34:       48 8b 85 50 ff ff ff    mov    -0xb0(%rbp),%rax
 400c3b:       48 89 c7                mov    %rax,%rdi
 400c3e:       e8 6d fd ff ff          callq  4009b0 
 400c43:       3b 85 40 ff ff ff       cmp    -0xc0(%rbp),%eax  
 400c49:       7f c7                   jg     400c12  
 400c4b:       48 8b 8d 58 ff ff ff    mov    -0xa8(%rbp),%rcx
 400c52:       8b 95 44 ff ff ff       mov    -0xbc(%rbp),%edx
 400c58:       48 8b b5 48 ff ff ff    mov    -0xb8(%rbp),%rsi
 400c5f:       48 8b 85 50 ff ff ff    mov    -0xb0(%rbp),%rax
 400c66:       48 89 c7                mov    %rax,%rdi
 400c69:       e8 92 fc ff ff          callq  400900 


On constate une boucle itérative sur la taille du VI. Egalement, on remarque l’utilisation d’une fonction « rand » de stdlib. Ce qui est intéressant ici, c’est que la fonction srand utilisée pour définir la graine du générateur pseudo-aléatoire n’est pas appelé dans le code. Et si l’on se fit à la « man page », il n’y a dès lors rien de vraiment aléatoire dans la génération du vecteur d’initialisation puisque pour chaque exécution, le VI sera toujours identique car la graine utilisée par rand() sera toujours 1.

Du coup si nous pouvons le reproduire :

#include ;
#include ;

int main(int argc, char *argv[])
{
  int j ;
  for (j = 0; j &lt; 16; j++)
     fprintf(stdout, "%02x", (unsigned char ) rand());
  return 0;
}
jshmendes@vima:~/omc$ gcc testrand.c -o iv
jshmendes@vima:~/omc$ ./iv
67c6697351ff4aec29cdbaabf2fbe346

Donc voilà, nous savons comment est généréré l’IV.

Nous pouvons donc dire que nous avons tout. Reste maintenant à coder un programme qui fasse la même chose. Mais, en y regardant de plus pres, les concepteurs avaient laissé volontairement une indication sur la source du challenge qui se trouve dans la bibliothèque mcrypt elle-même… On vous laisse chercher 🙂

Publié dans cryptobourrin, Cryptographie Asymétrique, Cryptographie Symétrique, Uncategorized | Tagué , , , , | Laisser un commentaire