Analyse LockBit
Analyse statique du code
VĂ©rification de l’Anti-Debug
Au début du programme, celui-ci vérifie que le flag NtGlobalFlag
(0x70
) est set. Si c’est le cas, le binaire rentre dans une boucle infinie.
Sinon le binaire continue son exécution.
Figure 1: VĂ©rification de l’Anti-Debug.
Chargement des DLL
Le binaire charge très peu de DLL et fonction au démarrage.
Figure 2: Liste des DLL chargés par le programme.
Si l’on continue dans le code, on peut voir des modifications de chaĂ®ne de caractère depuis la stack.
Figure 3: Ajout d’une string sur la stack.
On s’aperçoit ensuite que la chaĂ®ne est XORĂ© avec une clĂ© statique. Dans cette exemple, la clĂ© est 0x20
. On peut facilement le vérifier avec Python.
Figure 4: XOR de la chaîne avec la clé 0x20.
Figure 5: Code du binaire permettant de XOR la chaîne.
Chaque nom de DLL est encodé avec une fonction différente.
La liste des DLL encodé est la suivante :
gdiplus.dll
ws2_32.dll
shell32.dll
advapi32.dll
user32.dll
ole32.dll
netapi32.dll
gpredit.dll
oleaut32.dll
shlwapi.dll
msvcrt.dll
activeds.dll
gdiplus.dll
mpr.dll
bcrypt.dll
crypt32.dll
iphlpapi.dll
wtsapi32.dll
win32u.dll
Comdlg32.dll
cryptbase.dll
ombase.dll
winspool.drv
RĂ©solution des DLL Dynamique
Une fois le nom des DLL résolu, le binaire doit résoudre dynamiquement les adresses des DLL afin de pouvoir utiliser les fonctions.
Pour cela, il résout dans un premier temps Kernel32.dll
puis LoadLibraryA
afin de résoudre chacune des fonctions.
Figure 6: RĂ©solution des fonctions dynamiquement.
Kernel32.dll
Pour la rĂ©solution de cette DLL, le binaire rĂ©alise un hash FNV du nom de la DLL en minuscule et la vĂ©rifie avec une chaĂ®ne harcodĂ©. Si cette valeur est juste alors l’adresse de base de la DLL est retournĂ©.
Figure 7: VĂ©rification du nom de la DLL et renvoie de l’adresse de base.
Figure 8: RĂ©sultat d’un hash FNV sur la chaĂ®ne Kernel32.dll.
LoadLibraryA
Pour la résolution de cette fonction, le binaire réalise les mêmes opérations. Il boucle dans les fonctions présents dans Kernel32.dll
puis pour chaque fonction rĂ©alise son hash FNV et le compare Ă une valeur hardcodĂ©. Si la valeur est la mĂŞme alors il retourne l’adresse de base de la fonction.
Figure 9: VĂ©rification du nom de la fonction et renvoie l’adresse de base.
Figure 10: RĂ©sultat d’un hash FNV sur la chaĂ®ne LoadLibraryA.
Pas touche Ă ma langue
Le binaire va ensuite récupérer la fonction GetSystemDefaultUILanguage
afin de vĂ©rifier la langue par dĂ©faut sur l’ordinateur pour ne pas chiffrer les systèmes ayant une certaine langue par dĂ©faut.
Figure 11: RĂ©cupĂ©ration de l’adresse de base de la fonction GetSystemDefaultUILanguage
.
Figure 12: RĂ©sultat d’un hash FNV sur la chaĂ®ne GetSystemDefaultUILanguage
.
La valeur renvoyé par cette fonction est ensuite comparé avec des entiers qui correspondent à la langue du système.
Figure 13: Vérification de la langue du système.
En se basant sur la documentation officiel de microsoft, il est possible de récupérer la liste des langues comparés avec la variable.
- Azeri (Cyrillic)
- Azeri (Latin)
- Armenian - Armenia
- Belarusian
- Georgian
- Kazakh
- Kyrgyz (Cyrillic)
- Russian - Moldava
- Russian
- Tajik
- Turkmen
- Uzbek (Cyrillic)
- Uzbek (Latin)
- Ukrainian
Si la langue est dans la liste alors, le binaire résout la fonction ExitProcess
pour terminer l’exĂ©cution.
Figure 14: RĂ©solution de la fonction ExitProcess.
Figure 15: RĂ©sultat du hash FNV pour ExitProcess.
RĂ©duction des droits sur le process
Le binaire va rĂ©duire ses droits d’accès au process en modifiant sa propre liste d’accès.
Pour cela, il résout la fonction NtOpenProcess
pour avoir un handle sur son process en cours et récupère les droits via GetSecurityInfo
.
Suite Ă cela, il appelle RtlAllocateAndInitializeSid
pour crĂ©er une nouvelle structure SID afin d’appeler RtlAddAccessDeniedAce
et mettre les droits du groupe EVERYONE
Ă ACCESS_DENIED
.
Figure 16: Récupération des droits sur le process.
Enfin, le binaire va appeler RtlGetAce
afin de passer sur chaque ACE
et ajouter une ACL via RtlAddAce
. Le binaire appelle ensuite SetSecurityInfo
pour appliquer toutes les ACL et bloquer l’accès Ă tout le monde sur le process.
Figure 17: Blocage du process pour tout le monde.
Error Stack Trace
Le binaire utilise la fonction NtSetInformationProcess
afin de bloquer le moindre message d’erreur. Il utilise trois flags qui sont les suivants :
- SEM_FAILCRITICALERRORS
- SEM_NOGPFAULTERRORBOX
- SEM_NOALIGNMENTFAULTEXCEPT
Figure 18: Blocage des messages d’erreurs.
DĂ©codage de la configuration
La fonction suivante permet de décoder la configuration dans le binaire.
Un simple XOR avec la clé 0x5F
est réalisé, il est donc facile de récupérer les chaînes en réalisant un XOR sur tout le binaire.
Après avoir effectué le XOR, il est possible de récupérer une image via binwalk
. L’image affiche le logo de LockBit
.
Figure 19: RĂ©cupĂ©ration de l’image dans la configuration du binaire.
Une seule image ressort, pourtant il existe 9 fichiers.
- Fichier EMF: Contient le vecteur graphique du texte “ALL YOUR IMPORTANT FILES ARE STOLEN AND ENCRYPTED”
- Fichier EMF: Contient le vecteur graphique pour “LOCKBIT 2.0”
- Un fichier Blender Pro Medium TTF
- Un fichier Proxima Nova TTF
- Le texte du logo LockBit en PNG
- Le logo LockBit en PNG
- Un logo grand logo LockBit en PNG
- Une liste de processus
- Une liste de services
Le binaire va ensuite compter le nombre de processus dans la liste afin de les mettre dans une liste.
La configuration elle, est stocké dans une liste de bytes.
Si le byte contient 0xFF
alors l’option est activĂ© dans le cas contraire, la valeur du byte est 0xAA
.
Figure 20: Configuration du binaire.
Les index de la liste correspondent Ă :
- Index 0: DĂ©sactivation du bypass de l’UAC.
- index 1: Activation de l’auto suppression.
- Index 2: Activation de la page de log.
- Index 3: Activation du chiffrement par le réseau.
- Index 4, 5, 6: Si un de ces 3 flags est Ă
0xFF
alors le binaire se réplique via les GPO. - Index 7: Mise en place de clé de registre pour les fichiers .lockbit.
- Index 8: Impression de la page de ransom sur les imprimantes.
On remarque que contrairement aux malwares dans la nature, celui-ci à une configuration modifié.
Il n’active pas le chiffrement par le rĂ©seau et ne met pas en place de clĂ© de registre pour les fichiers .lockbit.
Escalade de privilège
Pour avoir tous les droits sur la machine courante, le binaire va utiliser une technique connu nommé Juicy Potato
pour Ă©lever ses droits. Cette technique abuse du Golden Privileges
afin d’Ă©lever ses droits en local.
Log
Le binaire va ensuite vĂ©rifier si le flag de Log est activĂ© dans la configuration. Etant donnĂ© que ce n’est pas le cas dans notre configuration, je vais passer cette partie.
Bypass UAC
Pour bypass l’UAC, le binaire va dans un premier temps vĂ©rifier qu’il est admin puis, va bypass l’UAC via l’interface COM ColorDataProxy/CCMLuaUtil
. Cette technique connu peut être trouvé sur Github.
RĂ©plication via GPO
Si le binaire est admin et qu’un des flags pour la rĂ©plication GPO est activĂ© alors, celui-ci va ensuite essayer de se rĂ©pliquer via les GPO.
Figure 21: Vérification des droits et des flags pour lancer la réplication via GPO.
Dans un premier temps, le binaire vĂ©rifie s’il est exĂ©cutĂ© sur l’Active Directory en rĂ©cupĂ©rant le nom de l’ordinateur courant et celui de l’Active Directory afin de comparer les deux.
Figure 22: Check si l’ordinateur actuel est un AD.
Si l’ordinateur actuel n’est pas un AD, alors cette partie s’arrĂŞte et le binaire n’essaye de pas de crĂ©er de GPO.
Le binaire, va ensuite rĂ©cupĂ©rer le nom DNS de l’AD ainsi que le nom du compte Administrateur afin de se connecter au domain.
Suite Ă cela, il va prĂ©parer la chaĂ®ne pour la crĂ©ation de la GPO. Pour cela, il s’aide de la format string %02X%02X%02X%02X%02X%02X%02X
utilisé sur la clé publique hardcodé dans le programme.
Cette clé publique aussi est différente des autres samples rencontré dans la nature.
A l’aide de cette chaĂ®ne, le binaire va ensuite se connecter au domaine.
Figure 23: CrĂ©ation de la chaĂ®ne Ă l’aide de la format string et connexion au domaine.
Dans cette continuitĂ©, en s’aidant de la chaĂ®ne LDAP formatĂ© juste avant, le binaire va crĂ©er la GPO dans le domaine.
Figure 24: Création de la GPO.
Une fois cette GPO créé, le binaire va créer et mettre à jour le fichier GPT.INI.
Ce fichier va contenir la chaîne suivante formaté:
[General]
Version=%s
displayName=%s
La version est contenu sur la stack est XORé ce qui permet de la récupérer. La valeur pour la version est 2621892
.
Figure 25: Contenu du fichier GPT.INI.
Maintenant, le binaire va mettre Ă jour le dossier de la GPO pour y ajouter les fichiers suivants :
- \MACHINE\Preferences\NetworkShares\NetworkShares.xml: Permet de mettre en partage réseau tous les disques du serveur.
- \MACHINE\Preferences\Services\Services.xml: Arrête une liste de service trouvé précédemment.
- \MACHINE\Preferences\Files\Files.xml: Place le binaire sur le Bureau de tous les partages.
- \MACHINE\Preferences\ScheduledTasks\ScheduledTasks.xml: Kill tous les process de la liste trouvé précédemment.
- \MACHINE\Registry.pol: Contient des clés de registre.
- \MACHINE\comment.cmtx
Les chaînes de caractères de chaque fichier sont situés sur la stack et encodé différemment à chaque fois. Pour le cas de ScheduledTasks.xml
le contenu du fichier est encodé de la manière suivante :
Figure 26: Décodage de la chaîne pour le fichier ScheduledTasks.xml.
Une fois le contenu des fichiers mise en place, le programme attend une minute avant de lancer une réplication.
Pour la réplication, le programme passe par PowerShell, cette chaîne est encodé dans la stack puis décodé avec une simple soustraction.
Figure 27: Commande de réplication PowerShell.
Le binaire vĂ©rifie Ă©videmment si la commande s’est bien dĂ©roulĂ©. En cas de problème celui-ci passe par le LDAP pour envoyer un gpudpate sur tous les postes.
Figure 28: Fin de la fonction de réplication.
Suppression des Shadows Copies
Une fois le malware implanté, celui-ci va supprimer les backups pour que le système ne soit plus récupérables. Pour cela, il va passer par des chaînes encodés sur la stack et va exécuter les commandes suivantes :
- cmd.exe /c vssadmin Delete Shadows /All /Quiet
- cmd.exe /c bcdedit /set {default} recoveryenabled No
- cmd.exe /c bcdedit /set {default} bootstatuspolicy ignoreallfailures
- cmd.exe /c wmic SHADOWCOPY /nointeractive
- cmd.exe /c wevtutil cl security
- cmd.exe /c wevtutil cl system
- cmd.exe /c wevtutil cl application
Figure 29: Exécute chacune des commandes pour supprimer les shadows copies.
Impression des notes du ransomware
Figure 30: Lancement de la fonction pour imprimer la ransomnote.
Pour ce qui est de l’impression, dans un premier temps le binaire rĂ©cupère toutes les imprimantes sur le système Ă l’aide de la fonction EnumPrintersW
.
Une fois la liste de toutes les imprimantes rĂ©cupĂ©rĂ©s, il va s’assurer de ne pas imprimer dans des fichiers en comparant les imprimantes avec les chaĂ®nes Microsoft Print to PDF
et Microsoft XPS Document Writer
.
Une fois ce filtrage effectuĂ©, le binaire va ouvrir l’imprimante, Ă©crire le contenu de la ransomnote et fermer l’imprimante pour chacune des imprimantes prĂ©sentes.
Figure 31: Fermeture de l’imprimante.
Processus de chiffrement
Le binaire appelle la fonction FindFirstVolumeW
afin de trouver le premier volume de disponible sur la machine pour commencer son chiffrement. Il itère les volumes suivants avec FindNextVolumeW
pour trouver ceux disponibles.
Figure 32: Itération pour récupérer tous les volumes.
Pour initialiser son contexte cryptographique, le binaire essaye d’importer la DLL bcrypt
, s’il Ă©choue il rĂ©cupère alors la fonction CryptAcquireContextW
présente dans la DLL advapi32
.
Figure 33: Initialisation de la fonction Cryptographique.
Le binaire crĂ©Ă© ensuite une paire de clĂ© publique et privĂ©e, Ă l’aide de l’algorithme Libsodium
. Il chiffre la clé publique et supprime la clé privée de la mémoire.
Figure 34: Génération, Chiffrement, Suppression.
Pour sa dernière partie de process, le binaire va lancer la fonction NtCreateIoCompletion
pour lui permettre d’accĂ©lĂ©rer son process de chiffrement et va lancer autant de Thread de chiffrement qu’en contient le CPU.
Durant son process, le binaire va Ă©viter de chiffrer les dossiers, fichiers et extensions suivantes:
Dossiers:
- $Windows.~bt
- intel
- msocache
- $recycle.bin
- $windows.~ws
- tor browser
- boot
- windows nt
- msbuild
- microsoft
- all users
- system volume information
- perflog
- application data
- windows
- windows.old
- appdata
- mozilla
- microsoft.net
- microsoft shared
- internet explorer
- common files
- opera
- windows journal
- windows defender
- windowsapp
- windowspowershell
- usoshared
- windows security
- windows photo viewer
Fichiers:
- ntldr
- ntuser.dat.log
- bootsect.bak
- autorun.inf
- thumbs.db
- iconcache.db
- restore-my-files.txt
Extensions:
- .386
- .cmd
- .ani
- .adv
- .msi
- .msp
- .com
- .nls
- .ocx
- .mpa
- .cpl
- .mod
- .hta
- .prf
- .rtp
- .rpd
- .bin
- .hlp
- .shs
- .drv
- .wpx
- .bat
- .rom
- .msc
- .spl
- .msu
- .ics
- .key
- .exe
- .dll
- .lnk
- .ico
- .hlp
- .sys
- .drv
- .cur
- .idx
- .ini
- .reg
- .mp3
- .mp4
- .apk
- .ttf
- .otf
- .fon
- .fnt
- .dmp
- .tmp
- .pif
- .wav
- .wma
- .dmg
- .iso
- .app
- .ipa
- .xex
- .wad
- .msu
- .icns
- .lock
- .lockbit
- .theme
- .diagcfg
- .diagcab
- .diagpkg
- .msstyles
- .gadget
- .woff
- .part
- .sfcache
- .winmd
Auto Suppression
Une fois le processus de chiffrement terminé, le programme va procéder à sa suppression.
Pour cela, il va lancer une commande shell toujours encodé sur la stack.
Figure 35: DĂ©codage de la chaĂ®ne d’auto suppression.
La commande fsutil
est utilisĂ© pour que le binaire ne soit plus sur le disque une fois l’exĂ©cution terminĂ©. C’est bien plus efficace qu’une simple suppression avec la commande rm
car le fichier est totalement remplacĂ© sur le disque, il n’y a donc pas de moyen de le rĂ©cupĂ©rĂ© avec des outils une fois la suppression effectuĂ©.
De plus, il utilise la fonction MoveFileExW
pour dire au système de supprimer le fichier après un reboot.
Fin d’exĂ©cution
Le binaire résout la fonction ExitProcess
afin de se fermer.
Figure 36: ArrĂŞt du binaire.
Conclusion
La génération de clé de 32 bits suivis du chiffrement de la clé publique avec la clé publique de Lockbit et la suppression de la clé privée en mémoire rend le processus de décryptage impossible.
De plus, le binaire ne communique pas avec l’extĂ©rieur. Il n’envoie pas de message et ne se connecte Ă aucun C2. Ils n’ont pas besoin de rĂ©cupĂ©rer d’information spĂ©cifique sur le chiffrement car toutes les informations sont stockĂ©s Ă la fin des fichiers. Ces informations sont bien Ă©videmment aussi chiffrĂ©s.
Pour ce qui est de la propagation, sachez que si la configuration GPO est activĂ© dans le binaire et que vous dĂ©tectez une GPO pour dĂ©ployer le malware. Celui-ci Ă de grande chance d’avoir Ă©tĂ© lancĂ© dans un premier temps sur l’Active Directory.