Analyse de codes malveillants : fichier Word avec Macro

Dans la partie 1, nous avons défini ce qu'était l'obfuscation de code, ce à quoi cela pouvait servir et, nous avons étudié un code avec une petite obfuscation. Maintenant que les bases sont posées, nous allons pouvoir passer aux choses sérieuses avec un cas plus concret que l'on retrouve tous les jours, à savoir, un fichier WORD avec une macro !

Les documents Office (Word, Excel, PowerPoint, ...) et PDF sont les formats les plus utilisés lors des attaques par mails. Pour cesdocuments, et c'est ce que nous allons voir aujourd'hui, la principale méthode utilisée à travers ce format est l'utilisation de macro.

Qu'est-ce qu'une macro et à quoi cela peut-il bien servir ? Pour répondre à cette question, rien de mieux que de citer la définition officielle de Microsoft.

Une macro est une série de commandes et d’instructions que vous regroupez au sein d’une même commande afin d’exécuter automatiquement une tâche.

Un fichier Office malveillant va donc utiliser une macro pour exécuter du code sur l'ordinateur de la victime. Aujourd'hui, nous allons voir comment les macros peuvent être obfusquées et comment faire pour comprendre ce qu'elles réalisent. L'analyse sera plus compliquée que dans l'article précédent mais pas de panique, nous allons l’effectuer pas à pas.

Beaucoup de code pour pas grand-chose...

Nous y voilà, c'est parti ! Le code que nous allons étudier provient d'une macro contenue dans le fichier Word ci-dessous.

Type fichier SHA1 VirusTotal VirusBay
Word a8a1b0191d35b4530afacab33cffb751d42d3d64

Lien

Lien

 

Code malveillant macro

Comme vous avez pu le voir (image ci-dessus) le code de la macro est obfusquée. L'obfuscation est plutôt bien réussie, même s'il reste encore quelques mots-clés que nous pouvons lire dans le code.

  • Ligne 7 : On remarque un "md, "/V", ":ON/C" et plus loin sur la ligne un "s^e^t" (set). Cela nous donne des indications sur la macro, à savoir que celle-ci va exécuter du code via l'invite de commande Windows.
  • Ligne 176 : on peut lire un "for" et "in", cela semble être une boucle.
  • Ligne 178 et 181 : il y a un "do", "set", "if et "equ". Tout semble indiquer que le code va exécuter une boucle avec des tests à l'intérieur.

Enfin, si on regarde attentivement le tout début de la ligne 176, on peut lire un "p", maintenant regardons la ligne 174 et si on la lit à l'envers, cela donne, "o", "wer", "sh", "ell". On concatène le tout et cela donne, "powershell" ! Du code PowerShell va être exécuté sur l'ordinateur. Continuons pour comprendre ce qui se passe réellement.

La première étape va consister à simplifier au maximum le code en retirant tout ce qui est inutile. Pour cela, nous allons le faire fonction par fonction, commençons par la dernière, que voici :

code malveillant macro image 2

Avec un peu d’expérience, on remarque que toutes les lignes dans le code commençant avec le mot clé "Hour" sont inutiles. C'est ce qu'on appelle du bruit : cette technique consiste à ajouter du code mort, qui ne sera pas utilisé par le programme, afin de compliquer la compréhension du code. Ici, on remarque rapidement le bruit mais c'est rarement le cas dans des obfuscations de code plus avancées où il peut être difficile de l'identifier. Voici ce que donne la fonction "Sub AutoOpen()" après avoir retiré le bruit :

code malveillant macro image3

Voici ce que donne une recherche du mot clé "AutoOpen" sur le site de microsoft :

La macro AutoOpen s'exécute lorsque vous ouvrez un nouveau document de l'une des manières suivantes :

Lorsque vous utilisez la commande Ouvrir dans le menu Fichier.

Lorsque vous utilisez la commande FileOpen ou la commande FileFind.

Lorsque vous sélectionnez un document dans la liste des derniers fichiers utilisés dans le menu Fichier.

Lorsqu'un document est ouvert, la macro AutoOpen s'exécute si elle fait partie intégrante de ce document ou si elle fait partie du modèle à partir duquel le document a été créé.

AutoOpen ne s'exécute pas si elle fait partie d'un complément global.

Vous pouvez empêcher une macro AutoOpen de s'exécuter en maintenant la touche MAJ enfoncée pendant que vous ouvrez un document.

Donc lorsque le document est ouvert, la macro AutoOpen exécute le code qui se trouve dans celle-ci. Ici, la macro fait une seule ligne (ligne 24). Le mot clé "Shell" est une fonction qui va exécuter un programme, cette fonction a besoin de 2 arguments.

Voici sa syntaxe :

Shell argument1, argument2
argument1 : Le nom du programme qui sera exécuté.
argument2 : Le focus du programme exécuté. Permet de déterminer si le programme exécuté sera caché, la taille qu'il aura, etc ...

Dans notre code, le premier argument est une suite d'addition de variables et si on regarde le reste du code on se rend compte que ce sont les retours des fonctions qui vont être additionnés pour ensuite être exécutés. Simplifions le reste du code pour y voir plus clair.

code malveillant macro image 4

Prenons la fonction ci-dessus pour exemple, regardons les différentes étapes :

  1. On supprime les lignes qui commencent avec le mot clé "Hour" comme expliqué précédemment.
  2. Pour les lignes restantes (ligne 7, 9, 12, 14 et 19), on additionne les chaines de caractères. Exemple, une ligne avec écrit : variable = "Powe" + "rSh" + "ell" donnerait ceci : variable = "PowerShell".
  3. La ligne 2 est utile uniquement lors de l'exécution du code donc nous pouvons aussi la supprimer.
  4. Pour finir, sur la ligne 20 on concatène les résultats obtenus dans les étapes précédentes.

Voici ce que nous obtenons à la fin :

code malveillant macro image6

Maintenant nous pouvons réaliser les étapes précédentes sur le reste du code, ci-dessous le résultat obtenu, on passe d'un code faisant 200 lignes à 23 lignes ! Plutôt pas mal non ? Nous pouvons encore faire bien mieux.

code malveillant macro image7

Nous allons réaliser 3 étapes en même temps.

  1. Comme ce que nous avons fait précédemment, nous pouvons remplacer le retour de chaque fonction directement dans la macro "AutoOpen".
  2. Puis remplacer la fonction "KeyString".
  3. Puis supprimer les caractères "^".

La fonction "KeyString()" retourne une combinaison de touches. Dans notre exemple il est demandé à la fonction de retourner la/les touches qui correspondent à la valeur 67. Voici la documentation de Microsoft pour voir à quoi correspond ce nombre. La fonction va donc retourner la touche 'C'.

Comme vous l'avez sûrement remarqué, les chaines de caractères contiennent plusieurs fois le caractère "^".

À quoi peut-il bien servir ? Ce caractère permet de faire de l'échappement d'autres caractères. Définition de Microsoft :

Un caractère d'échappement est un caractère unique qui supprime toute signification du caractère qui le suit.

Exemple :

  • ^          →       a
  • ^^^     →     ^a
  • ^^^^^a →  ^^a

Ici, comme le code ne sera pas exécuté, nous n'en n'avons pas besoin, nous pouvons donc les supprimer.

Regardons ce que donne le résultat une fois les 3 étapes réalisées.

Code Malveillant Macro image8

Parfait ! Le code commence à ressembler à quelque chose, vous ne trouvez pas ? Continuons, nous sommes sur la bonne voie !
Il reste encore 4 variables qui n'ont pas été remplacées. Les variables ne sont pas déclarées et ne sont utilisées nulle part, c'est du bruit, nous pouvons donc les supprimer et concaténer le reste du code.

code malveillant macro image9

Et voilà nous y sommes ! Nous sommes parvenus à avoir la syntaxe de la fonction "Shell", à savoir, "Shell argument1, argument2". Le programme qui sera exécuté est "cmd" (cmd.exe, l'invite de commande Windows) avec toute une liste d'options et d'arguments. Le deuxième argument est 0 qui correspond au focus que va avoir le programme une fois exécuté. Pour savoir à quoi correspond ce nombre, il faut regarder la documentation de la fonction sur le site de Microsoft, le deuxième argument se nomme "windowstyle" et la valeur 0 correspond à "fenêtre masquée".
À présent, nous savons ce que réalise la macro. Elle exécute l'invite de commande Windows puis cache la fenêtre qui sera créée pour que l'attaque soit furtive et que l'utilisateur ne se rende compte de rien. Que réalise réellement l'invite de commande ? C'est ce que nous allons voir maintenant.

Encore et toujours de l'obfuscation

Le code suivant sera exécuté sur l'ordinateur de la victime, il a été simplifié pour mieux comprendre ce qu'il réalise.

code malveillant macro image 10

Le code peut être divisé en 2 parties, les données obfusquées puis le code permettant la dé-obfuscation de celui-ci qui sont les 4 dernières lignes. Le code est une boucle partant de 1021 et allant jusqu’à 0 en faisant -1 à chaque tour de boucle, si on regarde bien les données et notamment en lisant à l'envers on peut le lire le mot "powershell" qui se situe à la fin des données obfusquées. Nous pouvons deviner ce que réalise le reste du code mais vérifions tout de même.

Regardons la ligne suivante :

set eDYP = !eDYP!!6k:~%X,1!

Que fait-elle ? Au départ la variable "eDYP" est vide puis à chaque tour de boucle on va ajouter 1 caractère qui se trouve à la position X dans les données obfusquées sachant que X correspond au numéro de tour de boucle (1021 puis 1020, 1019, ...).

Voici un bref exemple lors de l'exécution de la boucle :

1er tour :

X = 1021

eDYP = "p"

2ème tour :

X = 1020

eDYP = "po"

3ème tour :

X = 1019

eDYP = "pow"

Le code va simplement retourner les données, puis lorsque la boucle arrivera à 0, la variable "eDYP" sera exécutée. Voici les données une fois la boucle terminée :

code malveillant macro image11

Du code PowerShell va être exécuté, il est possible de donner des chaines encodées en base64 et, avec la bonne option en paramètre la chaine sera décodée puis exécutée. Voici la documentation de PowerShell pour les chaines encodées :

Code powershell malveillant

L'option "-e" est le diminutif de "-EncodedCommand", nous allons maintenant nous concentrer sur les données décodées.

code malveillant image12

Encore un bout de code qui semble incompréhensible au premier abord... Rectifions cela avec une simple mise en forme du code.

analyse du code malveillant macro image13

On va maintenant simplifier le code comme nous l'avons déjà fait à plusieurs reprises (concaténation de chaine, remplacement des variables, ...).

  • La fonction "Split" permet de découper une chaine en plusieurs parties via l'utilisation d'un token, dans notre code c'est le caractère "@".
  • La variable d'environnement "$env:public" permet de récupérer le dossier Public de Windows.

Analyse code malveillant macro

Et voilà ! Nous en avons enfin terminé avec cette obfuscation. Que réalise ce code ? Il va essayer, pour chaque URL de la variable "$raw", de télécharger un programme (qui sera nommé "735.exe" et stocké dans le dossier "C:\Users\Public\") puis de l'exécuter. Le programme s'arrêtera lorsqu'une URL aura fonctionné. Le fichier téléchargé est le malware Emotet qui est un trojan bancaire avec pour objectif de voler des identifiants bancaires.

 

Fichier SHA1 VirusTotal VirusBay
735.exe 58dab44d83c6f1ad4407d77b88874e126b732688

Lien

Lien

 

Comme nous avons pu le constater, l'obfuscation est plus compliquée que dans la première partie mais elle n'est pas insurmontable. Nous avons réussi à arriver au bout avec simplement des remplacements de variables, de la concaténation de chaines de caractères et en décodant une chaine de caractère. L'obfuscation que nous venons de voir est ce qui se fait actuellement en termes de difficulté dans les downloaders ainsi que les droppers. Néanmoins, il existe des obfuscations de codes beaucoup plus compliqués que ce que nous avons vu jusqu'à présent et qui peuvent être difficilement réalisés à la main comme nous le faisons.

Le monde de l'obfuscation est vaste, complexe et fascinant ! Nous en avons vu qu'une petite partie pour le moment.