Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
DotDumper — Un décompresseur et enregistreur automatique pour les fichiers ciblant le framework DotNet | Kitploit
Outils/GitHubGitHub/advanced-threat-research/dotdumper
Analyse Dynamique (Sandboxing)Criminalistique MémoireRétro-ingénierieDébogueursAnalyse ForensiqueAnalyse de MalwareAnalyse de Binaires
GitHubadvanced-threat-research/dotdumper

DotDumper

Un décompresseur et enregistreur automatique pour les fichiers ciblant le framework DotNet

Voir le dépôt
266315il y a 3 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
The DotDumper logo, a dumping truck

DotDumper

Un désemballeur et enregistreur automatique pour les fichiers ciblant DotNet Framework ! Cet outil a été présenté au Black Hat USA 2022. Au Black Hat Asia 2023, DotDumperGUI et DotDumperNative ont été publiés, accompagnés de la version 1.1-stable de DotDumper. Ces trois outils sont conçus pour être utilisés ensemble, où DotDumper 1.1-stable nécessite la présence des DLL de DotDumperNative, tandis que DotDumperGUI est destiné à servir d'interface utilisateur graphique pour ouvrir et filtrer la sortie JSON des exécutions de DotDumper.

La détection et la classification automatiques et fiables de tout fichier donné sont souvent considérées comme le Graal de l'analyse de logiciels malveillants. Les essais et tribulations pour y parvenir sont nombreux, c'est pourquoi la création d'un tel système est hautement estimée. En ce qui concerne les binaires ciblant DotNet, notre nouvel outil open source DotDumper vise à aider dans plusieurs étapes cruciales du processus : l'enregistrement (en mémoire) de l'activité, le vidage de segments mémoire intéressants et l'extraction de caractéristiques de l'échantillon donné.

Table des matières

  • Pourquoi DotDumper ?
  • Fonctionnalités
    • Utilisation de l'interface en ligne de commande
Enregistrement et vidage
  • Réflexion
  • Hooks (non) managés
  • Facilement extensible
  • Prise en charge du délai d'attente du sandbox
  • Différences avec les outils connus
  • Travaux futurs
  • Pourquoi DotDumper ?

    En bref, le désemballage manuel est un processus fastidieux qui consomme un temps disproportionné pour les analystes. Les binaires obscurcis augmentent encore le temps qu'un analyste doit passer à désemballer un fichier donné. En montant en échelle, les organisations ont besoin de nombreux analystes qui dissèquent quotidiennement des logiciels malveillants, probablement en combinaison avec un sandbox évolutif. Ce temps précieux perdu pourrait être utilisé pour fouiller des campagnes ou des échantillons intéressants afin de découvrir de nouvelles menaces, plutôt que le malware générique banal qui est largement répandu. Après tout, les analystes recherchent les quelques aiguilles dans la botte de foin.

    Alors, quelle différence DotDumper apporte-t-il ? Exécuter un échantillon de malware basé sur DotNet via DotDumper fournit des fichiers journaux des appels de fonctions cruciaux, contextualisants et courants dans trois formats (texte brut lisible, JSON et XML), ainsi que des copies de segments mémoire utiles. Ainsi, un analyste peut parcourir le journal des appels de fonctions. De plus, les fichiers vidés peuvent être scannés pour les classer, fournissant ainsi un aperçu supplémentaire de l'échantillon de malware et des données qu'il contient. Cela réduit le temps crucial pour les processus de triage et de réponse aux incidents, et libère du temps pour les analystes SOC et les chercheurs pour des besoins d'analyse plus sophistiqués.

    Fonctionnalités

    Pour enregistrer et vider les appels de fonctions contextualisants et leurs résultats, DotDumper utilise un mélange de réflexion et de hooks managés, le tout écrit en pur C#. Ci-dessous, les fonctionnalités clés seront mises en évidence et développées, en combinaison avec des extraits des résultats de DotDumper sur un échantillon du voleur AgentTesla empaqueté, dont les hachages sont ci-dessous.

    Type de hachageValeur du hachage
    SHA-256b7512e6b8e9517024afdecc9e97121319e7dad2539eb21a79428257401e5558d
    SHA-1c10e48ee1f802f730f41f3d11ae9d7bcc649080c
    MD-523541daadb154f1f59119952e7232d6b

    Utilisation de l'interface en ligne de commande

    DotDumper est accessible via une interface en ligne de commande, avec une variété d'arguments. L'image ci-dessous montre le menu d'aide. Notez que tous les arguments ne seront pas discutés, mais plutôt les plus utilisés.

    Menu de l'interface en ligne de commande de DotDumper

    L'exigence minimale pour exécuter un échantillon donné est de fournir l'argument "-file", accompagné d'un nom de fichier ou d'un chemin de fichier. Si un chemin complet est donné, il est utilisé. Si un nom de fichier est donné, le répertoire de travail courant est vérifié, ainsi que le dossier de l'exécutable de DotDumper.

    Sauf si un nom de répertoire est fourni, le nom du dossier "-log" est défini égal au nom de fichier de l'échantillon sans l'extension (le cas échéant). Le dossier se trouve dans le même dossier que celui où réside DotDumper, et c'est là que les journaux et les fichiers vidés seront sauvegardés.

    Dans le cas d'une bibliothèque, ou d'un point d'entrée alternatif dans un binaire, il faut remplacer le point d'entrée en utilisant "-overrideEntry true". De plus, il faut fournir la classe entièrement qualifiée, qui inclut l'espace de noms en utilisant "-fqcn My.NameSpace.MyClass". Cela indique à DotDumper quelle classe sélectionner, et c'est là que le nom de la fonction fournie (en utilisant "-functionName MyFunction") est récupéré.

    Si la fonction sélectionnée nécessite des arguments, il faut fournir le nombre d'arguments en utilisant "-argc" et le nombre d'arguments requis. Les types et valeurs des arguments doivent être fournis comme "string|myValue int|9". Notez que lorsque des espaces sont utilisés dans les valeurs, l'argument sur l'interface en ligne de commande doit être encapsulé entre guillemets pour garantir qu'il soit passé comme un seul argument.

    D'autres options moins fréquemment utilisées telles que "-raceTime" ou "-deprecated" sont sûres dans leurs paramètres par défaut mais pourraient nécessiter des ajustements à l'avenir en raison des changements dans DotNet Framework. Elles sont actuellement exposées dans l'interface en ligne de commande pour permettre facilement des modifications, si nécessaire, même si l'on utilise une version plus ancienne de DotDumper le moment venu.

    Enregistrement et vidage

    L'enregistrement et le vidage sont les deux fonctionnalités principales de DotDumper. Pour minimiser le temps d'analyse, l'enregistrement doit fournir un contexte à l'analyste. Cela se fait en fournissant à l'analyste les informations suivantes pour chaque appel de fonction enregistré :

    • Une trace de pile basée sur l'appelant de la fonction
    • Des informations concernant l'objet assembly d'où provient l'appel, telles que le nom, la version et les hachages cryptographiques
    • L'assembly parent, d'où provient l'appel s'il ne s'agit pas de l'échantillon original
    • Le type, le nom et la valeur des arguments de la fonction
    • Le type, le nom et la valeur de la valeur de retour de la fonction, le cas échéant
    • Une liste des fichiers qui sont vidés sur le disque et qui correspondent à l'appel de fonction donné

    Notez que pour chaque fichier vidé, le nom du fichier est égal au hachage SHA-256 du fichier.

    Pour clarifier ce qui précède, un extrait d'un journal est donné ci-dessous. L'extrait montre les détails pour l'échantillon AgentTesla mentionné précédemment, où il charge le deuxième étage en utilisant la fonction Assembly.Load de DotNet.

    Le journal pour un appel de fonction Assembly.Load(byte[] rawAssembly) intercepté

    Premièrement, l'heure système locale est donnée, ainsi que le type de retour, le nom et le(s) argument(s) de la fonction originale. Deuxièmement, la trace de pile est donnée, montrant que la fonction principale de l'échantillon mène à un constructeur, initialise les composants et appelle deux fonctions personnalisées. La fonction Assembly.Load a été appelée depuis "NavigationLib.TaskEightBestOil.GGGGGGGGGGGGGGGGGGGG(String str)". Cela fournit un contexte à l'analyste pour trouver le code autour de cet appel si cela l'intéresse.

    Ensuite, des informations concernant l'ordre des appels d'assembly sont données. Plus il y a d'étages chargés, plus il devient complexe de voir par quels étages l'appel est passé. On s'attend normalement à ce qu'un étage charge le suivant, mais dans certains cas, les étages ultérieurs utilisent les étages précédents de manière non linéaire. De plus, des informations concernant l'assembly d'origine sont données pour enrichir davantage les données pour l'analyste.

    Ensuite, le hachage parent est donné. Le parent d'un étage est l'étage précédent, qui dans cet exemple n'est pas encore présent. Le nouvel étage chargé aura cet étage comme parent. Cela permet à l'analyste de corréler plus facilement les événements.

    Enfin, le type de retour et la valeur de la fonction sont stockés, ainsi que le type, le nom et la valeur de chaque argument passé à la fonction hookée. Si une variable a une taille supérieure à 100 octets, elle est stockée sur le disque à la place. Une référence est alors insérée dans le journal pour référencer le fichier, plutôt que d'afficher la valeur. Le seuil a été fixé pour éviter les problèmes d'affichage du journal, car certains tableaux ont des milliers d'indices.

    Réflexion

    Selon la documentation de Microsoft, la réflexion est mieux résumée) comme "[...] fournit des objets qui encapsulent des assemblages, des modules et des types". En bref, cela permet la création et l'invocation dynamiques de classes et de fonctions DotNet à partir de l'échantillon de malware. DotDumper contient un chargeur réflexif qui permet à un analyste de charger et d'analyser à la fois des exécutables et des bibliothèques, tant qu'ils sont basés sur DotNet Framework.

    Pour utiliser le chargeur, il faut choisir de remplacer le point d'entrée dans l'interface en ligne de commande, spécifier la classe (y compris l'espace de noms dans lequel elle réside) et le nom de la fonction dans un fichier donné. Optionnellement, on peut fournir des arguments à la fonction spécifiée, pour tous les types natifs et leurs tableaux. Des exemples de types natifs sont int, string, char, et des tableaux tels que int[], string[], et char[]. Tous les arguments doivent être fournis via l'interface en ligne de commande, où le type et la valeur doivent être spécifiés.

    Ne pas remplacer le point d'entrée entraîne l'utilisation du point d'entrée par défaut. Par défaut, un tableau de chaînes vide est passé à la fonction principale de l'échantillon, comme si l'échantillon était exécuté sans arguments. De plus, la réflexion est souvent utilisée par les chargeurs pour invoquer une fonction donnée dans une classe donnée de l'étage suivant. Parfois, des arguments sont également passés, qui sont utilisés plus tard pour déchiffrer une ressource. Dans l'échantillon AgentTesla mentionné précédemment, ce scénario exact se produit. Les hooks liés à l'invocation de DotDumper enregistrent ces occurrences, comme on peut le voir ci-dessous.

    Le hook intercepté pour invoquer le deuxième étage

    Le nom de la fonction dans la première ligne n'est pas une fonction interne de DotNet Framework, mais plutôt un appel à une fonction spécifique dans le deuxième étage. Les types et noms des trois arguments sont répertoriés dans la signature de la fonction. Leurs valeurs peuvent être trouvées dans la section des informations sur les arguments de la fonction. Cela permettrait à un analyste de charger le deuxième étage dans un chargeur personnalisé avec les valeurs données pour les arguments, ou même de le faire en utilisant DotDumper en chargeant l'étage précédemment vidé et en fournissant les arguments.

    Hooks (non) managés

    Avant d'aborder les hooks managés, il faut comprendre comment fonctionnent les hooks. Deux variables principales sont à considérer ici : la fonction cible et une fonction contrôlée appelée le hook. En termes simples, la mémoire à la fonction cible (par exemple Assembly.Load) est modifiée pour sauter vers le hook à la place. Ainsi, le flux d'exécution du programme est détourné. Le hook peut alors effectuer des actions arbitraires, éventuellement appeler la fonction originale, après quoi il retourne l'exécution à l'appelant avec une valeur de retour si nécessaire. Le diagramme ci-dessous illustre ce processus.

    Le schéma de l'installation et de l'utilisation d'un hook

    Savoir ce que sont les hooks est essentiel pour comprendre ce que sont les hooks managés. Le code managé est exécuté dans un environnement virtuel et managé, tel que le runtime DotNet ou la machine virtuelle Java. Obtenir l'adresse mémoire où réside la fonction managée diffère d'un langage non managé comme le C. Une fois les adresses mémoire correctes pour les deux fonctions obtenues, le hook peut être défini en accédant directement à la mémoire en utilisant du C# non sécurisé, ainsi que le service d'interopérabilité de DotNet pour appeler les fonctionnalités natives de l'API Windows.

    Depuis DotDumper v1.1-stable, DotDumper peut également hooker des fonctions non managées (ou natives, si vous préférez). La redirection de fonction peut être n'importe quelle combinaison allant et venant de fonctions managées et non managées, avec une mise en garde importante. Toute fonction non managée qui utilise un hook managé ne pourra pas lire correctement les valeurs de la pile. Ainsi, un composant natif est nécessaire (appelé DotDumperNative). Ce composant communique via un pipe nommé avec DotDumper lui-même, utilisant ainsi son système de journalisation centralisé, tout en interceptant les appels non managés avec accès aux arguments de fonction trouvés sur la pile.

    Facilement extensible

    Étant donné que DotDumper est écrit en pur C# sans aucune dépendance externe, on peut facilement étendre le framework en utilisant Visual Studio. Le code est documenté dans ce blog, sur GitHub, et dans les classes, les fonctions, et en ligne dans le code source. Ceci, combiné à un schéma de nommage clair, permet à quiconque de modifier l'outil selon ses besoins, minimisant le temps et l'effort nécessaires pour comprendre l'outil. Au lieu de cela, il permet aux développeurs et aux analystes de concentrer leurs efforts sur l'amélioration de l'outil.

    Prise en charge du délai d'attente du sandbox

    Bien que la fonctionnalité de prise en charge du délai d'attente du sandbox n'ait pas été modifiée, elle n'avait pas été documentée auparavant. Étant donné que DotDumper exécute le fichier qui lui est fourni, son exécution se poursuit jusqu'à ce que l'échantillon se termine. Les logiciels malveillants entrent souvent dans un état "d'attente", où une certaine condition doit être remplie avant de se réactiver, ou bien le malware continue son exécution dans un processus différent (avec l'aide de l'injection de processus). Par exemple, un thread nouvellement créé dans un processus éviscéré ne retourne qu'une fois terminé.

    Pour éviter les blocages, DotDumper dispose d'un gestionnaire de stagnation. Chaque fois que les résultats d'un hook sont enregistrés, un compteur est incrémenté. Si ce compteur reste inchangé après trois intervalles consécutifs de 20 secondes, DotDumper suppose qu'un état de stagnation est rencontré. Dans ce cas, l'heure du système est réglée sur 30-12-2200 12:00 pour forcer le délai d'attente du sandbox, après quoi il notifie l'analyste via le journaliseur et se termine. Le délai d'attente du sandbox se produit lorsque le temps écoulé entre la date actuelle et la date nouvellement définie dépasse les 5 ou 10 minutes habituelles. Même si le temps d'exécution du sandbox est réglé sur des heures ou des jours, il est dépassé.

    La raison d'écourter l'analyse est d'économiser du temps et des ressources, car une soumission avec un délai de 10 minutes pourrait ne prendre que 2 minutes pour s'exécuter. Ainsi, on pourrait exécuter plusieurs échantillons dans le même laps de temps avec le gestionnaire de stagnation. Un aperçu de la logique du gestionnaire de stagnation est montré ci-dessous.

    Le schéma du gestionnaire de stagnation

    Différences avec les outils connus

    Maintenant que l'objectif et les fonctionnalités de DotDumper sont clairs, il peut sembler y avoir un chevauchement avec des outils publics connus tels que ILSpy, dnSpyEx, de4dot, ou pe-sieve. Notez qu'il n'y a aucune intention de proclamer qu'un outil est meilleur qu'un autre, mais plutôt de montrer en quoi les outils diffèrent.

    L'objectif de DotDumper est d'enregistrer et de vider les appels de fonctions cruciaux, contextualisants et courants des échantillons ciblant DotNet. ILSpy est un désassembleur et décompilateur DotNet, mais ne permet pas l'exécution du fichier. dnSpyEx (et son prédécesseur dnSpy) utilisent ILSpy comme composant de désassemblage et de décompilation, tout en ajoutant un débogueur. Cela permet d'inspecter et de manipuler manuellement la mémoire. de4bot est uniquement utilisé pour désobfusquer les binaires DotNet, améliorant la lisibilité du code pour les yeux humains. Le dernier outil de cette comparaison, pe-sieve, est destiné à détecter et à vider les logiciels malveillants des processus en cours d'exécution, sans tenir compte du langage de programmation utilisé. Le tableau ci-dessous fournit un aperçu graphique des outils mentionnés ci-dessus.

    Le tableau récapitulatif des différents objectifs des outils

    Travaux futurs

    DotDumper est en constante révision et développement, tout étant axé sur deux domaines principaux : la correction de bugs et l'ajout de nouvelles fonctionnalités. Au cours du développement, le code a été testé, mais en raison de l'injection de hooks dans les fonctions de DotNet Framework qui peuvent être sujettes à changement, il est tout à fait possible qu'il y ait des bugs dans le code. Toute personne rencontrant un bug est invitée à ouvrir un ticket sur le dépôt GitHub, qui sera ensuite examiné. La suggestion de nouvelles fonctionnalités est également possible via le dépôt GitHub. Pour ceux qui ont un compte GitHub, ou pour ceux qui préfèrent ne pas interagir publiquement, n'hésitez pas à m'envoyer un message privé sur mon Twitter.

    Inutile de dire que si vous avez utilisé DotDumper lors d'une analyse, ou si vous l'avez utilisé de manière créative, n'hésitez pas à me contacter en public ou en privé ! Rien de tel que d'entendre parler de l'utilisation d'un outil fait maison !

    D'autres choses sont prévues pour DotDumper, et une mise à jour sera envoyée à la communauté dès qu'elle sera disponible !

    Télécharger l’outil