Bienvenue dans le deuxième volet de notre série d’articles consacrés aux malwares .NET ! La première partie, disponible ici, explore quelques-unes des caractéristiques de la plateforme .NET, ainsi que les défis inhérents à l’analyse d’un malware écrit en C# ou VB.NET.
Dans cet article, nous vous proposons l’analyse d’un échantillon provenant de MalwareBazaar, identifié par le hash suivant :
L’objectif est de comprendre les activités de ce malware en nous concentrant sur deux aspects cruciaux :
- Sa configuration interne
- Ses indicateurs de compromission (IOC)
La configuration englobe tous les éléments qui orchestrent le comportement du malware une fois déployé sur une machine cible. Il est fréquent d’y trouver des IOC, tels que :
- Les adresses des serveurs C2 (Command & Control) vers lesquels il exfiltre les données
- Des identifiants de campagne
- Le mutex du malware
Au cours de cette analyse, nous mettrons en avant les étapes nécessaires à la découverte de ces informations et vous proposerons un script permettant d’automatiser le processus d’extraction, sans avoir à exécuter le malware.
1. Obtention des éléments de base
Ensuite, un recours aux commandes strings et strings -el n’est pas à négliger, car il permet d’avoir une idée générale des chaînes de caractères présentes au sein de l’exécutable :
S’il n’y a pas encore d’informations exploitables en termes de configuration (pas d’IP ou d’URL visibles, pas de hash spécifique non plus), quelques indices apparaissent néanmoins :
- La présence de chaînes de caractères obfusquées
- Les chaînes {1111-2222-xxxx-xxxx} indiquant une utilisation probable de .NET Reactor, un obfuscateur prisé tant par les acteurs malveillants que par les entreprises légitimes
Nous pouvons utiliser dnSpy, un décompilateur open-source, afin d’explorer le code en détail et confirmer nos doutes :
Le code est effectivement peu clair : les noms de plusieurs bibliothèques de fonctions (précédées par le mot-clef using) ont été altérés, tout comme ceux de la majorité des classes, méthodes et variables ; le flot de contrôle (ou CFG, pour Control Flow Graph) comprend des instructions goto et des switch inutiles et plusieurs conditions mortes {while (false) … } qui ne servent qu’à polluer l’ensemble.
En outre, on peut voir que « Akvwhmi2QHAgCb03kQ », aperçu grâce à strings -el, correspond à une ressource utilisée par le programme, c’est-à-dire une annexe contenant généralement des éléments permettant au programme de fonctionner, tels que du texte, des images, ou encore des fichiers audios.
2. Tentative de désobfuscation
Pour contrer ces mécanismes de protection et obtenir un binaire plus lisible, il est possible d’utiliser de4dot, un désobfuscateur écrit en C#, dont le fonctionnement repose sur deux axes majeurs :
- la détection du type d’obfuscateur utilisé et l’application d’algorithmes spécifiques à cet obfuscateur. Si l’obfuscateur n’est pas connu, ou si une nouvelle version d’un obfuscateur est en vigueur, il est possible de les rajouter soi-même grâce à des templates
- le traitement et la manipulation du code IL (Intermediate Language, l’assembleur qui sous-tend tout projet .NET), représenté par les blocs, une classe d’objets représentant les blocs d’instructions IL qu’il peut alors analyser, émuler et réécrire pour produire un exécutable plus propre
Fig.4 : Désobfuscation réussie par de4dot
Réitérer la commande strings -el sur le nouvel exécutable montre des résultats bien plus intéressants, car car la commande révèle alors un arsenal de fonctionnalités malveillantes potentiellement utilisées par le malware (la liste n’est pas exhaustive) :
1) Collecte d’informations
- Données système (configuration matérielle, antivirus)
- Identifiants de services populaires (Telegram, Discord, Steam)
- Données de navigation (cookies)
- Contenu du presse-papier
2) Surveillance active
- Enregistrement des frappes (keylogging)
- Captures d’écran
- Enregistrement audio via microphone
Fig. 6 : Exemples d’éléments indiquant un monitoring d’activités
3) Contrôle et persistance
- Exécution de commandes PowerShell et CMD
- Planification de tâches automatisées
- Modification du registre système
- Communication avec le C2 via requêtes HTTP POST
3. Identification du malware : DCRat
La présence d’un en-tête encodé en base64 nous donne le nom de cette famille de malware :
Nous savons désormais qu’il s’agit de DCRat, ou Dark Crystal RAT, un cheval de Troie d’accès à distance (Remote Access Trojan) originaire de Russie, connu pour être l’une des familles de malwares les moins chères du marché (le premier prix d’achat commence aux alentours de 10euros). Présent depuis 2018, ce malware a notamment été aperçu au début du conflit ukraino-russe, en outil de déstabilisation des forces ukrainiennes. Comme il existe une littérature abondante à son sujet, le but ici ne sera pas de dresser une liste complète de ses fonctionnalités.
Notons cependant que DCRat reste une menace active et continue à évoluer, tant dans ses méthodes de diffusion que ses méthodes d’obfuscation.
4. Automatisation de l’extraction des IOC
D’où viennent ces nouvelles chaînes de caractères ?
Afin de protéger l’échantillon de l’analyse statique, .NET Reactor a chiffré toutes les chaînes de caractères présentes dans le code source : celles-ci sont d’abord agrégées au sein de l’une des ressources au format [ taille de la chaîne (4 octets) ][ valeur de la chaîne ], puis chaque bloc de 4 octets est XORé avec un entier généré dynamiquement. Cet entier s’obtient grâce à trois éléments distincts :
- Une clé initiale
- Un vecteur d’initialisation (IV)
- Une valeur obtenue pendant l’exécution
Une fois la ressource chiffrée intégralement, toutes les références aux chaînes dans le code sont remplacées par des appels à une fonction de déchiffrement, qui ne les restaure qu’au moment de l’exécution :
Fig. 10 : Fonction utilisant la ressource avant désobfuscation
Que faire des dernières chaînes encore obfusquées ?
Il est nécessaire d’identifier, d’isoler et d’analyser l’utilisation de ces chaînes au sein du code.
Trois chaînes spécifiques ont été sélectionnées en raison de leur taille considérable et de leur passage à-travers un nombre important de fonctions :
Class95 et Class104 sont omniprésentes et modifient, entre autres, ces trois chaînes.
En les examinant de plus près, on leur découvre plusieurs fonctions internes :
- Conversion depuis la base-64 (Class95.smethod_5)
- Décompression (grâce à GZip) (Class95.smethod_6)
- Inversion des caractères (Class104.smethod_5)
- Application d’un dictionnaire (Class95.WhHkltotnc), dont les clés-valeurs semblent dériver de l’une des chaînes chiffrées
Les chaînes 1 et 3 nécessitent justement un dictionnaire pour être lisibles, à la différence de la chaîne 2.
En appliquant les opérations trouvées dans le code sur la chaîne 2 dans CyberChef (pour un résultat plus visuel), voici ce que l’on obtient :
Ces éléments peuvent être divisés en trois parties distinctes, toutes au format JSON :
- Un dictionnaire SCRT à utiliser pour déchiffrer chaîne 3
- Un dictionnaire PCRT pour déchiffrer chaîne 1
- Des éléments de configuration du malware, notamment le nom de son mutex, « DCR_MUTEX-vmlP5VtILfN63WggN4aM », ainsi que certaines des fonctionnalités activées (récupération des cookies et des mots de passe, captures d’écran, etc.)
Un simple script python a permis de déchiffrer rapidement le contenu des deux chaînes restantes en appliquant les mêmes étapes que pour chaîne 2, tout en rajoutant le dictionnaire correspondant :
- chaîne 1 correspond aux plugins optionnels accompagnés de leurs configurations
- chaîne 3 correspond aux serveurs distants
Notons également que la configuration des plugins et la dernière partie des URLs étaient toutes deux à convertir depuis la base-64 et à inverser, pour obtenir un résultat exploitable – une énième couche d’obfuscation qui trahit la volonté de complexifier encore plus une détection automatisée.
Automatisation et mise à l’échelle de l’extraction
Au cours de nos recherches, nous sommes tombés sur plusieurs échantillons DCRat partageant la même structure : obfusqués par .NET Reactor et contenant trois chaînes de caractères commençant par « H4sIAA », après désobfuscation. Nous avons choisi de créer une règle YARA fondée sur les chaînes de caractères au format wide char présentes dans le binaire avant désobfuscation. Vient ensuite la création d’un script permettant deux choses : désobfusquer les binaires validés par la règle, puis extraire les configurations de tous les binaires désobfusqués avec succès. C# a été utilisé afin d’intégrer quelques-unes des fonctionnalités de de4dot (notamment l’émulation de code IL) :
Le script produit de bons résultats pour tous les exécutables validés par la règle YARA, récupérés sur VirusTotal et MalwareBazaar :
La longueur de chaîne 1 étant due à la présence de plugins, il était préférable de les extraire et de n’afficher que leur hash en SHA-256.
Dernières améliorations
Un détail a cependant attiré notre attention. Pour la chaîne 3, lorsqu’ils ne sont pas accessibles immédiatement sous la forme « H1 / H2 », les C2 sont stockés en ligne grâce à l’application PasteBin, au format [C2_chiffré. Dictionnaire_chiffré], obfusqués avec les mêmes techniques vues précédemment, c’est-à-dire inversion des caractères, conversion depuis la base64 et utilisation d’un dictionnaire :
En outre, puisque qu’aucun URL obtenu n’est identique et que les noms semblent avoir été générés aléatoirement grâce à un DGA (Domain Generator Algorithm), il a semblé pertinent de retrouver les adresses IP contactées, afin de préparer le terrain pour une meilleure contextualisation des données. En effet, il est plus facile de regrouper les échantillons selon l’utilisation d’une même adresse IP, plutôt qu’en collectionnant un grand nombre d’URL différents :
Comment organiser et mettre en relation tous les IOC obtenus ?
Il est très facile de customiser la sortie du script pour mieux l’intégrer dans un logiciel interne. On peut sélectionner les serveurs, les IP, les mutexes ou les hash, selon les besoins, puis transformer la sortie en JSON.
Dans cet exemple, nous avons regroupé les IOC au sein d’un JSON au format STIX (Structured Threat Information eXpression) :
Fig. 24 : mise en image d’un fichier STIX dans l’outil STIX Visualizer
Puisque notre objectif reste avant tout la valorisation et la mise en contexte d’informations critiques, il est important de savoir adapter le type et le format des informations obtenues afin de créer une vision globale, essentielle à toute investigation cyber. La récupération des IOC de plusieurs malwares peut rapidement mener à un faisceau d’indices permettant l’identification d’acteurs malveillants, de zones géographiques ou de secteurs industriels ciblés par la menace.
Conclusion
Cette analyse nous a permis de :
- Comprendre les techniques d’obfuscation utilisées par DCRat
- Identifier des éléments de configuration critiques (serveurs C2, mutex, modules additionnels)
- Automatiser le processus d’extraction pour traiter un grand volume d’échantillons
La création d’un script d’automatisation montre l’importance cruciale de la mise à l’échelle et de l’intégration des capacités d’analyse dans des systèmes globaux afin de traiter efficacement les menaces émergentes. L’adoption de formats standardisés tels que STIX pour la gestion des IOC permet non seulement une caractérisation précise, mais aussi une coopération renforcée au sein de la communauté de la cybersécurité.
Face à des menaces en constante évolution, comme l’illustre l’exemple de DCRat qui s’est transformé à de nombreuses reprises, il est essentiel d’adopter une approche combinant rigueur méthodologique et innovation technique. Chaque IOC découvert, chaque configuration extraite et chaque outil perfectionné représente une information précieuse qui vient enrichir notre base de connaissances sur les tactiques, techniques et procédures (TTP) employées par les acteurs malveillants.
En consolidant systématiquement ces informations, l’équipe CTI de Chapsvision cherche à améliorer la capacité collective à détecter, analyser et atténuer proactivement les menaces, tout en se préparant aux évolutions futures des techniques utilisées par les cybercriminels.
Règle YARA :
rule dcrat_dotnetReactObfuscated {
meta:
description = "Détecte les configurations DCRat obfusquées avec .Net Reactor"
author = "Chapsvision-CyberGov"
hash = "de04994b9650e7f00f8f264ade023d530d292ab03ad672e0101d8e32b886d575"
hash = "3fa6ddcabcb03763ef1887117e16ebdf0553a1cc2a16b58bdecaba0735d4e60a"
hash = "0ade415868175c73d51330fb85ddcb58654ccd18254066fc1f9861482f649adb"
hash = "5d3aa443debb15bdf756b94980e0a6bcbef950edd72941905f70eded5238590c"
hash = "156a45b0743164c9fa027d10bcfc1f1a6ec3673cadf8c4b82f996e1bd12f95ed"
strings:
$s1 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" wide
$s2 = "GetDelegateForFunctionPointer" wide
$s3 = "file:///" wide
$s4 = "{11111-22222-20001-00001}" wide
$s5 = "{11111-22222-20001-00002}" wide
$s6 = "{11111-22222-30001-00001}" wide
$s7 = "{11111-22222-30001-00002}" wide
$s8 = "{11111-22222-40001-00001}" wide
$s9 = "{11111-22222-40001-00002}" wide
$s10 = "040904B0" wide
$s11 = "FileVersion" wide
$s12 = "5.15.2.0" wide
$s13 = "dclib" wide
$s14 = "H4sIAAA" wide
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and
(
all of ($s1, $s2, $s3, $s4, $s5, $s6, $s7, $s8, $s9, $s10, $s11, $s12)
or
$s13 and
#s14 == 3
)
}
Fig.25 : Règle YARA utilisée pour détecter les échantillons DCRat obfusqués par .NET Reactor
IOC :
(Re)découvrez notre précédent article :