Un chargeur Windows auparavant non documenté, suivi sous le nom d’OXLOADER, diffuse l’infostealer CASTLESTEALER via des annonces Google malveillantes, avec de faibles taux de détection via des moteurs statiques et des détonations en bac à sable. Le chargeur utilise plusieurs couches d’obfuscation (aplatissement du flux de contrôle, prédicats opaques, arithmétique booléenne mixte), des stubs de déchiffrement auto-modificateurs, et abuse de la section .reloc Windows pour établir le shellcode.
Elastic Security Labs a identifié OXLOADER dans une campagne active ciblant l’un de nos clients ; Les exclusions de la région CEI et des langues russes indiquent un acteur de menace russe motivé financièrement. Nous n’avons trouvé aucun rapport public antérieur sur cette famille.
Principaux points abordés dans cet article
- Elastic Security Labs découvre un nouveau chargeur (OXLOADER)
- OXLOADER observé dans des campagnes distribuant CASTLESTEALER via des Google Ads malveillants
- L’exclusion de la région de la CEI et les contrôles de langue russe suggèrent un acteur de menace russophone et motivé financièrement
- Faibles taux de détection sur les moteurs statiques et les détonations en bac à sable
- Elastic Defend arrête toute la chaîne d’attaque grâce à des capacités avancées de prévention
Comment le malvertising a livré OXLOADER aux victimes
OXLOADER est distribué via des Google Ads malveillants se faisant passer pour Node.js. Les victimes sont redirigées via un domaine intermédiaire vers un script batch hébergé sur Storj, qui télécharge et exécute OXLOADER.
L’infection a commencé lorsque l’utilisateur a recherché un lts version of node.js et cliqué sur un résultat sponsorisé menant à node-js[.]prentiva99[.]info, une page d’atterrissage malveillante conçue pour se faire passer pour une plateforme de déploiement Node.js légitime. L’acteur menait une campagne Google Ads ciblant des victimes basées aux États-Unis ; la publicité a été diffusée pour la dernière fois le 23avril 2026, et le site est désormais hors ligne. L’annonceur était enregistré sous le nom vérifié ВОЛОДИМИР ТЕРЕЩЕНКО, basé en Ukraine. Reste incertain si cela reflète l’opérateur réel, un compte de façade ou une identité achetée. Le 14mai 2026, l’annonceur ainsi que ses campagnes publicitaires associées ont été totalement retirés de Google.
Lors de l’interaction, l’utilisateur était redirigé via app[.]miloyannopoulos[.]com/download?subid1=download, qui répondait par un 302 Found à l’URL de la charge utile link[.]storjshare[.]io/raw/jux4e4ky5mruo4jkxsssp42sau4q/ruslan/BATPackageBuilderSetup.bat. Cela a livré un script batch Windows, hébergé sur le service légitime de partage de liens de Storj , que l’acteur malveillant a exploité pour échapper au filtrage de réputation basé sur le domaine.
Le script batch affiche une fausse interface d’assistant d’installation logicielle, télécharge immédiatement l’exécutable de l’étape suivante depuis le link.storjshare[.]io/raw/jwwvr4oskkkjsgevt774ta62ehya/ruslan/aBsvwbdas.exe URL Storj via PowerShell, puis le lance avec -Verb RunAs pour déclencher une invite d’élévation UAC.
Après l’exécution du script Batch, Elastic Defend détecta un comportement malveillant (la politique était réglée sur détection uniquement), déclenchant plusieurs règles comportementales, dont Microsoft Common Language Runtime Loaded from Suspicious Memory, suggérant un . Charge utile basée sur NET compatible avec CASTLESTEALER.
Voici le graphique d’exécution de la chaîne d’attaque, du téléchargement de la charge utile au déploiement CASTLESTEALER .
Chargeur de malwares OXLOADER : analyse technique
Le premier échantillon d’OXLOADER que notre équipe a analysé se fait passer pour l’outil populaire, API Monitor de rohitab.com. Grâce à la forte présence de code légitime et de techniques de dissimulation de code, ce chargeur peut passer inaperçu face aux analyseurs de fichiers statiques.
Comment OXLOADER se décompose à l’exécution
Le malware commence à s’exécuter pendant la phase d’initialisation du CRT, avant que tout code utilisateur ne soit exécuté. La fonction CRT cinit() invoque initterm(), qui parcourt la table d’initialisation C++ (__xc_a → __xc_z) appelant chaque entrée. Le développeur du malware a détourné l’une de ces entrées, pointant vers une fonction qui passe un appel RegisterClipboardFormatW() avant de passer directement au premier stub de déchiffrement.
Le chargeur utilise des techniques auto-modifiables avec plusieurs stubs de déchiffrement pour se dérouler lui-même. Voici un exemple d’un stub de déchiffrement patché pendant l’exécution, avant de passer dessus.
Après le patching, le chargeur déchiffre une région de 28 233 octets. Chaque octet est déchiffré avec une clé XOR d’un seul octet qui se met à jour après chaque itération : l’octet de texte clair juste déchiffré est ajouté à la clé, qui sert ensuite à déchiffrer le octet suivant. Cette routine de déchiffrement similaire s’exécute trois fois au total, chacune sur une région différente.
Techniques d’obfuscation utilisées pour éviter la détection statique
OXLOADER casse la détection automatisée des frontières de fonction dans des outils d’analyse binaire tels que IDA Pro en utilisant quatre techniques d’obfuscation en couches : aplatissement en flux de contrôle (CFF), arithmétique booléenne mixte (MBA), prédicats opaques et fragmentation de fonctions à travers des régions de code non contiguës. Les fonctions sont assemblées par des sauts inconditionnels, et certaines régions sont atteintes par des sauts indirects dont les adresses cibles sont calculées à l’exécution via l’arithmétique MBA. Le résultat est qu’IDA Pro ne peut pas reconstruire de manière fiable les limites de fonction, nécessitant des corrections manuelles.
Le chargeur déchiffre diverses chaînes à l’exécution en utilisant l’algorithme de déchiffrement suivant :
uint32_t obf_xor_a1_with_a2_plus_33FDA(uint32_t a1, uint32_t a2) {
return a1 ^ (a2 + 0x33FDA);
}
Une fois le code complètement décompressé/déchiffré, le malware combine cette fonction de déchiffrement de chaînes avec un algorithme de hachage API Adler-32 pour résoudre dynamiquement ses importations.
Comment OXLOADER évite-t-il la détection du bac à sable et des machines virtuelles ?
Après avoir résolu ses API, OXLOADER effectue diverses vérifications pour s’assurer que la machine s’exécute dans un environnement propre, évitant ainsi l’exécution dans des environnements bac à sable.
| C'est par ici | Méthode | Seuil |
|---|---|---|
| Émulation | WNetAddConnection2W avec ressource malformée | S’attend à ERROR_BAD_NAME (0x43) |
| Nombre de processeurs | Vérification de l’environnement de procédé | ≥ 3 CPU |
| RAM | GlobalMemoryStatusEx | ≥ 3 Go de mémoire physique |
| Taux de rafraîchissement d’affichage | Requête WMI Win32_VideoController | ≥ 20 Hz |
| Région géographique | GetUserGeoID | Exclut les GEOÏDES CIS |
La première vérification tente de se connecter à une ressource réseau délibérément déformée (*72s@1s) en utilisant mpr!WNetAddConnection2W. Cette technique semble contrer l’émulation/bacs à sable qui peuvent accrocher ou rétablir une connexion réussie sans condition. Le développeur du malware vérifie cet appel en accédant directement au TEB pour récupérer le LastErrorValue. Le chargeur s’attend à ce que ce code d’erreur soit ERROR_BAD_NAME (0x43); si le code d’erreur est autre que cette valeur, le malware prend la branche de défaillance et arrête l’exécution.
La seconde vérification est un test anti-bac à sable basé sur le nombre de processeurs : le chargeur exige que l’hôte ait au moins 3 processeurs pour continuer. De nombreux bacs à sable et machines virtuelles d’analyse sont équipés d’un ou deux CPU pour économiser des ressources, ce qui filtre donc ces environnements d’analyse automatisés.
La vérification suivante utilise GlobalMemoryStatusEx() pour vérifier que l’hôte dispose d’au moins 3 Go de mémoire physique disponible.
Une vérification supplémentaire utilise WMI pour interroger la fréquence de rafraîchissement de l’affichage système, exécuter la SELECT CurrentRefreshRate FROM Win32_VideoController de l’instruction WQL et comparer la valeur retournée (en Hertz) avec un seuil de 20. Les moniteurs physiques indiquent généralement autour de 60 Hz ou plus, tandis que les configurations headless et virtualisées par défaut indiquent généralement 0 ou 1, et des valeurs inférieures à 20 provoquent l’annulation du chargeur.
Exclusions géographiques et linguistiques
Les deux derniers contrôles arrêtent l’exécution si l’hôte est situé dans un pays de la CEI ou configuré pour la langue russe. La première vérification dans cette catégorie utilise GetUserGeoID pour récupérer la région géographique du système et la comparer à une liste codée en dur des GEOÏDES des pays de la CEI.
La seconde vérification utilise GetUserDefaultUILanguage et correspond à LANGID (0x419 - Russian, Russia), la configuration standard pour une installation Windows en langue russe.
Staging par shellcode via .reloc section et fichier OCX
Après toutes les vérifications, le malware effectue une copie du DLL Windows DirectUI Engine (C:\Windows\System32\dui70.dll), le stockant dans un emplacement temporaire à l’aide d’un nom généré aléatoirement avec l’extension .ocx (PFHemkxVk.ocx). Ce choix d’extension a inspiré le nom de famille OXLOADER.
OXLOADER crée alors une nouvelle section nommée (.xtext) dans cette DLL cible (PFHemkxVk.ocx).
Cette nouvelle section (.xtext) est configurée avec des protections RWX (lecture/écriture/exécution) en préparation du stockage et de l’exécution de l’étape suivante du code malveillant.
Cette DLL mise à jour (PFHemkxVk.ocx) est ensuite chargée dans le processus de chargement existant via LoadLibraryA.
Dans un exécutable Windows classique, la section .reloc contient un tableau de blocs de IMAGE_BASE_RELOCATION que le chargeur Windows applique pour corriger les adresses absolues lorsque l’image est chargée à une adresse autre que sa base préférée. Dans cet exemple, le développeur du malware utilise
la section .reloc pour loger du code malveillant au lieu des entrées de relocalisation de base. C’est un signal d’alarme fort pour l’analyse statique : les chaînes d’outils légitimes n’émettent pas de code dans la section .reloc .
Ce shellcode de la section .reloc est ensuite copié dans la nouvelle section (.xtext) du fichier OCX, et le chargeur appelle alors ce code.
Comme observé précédemment, un autre stub de déchiffrement est utilisé pour décomposer cette étape suivante.
Livraison infostealer en mémoire via DonutLoader et assembleur .NET
Ce shellcode de l’étape suivante est une charge utile configurée à partir de DonutLoader, un générateur de shellcode open source utilisé pour envelopper les assemblies, DLL et EXE .NET dans un shellcode indépendant de la position (PIC) pour une exécution en mémoire. Lors du décompressage, le shellcode déchiffre la configuration intégrée et le contexte d’exécution du chargeur en utilisant le chiffrement de blocs Chaskey-LTS en mode CTR avec la clé (6E0A1F8F77F7011561F6F9CA96B71B8F) et IV (956C6128E9362E075F8D006C93616A66).
Après le déchiffrement, la charge utile est décompressée via aPLib puis démarrée via la fonction RunPE() de DonutLoader. La dernière charge utile est un voleur d’information récemment découvert par Huntress appelé CASTLESTEALER. Cette attribution est basée sur la même clé AES utilisée pour les communications C2 que celle trouvée entre 0xDEADBEEF marqueurs dans un échantillon précédent.
Deuxième variante d’OXLOADER : même chargeur, programme masqué différent
Une seconde variante d’OXLOADER se fait passer pour un installateur Node.js plutôt qu’un moniteur API, mais utilise le même mécanisme de chargeur.
Le 13mai 2026, nous avons découvert que le point de terminaison du redirecteur répondait app.miloyannopoulos[.]com/download par l’un des deux champs d’en-tête de Location , choisis au hasard :
https://link.storjshare[.]io/raw/jv5uebuqwzfpmtahj34q753ptykq/node/BATPackageBulderSetup.bathttps://link.storjshare[.]io/raw/jvsmdybqmvwep2oawbobp6ub7aza/node/node-v24.15.0-x64-86.exe
Le script d’installation Batch (BATPackageBulderSetup.bat, avec une faute de frappe pour « Builder ») est resté en grande partie identique. La seule différence était que le lien de la charge utile Storj pointait désormais vers un autre binaire nommé node-v24.15.0-x64-86.exe.
La charge utile tente de se faire passer pour un code CMake bénin tout en conservant « nœud » dans le nom du fichier, probablement pour préserver le thème de leurre. Nous pensons que l’échantillon précédent « API Monitor » était probablement une erreur de distribution de l’opérateur.
Lors de l’exécution, nous avons remarqué le même schéma : des sauts indirects utilisés pour l’auto-déchiffrement en mémoire, suivis du chargement de mpr.dll et d’un appel à WNetAddConnection2W. Nous avons confirmé qu’il s’agit du mécanisme de chargement identique évoqué précédemment, et cet échantillon charge également CASTLESTEALER.
Voici un extrait où l’auto-déchiffrement a lieu. Les chaînes de chaînes liées à la CMake factice semblent être transmises comme arguments à un appel de fonction, qui patche un petit stub de déchiffrement en mémoire immédiatement après le site d’appel. L’exécution passe ensuite au stub pour déchiffrer les instructions suivantes, et ce processus se répète 2 fois jusqu’à ce que le corps principal du malware soit déchiffré.
Conclusion : pourquoi les défenseurs devraient suivre OXLOADER
OXLOADER en est à une phase opérationnelle précoce, mais l’ingénierie qui le sous-tend suggère que cette famille mérite d’être surveillée. L’obfuscation du code, les mesures anti-VM, le code à l’apparence bénigne utilisé pour masquer ses binaires, et les techniques de staging uniques reflètent des choix d’ingénierie délibérés pour échapper à l’analyse. Cet investissement porte ses fruits, entraînant de faibles taux de détection sur les moteurs statiques et les détonations, offrant à OXLOADER une fenêtre pour fonctionner avant d’être traqué.
REF8372 à 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
Les tactiques représentent le pourquoi d'une technique ou d'une sous-technique. Il s'agit de l'objectif tactique de l'adversaire : la raison pour laquelle il effectue une action.
- Développement de ressources
- Accès initial
- Exécution
- Évasion par la défense
- Découverte
- Commande et contrôle
- Collecte
- Exfiltration
Techniques
Les techniques représentent la manière dont un adversaire atteint un objectif tactique en effectuant une action.
- Acquisition d’infrastructures : Malvertising
- Capacités d'étape : Téléchargement de logiciels malveillants
- User Execution: Malicious File
- Interprète de commandes et de scripts : PowerShell
- Abuser d'un mécanisme de contrôle d'élévation : Contournement du contrôle de compte d'utilisateur
- Fichiers ou informations obscurcis : fichier chiffré/codé
- Décodage des fichiers ou des informations
- Fichiers ou informations obscurcis : charges utiles intégrées
- Mascarade : Faire correspondre un nom ou un lieu légitime
- Flux d'exécution du pirate : chargement latéral de DLL
- Évasion de virtualisation/sandbox : vérifications du système
- System Location Discovery: System Language Discovery
- Chargement du code réfléchissant
Assainissement REF8372
La prévention
- Découverte potentielle d'informations sur le navigateur
- Evasion potentielle avec les points d'arrêt matériels
- Manipulation suspecte du contexte des fils
- Appel API VirtualAlloc à partir d'une DLL non signée
- Allocation de mémoire à distance suspecte
- Exécution à partir d’octets suspects de pile
- Microsoft Common Language Runtime Loaded from Suspicious Memory
- Suspicious PowerShell Execution (Exécution suspecte de PowerShell)
- Piétinement de module à partir d’une bibliothèque copiée
YARA
Elastic Security a créé des règles YARA pour identifier cette activité.
Observations
Les observables suivants ont été examinés dans le cadre de cette recherche.
| Observable | Type | Nom | Référence |
|---|---|---|---|
node-js\[.\]prentiva99\[.\]info | nom de domaine | Page d’accueil de malvertisation | |
app\[.\]miloyannopoulos\[.\]com | nom de domaine | Redirecteur de malvertisation | |
fdfc7831e5c24cfa80152860dfe8c056ba079f7df1393bf6bb7b18ed974eda37 | SHA-256 | BATPackageBuilderSetup.bat | Téléchargeur et lanceur OXLOADER |
de4f51649ec1a33071854aefe93ffb3fc225e19f802d8dd914676dd5dfef2615 | SHA-256 | BATPackageBulderSetup.bat | Téléchargeur et lanceur OXLOADER |
9a9939dff297997732aaade9b243d695632cbd64033c5fbcb9de3d09b7e6c28d | SHA-256 | apimonitor-x64.exe | OXLOADER |
c85f2765a6c3c3f3907c17e57df12f8f68826f74bff3bbfd272af50666d065fe | SHA-256 | node-v24.15.0-x64-86.exe | OXLOADER |
4ec9d9d4d10ad78fc6d7bda7cb17d52984878ccd2dd4302fd1cef152313b9741 | SHA-256 | VOLEUR DE CHÂTEAU | |
39019279686c820c3af5684012a0085a7e2109f612c9fab886dd0577ace5b5c6 | SHA-256 | VOLEUR DE CHÂTEAU | |
89.124.95\[.\]161 | ipv4 | CASTLESTEALER C2 | |
89.124.115\[.\]82 | ipv4 | CASTLESTEALER C2 |