Reverse Engineering – focus sur l’analyse dynamique de malware

L’analyse dynamique d’un fichier correspond à analyser l’exécution de ce fichier. Cette analyse permet alors de déterminer le comportement réel du malware, là où certains éléments de l’analyse statique peuvent être présents uniquement pour détourner l’attention de l’analyste, ou lui compliquer la tâche.
Une première forme d’analyse dynamique correspond à l’exécution du malware et à l’observation des modifications qu’il entraine sur le système. Cette analyse a le plus souvent pour but de déterminer les actions à effectuer pour supprimer le malware, et/ou créer une signature.
Attention, ce type d’analyse doit absolument être fait dans un environnement contrôlé (machine virtuelle, poste dédié et déconnecté du SI, etc.) afin de ne pas risquer la propagation de l’infection.

1)     Analyse des opérations

L’analyse dynamique permet la surveillance de nombreuses informations : les registres, le système de fichiers et les processus. Cette étape est au début assez fastidieuse étant donné que de nombreuses informations sont accessibles. Il existe différents outils permettant d’accéder à ces informations. ProcessMonitor est l’un de ces outils qui a l’avantage de permettre à l’analyste de filtrer ses recherches sur un exécutable, ce qui est très pratique pour l’analyse de malwares.

Figure 1 : Résultat d’une analyse de ProcessMonitor sur un malware appelé mm32.exe

L’analyse de ces différents éléments permet à l’analyste d’avoir une meilleure compréhension de l’activité du malware. Cependant, étant donné le nombre d’informations renvoyées par ProcessMonitor dont la plupart représentent des évènements standards du lancement d’un exécutable, l’analyse demande beaucoup de pratique et de la patience.
Un autre outil permettant une analyse poussée des processus est Process Explorer. Il permet de lister les processus, les bibliothèques chargées par un processus, différentes informations sur ces processus, ainsi que des informations globales sur le système. L’avantage de cet outil est qu’il présente les informations sous forme d’arbre, exposant ainsi les relations entre les processus parents et enfants.
Les informations que Process Explorer renvoie sont le nom du processus, le PID (numéro d’identification du processus), l’utilisation du CPU, une description ainsi que le nom de l’entreprise ayant créé le binaire (champs laissés libres au créateur du binaire…). Par défaut les services sont surlignés en rose, les processus en bleu, les nouveaux processus en vert et les processus terminés en rouge. La vue se met alors à jour à chaque seconde. Lors de l’analyse de malware il est donc intéressant de repérer les différents processus qui sont modifiés ou créés afin de pouvoir enquêter dessus de manière plus approfondie.

Figure 2 : Résultat de Process Explorer sur un exécutable

Ces techniques sont très efficaces pour comprendre ce que fait un exécutable, mais il ne faut pas négliger leur utilité pour déterminer si un document est malveillant ou non. Un moyen rapide de savoir si un PDF est malveillant, par exemple, est de lancer Process Explorer puis d’ouvrir le PDF et de regarder si de nouveaux processus sont créés.
Remarque : Pour l’analyse de documents, il est souvent intéressant d’utiliser des versions intentionnellement non patchées des logiciels afin de s’assurer que l’attaque est efficace. Une bonne manière de faire cela est par exemple de créer plusieurs snapshots d’une machine virtuelle d’analyse, chaque snapshot ayant une version différente, et généralement assez âgée, des logiciels.
Pour l’analyse de registres, l’outil Regshot permet de comparer les registres sur deux snapshots différents. Un extrait de résultat de Regshot peut ressembler à la figure 3.
Dans ce résultat, le premier constat est la création d’un mécanisme de persistance HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run par le programme ckr.exe, le deuxième est la modification de la valeur de la seed pour le générateur de nombre aléatoire, ce qui représente un bruit habituel.

Figure 3 : Extrait de résultat de Regshot après lancement du programme ckr.exe

2)     Analyse réseau

De nombreux malwares récupèrent des ressources ou transmettent des informations sur le réseau (en particulier vers des serveurs C2 « Command & Control »). De ce fait il est très intéressant de réaliser une analyse réseau pour déterminer les actions du malware. L’environnement d’analyse n’étant pas connecté à internet, il se peut qu’une partie des fonctionnalités du malware restent non accessibles. Cependant il est préférable de récupérer de telles informations en faisant une analyse manuelle approfondie plutôt que de permettre au malware de se propager (une sortie directe vers Internet peut néanmoins être fortement utile aux équipes d’analyse).
Quelques outils peuvent permettre d’effectuer une analyse réseau d’un malware :
  • ApateDNS permet de récupérer les requêtes DNS faites par le malware. Il permet également de simuler les réponses d’une adresse IP spécifiée en écoutant sur le port 53 de la machine locale via le protocole UDP. Il affiche alors les requêtes reçues en hexadécimal ou en ASCII. Par défaut ApateDNS utilise la passerelle (gateway) ou les paramètres de DNS courants dans les réponses DNS.

Figure 4 : Interception des requêtes DNS et simulation des réponses par ApateDNS en utilisant l’IP 192.168.120.1

  • Netcat permet le scan de port, tunneling, proxying, transfert de ports et bien d’autres choses sur des connections aussi bien entrantes que sortantes. Il existe deux modes de fonctionnement pour Netcat, le mode écoute, pour lequel Netcat agit comme un serveur, et le mode connexion pour lequel il agit comme un client.
Remarque : les malwares utilisent souvent les ports 80 et 443 (HTTP et HTTPS respectivement) car ces ports ne sont généralement pas bloqués par les différents équipements de sécurité sur le réseau des entreprises (firewall, proxy, etc.).
Remarque 2 : certains malwares simulent des connexions usuelles afin de cacher leur comportement et tirer parti d’une méconnaissance de nombreux analystes réseau qui ne se concentrent que sur le début d’une session. Par exemple, en figure 5 le reverse shell RShell est instancié avec une redirection du domaine www.google.com vers l’hôte local 127.0.0.1 à l’aide d’ApateDNS. L’analyste écoute ensuite le trafic réseau sur le port 80 local avec Netcat.
Dans ce résultat, RShell simule une requête POST à www.google.com (comme le montre le point 2 sur la figure) mais par la suite, l’analyste récupère bien un shell (visible sur le point 3).

Figure 5 : Résultat renvoyé par Netcat lors de l’exécution de RShell en redirigeant les requêtes vers l’hôte grâce à ApateDNS

  • Wireshark permet la capture de paquets et de création de logs pour le trafic réseau. Il permet la visualisation, l’analyse de trames et l’analyse en détail de paquets individuels.

Figure 6 : Capture d’écran d’une analyse Wireshark

Une des fonctionnalités très utiles de Wireshark est la fonctionnalité Follow TCP stream qui permet à partir d’un paquet de reconstituer le flot entier auquel il appartient.
Figure 7 : Fonctionnalité Follow TCP Stream de Wireshark
Wireshark peut permettre à l’analyste de comprendre comment le malware réalise ses communications réseau.

3)     Analyse via débogueur

Étape la plus complexe de l’analyse, l’analyse dynamique avancée correspond au passage de l’exécutable dans un débogueur afin de déterminer les actions qu’il effectue les unes après les autres, ainsi que les différents états qu’il génère sur le poste analysé. Il existe plusieurs débogueurs utilisables pour cette étape, notamment IDA Pro, OllyDbg et WinDbg.
Cette étape est extrêmement efficace mais nécessite de nombreuses connaissances et beaucoup de temps. Dans cette partie sera présenté un aperçu de ce qu’il est possible de faire avec un débogueur. Il est important de retenir que l’analyse dynamique révèle ce que le malware fait véritablement, contrairement à l’analyse statique qui montre ce que le malware est en théorie capable de faire. Certains bouts de code présents dans le malware peuvent en effet ne jamais être appelés, et les repérer durant l’analyse statique peut induire en erreur l’analyste sur l’action du malware.
L’utilisation d’un débogueur permet également d’obtenir des informations impossibles à récupérer avec un désassemblage, comme par exemple les valeurs prises par les registres au fur et à mesure de l’exécution.
Il existe en fait deux types de débogueurs, ceux dits source-level qui sont généralement intégrés dans les IDE et bien connus des développeurs, leur permettant d’agir sur le code source afin de déterminer les comportements étranges de leurs programmes, et ceux dits assembly-level ou low-level qui agissent sur le code assembleur. C’est ce deuxième type de débogueur qui est utilisé par les analystes de malware, étant donné qu’ils n’ont pas accès au code source de l’application.
De même il existe deux niveaux de débogage, celui en mode utilisateur, où le débogueur est lancé sur le même système d’exploitation que le programme en cours d’exécution, et celui plus complexe en mode noyau, qui permet de déboguer des applications ayant ce niveau d’interactions, mais qui nécessite deux machines reliées, l’une faisant tourner le programme, et l’autre permettant le débogage. Une deuxième machine est en effet nécessaire car il n’existe qu’un noyau par système d’exploitation, et si un breakpoint est mis sur une instruction exécutée par ce noyau, plus aucune application ne pourra répondre, le débogueur compris.
Dans les deux cas d’exécution, le résultat sera la mise en suspens du programme. Dans le premier cas le programme sera stoppé dès le point d’entrée (sauf configuration particulière) alors que dans le deuxième il sera arrêté là où il se trouvait. Une fois cela effectué, il est possible d’agir de différentes manières sur le programme :
  • Avancer d’une instruction (single-stepping) : cette action est généralement utilisée uniquement sur les passages identifiés comme importants afin d’obtenir des détails sur le fonctionnement comme les valeurs prises par les registres.
  • Avancer d’une fonction (Stepping-over) : cela peut permettre de passer des détails inutiles. Par exemple si le programme appelle la fonction LoadLibrary, il n’est pas nécessaire de rentrer dans les détails de cette fonction. 
  • Rentrer dans une fonction (Stepping-into) : en opposition à l’action précédente, il peut parfois être intéressant de rentrer dans une fonction pour en comprendre les détails.
  • Avancer jusqu’au prochain breakpoint : pour cela il faut souvent placer un breakpoint plus loin dans le code et relancer l’exécution, le débogueur s’arrêtera automatiquement au breakpoint.
  • Modifier l’exécution d’un programme : par exemple pour éviter l’appel à une fonction, il est possible de mettre un breakpoint sur cette fonction et, lorsque l’interruption est levée, changer le pointeur d’instruction à après son appel.
Il existe trois types de breakpoints :
  • Les software breakpoints : ces points d’arrêt sont utilisés pour faire en sorte que le programme s’arrête lorsque l’instruction sur laquelle ils sont placés est appelée. Pour réaliser cela, le débogueur remplace le premier octet de l’instruction par 0xCC, l’instruction pour INT3.

Figure 8 : Remplacement du premier octet de l’instruction par 0xCC lors d’un software breakpoint.

  • Les hardware breakpoints : ils sont placés sur une adresse mémoire, et déclenchés lorsque le programme tente d’accéder à cette ressource. L’avantage est qu’ils ne dépendent pas de la valeur présente dans cette adresse mémoire, et qu’ils interviennent à l’accès et non à l’exécution. Néanmoins ils nécessitent des registres particuliers qui sont en nombre limités sur un système.
  • Les conditional breakpoints : ce sont des software breakpoints qui ne vont déclencher l’arrêt que si une certaine condition est vérifiée. Cela peut par exemple être utile si l’on veut s’arrêter à l’appel d’une fonction que si un certain paramètre est appelé.
Ces différentes techniques d’analyse dynamique viennent en complément d’une analyse statique.
Il convient néanmoins de prendre toutes les précautions nécessaires avant de se lancer dans une analyse de malware. Chaque résultat obtenu par les analystes doit être contrevérifié pour s’assurer qu’aucune technique anti-reverse n’est mise en œuvre dans le binaire.
Back to top