Préambule
Elastic Security Labs a découvert un nouveau voleur d'informations basé sur Rust et distribué via de fausses campagnes CAPTCHA. Ces logiciels malveillants sont hébergés sur plusieurs sites web contrôlés par les adversaires. Cette campagne s'appuie sur des pages de vérification CAPTCHA trompeuses qui incitent les utilisateurs à exécuter un script PowerShell malveillant, qui déploie finalement l'infostealer, récoltant des données sensibles telles que des identifiants, des informations de navigation et des détails de portefeuilles de crypto-monnaies. Nous appelons ce logiciel malveillant EDDIESTEALER.
L'adoption de Rust dans le développement de logiciels malveillants reflète une tendance croissante chez les acteurs de la menace qui cherchent à exploiter les caractéristiques des langages modernes pour améliorer la furtivité, la stabilité et la résistance face aux flux de travail d'analyse traditionnels et aux moteurs de détection des menaces. Un voleur d'informations apparemment simple écrit en Rust nécessite souvent des efforts d'analyse plus importants que son homologue en C/C++, en raison de facteurs tels que les abstractions à coût nul, le système de types de Rust, les optimisations du compilateur et les difficultés inhérentes à l'analyse des binaires à sécurité mémoire.
Principaux points abordés dans cet article
- Une fausse campagne CAPTCHA charge EDDIESTEALER
- EDDIESTEALER est un nouveau voleur d'informations Rust qui cible les hôtes Windows.
- EDDIESTEALER reçoit du serveur C2 une liste de tâches identifiant les données à cibler.
Accès initial
Aperçu
Les faux CAPTCHA sont des constructions malveillantes qui reproduisent l'apparence et la fonctionnalité des systèmes CAPTCHA légitimes, utilisés pour distinguer les utilisateurs humains des robots. Contrairement à leurs homologues légitimes, les faux CAPTCHA servent de passerelles pour les logiciels malveillants, en s'appuyant sur l'ingénierie sociale pour tromper les utilisateurs. Ils apparaissent souvent sous la forme d'invites telles que "Verify you are a human" ou "I'm not a robot," et s'intègrent parfaitement dans les sites web compromis ou les campagnes d'hameçonnage. Nous avons également rencontré une campagne similaire distribuant GHOSTPULSE à la fin de l'année 2024.
D'après notre analyse de la télémétrie qui a précédé la diffusion d'EDDIESTEALER, le vecteur initial était un site web compromis déployant une charge utile JavaScript obfusquée basée sur React qui affiche un faux écran de vérification "Je ne suis pas un robot".
Imitant l'interface de vérification reCAPTCHA de Google, le logiciel malveillant utilise la méthode document.execCommand("copy") pour copier une commande PowerShell dans le presse-papiers de l'utilisateur. Ensuite, il demande à l'utilisateur d'appuyer sur Windows + R (pour ouvrir la boîte de dialogue d'exécution de Windows), puis sur Ctrl + V pour coller le contenu du presse-papiers, et enfin sur Entrée pour exécuter la commande PowerShell malveillante.
Cette commande télécharge silencieusement une charge utile de deuxième niveau (gverify.js) à partir du domaine hxxps://llll.fit/version/ contrôlé par l'attaquant et l'enregistre dans le dossier Downloads de l'utilisateur.
Enfin, le logiciel malveillant exécute gverify.js à l'aide de cscript dans une fenêtre cachée.
gverify.js est une autre charge utile JavaScript obfusquée qui peut être désobfusquée à l'aide d'outils open-source. Son fonctionnement est relativement simple : il récupère un exécutable (EDDIESTEALER) à partir de hxxps://llll.fit/io et enregistre le fichier dans le dossier Downloads de l'utilisateur avec un nom de fichier pseudo-aléatoire à 12 caractères.
EDDIESTEALER
Aperçu
EDDIESTEALER est un nouveau voleur d'informations sur les marchandises basé sur Rust. La majorité des chaînes qui révèlent ses intentions malveillantes sont cryptées. Le logiciel malveillant ne dispose pas de solides protections anti-sandbox/VM contre l'empreinte comportementale. Toutefois, de nouvelles variantes suggèrent que les contrôles anti-sandbox/VM pourraient avoir lieu du côté du serveur. Doté de capacités relativement simples, il reçoit une liste de tâches du serveur C2 dans le cadre de sa configuration pour cibler des données spécifiques et peut s'autodétruire après l'exécution si cela est spécifié.
Symboles rayés
Les échantillons EDDIESTEALER comportaient des symboles de fonction dépouillés, probablement en utilisant l'option de compilation par défaut de Rust, nécessitant la restauration des symboles avant l'analyse statique. Nous avons utilisé rustbinsign, qui génère des signatures pour les bibliothèques standard et les crates Rust en fonction des versions spécifiques de Rust/compilateur/dépendance. Alors que rustbinsign n'a détecté que hashbrown et rustc-demangle, ce qui suggère que peu de caisses externes sont utilisées, il n'a pas identifié les caisses telles que tinyjson et tungstenite dans les variantes plus récentes. Cela s'explique par l'absence d'artefacts clairs au niveau des cordes. Il est toujours possible d'identifier manuellement les crates en trouvant des chaînes uniques et en recherchant le dépôt sur GitHub, puis de télécharger, compiler et construire des signatures pour eux en utilisant le mode download_sign. C'est un peu lourd si nous ne connaissons pas la version exacte de la caisse utilisée. Toutefois, la restauration de la bibliothèque standard et des symboles d'exécution suffit à faire avancer le processus d'analyse statique.
Obfuscation des chaînes de caractères
EDDIESTEALER crypte la plupart des chaînes de caractères à l'aide d'un simple code XOR. Le décryptage se fait en deux étapes : tout d'abord, la clé XOR est dérivée en appelant l'une des nombreuses fonctions de dérivation de clé ; ensuite, le décryptage est effectué en ligne au sein de la fonction qui utilise la chaîne de caractères.
L'exemple suivant l'illustre : sub_140020fd0 est la fonction de dérivation de la clé et data_14005ada8 est l'adresse du blob crypté.
Chaque routine de décryptage utilise sa propre fonction de dérivation de clé. Ces fonctions acceptent systématiquement deux arguments : une adresse dans le système binaire et une valeur constante de 4 octets. Quelques opérations de base sont ensuite effectuées sur ces arguments pour calculer l'adresse où se trouve la clé XOR.
Binary Ninja dispose d'une fonction pratique appelée User-Informed Data Flow (UIDF), que nous pouvons utiliser pour fixer les variables à des valeurs connues afin de déclencher une analyse de propagation constante et de simplifier les expressions. Sinon, un émulateur de CPU comme Unicorn associé à un outil d'analyse binaire scriptable peut également s'avérer utile pour l'analyse par lots.
Il existe un modèle général d'initialisation paresseuse et sûre pour les threads des ressources partagées, telles que les chaînes cryptées pour les noms de modules, le domaine et le port C2, l'identifiant unique de l'échantillon - qui ne sont décryptées qu'une seule fois mais référencées de nombreuses fois pendant le temps d'exécution. Chaque fonction d'obtention spécifique vérifie un indicateur d'état pour sa ressource ; si elle n'est pas initialisée, elle appelle une fonction de synchronisation partagée de bas niveau. Cette routine de synchronisation utilise des opérations atomiques et des primitives d'attente du système d'exploitation (WaitOnAddress/WakeByAddressAll) pour s'assurer qu'un seul thread exécute la logique d'initialisation réelle, qui est invoquée indirectement via un pointeur de fonction dans la table virtuelle d'un objet dyn Trait.
Obfuscation de l'API
EDDIESTEALER utilise un mécanisme de recherche WinAPI personnalisé pour la plupart des appels API. Il commence par décrypter les noms du module et de la fonction cibles. Avant de tenter la résolution, il vérifie dans une table de hachage gérée localement si le nom et l'adresse de la fonction ont déjà été résolus. S'il ne le trouve pas, il charge dynamiquement le module requis à l'aide d'un wrapper LoadLibrary personnalisé, dans l'espace d'adressage du processus, et invoque une implémentation bien connue de GetProcAddress pour récupérer l'adresse de la fonction exportée. Le nom et l'adresse de l'API sont ensuite insérés dans la table de hachage, ce qui permet d'optimiser les recherches futures.
Création de mutex
EDDIESTEALER commence par créer un mutex pour s'assurer qu'une seule instance du logiciel malveillant s'exécute à tout moment. Le nom du mutex est une chaîne UUID décryptée 431e2e0e-c87b-45ac-9fdb-26b7e24f0d39 (unique par échantillon), qui est ensuite référencée une fois de plus lors de son contact initial avec le serveur C2.
Détection du bac à sable
EDDIESTEALER effectue une vérification rapide pour évaluer si la quantité totale de mémoire physique est supérieure à ~4.0 GB comme un mécanisme de détection de bac à sable faible. Si la vérification échoue, il se supprime lui-même du disque.
Auto-élimination
S'inspirant d'une technique d'autodestruction similaire observée chez LATRODECTUS, EDDIESTEALER est capable de s'autodétruire par le biais du renommage NTFS Alternate Data Streams, afin de contourner les verrous de fichiers.
Le logiciel malveillant utilise GetModuleFileName pour obtenir le chemin complet de son exécutable et CreateFileW (enveloppé dans jy::ds::OpenHandle) pour ouvrir une poignée vers son fichier exécutable avec les droits d'accès appropriés. Ensuite, une structure FILE_RENAME_INFO avec un nouveau nom de flux est transmise à SetFileInformationByHandle pour renommer le flux par défaut $DATA en :metadata. La poignée du fichier est fermée et rouverte, cette fois en utilisant SetFileInformationByHandle sur la poignée avec l'indicateur FILE_DISPOSITION_INFO.DeleteFile mis à TRUE pour permettre un indicateur "delete on close handle".
Demande de configuration supplémentaire
Les données de configuration initiales sont stockées sous forme de chaînes cryptées dans le fichier binaire. Une fois décryptées, ces données sont utilisées pour construire une requête suivant le modèle URI : <C2_ip_or_domain>/<resource_path>/<UUID>. Le site resource_path est spécifié comme api/handler. Le UUID, utilisé précédemment pour créer un mutex, est utilisé comme identifiant unique pour le suivi de la construction.
EDDIESTEALER communique ensuite avec son serveur C2 en envoyant une requête HTTP GET avec l'URI construit pour récupérer une configuration de deuxième étape contenant une liste de tâches à exécuter par le logiciel malveillant.
Les données de configuration de la deuxième étape sont cryptées par AES CBC et encodées en Base64. L'IV codé en Base64 est ajouté au message avant les deux points (:).
Base64(IV):Base64(AESEncrypt(data))
La clé AES permettant de décrypter le message serveur-client est stockée en clair en encodage UTF-8, dans la section .rdata. Il est récupéré par le biais d'une fonction getter.
La configuration décryptée pour cet exemple contient les éléments suivants au format JSON :
- ID session
- Liste des tâches (données à cibler)
- Clé AES pour le cryptage des messages entre le client et le serveur
- Drapeau d'autosuppression
{
"session": "<unique_session_id>",
"tasks": [
{
"id": "<unique_task_id>",
"prepare": [],
"pattern": {
"path": "<file_system_path>",
"recursive": <true/false>,
"filters": [
{
"path_filter": <null/string>,
"name": "<file_or_directory_name_pattern>",
"entry_type": "<FILE/DIR>"
},
...
]
},
"additional": [
{
"command": "<optional_command>",
"payload": {
"<command_specific_config>": <value>
}
},
...
]
},
...
],
"network": {
"encryption_key": "<AES_encryption_key>"
},
"self_delete": <true/false>
}
Pour cet échantillon particulier et sur la base des tâches reçues du serveur au cours de notre analyse, voici la liste des cibles d'exfiltration basées sur le système de fichiers :
- Portefeuilles de crypto-monnaie
- Navigateurs
- Gestionnaires de mots de passe
- Clients FTP
- Applications de messagerie
| Portefeuille de crypto-monnaie | Filtre de chemin cible |
|---|---|
| Armurerie | %appdata%\\Armory\\*.wallet |
| Bitcoin | %appdata%\\Bitcoin\\wallets\\* |
| WalletWasabi | %appdata%\\WalletWasabi\\Client\\Wallets\\* |
| Réseau principal Daedalus | %appdata%\\Daedalus Mainnet\\wallets\\* |
| Coinomi | %localappdata%\\Coinomi\\Coinomi\\wallets\\* |
| Electrum | %appdata%\\Electrum\\wallets\\* |
| Exodus | %appdata%\\Exodus\\exodus.wallet\\* |
| DashCore | %appdata%\\DashCore\\wallets\\* |
| ElectronCash | %appdata%\\ElectronCash\\wallets\\* |
| Electrum-DASH | %appdata%\\Electrum-DASH\\wallets\\* |
| Guarda | %appdata%\\Guarda\\IndexedDB |
| Atomique | %appdata%\\atomic\\Local Storage |
| Navigateur | Filtre de chemin cible |
|---|---|
| Microsoft Edge | %localappdata%\\Microsoft\\Edge\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Courageux | %localappdata%\\BraveSoftware\\Brave-Browser\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Google Chrome | %localappdata%\\Google\\Chrome\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Mozilla Firefox | %appdata%\\Mozilla\\Firefox\\Profiles\\[key4.db,places.sqlite,logins.json,cookies.sqlite,formhistory.sqlite,webappsstore.sqlite,*+++*] |
| Gestionnaire de mots de passe | Filtre de chemin cible |
|---|---|
| Bitwarden | %appdata%\\Bitwarden\\data.json |
| 1Password | %localappdata%\\1Password\\[1password.sqlite,1password_resources.sqlite] |
| KeePass | %userprofile%\\Documents\\*.kdbx |
| Client FTP | Filtre de chemin cible |
|---|---|
| FileZilla | %appdata%\\FileZilla\\recentservers.xml |
| FTP Manager Lite | %localappdata%\\DeskShare Data\\FTP Manager Lite\\2.0\\FTPManagerLiteSettings.db |
| FTPbox | %appdata%\\FTPbox\\profiles.conf |
| FTP Commander Deluxe | %ProgramFiles(x86)%\\FTP Commander Deluxe\\FTPLIST.TXT |
| Gestionnaire FTP automatique | %localappdata%\\DeskShare Data\\Auto FTP Manager\\AutoFTPManagerSettings.db |
| 3D-FTP | %programdata%\\SiteDesigner\\3D-FTP\\sites.ini |
| FTPGetter | %appdata%\\FTPGetter\\servers.xml |
| Total Commandant | %appdata%\\GHISLER\\wcx_ftp.ini |
| Application de messagerie | Filtre de chemin cible |
|---|---|
| Bureau Telegram | %appdata%\\Telegram Desktop\\tdata\\* |
Une liste des extensions de navigateur ciblées est disponible ici.
Ces cibles sont susceptibles d'être modifiées car elles sont configurables par l'opérateur C2.
EDDIESTEALER lit ensuite les fichiers ciblés à l'aide des fonctions standard de kernel32.dll telles que CreateFileW, GetFileSizeEx, ReadFile et CloseHandle.
Trafic C2 ultérieur
Après avoir récupéré les tâches, EDDIESTEALER effectue un profilage du système afin de recueillir des informations sur le système infecté :
- Emplacement de l'exécutable (
GetModuleFileNameW) - ID de la localité (
GetUserDefaultLangID) - Nom d'utilisateur (
GetUserNameW) - Quantité totale de mémoire physique (
GlobalMemoryStatusEx) - Version du système d'exploitation (
RtlGetVersion)
Suivant le même format de données (Base64(IV):Base64(AESEncrypt(data))) pour les messages client-serveur, les informations initiales sur l'hôte sont cryptées en AES à l'aide de la clé récupérée dans la configuration supplémentaire et envoyées via une requête HTTP POST à <C2_ip_or_domain>/<resource_path>/info/<session_id>. Ensuite, pour chaque tâche accomplie, les données collectées sont également cryptées et transmises dans des requêtes POST distinctes à <C2_ip_or_domain>/<resource_path><session_id>/<task_id>, juste après l'achèvement de chaque tâche. Cette méthode génère un modèle de trafic C2 distinct, caractérisé par des demandes POST multiples et spécifiques à une tâche. Ce schéma est particulièrement facile à identifier car cette famille de logiciels malveillants s'appuie principalement sur HTTP au lieu de HTTPS pour ses communications C2.
Notre analyse a permis de découvrir des chaînes cryptées qui se décryptent en chaînes de métadonnées de panique, révélant des chemins d'accès aux fichiers sources internes de Rust tels que
apps\bin\src\services\chromium_hound.rsapps\bin\src\services\system.rsapps\bin\src\structs\search_pattern.rsapps\bin\src\structs\search_entry.rs
Nous avons découvert que les messages d'erreur envoyés au serveur C2 contiennent ces chaînes, y compris le fichier source exact, le numéro de ligne et le numéro de colonne d'où provient l'erreur, ce qui permet au développeur du logiciel malveillant de disposer d'un retour d'information intégré pour le débogage.
Capacités spécifiques au chrome
Depuis l'introduction du cryptage lié aux applications, les développeurs de logiciels malveillants se sont adaptés à d'autres méthodes pour contourner cette protection et accéder à des données sensibles non cryptées, telles que les cookies. ChromeKatz est l'une des solutions open source les mieux accueillies que nous avons vu mettre en œuvre pour lutter contre les logiciels malveillants. EDDIESTEALER ne fait pas exception à la règle : les développeurs du logiciel malveillant l'ont réimplémenté en Rust.
Vous trouverez ci-dessous un extrait de la logique de vérification de la version du navigateur similaire à COOKIEKATZ, après avoir récupéré les informations sur la version à partir de %localappdata%\<browser_specific_path>\\User Data\\Last Version.
Modèle de signature COOKIEKATZ pour détecter les instances de COOKIEMONSTER :
Modèle de signature CredentialKatz pour la détection des instances de CookieMonster :
Voici un exemple de la logique copiée-collée exacte du site FindPattern de COOKIEKATZ, où PatchBaseAddress est souligné.
Les développeurs ont introduit une modification pour gérer les cas où le navigateur Chromium ciblé n'est pas en cours d'exécution. S'il est inactif, EDDIESTEALER crée une nouvelle instance de navigateur en utilisant les arguments de la ligne de commande --window-position=-3000,-3000 https://google.com. La nouvelle fenêtre est ainsi positionnée loin de l'écran, ce qui la rend invisible pour l'utilisateur. L'objectif est de s'assurer que le logiciel malveillant peut toujours lire la mémoire (ReadProcessMemory) du processus enfant nécessaire - le processus de service réseau identifié par le drapeau --utility-sub-type=network.mojom.NetworkService. Pour une explication plus détaillée de l'interaction de ce processus de navigation, reportez-vous à nos recherches précédentes sur les voleurs d'informations MaaS.
Différences avec les variantes
Après analyse, des échantillons plus récents ont été identifiés avec des capacités supplémentaires.
Les informations recueillies sur les machines des victimes sont désormais les suivantes
- Running processes
- Informations sur le GPU
- Nombre de cœurs de l'unité centrale
- Nom de l'unité centrale
- Fournisseur de CPU
Le modèle de communication C2 a été légèrement modifié. Le logiciel malveillant envoie maintenant de manière préemptive des informations sur le système hôte au serveur avant de demander sa configuration déchiffrée. Dans quelques cas où la machine victime a pu atteindre le serveur C2 mais a reçu une liste de tâches vide, l'ajustement suggère une tactique d'évasion : les développeurs ont probablement introduit des contrôles côté serveur pour établir le profil de l'environnement client et retenir la configuration principale si un bac à sable ou un système d'analyse est détecté.
La clé de chiffrement pour la communication client-serveur n'est plus reçue dynamiquement du serveur C2 ; elle est désormais codée en dur dans le fichier binaire. La clé utilisée par le client pour décrypter les messages serveur-client reste également codée en dur.
Les échantillons compilés les plus récents font un usage intensif de l'extension de fonction en ligne, où de nombreuses fonctions - définies par l'utilisateur ou provenant de bibliothèques standard et de caisses - ont été plus souvent intégrées directement dans leurs appelants, ce qui donne des fonctions plus volumineuses et rend difficile l'isolation du code de l'utilisateur. Ce comportement est probablement dû à l'utilisation de l'inliner de LLVM. Bien que certaines fonctions ne soient pas intégrées, l'intégration généralisée complique encore l'analyse.
Afin d'obtenir toutes les entrées du gestionnaire de mots de passe de Chrome, EDDIESTEALER commence sa routine de vol d'informations d'identification en lançant un nouveau processus Chrome avec le drapeau --remote-debugging-port=<port_num>, activant le protocole DevTools de Chrome via une interface WebSocket locale. Cela permet au logiciel malveillant d'interagir avec le navigateur de manière autonome, sans nécessiter d'interaction visible de la part de l'utilisateur.
Après avoir lancé Chrome, le logiciel malveillant interroge http://localhost:<port>/json/version pour récupérer le site webSocketDebuggerUrl, qui fournit le point d'extrémité permettant d'interagir avec l'instance du navigateur par l'intermédiaire de WebSocket.
En utilisant cette connexion, il émet une commande Target.createTarget avec le paramètre chrome://password-manager/passwords, demandant à Chrome d'ouvrir son gestionnaire de mot de passe interne dans un nouvel onglet. Bien que cette page interne n'expose pas son contenu au DOM ou à DevTools directement, son ouverture entraîne le déchiffrement et le chargement en mémoire des informations d'identification stockées par Chrome. Ce comportement est exploité par EDDIESTEALER dans les étapes suivantes par le biais d'un code sosie de CredentialKatz, qui analyse la mémoire du processus Chrome pour extraire les informations d'identification en clair après leur chargement par le navigateur.
Sur la base des chaînes décryptées os_crypt, encrypted_key, CryptUnprotectData, local_state_pattern, et login_data_pattern, les variantes d'EDDIESTEALER semblent être rétrocompatibles, prenant en charge les versions de Chrome qui utilisent encore le cryptage DPAPI.
Nous avons identifié 15 échantillons supplémentaires d'EDDIESTEALER grâce à des similitudes de code et d'infrastructure sur VirusTotal. Le tableau des observations comprendra les échantillons découverts, les adresses IP/domaines C2 associés et une liste des infrastructures hébergeant EDDIESTEALER.
Quelques conseils d'analyse
Tracing
Pour mieux comprendre le flux de contrôle et localiser les destinations exactes des sauts ou appels indirects dans de grands blocs de code, nous pouvons utiliser des techniques de traçage binaire. Des outils tels que TinyTracer peuvent capturer une trace d'API et générer un fichier .tag, qui associe les appels d'API sélectionnés à enregistrer à la ligne d'exécution dans l'assemblage. Les fonctions de la bibliothèque standard de Rust font appel aux WinAPI sous le capot, et cela capture également tout code qui appelle directement les fonctions WinAPI, en contournant l'abstraction de la bibliothèque standard. Le fichier de balises peut ensuite être importé dans des outils de décompilation pour baliser automatiquement les blocs de code à l'aide de plugins tels que IFL.
Métadonnées de panique pour la segmentation du code
Les métadonnées de panique - les chemins d'accès au fichier source intégré (fichiers .rs), les numéros de ligne et de colonne associés aux emplacements de panique - offrent des indices précieux pour segmenter et comprendre les différentes parties du fichier binaire. Ce n'est toutefois le cas que si ces métadonnées n'ont pas été retirées du fichier binaire. Les chemins tels que apps\bin\src\services\chromium.rs, apps\bin\src\structs\additional_task.rs ou tout chemin qui semble faire partie d'un projet personnalisé renvoient généralement à la logique unique de l'application. Les chemins commençant par library<core/alloc/std>\src\ indiquent du code provenant de la bibliothèque standard Rust. Les chemins contenant le nom et la version du produit, tels que hashbrown-0.15.2\src\raw\mod.rs, renvoient à des bibliothèques externes.
Si le projet de logiciel malveillant dispose d'une base de code quelque peu organisée, les chemins d'accès aux fichiers dans les chaînes de panique peuvent directement correspondre à des modules logiques. Par exemple, la chaîne décryptée apps\bin\src\utils\json.rs:48:39 est référencée dans sub_140011b4c.
En examinant l'arbre des appels entrants à la fonction, beaucoup d'entre eux remontent jusqu'à sub_14002699d. Cette fonction (sub_14002699d) est appelée dans le cadre d'une routine de communication C2 connue (jy::C2::RetrieveAndDecryptConfig), juste après le décryptage de données de configuration supplémentaires dont on sait qu'elles sont au format JSON.
Sur la base du chemin d'accès json.rs et de son contexte d'appel, on peut supposer que sub_14002699d est responsable de l'analyse des données JSON. Nous pouvons le vérifier en parcourant l'appel de fonction. Bien sûr, en inspectant la structure de la pile qui est passée comme référence à l'appel de la fonction, elle pointe maintenant vers une adresse du tas peuplée de champs de configuration analysés.
Pour la bibliothèque standard et les crates tiers open-source, le chemin d'accès au fichier, le numéro de ligne et (si disponible) le hash du commit rustc ou la version du crate vous permettent de consulter le code source exact en ligne.
Réutilisation de l'emplacement de la pile
L'une des fonctions d'optimisation consiste à réutiliser les emplacements de pile pour les variables/structures de pile dont les échéances ne se chevauchent pas. Les variables qui ne sont pas "live" au même moment peuvent partager le même emplacement de mémoire de pile, ce qui réduit la taille globale de la pile. Essentiellement, une variable est vivante à partir du moment où une valeur lui est attribuée jusqu'au dernier point d'accès à cette valeur. Cela rend la sortie décompilée confuse, car le même décalage de mémoire peut contenir des types ou des valeurs différents à différents moments.
Pour ce faire, nous pouvons définir des unions englobant tous les types possibles partageant le même décalage de mémoire au sein de la fonction.
Gestion des erreurs en Rust et Enums
Les énumérations Rust sont des unions étiquetées qui définissent des types avec plusieurs variantes, chacune contenant éventuellement des données, ce qui est idéal pour modéliser des états tels que le succès ou l'échec. Les variantes sont identifiées par un discriminant (tag).
Le code de gestion des erreurs est présent dans tout le binaire et représente une part importante du code décompilé. Le principal mécanisme de gestion des erreurs de Rust est l'énumération générique Result<T, E>. Il existe deux variantes : Ok(T) T Err(E), indiquant un échec et contenant une valeur d'erreur de type E.
Dans l'exemple ci-dessous, une valeur discriminante de 0x8000000000000000 est utilisée pour différencier les résultats de la résolution de l'API CreateFileW. Si CreateFileW est résolu avec succès, le type de variable reuse contient le pointeur de fonction API et la branche else s'exécute. Dans le cas contraire, la branche if s'exécute et attribue une chaîne d'information d'erreur de reuse à arg1.
Pour plus d'informations sur la façon dont d'autres types de rouille courants peuvent se présenter dans la mémoire, consultez cette feuille de contrôle et cet exposé étonnant de Cindy Xiao !
Logiciels malveillants et MITRE ATT&CK
Elastic utilise le cadre MITRE ATT& CK pour documenter les tactiques, techniques et procédures communes que les menaces utilisent contre les réseaux d'entreprise.
Tactiques
- Accès initial
- Exécution
- Évasion par la défense
- Exfiltration
- Accès aux identifiants
- Découverte
- Collecte
Techniques
Les techniques représentent la manière dont un adversaire atteint un objectif tactique en effectuant une action.
- Phishing
- Injection de contenu
- Interprète de script et de commande
- Identifiants venant de magasins de mots de passe
- User Execution
- Masquage des fichiers ou des informations
- Exfiltration par le canal C2
- Virtualisation/évasion de la sandbox
Détections
YARA
Elastic Security a créé les règles YARA suivantes en rapport avec cette recherche :
Règles de prévention comportementale
- Suspicious PowerShell Execution
- Transfert de l'outil d'ingérence via PowerShell
- Découverte potentielle d'informations sur le navigateur
- Potential Self Deletion of a Running Executable
Observations
Les observables suivants ont été examinés dans le cadre de cette recherche.
| Observable | Type | Nom | Référence |
|---|---|---|---|
47409e09afa05fcc9c9eff2c08baca3084d923c8d82159005dbae2029e1959d0 | SHA-256 | MvUlUwagHeZd.exe | EDDIESTEALER |
162a8521f6156070b9a97b488ee902ac0c395714aba970a688d54305cb3e163f | SHA-256 | :metadata (copy) | EDDIESTEALER |
f8b4e2ca107c4a91e180a17a845e1d7daac388bd1bb4708c222cda0eff793e7a | SHA-256 | AegZs85U6COc.exe | EDDIESTEALER |
53f803179304e4fa957146507c9f936b38da21c2a3af4f9ea002a7f35f5bc23d | SHA-256 | :metadata (copy) | EDDIESTEALER |
20eeae4222ff11e306fded294bebea7d3e5c5c2d8c5724792abf56997f30aaf9 | SHA-256 | PETt3Wz4DXEL.exe | EDDIESTEALER |
1bdc2455f32d740502e001fce51dbf2494c00f4dcadd772ea551ed231c35b9a2 | SHA-256 | Tk7n1al5m9Qc.exe | EDDIESTEALER |
d905ceb30816788de5ad6fa4fe108a202182dd579075c6c95b0fb26ed5520daa | SHA-256 | YykbZ173Ysnd.exe | EDDIESTEALER |
b8b379ba5aff7e4ef2838517930bf20d83a1cfec5f7b284f9ee783518cb989a7 | SHA-256 | 2025-04-03_20745dc4d048f67e0b62aca33be80283_akira_cobalt-strike_satacom | EDDIESTEALER |
f6536045ab63849c57859bbff9e6615180055c268b89c613dfed2db1f1a370f2 | SHA-256 | 2025-03-23_6cc654225172ef70a189788746cbb445_akira_cobalt-strike | EDDIESTEALER |
d318a70d7f4158e3fe5f38f23a241787359c55d352cb4b26a4bd007fd44d5b80 | SHA-256 | 2025-03-22_c8c3e658881593d798da07a1b80f250c_akira_cobalt-strike | EDDIESTEALER |
73b9259fecc2a4d0eeb0afef4f542642c26af46aa8f0ce2552241ee5507ec37f | SHA-256 | 2025-03-22_4776ff459c881a5b876da396f7324c64_akira_cobalt-strike | EDDIESTEALER |
2bef71355b37c4d9cd976e0c6450bfed5f62d8ab2cf096a4f3b77f6c0cb77a3b | SHA-256 | TWO[1].file | EDDIESTEALER |
218ec38e8d749ae7a6d53e0d4d58e3acf459687c7a34f5697908aec6a2d7274d | SHA-256 | EDDIESTEALER | |
5330cf6a8f4f297b9726f37f47cffac38070560cbac37a8e561e00c19e995f42 | SHA-256 | verifcheck.exe | EDDIESTEALER |
acae8a4d92d24b7e7cb20c0c13fd07c8ab6ed8c5f9969504a905287df1af179b | SHA-256 | 3zeG4jGjFkOy.exe | EDDIESTEALER |
0f5717b98e2b44964c4a5dfec4126fc35f5504f7f8dec386c0e0b0229e3482e7 | SHA-256 | verification.exe | EDDIESTEALER |
e8942805238f1ead8304cfdcf3d6076fa0cdf57533a5fae36380074a90d642e4 | SHA-256 | g_verify.js | EDDIESTEALER chargeur |
7930d6469461af84d3c47c8e40b3d6d33f169283df42d2f58206f43d42d4c9f4 | SHA-256 | verif.js | EDDIESTEALER chargeur |
45.144.53[.]145 | ipv4-addr | EDDIESTEALER C2 | |
84.200.154[.]47 | ipv4-addr | EDDIESTEALER C2 | |
shiglimugli[.]xyz | nom de domaine | EDDIESTEALER C2 | |
xxxivi[.]com | nom de domaine | EDDIESTEALER Infrastructures C2 et intermédiaires | |
llll[.]fit | nom de domaine | EDDIESTEALER infrastructure intermédiaire | |
plasetplastik[.]com | nom de domaine | EDDIESTEALER infrastructure intermédiaire | |
militrex[.]wiki | nom de domaine | EDDIESTEALER infrastructure intermédiaire |
Références
Les éléments suivants ont été référencés tout au long de la recherche ci-dessus :
- https://github.com/N0fix/rustbinsign
- https://github.com/Meckazin/ChromeKatz
- https://github.com/hasherezade/tiny_tracer
- https://docs.binary.ninja/dev/uidf.html
- https://www.unicorn-engine.org/
- https://github.com/LloydLabs/delete-self-poc/tree/main
- https://cheats.rs/#memory-layout
- https://www.youtube.com/watch?v=SGLX7g2a-gw&t=749s
- https://cxiao.net/posts/2023-12-08-rust-reversing-panic-metadata/
