BumbleCrypt
Un Crypter inspiré de Bumblebee
Contexte
Le BumbleCrypt est inspiré du crypter de Bumblebee. Dans le cas de Bumblebee, la DLL principale de Bumblebee est chargée en mémoire et exécutée de la manière suivante :
- Déchiffre la charge utile et l'écrit dans le tas (Heap)
- Hooke trois API Nt - NtOpenFile, NtCreateSection et NtMapViewOfSection
- Appelle LoadLibraryW("gdiplus.dll"), ce qui déclenche les hooks inline car les trois API ci-dessus sont utilisées par LoadLibrary() pour charger n'importe quelle bibliothèque.
- Les hooks inline et LoadLibrary elle-même chargent ensuite la DLL principale de Bumblebee à la place de "gdiplus.dll"
- Enfin, le contrôle est transféré à la fonction exportée "SetPath" de la DLL principale de Bumblebee
Fonctionnement de BumbleCrypt
En analysant le crypter de BumbleBee, je me suis rendu compte que la DLL déchiffrée pouvait être chargée avec un seul hook inline sur "NtMapViewOfSection" au lieu des trois hooks inline utilisés dans le crypter de Bumblebee.
C'est ainsi que "BumbleCrypt" a été développé.
Le BumbleCrypt:
-
Le BumbleCrypt charge d'abord une ressource chiffrée depuis la section .rsrc puis déchiffre la charge utile finale de la DLL : res chiffrée -> décodage Base64 -> déchiffrement Rc4 -> déchiffrement xor
-
Le crypter utilise le tas (Heap) pour stocker la charge utile de la DLL déchiffrée, tout comme le crypter de Bumblebee
-
Une fois la charge utile finale déchiffrée, BumbleCrypt hooke l'API Nt "NtMapViewOfSection", qui est utilisée pour mapper une vue de la section dans l'espace d'adressage virtuel.
-
Ensuite, BumbleCrypt appelle LoadLibraryW("msimg32.dll"). Voyons maintenant comment le hook inline est déclenché :
- LoadLibraryW() appelle d'abord NtOpenFile pour obtenir le handle du module passé en argument
- Ensuite, elle crée un objet section avec le handle du module à l'aide de NtCreateSection
- Une fois la section créée, LoadLibrary appelle NtMapViewOfSection afin de mapper la vue d'une section en mémoire
- C'est ici que notre hook sur NtMapViewOfSection est déclenché et où la fonction proxy effectue les actions suivantes :
- Désinstalle d'abord le hook de NtMapViewOfSection
- Crée une section de la taille requise à l'aide de NtCreateSection()
- Mappe ensuite la vue de la section créée dans l'espace d'adressage virtuel à l'aide de NtMapViewOfSection (désinstallé précédemment)
- Enfin, il mappe manuellement la DLL finale préalablement déchiffrée à l'adresse de base de la section mappée en mémoire, puis retourne NTSTATUS_SUCCESS à LoadLibraryW et sort de la fonction proxy
- LoadLibraryW reçoit alors NTSTATUS_SUCCESS comme réponse à NtMapViewOfSection ainsi que l'adresse de base de la section mappée en mémoire où se trouve la DLL malveillante déchiffrée. Ensuite, LoadLibrary charge la DLL selon les valeurs de retour ; le résultat est que msimg32.dll apparaît dans les modules chargés mais pointe vers la charge utile déchiffrée. Le crypter transfère ensuite le contrôle à la DLL déchiffrée en exécutant la fonction exportée "CallPath".
-
Maintenant, si l'on regarde la capture d'écran des modules chargés par BumbleCrypt, on voit qu'elle contient "msimg32.dll", mais que l'adresse de base pointe vers la charge utile malveillante déchiffrée.
Capture d'écran


PoC - BumbleCrypter

Merci beaucoup ! J'espère que cela vous a plu =D
Ciao.
Vous pouvez me contacter sur Twitter si vous avez des retours ou des commentaires
Twitter : https://twitter.com/knight0x07
Remarque
Uniquement à des fins éducatives. C'est un projet personnel du week-end =)