Version de test Windows
Version de test Linux
Drltrace est un traceur d'appels API dynamique pour les applications Windows et Linux. Drltrace est construit sur le cadre d'instrumentation binaire dynamique DynamoRIO. Drltrace a été initialement implémenté par Derek Bruening et distribué avec les frameworks DynamoRIO et DrMemory. Ce référentiel contient une version autonome de drltrace avec des scripts et des documents supplémentaires sur la façon de l'utiliser pour l'analyse des logiciels malveillants. La version de version peut être téléchargée ici.
L'utilisation de drltrace est très simple. Un utilisateur doit spécifier un répertoire de journaux et le nom d'un processus cible de la manière suivante :
drltrace -logdir . -- calc.exe
C'est tout, l'outil injectera les DLL requises dans le processus cible, démarrera l'instrumentation et enregistrera en parallèle des informations sur tous les appels de bibliothèque exécutés dans le processus cible :
~~43600~~ msvcrt.dll!__wgetmainargs
arg 0: 0x010d2364
arg 1: 0x010d2368
and return to module id:0, offset:0x193a
~~43600~~ ntdll.dll!EtwEventRegister
arg 0: 0x002ff994
arg 1: 0x010d1490
and return to module id:0, offset:0x157e
~~43600~~ ntdll.dll!EtwEventSetInformation
arg 0: 0x007b4b40
arg 1: 0x00000033
and return to module id:0, offset:0x15a1
~~43600~~ SHELL32.dll!ShellExecuteW
arg 0: <null> (type=<unknown>, size=0x0)
arg 1: <null> (type=wchar_t*, size=0x0)
arg 2: calculator:// (type=wchar_t*, size=0x0)
arg 3: <null> (type=wchar_t*, size=0x0)
arg 4: <null> (type=wchar_t*, size=0x0)
arg 5: 0x1 (type=int, size=0x4)
and return to module id:0, offset:0x167d
Le format de la sortie est simple et peut être facilement analysé par un script externe :
~~[thread id]~~ [dll name]![api call name]
arg [arg #]: [value] (type=[Windows type name], size=[size of arg])
and return to module id:[module unique id], offset:[offset in memory]
L'analyse avec grep
peut être effectuée lorsque l'argument -grepable
est utilisé ; cela imprime les noms de fonctions et les arguments sur une seule ligne :
~~4824~~ KERNELBASE.dll!CreateFileW {0: C:WindowsFontsstaticcache.dat (type=wchar_t*, size=0x0)} {1: 0x80000000 (type=DWORD, size=0x4)} {2: 0x3 (type=DWORD, size=0x4)} {3: 0x005cde8c (type=<unknown>*, size=0x0)} {4: 0x3 (type=DWORD, size=0x4)} {5: 0x80 (type=DWORD, size=0x4)}
Le tableau des identifiants uniques du module est imprimé à la fin du fichier journal :
Module Table: version 3, count 70
Columns: id, containing_id, start, end, entry, checksum, timestamp, path
0, 0, 0x010d0000, 0x010da000, 0x010d1b80, 0x0000f752, 0xb5fe3575, C:WindowsSysWOW64calc.exe
1, 1, 0x6d4c0000, 0x6d621000, 0x6d563940, 0x00136d65, 0x59ce1b0b, C:UsersMaxDownloadsdrltracedrltracedynamoriolib32releasedynamorio.dll
2, 2, 0x73800000, 0x73975000, 0x7380dbf7, 0x00000000, 0x59ce1b0f, C:UsersMaxDownloadsdrltracedrltracebinrelease/drltracelib.dll
3, 3, 0x742f0000, 0x742fa000, 0x742f2a00, 0x0000c877, 0x0adc52c1, C:WindowsSystem32CRYPTBASE.dll
4, 4, 0x74300000, 0x74320000, 0x7430c9b0, 0x0002c617, 0x245970b4, C:WindowsSystem32SspiCli.dll
5, 5, 0x74410000, 0x74431000, 0x74416900, 0x0002a940, 0x88a53c1d, C:WindowsSystem32GDI32.dll
6, 6, 0x74440000, 0x74500000, 0x7446fb20, 0x000cc410, 0xd343d532, C:WindowsSystem32RPCRT4.dll
7, 7, 0x74500000, 0x74525000, 0x745047d0, 0x00026737, 0xa39c8991, C:WindowsSystem32IMM32.DLL
8, 8, 0x74550000, 0x745c7000, 0x7456e8a0, 0x00081857, 0x73b971e1, C:WindowsSystem32advapi32.dll
9, 9, 0x748f0000, 0x74929000, 0x748febd0, 0x00045303, 0xa58be652, C:WindowsSystem32cfgmgr32.dll
10, 10, 0x74930000, 0x75c78000, 0x74aa09d0, 0x01377aa6, 0x4b39926b, C:WindowsSystem32SHELL32.dll
Drltrace peut facilement filtrer les appels entre bibliothèques et imprimer uniquement les appels d'API effectués à partir du module principal (ou à partir d'un tas) d'une application cible en spécifiant l'option -only_from_app
qui est très utile dans le cas d'applications générant d'énormes journaux. Pour un contrôle plus granulaire, l'option -filter
permet à l'utilisateur de spécifier un fichier de configuration de filtre afin de filtrer des fonctions spécifiques sur liste blanche, ou d'ignorer les fonctions sur liste noire (voir le fichier filter.config pour des exemples). Drltrace dispose également de plusieurs scripts externes utiles pour filtrer les appels d'API pour certaines bibliothèques et imprimer uniquement les appels et les chaînes d'API potentiellement intéressants.
Les modules principaux de Drltrace sont distribués sous BSD.
Certains fichiers nécessaires à drltrace sont distribués sous LGPL. Voir les fichiers sources pour plus de détails.
L'analyse des logiciels malveillants n'est pas une tâche facile. Des packers de logiciels sophistiqués comme Themida et Armadillo et bien sûr des dizaines de packers anonymes écrits par des auteurs de logiciels malveillants, ainsi que le cryptage du code et des données facilitent considérablement (dans certains cas, le rendant complètement impossible) l'ingénierie inverse statique de tels échantillons, compliquant ainsi la vie des analystes de logiciels malveillants. Dans ce cas, le suivi des appels API peut réduire considérablement le temps nécessaire pour comprendre une intention malveillante réelle et révéler de nombreux détails techniques sur le code malveillant protégé.
Bien que la technique traditionnelle d'accrochage d'API ait été mise en œuvre avec succès dans plusieurs solutions, cette approche est bien étudiée par les auteurs de logiciels malveillants et peut être facilement détectée et/ou contournée. De plus, ces outils sont distribués sous forme d'applications GUI autonomes et lourdes (en tant que produits propriétaires) qui ne sont pas souvent faciles à intégrer dans le flux de travail d'analyse des logiciels malveillants existant.
Si nous regardons le monde Linux, il existe un merveilleux outil appelé ltrace. En utilisant une seule commande bash, nous pouvons facilement obtenir la trace complète des appels API d'un certain exécutable.
Pourquoi n'avons-nous pas un tel outil (comme ltrace sous Linux) pour Windows qui est également transparent contre les astuces anti-recherche utilisées par les logiciels malveillants modernes ?
Il s'avère qu'il existe une technique qui peut nous aider à disposer d'un tel outil pour Windows et à tracer les appels d'API de manière transparente vers le programme exécuté. Cette technique est appelée instrumentation binaire dynamique, également appelée DBI. DBI est une technique d'analyse du comportement d'une application binaire au moment de l'exécution grâce à l'injection de code d'instrumentation.
Cependant, l'application de DBI pour l'analyse des logiciels malveillants est injustement limitée par l'automatisation du déballage et par plusieurs preuves de concept pour les instructions, les blocs de base et le traçage des appels de fonction. À notre connaissance, drltrace est un premier outil de traçage des appels API basé sur DBI qui peut être utilisé en pratique pour l'analyse des malwares. Nous avons fourni plusieurs exemples d'analyse de malwares dans notre wiki où nous décrivions comment drltrace permettait de révéler en quelques minutes de nombreux détails techniques internes sur des échantillons malveillants sophistiqués sans même démarrer IDA ou débogueur.
-logdir [ .] Log directory to print library call data
-only_from_app [ false] Reports only library calls from the app
-follow_children [ true] Trace child processes
-print_ret_addr [ false] Print library call's return address
-num_unknown_args [ 2] Number of unknown libcall args to print
-num_max_args [ 6] Maximum number of arguments to print
-default_config [ true] Use default config file.
-config [ ""] The path to custom config file.
-filter [filter.config] The path of the whitelist/blacklist file.
-ignore_underscore [ false] Ignores library routine names starting with "_".
-help [ false] Print this message.
-version [ false] Print version number.
-verbose [ 1] Change verbosity.
-use_config [ true] Use config file
-grepable [ false] Grepable output
Drltrace prend en charge les fichiers de configuration externes dans lesquels un utilisateur peut décrire comment drltrace doit imprimer les arguments pour certains appels d'API.
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
Chaque argument de fonction doit être séparé par |
. Le premier argument est le type de retour, le deuxième argument est le nom de la fonction lui-même et le reste sont les arguments de la fonction. Un jeton __out
est utilisé pour marquer les arguments de sortie et ___inout
est utilisé pour marquer les arguments d'entrée+de sortie.
Vous pouvez trouver des exemples d'utilisation de drltrace pour l'analyse de logiciels malveillants complexes sur notre page Wiki.
Pour faciliter le travail avec les fichiers journaux, nous avons implémenté un script appelé api_calls_viz.py
qui peut être utilisé pour générer des images RVB où chaque couleur de pixel représente un appel API unique. Par exemple, l'image ci-dessous représente le fichier journal du malware WannaCry.
Les grandes zones vertes sur l'image représentent les appels API ( wcscmp/wcsicmp
) qui sont utilisés pour sélectionner des fichiers avec des extensions intéressantes (par exemple docx, xls, py) pour les chiffrer. Les zones violettes représentent les appels API ( FindFirstFile/FindNextFile/CryptEncrypt
) qui sont utilisés pour énumérer et chiffrer les fichiers et dossiers sur le disque.
Le script peut également générer une représentation HTML de l'image RVB générée où chaque élément peut être sélectionné pour afficher un nom d'appel API.
Fichier HTML brut.
Consultez le répertoire api_calls_viz
pour plus de détails.
Vous pouvez trouver un manuel détaillé sur cette page Wiki.
Windows, Linux (macOS à l'avenir).
x86, x64 (ARM sur la liste).
Bibliothèque standard C et C++ (et scripts de gestion des logs écrits en Python).
Nous avons décidé d'implémenter notre traceur d'appels API au-dessus du cadre d'instrumentation binaire dynamique DynamoRIO. Drltrace demande à DynamoRIO d'effectuer l'instrumentation de l'appel LoadLibrary pour pouvoir gérer les nouvelles bibliothèques chargées par le processus cible. Lorsque le processus tente de charger une nouvelle bibliothèque, DynamoRIO redirige le flux de contrôle vers drltracelib.dll
. À son tour, drltrace énumère les fonctions exportées dans la DLL nouvellement chargée et enregistre un rappel spécial pour chacune d'elles. Ainsi, si une fonction exportée devait être appelée par un malware, le rappel de drltrace sera exécuté avant cette fonction et l'outil pourra enregistrer toutes les informations requises telles qu'un nom de fonction et des arguments. Un autre rappel peut être enregistré après la fonction pour enregistrer les résultats de l'exécution.
Pourquoi pas Intel Pin ? Nous avons décidé d'utiliser DynamoRIO motivé par les raisons suivantes :
-syswide_on
de drrun.exe
). Cependant, à l’avenir, il sera nécessaire de mettre en œuvre un support spécial dans drltrace pour de telles situations.Notre outil de suivi des problèmes contient plus de détails sur l'avenir de drltrace.
Maksim Shudrak https://github.com/mxmssh
Derek Bruening https://github.com/derekbruening
Joe Testa https://github.com/jtesta