L’investigation numérique d’un système d’information (SI) consiste à comprendre d’un point de vue temporel et factuel les évènements ayant conduit à l’incident. Bien que les SI présentent une architecture bien souvent commune, les interventions sont toutes différentes et mettent en lumière l’ingéniosité des attaquants afin d’œuvrer de la manière la plus discrète possible. Nous allons présenter au cours de cet article, notre retour d’expérience relatif à une intervention auprès d’un client début 2020.
1. Premier contact
Début 2020, la société TERRAC (volontairement anonymisée) spécialisée dans la gestion des matériaux de forage nous contacte suite à plusieurs évènements suspects. De nombreux ralentissements ont été observés au sein de certains serveurs de la société. Le moment exact des premiers signes n'est pas connu, mais cela remonte à quelques semaines. Nous avons obtenu quelques informations techniques lors de notre premier échange téléphonique, suffisamment pour définir le nombre de personnes à envoyer et le matériel nécessaire.
Nous savons que le système d'information (SI) impacté est composé de :
- Serveurs : Microsoft Windows 2016 server, Frontal web ;
- Serveurs impactés : serveur frontal et serveur de maintenance.
2. Logistique
Dans la grande majorité des cas, deux personnes sont envoyées en intervention. En fonction de l’avancée et des difficultés rencontrées, ce chiffre peut évoluer.
Nous aurons également besoin d’un certain nombre de matériels spécifiques. Rien que pour les divers prélèvements de la mémoire vive et des données présentes sur les périphériques de stockage, une puissance de stockage adaptée est nécessaire. Ce besoin prend tout son sens, car chacun des prélèvements devra être dupliqué pour effectuer les analyses, l’original sera quant à lui mis sous séquestre. Il existe de nombreuses solutions de stockage sur le marché de type SAN, NAS, avec ou sans RAID. Afin d’anticiper toutes ces configurations possibles, nous nous sommes munis de copieur/bloqueur de l’entreprise Tableau. Ils présentent l’avantage d’être reconnus au niveau légal pour le cas où l’affaire prendrait une dimension judiciaire.
3. La mémoire vive
L'entreprise possède une infrastructure assez simple. L’écosystème est composé exclusivement d'équipements sous Windows et les éléments actifs sont de la marque CISCO. Au cœur du SI, deux serveurs ESXi. Un seul est en fonctionnement, le second assure la continuité du service en cas de défaillance.
Les données relatives aux machines virtuelles sont stockées au sein d'une partition nommée « Datastore ». Chaque machine virtuelle est stockée dans un répertoire prévu à cet effet.
Les fichiers « .vmdk » correspondent aux disques durs virtuels et les fichiers « .vmem », « .vmsn » et « .vmss » sont relatifs à la mémoire vive. Depuis notre appel, aucun poste n'a été arrêté et le DSI ne prévoit aucun arrêt des systèmes durant notre intervention.
La mémoire vive est le premier élément à prélever. Dans le cas d’une infrastructure virtualisée, l’opération est plus simple. Nous demandons à l’administrateur de nous fournir les fichiers vmem. L’analyse sera effectuée avec l’outil volatility en version 2.6.
En premier lieu, nous recherchons le profil qui sera le plus adapté au dump mémoire à analyser grâce au plugin kdbgscan.
Pour déterminer le profil adéquat, nous allons comparer la version de compilation « Build string » avec le nom du profil proposé. La version de compilation ici présente est 14393.693.amd64fre.rs1_release.1, seul le profil Win2016x64_14393 correspond à notre version de compilation.
Nous confirmerons le bon fonctionnement du profil sélectionné grâce aux résultats obtenus des plugins PsActiveProcessHead (nombre de processus identifiés), et PsLoadedModuleList (nombre de modules identifiés). Nous sélectionnerons le profil qui obtient le plus de résultats.
Une fois le profil identifié, nous utiliserons la valeur des paramètres KDBG et DTB à chaque exécution de la commande volatility. KDBG est une structure maintenue par le kernel Windows qui contient la liste des processus en cours d’exécution ainsi que les modules kernel. Tandis que DTB (Directory Table Base) est utilisé par volatility pour traduire les adresses mémoires. Il est possible de ne pas les utiliser, mais le gain de temps pour chaque requête est vraiment important et dans ce genre d'activité, cela n'est pas négligeable.
3.1 Analyse des processus
Une bonne pratique est d'utiliser un alias pour chacune de nos requêtes. Cela soulage le prompt et offre une meilleure visibilité.
La première étape va consister à lister les nombreux processus chargés en mémoire à la recherche d'incohérence. Par incohérence, comprendre la présence de parents illégitimes, l’exécution à partir de répertoire possédant des droits d’écriture (c:/users/ ou c:/windows/temp) ou bien la création d'un processus non prévu tel que cmd.exe, ou powershell.exe par exploitation d’une vulnérabilité d’un exécutable.
La commande pstree permet d’avoir cette vision hiérarchique.
Volatility permet également de générer des fichiers au format dot. Il permet d’avoir une visualisation des dépendances sous forme de graphe. Il faut ajouter l’option --output=dot --output-file=pstree.dot à la commande précédente.
En figure 1, voici une représentation graphique obtenue.
Le processus java.exe possède des processus fils dont plusieurs cmd.exe, et rundll32.exe. Il ne s’agit pas d’un comportement normal. L’analyse de la mémoire va se poursuivre avec l’utilisation du plugin malfind. Ce dernier va parcourir la mémoire de chacun des processus à la recherche d’incohérences qui refléteraient une possible injection de code. Pour ce faire, il va rechercher des sections de mémoire étant PAGE_EXECUTE_READWRITE et contenant du code.
Ce plugin est très performant, mais n’est pas fiable à 100 %. Nous verrons un peu plus loin comment vérifier ses résultats.
Le processus rundll32.exe identifié précédemment fait partie de la liste des résultats du plugin malfind.
Les lettres MZ indiquent qu’il s’agit d’un fichier au format Portable Executable (PE) et donc un exécutable pour Windows. Le plugin malfind a identifié un certain nombre d'anomalies au sein du processus.
Gardez à l’esprit que le résultat affiché ne contient que 64 bytes de la section de mémoire contenant potentiellement une injection de code. Il est important de ne pas baser son analyse uniquement sur la recherche des lettres MZ sur le résultat affiché. Certaines techniques d’injection utilisent désormais des techniques d’offuscation ou le marqueur MZ n’est plus présent.
Nous avons donc décidé d'extraire grâce à l’argument -D ces sections de mémoire afin de les analyser plus en détail.
Il peut être difficile au premier abord de faire le lien entre le nom des fichiers « .dmp » et les processus identifiés par le plugin malfind. Prenons l’exemple du processus rundll32.exe qui a pour PID 5716. Malfind affiche l’adresse du processus au sein de la mémoire qui est : 0x850000. Si nous visualisons le nom des fichiers extraits, nous retrouvons cette adresse en dernière partie de nommage process.0xffff9a0fd5218080.0x850000.dmp.
Il est possible que le plugin malfind considère à tort qu’une partie de la mémoire présente des similitudes avec une injection de code. Pour valider les résultats du plugin, il est possible d’utiliser la commande clamav pour scanner les fichiers extraits et mettre en avant les éventuels logiciels malveillants.
L’analyse de Clamav confirme que le processus rundll32.exe ayant pour PID 5716 comporte un implant Meterpreter.
Pour valider les résultats du plugin, il est possible d’utiliser la commande binwalk qui identifiera le type des fichiers extraits de la mémoire du processus. S’il s’agit de fichiers de type « data », nous considérons que le plugin s’est trompé. Dans le cas contraire, nous ferons face à un binaire qui aura été injecté dans notre processus légitime.
Le résultat de la commande précédente confirme que sur les 5 fichiers, 4 sont des exécutables.
Nous envoyons le tout vers le site VirusTotal qui permet d’effectuer une analyse statique et dynamique des fichiers (figure 2).
3.2 Analyse des DLLs chargées par les processus
Afin de comprendre au mieux le rôle du binaire rundll32.exe, nous regardons du côté des bibliothèques chargées.
Aucune information intéressante. Regardons du côté de son processus père (5704).
3.3 Analyse des connexions réseau
L’analyse du processus rundll32.exe (PID : 5704) a permis de mettre en avant une donnée très importante. Nous avons obtenu l’adresse IP hébergeant la DLL chargée. D’après les résultats d’analyse de VirusTotal, cette DLL a également permis à l’utilisateur distant ayant cette adresse IP d’exécuter des commandes.
Pour confirmer les connexions réseaux entre le système impacté et l’adresse IP distante, nous avons utilisé le plugin netscan.
Plusieurs connexions réseaux à destination de l’adresse IP ressortent avec le plugin dlllist.
Les processus impactés sont :
- rundll32.exe (PID : 5856) : TCP / 192.168.205.186:49768 → 192.168.205.180:443 CLOSED : correspond comme nous l’indique VirusTotal à un reverse shell qui a eu lieu à 2020-01-16 13:25:09 UTC+0000 ;
- java.exe (PID : 4168) : TCP / 192.168.205.186:8080 ← 192.168.205.180:35132 CLOSED : correspond à une connexion légitime au service jboss qui s’est déroulé à 2020-01-16 13:24:23 UTC+0000 ;
- system (PID : 4) : TCP / 192.168.205.186:49765 → 192.168.205.180:445 CLOSED : correspond au chargement de la dll par rundll32 sur un partage réseau à 2020-01-16 13:24:57 UTC+0000.
3.4 Analyse des droits obtenus sur le système
Nous avons précédemment recueilli un certain nombre d’éléments confirmant la présence d’une personne non autorisée sur le système d’information le 16 janvier 2020 aux alentours de 13h24 UTC. Le plugin getsids identifie les droits des processus exploités. Il s’agit d’un bon indicateur pour déterminer le niveau de gravité de cette intrusion.
L’analyse des résultats du plugin getsids s’effectue de la manière suivante.
Le résultat indique que le processus avait les droits SYSTEM, appartenant au groupe Administrators lors de son exécution (1). Les lignes suivantes correspondent aux divers groupes dépendant du groupe ayant le plus de privilèges, ici Administrators.
3.5 Timeline
La timeline ou la suite factuelle des évènements est réalisable via les modules timeliner, mftparser et shellbags.
timeliner va extraire les métadonnées de tous les fichiers présents sur le système, mftparser va parcourir la master file table (MFT) indiquant notamment les dates de création, suppression et modification de chaque fichier et enfin shellbag va extraire les métadonnées présentes en base de registre.
Lorsque les fichiers body ont été générés, nous les avons regroupés dans le but de faciliter les pré-traitements.
Si nous analysons de plus près la timeline générée, nous constatons qu’au moment où l’adresse IP a accédé au service jboss, une application JAVA nommée jexws4.war a été déployée.
Après quelques recherches en sources ouvertes, nous nous sommes aperçus qu’il s’agissait d’un outil utilisé pour exploiter les vulnérabilités de services Jboss. Ce dernier nommé « Jexboss » permet ainsi à une personne malveillante d’obtenir un shell sur un serveur vulnérable.
La connexion réseau qui a eu lieu à 2020-01-16 13:25:09 UTC+0000 à destination de l’adresse IP identifiée précédemment sur le port 443, confirme cette hypothèse.
Conclusion
Nous venons de présenter dans cette première partie la méthodologie utilisée pour analyser la mémoire vive. Ont été présentés que les outils ayant permis d'avancer dans l'investigation et cette approche n'est qu'une parmi d'autres. Le schéma en figure 4 regroupe factuellement les actions observées.