Don't Judge a PNG by Its Header: Analyse du Infostealer PURELOGS
Swiss Post Cybersecurity a retracé un fichier JavaScript suspect jusqu'à une campagne PURELOGS furtif qui cachait sa charge utile dans un fichier PNG.
Louis Schürmann, analyste de sécurité de Swiss Post Cybersecurity, a identifié et analysé une campagne de vol de PURELOGS passée inaperçue. Dans notre article de blog, il décrit la chaîne d'attaque complète, depuis l'utilisation initiale d'une infrastructure légitime jusqu'à l'exfiltration finale des données.
Le triage de phishing est généralement prévisible, mais cet sample faisait exception. Se faisant passer pour une facture pharmaceutique, le chargeur a immédiatement contacté archive.org pour récupérer une image PNG. Cela a attiré l'attention de notre analyste de la sécurité. Après quatre couches de désobfuscation, il a découvert PURELOGS. Si le malware lui-même est bien connu, l'infrastructure de mise en place de cette campagne offre une étude de cas précieuse en matière d'évasion.
Accès initial : Le dropper JScript
L'infection commence par un e-mail de phishing se faisant passer pour une facture pharmaceutique. L'archive ZIP contient un fichier avec une extension .js. La plupart des utilisateurs associent JavaScript à leur navigateur, mais il ne s'agit pas ici de JavaScript de navigateur.
Il s'agit d'un fichier JScript Windows Script Host (WSH), ce qui signifie qu'il s'exécute avec tous les privilèges au niveau du système d'exploitation via le moteur de script Windows. Il accède directement aux objets COM tels que WScript.Shell et Win32_Process, ce qui lui permet de créer des fichiers, de lancer des processus et d'interagir avec le système comme il le souhaite.
À première vue, le fichier est illisible :
Il est rempli de caractères non ASCII qui perturbent l'analyse statique et brouillent la détection basée sur les signatures. Cependant, une fois les caractères indésirables supprimés, la logique du script est assez simple : il construit une commande PowerShell avec une charge utile encodée en Base64 et la lance à l'aide de WMI.
Il lance un processus PowerShell caché et exécute la charge utile décodée en mémoire avec Invoke-Expression. Aucun fichier n'est enregistré sur le disque, donc les antivirus classiques basés sur les fichiers ne le détectent pas. Il s'agit d'une exécution standard sans fichier. Ce qui a attiré l'attention de notre analyste de sécurité, c'est ce que la charge utile PowerShell a fait ensuite : elle a commencé à chercher un fichier PNG sur archive.org.
Stage 1 : Le PNG polyglotte
Le script PowerShell décodé agit comme un téléchargeur de première stage. Au lieu de récupérer un exécutable à partir d'un domaine jetable, il télécharge une image PNG à partir d'archive.org, un site web légitime et bien connu. Lorsque les analystes examinent les journaux réseau et voient du trafic vers archive.org, cela ne soulève généralement pas de soupçons. Les attaquants utilisent la réputation du site comme couverture.
Mais il ne s'agit pas en réalité d'un fichier PNG standard. Enfin, si, mais avec des extras. Les attaquants ont intégré une charge utile codée en Base64 après le bloc IEND du fichier PNG, qui marque la fin officielle des données d'image. Le fichier s'affiche toujours comme une image valide dans n'importe quel visualiseur. Le malware proprement dit se trouve entre deux marqueurs personnalisés (BaseStart et BaseEnd).
Le script PowerShell utilise une expression régulière pour extraire la charge utile entre ces marqueurs :
$imageData -match 'BaseStart-(.+ ?)-BaseEnd'
$valor = $matches[1]
Notez qu'il utilise DownloadString() au lieu de DownloadFile(). L'« image » ne touche jamais le disque sous sa forme originale. Elle n'existe qu'en mémoire sous forme de variable de chaîne. Les contrôles de sécurité basés sur les fichiers n'ont jamais la possibilité de l'inspecter.
Une fois extraite, le script décode la charge utile en Base64 et la charge directement en mémoire à l'aide de .NET Reflection :
C'est là que l'exécution sans fichier prend tout son sens. Les antivirus traditionnels analysent les fichiers sur le disque, calculent les hachages et comparent les signatures. Lorsqu'un assemblage est chargé directement depuis un tableau d'octets dans la mémoire, il contourne tout cela. Le logiciel malveillant n'existe que dans l'espace mémoire du processus PowerShell.
Le script transmet ensuite plusieurs arguments à l'assembly chargé, y compris une autre URL codée, et invoque une méthode à l'aide de Reflection. Nous sommes passés d'un simple dropper à un chargeur configurable, et c'est à l'étape suivante que les choses se compliquent.
Stage 2 : Configuration de VMDetectLoader
L'assemblage .NET chargé par le stager PowerShell est ce que les chercheurs d'IBM X-Force appellent « VMDetectLoader ». Il s'agit d'un chargeur modulaire responsable des options de persistance, des vérifications d'environnement et de l'injection de l'étape suivante. Son comportement est entièrement dicté par les arguments transmis depuis le stage 1.
Dans cette campagne, les attaquants ont fait certains choix de configuration spécifiques :
Pas de persistance : le chargeur prend en charge plusieurs mécanismes de persistance (VBScript avec clés de registre Run, tâches planifiées), mais aucun n'a été activé ici.
Détection de VM activée : une vérification standard de contournement du bac à sable. Si le chargeur détecte qu'il s'exécute dans une machine virtuelle, il se termine. La plupart des analyses automatisées de logiciels malveillants s'appuient sur des machines virtuelles, ce qui aide le logiciel malveillant à éviter une détection précoce.
Processus cible : CasPol.exe : il s'agit du processus hôte que le chargeur utilisera pour l'injection. CasPol.exe est un outil .NET Framework légitime (Code Access Security Policy Tool), ce qui en fait une couverture parfaite. Pour les outils de sécurité, il ressemble à un utilitaire Microsoft fiable qui fait son travail.
Détail intéressant : de nombreux noms de variables internes sont en portugais (comme « nativo » pour « natif »). IBM X-Force attribue VMDetectLoader à Hive0131, un groupe de cybercriminels sud-américain. Cependant, comme VMDetectLoader est le seul indicateur reliant cette campagne PURELOGS à cet acteur, j'estime que cette attribution est peu fiable.
La tâche principale du chargeur est de récupérer la charge utile de l'étape suivante. Il prend l'un des arguments de l'étape 1 (stocké dans la variable $olinia), l'inverse et le décode en Base64 pour obtenir une URL pointant vers un fichier .txt.
Ce fichier contient un autre PE encodé, que le chargeur récupère, décode et prépare pour l'injection à l'aide d'une technique appelée injection de processus.
Injection de processus via RunPE
Une fois que la charge utile de l'étape suivante est décodée et en mémoire, la dernière tâche du chargeur consiste à l'exécuter. Pour ce faire, il utilise une technique d'injection de processus classique et bien documentée : RunPE, également connue sous le nom de « process hollowing » (vidage de processus).
Il lance l'utilitaire légitime .NET Framework CasPol.exe dans un état suspendu, extrait son code d'origine de la mémoire et le remplace par la charge utile décodée. En détournant le thread principal et en redirigeant le pointeur d'instruction vers le point d'entrée de la charge utile, le logiciel malveillant se fait passer pour un processus Microsoft de confiance. Du point de vue du système d'exploitation et de nombreux outils de sécurité, il s'agit simplement de CasPol.exe qui s'exécute comme prévu, permettant au stage suivante de commencer son travail en tant que processus « fiable ».
Stage 3 : Le décompresseur secondaire
La charge utile injectée via le processus de hollowing n'est pas le voleur PURELOGS final. Il s'agit plutôt d'un décompresseur .NET obscurci avec .NET-Reactor. Son seul objectif est de déchiffrer, décompresser et exécuter la charge utile finale entièrement en mémoire.
Un pipeline de décompression piloté par les événements
Le code du décompresseur semble initialement désorganisé. Cependant, le constructeur de la classe ExecutionEngine révèle l'architecture réelle : chaque méthode est abonnée à un événement spécifique, formant un pipeline séquentiel où la réalisation d'une étape déclenche la suivante dans la chaîne.
Cette architecture divise le processus de décompression en cinq étapes distinctes et séquentielles. La méthode Main lance simplement cette chaîne en créant une instance ExecutionEngine et en déclenchant le premier événement.
Étape 1 : Décryptage avec Legacy 3DES
La première étape opérationnelle consiste à déchiffrer avec DecompressDispatcher. Cette fonction prend la charge utile chiffrée, une clé et un vecteur d'initialisation (IV) à partir des ressources intégrées du décompresseur.
Le choix de la cryptographie est ici remarquable. Au lieu d'une norme moderne comme AES, le logiciel malveillant utilise l'algorithme Triple DES (3DES). 3DES est un chiffrement hérité qui a été officiellement déprécié par le NIST pour être trop lent et inefficace. Son utilisation ici est probablement un choix délibéré pour échapper aux systèmes de détection automatisés. De nombreux outils de sécurité sont configurés pour rechercher les constantes cryptographiques et les signatures associées à AES. L'utilisation d'un algorithme plus ancien et moins courant peut donc aider le logiciel malveillant à passer inaperçu.
Étape 2 : Décompression avec GZip
Après le déchiffrement, les données obtenues ne constituent toujours pas un fichier PE valide. Il s'agit d'une archive compressée au format GZip. L'événement suivant dans la chaîne déclenche le processus de décompression : EncryptEfficientDecryptor.
Cette approche à deux niveaux, consistant à crypter puis à compresser, est une technique courante et efficace pour protéger une charge utile. Elle garantit que l'assemblage final n'est jamais exposé avant le dernier moment possible, le protégeant ainsi des outils d'analyse statique qui pourraient autrement le signaler.
Étape 3 et 4 : Chargement de l'assemblage et transfert final via la réflexion
L'assemblage PURELOGS final étant désormais entièrement décompressé en mémoire, les deux dernières étapes du pipeline sont consacrées à son exécution. Cela est réalisé à l'aide de .NET Reflection afin d'obtenir un transfert complet sans fichier.
- Chargement de l'assemblage : la méthode LoadAssemblyFromBytes est déclenchée, qui appelle Assembly.Load() sur le tableau d'octets bruts de la charge utile PURELOGS. L'assemblage est maintenant chargé dans l'espace mémoire du décompresseur.
- Invocation du point d'entrée : l'événement final déclenche la méthode InvokeEntryPoint. Cette méthode utilise la réflexion pour trouver et exécuter le point d'entrée du nouvel assemblage chargé.
Stage 4 : PURELOGS enfin
Après quatre étapes de décompression et d'injection, I'infostealer PURELOGS s'exécute désormais dans le processus CasPol.exe vidé.
Découvrez PURELOGS
PURELOGS est un infostealer .NET courant qui est apparu pour la première fois à la vente sur divers forums clandestins en 2022. Il est développé et vendu par un développeur connu sous le nom de PureCoder, qui propose également une suite d'autres outils malveillants, notamment PureRAT, BlueLoader et PureCrypter.
Comme la plupart des infostealers d'informations actuels, PURELOGS fonctionne comme un Malware-as-a-Service (MaaS), ce qui le rend accessible à un large éventail d'acteurs malveillants, quelles que soient leurs compétences techniques. Le stealer est annoncé sur des sites clearnet et darknet, et les ventes sont gérées par un bot Telegram entièrement automatisé. Pour seulement 150 dollars par mois, n'importe qui peut souscrire un abonnement et déployer un infostealer d'informations sophistiqué en quelques minutes.
Le malware lui-même est conçu pour être modulaire et furtif, avec des fonctionnalités destinées à séduire à la fois les opérateurs peu sophistiqués et les acteurs plus compétents. Il comprend notamment des chargeurs .NET en mémoire, des canaux de commande et de contrôle (C2) flexibles et un système de plugins permettant de récolter une grande variété de données à partir des systèmes compromis.
Architecture et obscurcissement
Le stub PURELOGS lui-même est obscurci à l'aide d'une combinaison de ConfuserEx, .NET Reactor et de techniques de virtualisation personnalisées. Il en résulte des noms de classes et de méthodes déformés, un flux de contrôle virtualisé et des chaînes cryptées. Cela rend l'analyse plus difficile, mais pas impossible.
À la base, le flux d'exécution du voleur est simple :
- Décryptage de la configuration : il commence par décrypter sa configuration C2 à partir d'une ressource intégrée.
- Exécuter les modules : il exécute ses différents modules de vol en fonction des indicateurs de fonctionnalité définis dans la configuration.
- Exfiltration des données : il compile et renvoie les données volées au serveur C2.
Configuration
La configuration C2 est stockée sous forme de blob sérialisé Protobuf et chiffré XOR intégré dans les ressources du logiciel malveillant. Pour accéder à sa configuration, le logiciel malveillant applique d'abord une routine de déchiffrement XOR personnalisée au blob de ressources. Il en résulte un message Protobuf qui contient une autre couche de chiffrement : les données de configuration réelles sont chiffrées avec 3DES.
L'extrait de code ci-dessous montre la routine de décryptage 3DES finale. Elle prend en entrée les données cryptées et une chaîne codée en Base64 (la clé).
- Il décode d'abord la chaîne Base64 et calcule son hachage MD5 pour dériver la clé 3DES réelle.
- Il initialise ensuite un TripleDESCryptoServiceProvider avec la clé dérivée et définit le mode sur ECB (Electronic Codebook).
- Enfin, elle appelle CreateDecryptor().TransformFinalBlock() pour déchiffrer les données.
Une fois déchiffrée, la configuration révèle :
- Détails du serveur C2: l'adresse IP et le numéro de port pour la communication de commande et de contrôle.
- Clé de chiffrement 3DES : une clé codée en Base64 utilisée pour chiffrer toutes les données sortantes.
- ID de build: identifiant unique pour la campagne de logiciels malveillants.
- Drapeaux de fonctionnalité : une série de valeurs booléennes qui activent ou désactivent les modules de vol individuels.
Modules
Comme mentionné précédemment, PURELOGS est modulaire, ce qui signifie qu'il comprend de nombreux modules, chacun ciblant différentes applications et informations d'identification. Étant donné le grand nombre de modules disponibles, ils ne sont pas tous examinés en détail ici. L'accent est mis sur les deux modules les plus importants. Une liste complète est fournie à la fin.
Chromium : DPAPI disparaît
Le module principal de collecte de données d'infostealer cible les navigateurs basés sur le projet open source Chromium, qui utilise le moteur de rendu Blink. Cela lui permet d'attaquer un large éventail de navigateurs populaires tels que Google Chrome, Microsoft Edge et Opera à partir d'une seule base de code.
PURELOGS commence par lire le fichier Local State afin de trouver la clé principale cryptée. Cette clé est protégée par l'API Windows Data Protection (DPAPI). Cependant, la protection de DPAPI dépend du contexte et n'offre aucune défense réelle dans ce scénario. Comme le logiciel malveillant s'exécute dans la session utilisateur de la victime, un appel à la fonction native CryptUnprotectData suffit pour que le système d'exploitation déchiffre de manière transparente la clé principale. Cela rend la protection inutile contre un attaquant qui a déjà réussi à exécuter du code.
Pour en savoir plus sur les autres techniques de vol d'informations d'identification de Chromium, consultez notre précédent article de blog sur The ClickFix Deception.
Une fois en possession de la clé principale AES-256-GCM en clair, l'infostealer accède aux bases de données SQLite, aux données de connexion, aux cookies et aux données Web afin de déchiffrer et d'extraire les identifiants stockés, les cookies de session, les informations de remplissage automatique, l'historique et les cartes de crédit. Enfin, toutes les informations récoltées sont collectées, sérialisées et compressées dans une structure de données Protobuf, prêtes à être exfiltrées.
Crypto-monnaie :
Le logiciel malveillant utilise une double approche pour voler des cryptomonnaies, ciblant à la fois les applications de portefeuille traditionnelles pour ordinateurs de bureau et les extensions de portefeuille modernes basées sur les navigateurs. Pour les portefeuilles de bureau, la classe WalletStealer maintient une liste exhaustive codée en dur de plus de 30 applications de portefeuille, notamment Bitcoin Core, Electrum, Exodus et Monero. Elle vérifie systématiquement les chemins d'installation par défaut (généralement dans %APPDATA%) et les clés de registre de ces applications. Si un fichier de portefeuille (tel que wallet.dat ou default_wallet) est trouvé, il est mis en file d'attente pour être exfiltré.
Cependant, la menace la plus grave réside dans le ciblage des extensions de navigateur, mis en œuvre dans le module ChromiumBrowserStealer. Ce composant cible plus de 70 portefeuilles Web3 différents basés sur un navigateur, tels que MetaMask, Phantom, Trust Wallet et Binance Chain Wallet. Il fonctionne en énumérant le répertoire Local Extension Settings des navigateurs compromis. Il compare les noms de répertoires à un dictionnaire d'identifiants d'extensions de portefeuille connus (par exemple, nkbihfbeogaeaoehlefnkodbefgpgknn pour MetaMask). Lorsqu'une correspondance est trouvée, le logiciel malveillant compresse l'ensemble du dossier de données de l'extension, qui contient les phrases de départ cryptées et les clés privées, dans une archive ZIP. Il est important de noter que, comme ces extensions utilisent souvent les mécanismes de stockage du navigateur, l'attaquant peut potentiellement décrypter ces données à l'aide de la même clé principale volée dans le profil du navigateur.
Modules restants
La liste complète des applications et services ciblés comprend :
Navigateurs Firefox / Gecko, Navigateur Opera, Navigateur Yandex, FileZilla, WinSCP, Outlook, Thunderbird, Foxmail, Mailbird , MailMaster, Telegram, Signal, Pidgin, Steam, OpenVPN, ProtonVPN, Ngrok, OBS Studio, Internet Download Manager (IDM).
Conclusion
PURELOGS démontre comment les logiciels malveillants courants se sont adaptés au paysage actuel des menaces, non pas grâce à des innovations révolutionnaires, mais grâce à des techniques d'évasion pratiques mises en œuvre à chaque stage. Ce qui est important ici, ce n'est pas la sophistication, mais l'économie de volume. Ces campagnes ne ciblent pas des secteurs spécifiques ou des entités de grande valeur. Il s'agit d'opérations de type « spray-and-pray » (pulvériser et prier) où le succès se mesure en nombre d'infections, et non en impact par victime. Pour 150 dollars par mois, les acteurs malveillants peuvent déployer cet outil et jeter un large filet sur des milliers de cibles potentielles. Plus il y a d'infections, plus il y a d'identifiants volés, de portefeuilles cryptographiques et de données à monétiser.
Cela crée une dynamique intéressante : les attaques n'ont pas besoin de contourner les EDR de pointe, car les cibles n'en disposent généralement pas. Les particuliers, les petites entreprises, les freelances utilisent au mieux Windows Defender et un antivirus basique. La chaîne de livraison en quatre étapes n'est pas excessive, elle est parfaitement adaptée à ce modèle de menace. Elle contourne les défenses grand public tout en restant peu coûteuse et évolutive.
Mais voici ce qui importe pour les organisations : ces campagnes ne font pas de discrimination. Les employés d'entreprise travaillant à domicile, les sous-traitants utilisant leurs appareils personnels, les partenaires de votre chaîne d'approvisionnement, tous sont dans le champ d'action. Une fois les identifiants compromis, ils sont testés sur les VPN d'entreprise, les services cloud et les plateformes SaaS. Un voleur d'informations qui s'attaque à l'ordinateur portable personnel d'un employé à distance peut rapidement devenir un incident de sécurité pour l'entreprise.
La défense n'est pas complexe. L'exécution basée sur la mémoire laisse des traces comportementales. Le creusement de processus crée des anomalies. L'abus de réflexion génère de la télémétrie. Mais vous avez besoin de visibilité pour le voir, et vous avez besoin d'une surveillance pour agir.
Le logiciel malveillant est peut-être bon marché, mais le risque ne l'est pas.
The only system which is truly secure is one which is switched off and unplugged locked in a titanium lined safe, buried in a concrete bunker, and is surrounded by nerve gas and very highly paid armed guards. Even then, I wouldn't stake my life on it.
- Gene Spafford, Director, Computer Operations, Audit, and Security Technology (COAST) Project, Purdue University
IOCs
| IOC | Type | Nom | Context |
| c3857a086bdac485a5e65fc88828cb0c4c831be7a1f63e2dab32a47f97b36289 | SHA256 |
PO 4501054441 Luan Pharm.js |
JS Stager |
| c208d8d0493c60f14172acb4549dcb394d2b92d30bcae4880e66df3c3a7100e4 | SHA256 | Microsoft.Win32.TaskScheduler.dll | Loader |
| 3050a5206d0847d5cfa16e79944ce348db688294e311db4d7b6045ffbe337450 | SHA256 | Qgwwal.exe | Sec. Loader |
| bb723217f9c2932116c9e1313d558a7baddb921886eaa3beca95f7b3c5b848b0 | SHA256 | ClassLibrary4.dll | Payload |
| 08a5d0d8ec398acc707bb26cb3d8ee2187f8c33a3cbdee641262cfc3aed1e91d | SHA256 | optimized_MSI.png | Payload |
| hxxps[://]archive[.]org/download/optimized_msi_20250904/optimized_MSI[.]png | url | Payload | |
| hxxps[://]ia902909[.]us[.]archive[.]org/16/items/optimized_msi_20250904/optimized_MSI[.]png | url | Payload | |
| hxxp[://]lineclearexpress[.]wuaze[.]com/arquivo_20250908023227[.]txt | url | Payload | |
| 185.27.134.206 | IP | Payload Delivery | |
| 45.137.70.55:5888 | IP:Port | C2 |
Références
https://www.ibm.com/think/x-force/dcrat-presence-growing-in-latin-america
https://github.com/SychicBoy/NETReactorSlayer
https://hackforums.net/showthread.php?tid=5926879
https://www.netresec.com/?page=Blog&month=2025-07&post=PureLogs-Forensics
