Salim Bitam

PHANTOMPULSE : anatomie d'un RAT C2 basé sur la blockchain et susceptible d'être piraté

Elastic Security Labs présente une analyse détaillée par rétro-ingénierie de PHANTOMPULSE, un RAT de longue durée déployé auprès de victimes du secteur de la cryptographie via le kit d'intrusion REF6598.

Dans son analyse précédente du rapport REF6598, Elastic Security Labs a mis en évidence un ensemble d'intrusions dont la chaîne d'outils Windows a été introduite via une exploitation du plugin Obsidian, a permis une élévation de privilèges grâce à un chargeur PE en mémoire (PHANTOMPULL) et s'est conclue par l'installation d'un RAT (PHANTOMPULSE). Cet article portait sur la livraison. Cet article analyse la phase finale : PHANTOMPULSE, un implant qui intègre trois techniques d'injection de processus, résout son C2 via des entrées de transaction Ethereum/Base/Optimism et contourne l'UAC grâce à la technique de l'schuac e publique. L'analyse met en évidence un canal de commande et de contrôle (C2) basé sur la blockchain et susceptible d'être neutralisé, ainsi qu'une primitive matérielle unifiée de point d'arrêt qui désactive les technologies AMSI, WLDP et ETW, et élimine les traces omniprésentes de développement assisté par IA dans les chaînes de débogage de l'implant.

Principaux points abordés dans cet article

  • PHANTOMPULSE met en œuvre trois techniques d'injection inspirées de récents PoC (preuves de concept) publics en matière de sécurité offensive.
  • Les primitives AMSI, WLDP et ETW sont contournées via une seule primitive HWBP partagée
  • Le résolveur C2 de la blockchain ne procède à aucune vérification de l'expéditeur, ce qui permet à un attaquant de remplacer l'URL C2 de chaque implant en envoyant une seule transaction
  • Le fichier binaire contient des indicateurs clairs d'un développement assisté par l'IA

Remarque sur le développement assisté par l'IA

PHANTOMPULSE porte clairement la marque de l'assistance au codage par IA, comme en témoignent les chaînes de débogage.

Les indices les plus évidents :

  • Numérotation structurée des étapes dans les journaux d'exploitation : [STEP 1] Staged mode — payload downloaded from C2 at runtime, [STEP 1/3] Scheduled Task (DotNetSvcUpdateTask, logon + every 3 min), [STEP 2/3] Boot Task (DotNetSvcCoreTask, INTERACTIVE_TOKEN + BootTrigger), [UNINSTALL 4/6] Removing persist_loader DLL + registry PE data..., [REPAIR] Reinstalling boot task (INTERACTIVE_TOKEN)....
  • Suivi de la fonction ENTER/DONE: "[HEIS] encrypt_text_only ENTER" / "[HEIS] encrypt_text_only DONE", "KeylogResolveAPIs: ENTER". Le style de diagnostic que les modèles de langage de grande envergure (LLM) adoptent par défaut lorsqu'ils génèrent de nouvelles fonctions.
  • Diagnostics détaillés: "FindHostProcessEx: scan stats: total=%lu sessSkip=%lu openFail=%lu native=%lu wow64=%lu mapReject=%lu dbgReject=%lu sess=%lu", "ManualMap: thread hijacked and resumed — DLL injection via thread hijack complete". Un message d'erreur clair, ce qui est inhabituel pour un logiciel malveillant.
  • Tirets dans les chaînes C: "elevate: FAIL — no deployed DLL path", ">>> .elevate: NOT proxy — spawning trusted host to handle elevation".

Chaîne d'exécution

MainEntryLogic Il s'agit de la fonction d'orchestration qui exécute la séquence d'initialisation complète avant d'entrer dans la boucle C2 :

start
 └─ WinMain
     └─ MainEntryLogic
         1. DynInit                // Bootstrap API resolution
         2. ElevationStateCheck    // ".elevate" marker detection, routes by token elevation state
         3. SingleInstanceCheck    // XOR-decrypted mutex, exit if already running
         4. EvasionInit            // Direct syscalls + ETW HWBP
         5. SyscallResolverInit    // CPUID + hash-based kernel32 resolution
         6. SleepMaskInit          // Sleep obfuscation setup
         7. ComputeMachineID       // DJB2(module name) ^ volume serial
         8. IsRunningHollowed      // Process hollowing self-check
         9. CollectSysInfo         // CPU, GPU, RAM, OS, AV, apps
        10. FilelessPersist        // Drop stub DLL, registry artifact
        11. InstallPersistence     // Three scheduled tasks via COM ITaskService
        12. C2Loop_Init → C2Loop_Main

Au démarrage, l'implant effectue un hachage DJB2 du nom d'utilisateur et du nom de l'ordinateur, puis recherche chacun d'eux dans une table précalculée. Une correspondance quitte le processus. Une attaque par force brute menée sur le tableau à l'aide de listes de mots publiques anti-sandbox a permis de récupérer l' 20 s sur les entrées de l' 61 : WDAGUtilityAccount (Windows Defender Application Guard), plusieurs noms de machines virtuelles par défaut de DESKTOP-XXXXXXX, ainsi que les personas de Joe Sandbox (abby, patex, george, john, lisa, frank, RDhJ0CNFevzX).

Évasion par la défense

Appels système directs et wrappers d'API

PHANTOMPULSE résout les fonctions ntdll en parcourant les structures « PEB→Ldr » à l'aide des hachages DJB2, extrait les numéros de service système (SSN) du prologue de chaque fonction NT et génère des stubs d'appels système privés. Ces ébauches sont intégrées dans des fonctions d'assistance de niveau supérieur utilisées dans le reste de l'implant :

  • NtCreateFile_Wrap
  • NtWriteFile_Wrap
  • NtClose_Wrap
  • NtCreateSection_Wrap
  • NtMapViewOfSection_Wrap
  • NtProtectVirtualMemory_Wrap
  • NtWriteVirtualMemory_Wrap

Le reste de l'implant appelle ces wrappers au lieu des exportations kernel32/ntdll, contournant ainsi les hooks d'ntdll s en mode utilisateur (remplacements IAT, détournements en ligne ou correctifs trampoline) que les produits EDR injectent dans l'interface API documentée.

Une seule fonction d'aide achemine directement chaque écriture sur disque via NtCreateFile + NtWriteFile, en procédant à une suppression puis à une nouvelle tentative en cas d'erreur d'accès.

Obfuscation des chaînes de caractères et des paramètres de configuration

PHANTOMPULSE utilise quatre couches XOR pour différents artefacts :

QuoiCléOù se trouve la clé
URL de secours C2, mutex, noms de fichiers du chemin de secours16 octets : F7 7C 8E 40 DF C1 7B E5 E7 4D 86 79 D5 B3 53 41Intégré dans .rdata
Noms d'hôte des fournisseurs de blockchain (UTF-16 LE)8 octets : 5A 3C 7E 1D 9F 2B 4E 8AIntégré dans .rdata
Nom du fichier « COM Elevation », contenu du fichier keylog0xE95CA237, calculée lors de l'exécution afin d'éviter d'inclure la constante dans .rdataCalculé, non enregistré
URL C2 extraite d'une transaction sur la blockchain inputL'adresse du portefeuille du résolveur elle-mêmeRepris de la clé de recherche publique

Contournement des fonctions AMSI, WLDP et ETW via des points d'arrêt matériels

PHANTOMPULSE désactive AMSI, la vérification de la fiabilité du code dans la stratégie de verrouillage de Windows, ainsi que la télémétrie ETW, grâce à une seule primitive commune : un point d'arrêt matériel placé à chaque entrée d'API, intercepté par un gestionnaire d'exceptions vectorisé qui simule la valeur de retour sans recourir à un patch en ligne.

Machine à sousAPI cibleRetour falsifié (RAX)
DR0WldpQueryDynamicCodeTrust0 (S_OK)
DR1AmsiScanBuffer0x80070057 (E_INVALIDARG)
DR2EtwEventWrite0 (STATUS_SUCCESS)

Le fonctionnement, étape par étape :

  1. L'implant résout l'API cible. AMSI et WLDP passent par LoadLibraryA + une recherche d'exportation basée sur le hachage ; ETW utilise un parcours PEB→Ldr puisque ntdll est déjà chargé.
  2. Le descripteur HWBP (adresse API cible, mode, valeur de retour falsifiée) est écrit dans l'un des quatre emplacements de 40 octets d'une table d'emplacements globale.
  3. Un thread d'assistance suspend le thread cible, appelle les fonctions NtGetContextThread / NtSetContextThread pour écrire les registres DR0 à DR3 et DR7, puis reprend son exécution. STATUS_BREAKPOINT (Si le gestionnaire d'exceptions vectorisé de l'implant est déjà installé, une exception « in-process » est alors déclenchée, ce qui permet au VEH de lire la table des emplacements et de programmer les DR sans recourir à un thread d'assistance.)
  4. Lorsque l'API protégée est appelée, le processeur génère une exception « Debug Exception » dès la première instruction de la fonction.
  5. Le gestionnaire d'exceptions vectorisé de l'implant intercepte l'Debug Exception, parcourt sa table à 4 emplacements pour trouver l'adresse d'exécution, puis modifie le contexte du thread : CONTEXT.Rax est défini sur la valeur de retour falsifiée propre à chaque emplacement, tandis que CONTEXT.Rip est redirigé vers un thunk de saut "préenregistré" qui renvoie le contrôle à l'appelant.
  6. Le gestionnaire renvoie EXCEPTION_CONTINUE_EXECUTION. L'appelant perçoit le RAX falsifié comme si l'API avait été exécutée.

Le répartiteur gère deux itinéraires. Un gestionnaire (VEH_Dispatcher) traite à la fois les appels ` RaiseException(STATUS_BREAKPOINT) ` propres à l'implant (utilisés pour initialiser et reprogrammer les registres DR à partir de la table des emplacements) et les exceptions ` STATUS_SINGLE_STEP ` qui se déclenchent lorsqu'une API protégée est appelée. Le code d'exception détermine la branche : « STATUS_BREAKPOINT » déclenche la programmation DR, tandis que « STATUS_SINGLE_STEP » déclenche la simulation.

Le gestionnaire n'est pas non plus enregistré directement. AddVectoredExceptionHandler reçoit un petit thunk JMP alloué à l'exécution dans une nouvelle page d'MEM_PRIVATE s (VirtualAlloc + VirtualProtect vers PAGE_EXECUTE_READ). Le thunk est un saut indirect de type « JMP [RIP-relative] » (code d'opération de 6 octets : FF 25 00 00 00 00) suivi, en ligne, de l'adresse du dispatcher. Étant donné qu'aucun octet n'est jamais écrit dans les fichiers AmsiScanBuffer, WldpQueryDynamicCodeTrust ou EtwEventWrite, la détection basée sur les signatures qui recherche des modifications du prologue passe complètement à côté de ce problème.

Variante de construction : sous-systèmes actifs et dormants

Plusieurs sous-systèmes sont présents dans le fichier binaire sous forme de code ou de chaînes de caractères, mais ne sont pas actifs dans cette version. Il s'agit d'une version allégée d'un code source plus volumineux.

  • Désactivation de NTDLL: les chaînes de débogage relatives au sous-système de désactivation se trouvent dans .rdata (UnhookNtdll: ntdll base = %p, applied %d relocation fixups to .text), mais aucune référence n'y est faite. Cette variante est obsolète.
  • Chargeur de blobs PE résidant dans le registre: les versions antérieures stockaient le fichier PE de l'étape suivante dans le registre. Ce programme ne le fait pas, mais la routine de désinstallation supprime tout de même les entrées obsolètes du registre.
  • Persistance du détournement COM: n'est jamais installée par cette version. La logique de nettoyage correspondante reste dans la routine de désinstallation.
  • Persistance du moniteur d'impression: même schéma que pour le détournement COM ; chemin d'installation absent, chemin de désinstallation conservé.

Les trois derniers (chargeur de blobs du registre, détournement COM, moniteur d'impression) présentent un schéma inverse : une logique de nettoyage sans logique d'installation, conservée pour assurer la compatibilité ascendante avec les anciens déploiements.

Fonctionnalitécompilation des charges utilesDonnées probantes
Appels système directs (extraction du SSN)ActifExtraction du numéro de sécurité sociale + génération du stub confirmées
Contournement AMSI / WLDP / ETW HWBPActifDR0/DR1/DR2 via une primitive de thread d'assistance partagé
Injection en trois étapesActifPhantomInject, DbgNexum, ManualMap sont tous opérationnels
Résolution C2 relative à la blockchainActifTrois fournisseurs de Blockscout ont été interrogés
Désactivation de NTDLLCode mortChaînes présentes, aucune référence au code
Cryptage HEISDésactivéCode de chiffrement/déchiffrement simulé
Chargeur de blobs PE résidant dans le registreAncienne version uniquementNettoyage effectué uniquement lors de la désinstallation
Persistance du détournement COMAncienne version uniquementSupprimé lors de la désinstallation, jamais installé
Persistance de l'impressionAncienne version uniquementSupprimé lors de la désinstallation, jamais installé
Chaînes leurresActif4 chaînes factices non référencées dans .rdata

Commande et contrôle

Résolution C2 relative à la blockchain

PHANTOMPULSE décentralise la recherche C2 via trois fournisseurs Blockscout :

  • eth.blockscout[.]com (Ethereum L1)
  • base.blockscout[.]com (Base L2)
  • optimism.blockscout[.]com (Optimisme L2)

L'adresse de portefeuille 0xc117688c530b660e15085bF3A2B664117d8672aA est déchiffrée par XOR à partir de la mémoire à l'aide d'une clé de 16 octets. Pour chaque fournisseur, l'implant envoie une requête GET HTTPS (port 443, erreurs de certificat SSL ignorées), récupère le champ « input » de la dernière transaction, le convertit en décimal, le déchiffre par XOR en utilisant les octets de l'adresse du portefeuille comme clé, puis vérifie que le résultat commence par http. En cas d'échec total, le système se rabat sur l'URL fixe https://panel.fefea22134[.]net.

Le résolveur ne vérifie pas l'identité de l'expéditeur de la transaction. Il vérifie simplement que l'input e décodée la plus récente commence par http. N'importe qui peut envoyer une transaction vers ce portefeuille en incluant sa propre URL codée en XOR dans les octets du portefeuille, et chaque instance PHANTOMPULSE de cette campagne qui effectuera une interrogation par la suite sera redirigée vers cette URL. Pour les responsables de la sécurité réseau, il s'agit d'un piège efficace qui ne coûte qu'une seule transaction.

Points de terminaison et signal de santé

Cinq chemins d'accès API sont générés lors de l'exécution, puis rechiffrés en mémoire à l'aide d'une clé propre à chaque session :

CheminMéthodeType de contenuFinalité
/v1/telemetry/reportPOSTapplication/jsonHeartbeat avec télémétrie complète du système
/v1/telemetry/tasks/<machine_id>GETRecherche de commandes
/v1/telemetry/upload/POSTimage/bmpCapture d'écran / téléchargement de fichiers
/v1/telemetry/resultPOSTapplication/jsonCommande livraison du résultat
/v1/telemetry/keylog/POSTtext/plainTéléchargement des données du journal de bord

Le heartbeat envoie un profil complet du système au format JSON :

{
  "machine_id": "<uint32>",
  "status": "online",
  "cpu": "<model>",
  "gpu": "<description>",
  "ram_mb": "<uint32>",
  "os": "<version>",
  "username": "<user>",
  "computer_name": "<name>",
  "cores": "<uint32>",
  "screen_w": "<int>",
  "screen_h": "<int>",
  "privilege": "<user|admin|admin_nouac|system>",
  "build": "payloads",
  "public_ip": "<ip>",
  "av_list": ["<av1>", "<av2>"],
  "apps": ["<app1>", "<app2>"],
  "last_cmd": "<cmd>",
  "last_cmd_result": "<result>"
}

Deux champs de réponse sont analysés : "status":"deleted" déclenche une désinstallation complète ; "ip":"<value>" alimente le cache des adresses IP publiques, mais uniquement si la découverte locale (ipif[.]org / icanhazip[.]com/ checkip.amazonaws[.]com) si ce n'est pas déjà fait.

Cadence de boucle et résilience

  • Sommeil: durée aléatoire uniforme comprise entre 20 et 40 secondes
  • Auto-réparation: s'exécute à la 2e itération, puis toutes les 10 itérations
  • Contrôle de l'état de santé: premier appel dès la mise en service de l'implant, puis tous les cinq cycles par la suite. Remplit une structure d'informations système locale (% s sur le processeur, la mémoire vive, la version du système d'exploitation, la durée de fonctionnement et le nom de l'ordinateur).
  • Seuil de défaillance: 10 défaillances consécutives du signal de pulsation déclenchent un redémarrage automatique pour la récupération SSL/TLS bloquée
  • Nouvelle résolution: en cas d'échec, le processus de nouvelle résolution de la blockchain est lancé ; si l'URL résolue change, le compteur d'échecs est remis à zéro
  • Adresse IP publique: api4.ipify[.]orgipv4.icanhazip[.]comcheckip.amazonaws[.]com
  • Vérification de la connectivité: sondes microsoft[.]com, google[.]com, cloudflare[.]com, github[.]com

Envoi des commandes

Le répartiteur de commandes achemine les commandes en fonction du hachage DJB2. Huit commandes au total :

HachuresCommandementComportement
0x04CF1142injectInjecter du shellcode, une DLL ou un fichier EXE. Pistes par type : shellcode → PhantomInject; DLL → ManualMap; EXE → DbgNexum. Les contournements AMSI et WLDP HWBP sont installés lors du premier appel à l'inject (le contournement ETW HWBP est déjà en place depuis EvasionInit).
0x7C95D91AdropPlacez le fichier sur le disque et exécutez-le. Prend en charge les charges utiles au format DLL, EXE, shellcode (injection APC) et MSI.
0x9A37F083screenshotCapturez l'image GDI, réduisez-la à une largeur de 960 pixels, puis téléchargez-la au format BMP.
0x08DEDEF0keylogDémarrez ou arrêtez l'enregistreur de frappe intégré.
0x4EE251FFuninstallNettoyage et désinstallation en 6 étapes.
0x65CCC50BelevateContournement de l'UAC via la technique « schuac » (IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)) ; enregistrement d'une tâche à privilèges élevés de courte durée qui relance l'implant.
0xB3B5B880downgradeSYSTÈME → transition vers un compte administrateur.
0x20CE3BC8(redémarrage automatique)Arrêt automatique en cascade : NtTerminateProcess(-1, 0) effectue d'abord l'appel système direct ; si celui-ci échoue, le système se rabat sur ExitProcess(0). Persistence relance l'implant lors du prochain cycle de tâche prévu. Cela revient, en pratique, à un redémarrage en douceur.

Le huitième gestionnaire n'apparaît dans aucun journal de débogage. Elle se termine automatiquement ; la tâche planifiée relance l'implant au prochain cycle. L'absence de structure de type LLM (chaînes de débogage) fait de ce gestionnaire l'un des rares du binaire à sembler avoir été ajouté par un développeur humain plutôt que généré par un LLM.

Techniques d'injection

PHANTOMPULSE propose trois techniques d'injection, une par type de charge utile. La commande C2 de l'inject redirige le shellcode vers PhantomInject, les DLL vers ManualMap et les fichiers EXE vers DbgNexum.

Les contournements des points d'arrêt matériels AMSI/WLDP sont installés lors du premier appel à ` inject `, avant l'exécution de tout injecteur.

Type de charge utileInjecteurStratégie
ShellcodePhantomInjectUtilisation de modules dans « dbghelp.dll » via SEC_IMAGE
EXEDbgNexumMachine à états de l'API de débogage
DLLManualMapMappage manuel complet de la mémoire physique

PhantomInject : module qui s'intègre à dbghelp.dll

Le « module stomping » permet d'éviter l'allocation de mémoire par l'MEM_PRIVATE, en mappant une DLL Windows légitime en tant qu'« SEC_IMAGE » et en écrasant « .text » :

  1. Récupère l'SeDebugPrivilege (via OpenProcessToken / LookupPrivilegeValueW / AdjustTokenPrivileges), puis parcourt l'instantané du processus pour l'un des sept processus hôtes candidats (correspondance sans distinction de casse). Essayés par ordre de priorité : sihost.exe, taskhostw.exe, backgroundTaskHost.exe, RuntimeBroker.exe, dllhost.exe, ctfmon.exe, explorer.exe.

  2. Ouvre dbghelp.dll via NtOpenFile, crée la section SEC_IMAGE, et la mappe vers la cible via NtMapViewOfSection

  3. Analyse la copie locale pour déterminer l'adresse RVA et la taille de la mémoire allouée ( .text ), puis la libère

  4. Sélectionne et suspend un thread, capture le contexte

  5. Crée un trampoline « save-call-restore » de 82 octets

  6. Écrit du shellcode et un trampoline dans l'.text e de la DLL mappée

  7. Active la protection PAGE_EXECUTE_READ

  8. Renvoie vers le trampoline, reprend le fil de discussion

Pour un analyseur de mémoire, le résultat ressemble à un thread s'exécutant au sein d'une instance légitime d'dbghelp.dll, une zone d'image associée à un fichier comportant le chemin d'accès, le nom de section et le hachage de la première page corrects.

DbgNexum : une API de débogage servant de contrôleur d'exécution

DbgNexum prend en charge les charges utiles EXE. Plutôt que d'écrire d'emblée du code exécutable dans la cible, il utilise l'API de débogage Windows pour faire avancer l'exécution exception par exception : une chaîne ROP dont les gadgets sont des API Windows complètes dans la cible.

Cette technique n'est pas une invention de PHANTOMPULSE. Il s'agit d'une reproduction mot pour mot de dis0rder0x00/DbgNexum, une démonstration publique de faisabilité publiée sur GitHub le 4 janvier 2026. L'opérateur a conservé tel quel le nom de la technique publiée ("DbgNexum") dans les chaînes de débogage de l'implant, et la machine à états interne correspond en tous points : même API d'appât, même nom de section, même chaîne de gadgets et mêmes constantes. PHANTOMPULSE intègre le cœur x64 extrait à une infrastructure opérationnelle dont le PoC ne dispose pas : la sélection du processus hôte (FindHostProcessEx), un mécanisme de secours qui lance une nouvelle instance de SysWOW64\cmd.exe / rundll32.exe / notepad.exe, un programme de démarrage personnalisé pour le chargement de fichiers PE (afin de pouvoir prendre en charge des fichiers EXE complets plutôt que du shellcode brut), et une variante inter-architectures WoW64 distincte.

Pour les charges utiles x64 natives, l'implant pré-positionne le fichier PE, le stub de démarrage et la configuration du trampoline au sein d'une section de mappage de fichiers nommée. Le nom de la section est la chaîne littérale de deux octets « "MZ" » ; l'implant se connecte à l'adresse « DebugActiveProcess » et crée un thread distant à l'adresse « FileTimeToSystemTime » avec un point d'arrêt matériel sur DR0.

Lorsque l'appât atteint le point de rupture, un automate d'états guide la cible à travers cette chaîne d'API :

  1. Redirigez RIP vers DbgBreakPoint+1 en activant le drapeau « trap » ; l'exception à étape unique qui en résulte se propage vers le reste de la chaîne.
  2. LocalAlloc(LMEM_ZEROINIT, 3), allouez le tampon de nom de 3 octets.
  3. memcpy(buf, kernel32_base, 2), copiez le contenu de la ligne « "MZ" » de l'en-tête DOS du fichier « kernel32.dll » dans le tampon.
  4. memset(stack+40, 0, 8): réinitialiser un emplacement d'argument de la pile.
  5. OpenFileMappingA(0x1F, FALSE, "MZ"), ouvrez la section préparée avec un accès complet à la cartographie de la section.
  6. MapViewOfFile(...), et l'appliquez à la cible.
  7. Redirigez RIP vers mapped_base + 0x400, la page de démarrage. Il s'agit de la seule étape enregistrée directement : DbgNexumLoop64: stage 6 -> stub at %llx, base=%llx. (Le PoC redirige vers mapped_base + 0 pour le shellcode brut ; PHANTOMPULSE ajoute le décalage +0x400 pour accéder à son chargeur PE personnalisé.)

Chaque transition intercepte l'événement de débogage suivant, rétablit l'état de l'instruction de branchement ( RSP), efface l'indicateur de trap, modifie l'instruction de branchement ( RIP ) et les registres d'arguments (RCX, RDX, R8, R9) pour l'appel suivant, puis poursuit l'exécution du programme débogué. DR0 est réutilisé comme point d'arrêt matériel d'exécution à chaque adresse de retour enregistrée ; il n'est donc pas nécessaire d'appliquer des correctifs en ligne ni de procéder à des modifications du code ( WriteProcessMemory ) sur la cible. Du point de vue du noyau, tout ce qui s'est passé, c'est qu'un thread au sein de kernel32.dll a appelé LocalAlloc, OpenFileMappingA et MapViewOfFile.

La voie inter-architectures (PE32 à partir d'un implant 64 bits) est une variante propre à PHANTOMPULSE qui n'est pas présente dans la démonstration de faisabilité publique. Il emprunte un raccourci : l'implant parcourt l'PEB.Ldr e de la cible via NtReadVirtualMemory (en utilisant ProcessWow64Information pour choisir la structure PEB 32 bits ou 64 bits) afin de trouver une DLL dotée d'un point d'entrée appelable, puis pré-mappe une section contenant un stub de chargeur 32 bits et un trampoline dans les deux processus via NtCreateSection + NtMapViewOfSection. La redirection se fait en deux étapes : un appât sur RtlExitUserThread, puis un saut en une seule étape via DbgBreakPointqui redirige vers RIP, le site de destination. Il n'y a pas de chaîne API sur ce chemin, car la section est déjà mappée des deux côtés ; les adresses OpenFileMappingAetMapViewOfFile ne sont donc pas nécessaires.

La sélection d'un hôte inter-architectures s'effectue via FindHostProcessEx, ce qui exclut les processus système critiques (csrss.exe, lsass.exe, smss.exe, winlogon.exe, services.exe, wininit.exe, svchost.exe, MsMpEng.exe) et, si aucun hôte WoW64 utilisable n'est trouvé, revient à la création d'un nouvel hôte SysWOW64\cmd.exe / rundll32.exe / notepad.exe.

ManualMap : outil complet de cartographie PE

ManualMap gère les charges utiles DLL grâce à une implémentation complète du mappage manuel PE :

  1. Valide la signature MZ/PE ; rejette PE32 dans le chemin d'accès de l'hôte x64 (journal de débogage : "PE32 DLL in x64 host is impossible")

  2. Alloue l'SizeOfImage e dans la cible via NtAllocateVirtualMemory

  3. Copie les en-têtes et les sections dans une mémoire tampon locale

  4. Applique les relocalisations de base (IMAGE_REL_BASED_DIR64, IMAGE_REL_BASED_HIGHLOW)

  5. Résout les problèmes d'importation via LoadLibraryA + GetProcAddress

  6. Efface les en-têtes PE (octets de zéro SizeOfHeaders )

  7. Enregistre l'image mise en scène dans l'allocation distante

  8. Définit la protection de la mémoire par section

  9. Crée un trampoline de 137 octets dans une allocation distante distincte de 2 000 octets (définie sur PAGE_EXECUTE_READ) :

Le gist complet du shellcode Trampoline contient l'ensemble des octets.

10. Détourne un thread via suspend / get-context / set-context

Escalade des privilèges

La commande « elevate » permet de contourner le contrôle de compte d'utilisateur (UAC) grâce à la technique «schuac » (IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)), publiée sous le numéro 129 de l'UACME par zcgonvh, et actuellement référencée sous l'identifiant 74.

Mécanisme

MaintenanceUI.dllLe service « CMaintenanceUIVirtualFactory » (CLSID {A6BFEA43-501F-456F-A845-983D3AD7B8F0}) est enregistré via la clé de registre Elevation; par conséquent, le système d'exploitation fournit aux utilisateurs non administrateurs une instance avec des privilèges élevés. Son interface ` IElevatedFactoryServer ` expose ` ServerCreateElevatedObject(rclsid, riid, ppv)`, que le serveur privilégié utilise pour instancier tout autre CLSID dans son contexte privilégié. PHANTOMPULSE transmet l'adresse CLSID_TaskScheduler, obtient en retour une instance de ITaskService, puis utilise ce service pour enregistrer une tâche HighestAvailable-RunLevel qui relance l'implant.

La commande C2 de l'elevate

Dans le fichier ` ProcessCommands`, le gestionnaire `elevate` :

  1. Crée l'action de la tâche. La commande est « <system_dir>\rundll32.exe » avec les arguments « \"<deployed_dll>\",DllRegisterServer ». L'identifiant de l'utilisateur est COMPUTERNAME\USERNAME, issu de GetEnvironmentVariableW. ![Appel de la commande « Elevate »][/assets/images/blockchain-c2-phantompulse-rat-sinkhole/image17.png]
  2. Écrit le marqueur « .elevate » sous la forme d'un seul octet ("1", 0x31), et non sous forme de paramètres encodés. L'écriture passe par NtCreateFile + NtWriteFile afin de contourner les hooks en mode utilisateur. Le marqueur sert uniquement à signaler sa présence ; les paramètres d'élévation sont intégrés dans la définition de la tâche que l'implant s'apprête à enregistrer.
  3. XOR-décrypte le moniker d'élévation de privilèges COM lors de l'exécution : 66 octets provenant de .rdata, soumis à une opération XOR avec la clé de départ 0xE95CA237, ce qui donne Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}.
  4. Appelle la fonction ` CoGetObject(moniker, &BIND_OPTS3{dwClassContext=CLSCTX_LOCAL_SERVER}, IID_IElevatedFactoryServer, &factory) ` pour obtenir un objet ` IElevatedFactoryServer*` disposant de privilèges élevés, puis la fonction ` factory->ServerCreateElevatedObject(CLSID_TaskScheduler, IID_ITaskService, &elevatedTaskService) ` pour obtenir un objet ` ITaskService* ` qui hérite de ces privilèges.
  5. Enregistre une tâche temporaire DotNetSvcElevateTask au niveau d'exécution HighestAvailable à l'aide de l'action rundll32 ci-dessus.
  6. Supprime toutes les tâches persistantes non privilégiées existantes afin d'éviter que l'ancienne persistance à faible niveau d'intégrité ne se chevauche avec le redémarrage privilégié.
  7. Appelle la fonction ` ITaskService::Run ` sur la tâche temporaire, puis la supprime immédiatement après. Libère le mutex à instance unique et quitte l'implant à niveau d'implémentation intermédiaire.

Nouvelle tentative de secours via le proxy rundll32

Si la chaîne CoGetObject / RegisterTask ne fonctionne pas, un chemin de secours prend le relais. Un processus de démarrage distinct lance une nouvelle instance d'rundll32.exe "<deployed_dll>",DllRegisterServer directement via CreateProcessW, avec des tentatives de reconnexion (">>> .elevate redirect attempt %d"). Au sein de cette fonction rundll32, l'implant détecte les adresses isProxy=1 et elevated=0, puis relance la séquence SCHUAC avec trois variantes d'enregistrement (ELEVATED+INTERACTIVE+user, ELEVATED+INTERACTIVE et INTERACTIVE). En cas de réussite, la tâche exécutée avec des privilèges élevés se lance et le redémarrage avec des privilèges élevés prend le relais. En cas d'épuisement, le proxy enregistre la ligne « ">>> Phase 1: all registration methods failed, cleaning marker" » dans le journal et se ferme.

Relance de rundll32 avec droits d'administrateur

Lorsque la tâche temporaire se déclenche, svchost.exe (Schedule) lance rundll32.exe "<deployed_dll>",DllRegisterServer sous un nouveau jeton à niveau d'intégrité élevé. Le flux de sortie de l'DllRegisterServer ation de l'implant s'exécute en tant que processus d'entrée ; au démarrage, il détecte le marqueur « .elevate » et un jeton à privilèges élevés, puis est redirigé vers le chemin d'accès privilégié :

  • Lit et supprime le marqueur « .elevate ».
  • Réinstalle la persistance dans un contexte privilégié, y compris la tâche de démarrage DotNetSvcCoreTask disponible à l'adresse \Microsoft\Windows\NetFramework\, enregistrée sur INTERACTIVE_TOKEN et BootTrigger, ce qui nécessite un compte administrateur pour l'enregistrement.
  • L'implant continue de fonctionner normalement en tant que service à haut niveau d'intégrité.

Routage par état des marqueurs

À chaque démarrage, la fonction ` MainEntryLogic ` appelle la fonction ` GetFileAttributesW ` dans le chemin d'accès ` .elevate `. Si la valeur renvoyée est « INVALID_FILE_ATTRIBUTES », l'implant ignore toute la logique d'élévation et démarre normalement. Si le marqueur existe, l'implant recueille deux informations supplémentaires : si le processus en cours est un proxy rundll32.exe/regsvr32.exe, et si le jeton dispose de privilèges élevés, puis effectue le routage en fonction de cette combinaison :

MarqueurProxySurélevéCe qui se passe
absentn/an/adémarrage normal, sans routage particulier
PrésentNonNonlancer le proxy rundll32 pour relancer la chaîne SchuAC, puis quitter
PrésentOuiNonréessayez la fonction schuac à l'intérieur de rundll32 ; en cas d'échec, supprimez le marqueur et quittez
Présent*OuiSupprimer le marqueur, réactiver la persistance via la tâche de démarrage, poursuivre en mode haute intégrité

Le contenu du fichier de marqueurs n'est jamais lu ; sa simple présence détermine le routage.

Le document « Exploring Windows UAC Bypasses » d'Elastic Security Labs traite directement des modèles de détection pour la catégorie de contournements « IElevatedFactoryServer ».

Persistance

Trois tâches planifiées

PHANTOMPULSE installe trois tâches planifiées via l'interface COM ITaskService, chacune exécutant rundll32.exe "<stub_dll>",DllRegisterServer:

TâcheDéclencheurIntervalleNiveau d'exécution
DotNetSvcUpdateTaskIdentifiant de l'utilisateur + Heure3 minStandard
DotNetSvcCoreTaskDémarrage + Heure15 minMax. disponible + Caché
DotNetSvcUserTaskConnexion de l'utilisateurÀ la connexionStandard

La tâche de démarrage se trouve sous \Microsoft\Windows\NetFramework\ afin de se fondre parmi les tâches de maintenance .NET légitimes. Son corps XML complet est intégré dans .rdata; il n'est pas généré au moment de l'exécution. Les signatures associées à ce bloc de données brut sont conservées d'une compilation à l'autre.

Le programme d'installation essaie plusieurs variantes de secours d'RegisterTask s par tâche, en combinant les types de connexion INTERACTIVE_TOKEN et S4U avec différents formats d'identifiant utilisateur (COMPUTER\User, SID, nom d'utilisateur court). L'ordre exact des tentatives dépend du niveau de privilèges de l'implant (SYSTEM, administrateur ou utilisateur standard) ; en cas d'échec, le système passe à la variante suivante jusqu'à ce que l'une d'entre elles aboutisse.

Déploiement de DLL de base

L'agent déployé est stocké sous forme cryptée et compressée dans le fichier EXE lui-même .rdata. FilelessPersist le déchiffre à la demande et enregistre le résultat sur le disque via (NtCreateFile + NtWriteFile).

Le déchiffrement se déroule en deux étapes :

  1. Décodez un blob par opération XOR à l'aide d'une clé rotative de 16 octets disponible à l'adresse (decoded[i] = blob[i] ^ key[i & 0xF]), en utilisant decoded[0] = 0x1E comme premier octet codé en dur qui initialise l'en-tête du bloc LZNT1.
  2. RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, ...) sur le tampon décodé, qui est une DLL (svcagent.dll).

Supprimer les chemins d'accès par ordre de priorité, en passant au niveau inférieur en cas d'erreur d'accès :

  1. %ProgramData%\AssetMon\svcagent.dll (primaire)
  2. %APPDATA%\AssetMon\svcagent.dll
  3. %TEMP%\svcagent.dll
  4. Une copie de sauvegarde de l'article « %ProgramData% » ( ") et de l'article « sleeper » (" ) sur un chemin d'accès distinct

Les analystes peuvent reproduire la DLL déployée hors ligne en extrayant les deux zones ci-dessus de l'EXE, en appliquant la boucle XOR, puis en transmettant le résultat à RtlDecompressBuffer (ou à n'importe quelle implémentation de LZNT1), comme le montre la capture d'écran de CyberChef ci-dessous.

Migration du chargement latéral des DLL

Un bloc situé dans le fichier « SetupRegistryPE » (enregistré avec les préfixes de chaîne de débogage « MigrateSideload » / « MigrateLegacySideloads ») répertorie les processus en cours d'exécution et leurs répertoires d'exécutables, à la recherche de « diagcore.dll ». S'il est trouvé, il remplace le fichier par le fichier de remplacement actuel via CopyFileW.

Réparation automatique

La fonction d'auto-réparation s'exécute à l' 2 e itération de la boucle C2, puis toutes les 10 itérations par la suite, sous réserve que l'indicateur de persistance différée soit désactivé. L'ordre de paiement :

  1. Vérifiez d'abord la persistance du registre. CheckRegistryPersistence se trouve en haut du bloc. Si l'état est jugé anormal, l'implant relance immédiatement les processus FilelessPersist (il déchiffre à nouveau et réimplante la DLL stub) et InstallPersistence (il réenregistre les déclencheurs de tâches).
  2. Vérification des tâches. SelfHealCheckTasks puis vérifie les trois tâches de persistance (DotNetSvcUpdateTask, DotNetSvcCoreTask, DotNetSvcUserTask) et réinstalle celles qui manquent. La vérification de la tâche de démarrage est conditionnée au contexte SYSTEM ou admin ; les appelants non privilégiés la sautent.
  3. Mise à jour du parc audiovisuel. DetectInstalledAV s'exécute à la fin pour actualiser la liste des produits audiovisuels visible par l'opérateur.

La condition de privilège est déterminante pour l'expulsion. Dans un contexte non privilégié, la vérification de la tâche de démarrage est ignorée ; la tâche de démarrage n'est donc pas inspectée lors du nettoyage. Pour procéder à une suppression complète, il faut supprimer les trois tâches ainsi que l'entrée de registre dans une seule fenêtre à partir d'un compte administrateur.

Au-delà de la fonction d'auto-réparation par itération, l'implant intègre un mécanisme de persistance différée déclenché par un seul indicateur. Dans les chemins de traitement des signaux de pulsation réussis de la fonction ` C2Loop_Main`, dès que le compteur de signaux de pulsation réussis dépasse la valeur 1 et que l'indicateur est activé, l'implant réexécute les fonctions ` FilelessPersist ` et ` InstallPersistence `, puis désactive l'indicateur. Cela offre à PHANTOMPULSE une deuxième voie de réparation de la persistance qui se déclenche sur la base d'un autre événement que l'auto-réparation par itération.

Collecte

Enregistreur de frappe intégré avec surveillance du presse-papiers

Le keylogger s'exécute en ligne dans la boucle C2, sans thread dédié. Il résout les API provenant de user32.dll lors de l'exécution :

APIFinalité
GetAsyncKeyStateSondage dans un État clé
GetForegroundWindowDétection de la fenêtre active
GetWindowTextACapture du titre de la fenêtre
MapVirtualKeyA / ToUnicodeTraduction des clés
GetClipboardSequenceNumberDétection des modifications dans le presse-papiers
OpenClipboard / GetClipboardDataLecture du presse-papiers (CF_UNICODETEXT)

Le fichier journal est chiffré par XOR à l'aide de la graine 0xE95CA237. Les téléchargements n'envoient que les modifications afin d'éviter toute retransmission.

Capture

Les captures d'écran utilisent les API GDI identifiées par hachage. Si la largeur de l'écran dépasse 960 px, l'image est réduite avant le téléchargement. Le fichier BMP brut est généré en mémoire et téléchargé à l'aide de la commande ` Content-Type: image/bmp`. Déclenché à la demande par la commande C2 de l'screenshot (hachage 0x9A37F083).

Reconnaissance du système

Données de reconnaissance recueillies par l'implant :

DonnéesSource
ProcesseurRegistre : ProcessorNameString
GPUDriverDesc de la carte graphique dans le Registre (filtres "Microsoft Basic")
RAMGlobalMemoryStatusEx
OSRtlGetVersion avec mise en correspondance des versions de build (de Windows 7 à Windows 11, de Server 2008 à Server 2025)
Nom d'utilisateurGetUserNameW avec redirection vers LookupAccountSidW à partir du jeton explorer.exe
PrivilègeTypes d'élévation de jetons : user, admin, admin_nouac, system
AVDetectInstalledAV compare les processus en cours d'exécution à une liste fixe comprenant environ 25 à 30 noms de processus de fournisseurs d'antivirus
ApplicationsDetectInstalledApps passe en revue une liste de 19 applications sélectionnées avec soin
État du pare-feuLit la variable « SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\{Domain,Standard,Public}Profile » pour enregistrer l'état d'activation par profil
ServicesComptage des services en cours d'exécution via l'énumération des services
Identifiant de la machineDJB2 (nom du module) ^ numéro de série du volume
Adresse IP publiqueChaîne HTTPS multi-API

La liste des antivirus couverts est exceptionnellement vaste et inclut les principaux produits antivirus grand public occidentaux tels que Defender, Norton, McAfee, Avast, AVG, Avira, Bitdefender, ESET, F-Secure, G Data, Kaspersky, Panda, Sophos, Trend Micro, VIPRE, Webroot, ZoneAlarm, Comodo ainsi que les fournisseurs de solutions EDR (CrowdStrike, SentinelOne, Cylance, Malwarebytes, HitmanPro) sont tous pris en compte. L'implant recherche également AhnLab V3 (sud-coréen), Qihoo 360 / 360 Total Security et Tencent QQPC (chinois), ainsi que K7 Computing (indien). La présence d'éléments Asian-AV est inhabituelle pour les logiciels de vol de données destinés au marché occidental, ce qui correspond à un implant conçu pour des victimes issues de plusieurs marchés régionaux.

L'implant vérifie également si une liste sélectionnée d'applications à forte valeur ajoutée de l' 19 , classées par nom, est présente, et signale les correspondances dans le signal de santé (App detection: found %d apps) :

CatégorieObjectifs
Portefeuilles de crypto-monnaiesledger, trezor, bitcoin-core, electrum, exodus, atomic, guarda
Messagerstelegram, discord, signal, viber, slack, whatsapp
Clients de messageriethunderbird, outlook
Application d'authentification à deux facteursauthy
Transfert de fichiers / SSHfilezilla, winscp
Jeuxsteam

La fonction de détection (DetectInstalledApps) n' analyse pas le registre et ne répertorie pas les processus. Il développe trois racines de variables d'environnement (%LOCALAPPDATA%, %APPDATA%, %ProgramFiles(x86)%), puis concatène un suffixe de chemin relatif en UTF-16 prédéfini pour chaque application (par exemple \Telegram Desktop\, \Authy Desktop\, \Ledger Live\, \@trezor\trezor-suite\, \Steam\steam.exe), et appelle la fonction GetFileAttributesW pour chaque chemin. Un retour sans erreur signifie que l'application est installée et que son nom est enregistré dans la mémoire tampon des résultats de la vérification de l'état.

PHANTOMPULSE n'extrait lui-même aucune donnée de ces sources. Cette liste sert à la reconnaissance des cibles en vue de missions ultérieures. L'opérateur identifie, grâce à Heartbeat, les applications à forte valeur ajoutée dont dispose une victime donnée et détermine quelle charge utile spécialisée il convient d'injecter ensuite via inject ou drop.

Aucune fonctionnalité de vol de portefeuille, de navigateur, de messagerie instantanée ou d'identifiants n'a été identifiée dans l'échantillon analysé ; la liste des cibles sert uniquement à vérifier la présence des éléments concernés et alimente l'arbre de décision de l'opérateur.

Désinstaller

Une procédure de nettoyage en 6 étapes, déclenchée par la commande « uninstall », par la commande « "status":"deleted" » dans une réponse Heartbeat, ou par un indicateur de suppression dans le registre :

ÉtapeAction
1/6Enregistrer le drapeau d'arrêt dans HKCU et HKLM, arrêter le processus hôte
2/6Supprimez toutes les tâches planifiées d' 3 s via le mode de secours COM+ CreateProcessW
3/6Supprimer les entrées obsolètes du registre : la valeur NTLoad, les clés de détournement COM et les clés du moniteur d'impression
4/6Supprimer les fichiers DLL fantômes, les journaux dormants, les blobs PE du registre et les répertoires ProgramData
5/6Supprimer le chemin d'installation et le chemin d'accès au programme du disque
6/6Fermez les instances résiduelles d'healthmon.exe, ainsi que toutes les instances d'rundll32.exe qui hébergent svcagent.dll

L'étape n° 3 e les techniques de persistance héritées : la logique de nettoyage pour le détournement COM et les clés du moniteur d'impression que cette version n'installe jamais.

Attribution

Les techniques opérationnelles, les cibles et les choix d'infrastructure de PHANTOMPULSE correspondent à ceux des groupes d'intrusion cryptographiques liés à la RPDC, parmi lesquels figurent Lazarus, BlueNoroff, UNC5342 (Contagious Interview) et APT38. Plusieurs aspects distincts concordent avec les informations rendues publiques récemment concernant ces groupes.

Des indices qui concordent avec les informations fournies par la RPDC :

  • Le C2 identifié via la blockchain grâce aux champs d'input s de transaction correspond au modèle de résolveur de « dead drop » que Mandiant attribue à UNC5342 (Contagious Interview) dans l'article « La RPDC adopte EtherHiding ». Les caractéristiques spécifiques de PHANTOMPULSE (XOR de données de portefeuille, Blockscout multi-chaînes) ne constituent pas une empreinte digitale exacte, mais cette catégorie de techniques est désormais associée à la Corée du Nord.
  • La liste des crypto-portefeuilles de bureau recensés (ledger, trezor, bitcoin-core, electrum, exodus, atomic, guarda) correspond étroitement à la liste des cibles du logiciel RustDoor / Koi Stealer pour macOS identifié par Unit 42, attribué à la RPDC.
  • Les implants multiplateformes Windows + macOS ciblant le même profil de victime (le précédent article REF6598 décrivait un variant macOS avec un serveur de commande et de contrôle accessible à l'adresse 0x666[.]info et un canal Telegram de secours à l'adresse t[.]me/ax03bot) constituent une signature de BlueNoroff.
  • Le ciblage sur Telegram et Messenger est précisément l'une des spécialités de BlueNoroff, comme l'indique la couverture d'Arctic Wolf BlueNoroff.

Recherche de nouveaux domaines C2 à l'aide de la signature en texte clair connue du portefeuille Resolver

Le schéma XOR utilisé par le résolveur de la blockchain divulgue une signature stable de 2 octets que les pirates peuvent exploiter sur l'ensemble de la chaîne, et pas seulement sur un seul portefeuille.

Deux éléments se combinent : chaque URL C2 commence par ht (provenant de http:// ou https://), et la clé XOR correspond exactement à l'adresse ASCII du portefeuille ; par conséquent, ses deux premiers octets sont toujours les caractères littéraux 0 et x. En effectuant une opération XOR entre ht et 0x, on obtient \x58 \x0c. Chaque champ « input » chiffré généré par un résolveur de type PHANTOMPULSE, sur n'importe quelle chaîne, et signé par n'importe quel portefeuille associé, commence par les quatre caractères hexadécimaux « 580c ».

Cela transforme la recherche, qui consistait à surveiller un seul portefeuille, en une analyse systématique de la chaîne à la recherche de la signature. Les données publiques relatives aux transactions sur Ethereum, Base et Optimism peuvent être consultées via BigQuery, Dune ou des nœuds d'archivage complets. Une requête effectuée sur l'ensemble de données public des transactions Ethereum, visant les valeurs d'adresse de type « input » commençant par « 0x580c » et limitée à une fenêtre de temps de bloc récente, a permis de mettre en évidence des portefeuilles de résolution jusqu'alors inconnus, utilisés par la même base de code. Chaque correspondance est validée par décodage, en utilisant l'adresse ASCII du portefeuille de l'expéditeur comme clé : une véritable URL C2 commence par http après décodage. La recette CyberChef suivante permet de déchiffrer l'URL C2.

SELECT 
    block_timestamp AS block_time, 
    from_address AS `from`, 
    to_address AS `to`, 
    input AS data
FROM `bigquery-public-data.crypto_ethereum.transactions`
WHERE block_timestamp >= '2026-04-01 00:00:00'
  AND input LIKE '0x580c%'
ORDER BY block_timestamp DESC
LIMIT 10000;

CyberChef peut déchiffrer les données d'entrée pour révéler le domaine, comme le montre la capture d'écran ci-dessous.

Conclusion

PHANTOMPULSE est conçu à partir de composants connus : module de « stomping », machines à états via l'API de débogage, mappage manuel, contournement des points d'arrêt matériels AMSI/WLDP/ETW, persistance des tâches planifiées et communication C2 via la blockchain. La cohésion et la solidité de l'ensemble témoignent d'un code mature en cours de développement actif. Ces signaux persistants sont de nature comportementale et sont couverts par les protections comportementales d'Elastic pour REF6598.

PHANTOMPULSE et MITRE ATT&CK

Elastic utilise le cadre MITRE ATT&CK pour documenter les tactiques, techniques et procédures communes que les menaces persistantes avancées utilisent contre les réseaux d'entreprise.

Tactiques

Les tactiques expliquent le pourquoi d'une technique ou d'une sous-technique. C'est l'objectif tactique de l'adversaire : la raison pour laquelle il mène une action.

Techniques

Les techniques représentent la manière dont un adversaire atteint un objectif tactique en effectuant une action.

Remédiation

YARA

Elastic Security a créé des règles YARA pour identifier cette activité.

Observations

ObservableTypeNomRéférence
33dacf9f854f636216e5062ca252df8e5bed652efd78b86512f5b868b11ee70fSHA-256PHANTOMPULSE RATFinal payload
70bbb38b70fd836d66e8166ec27be9aa8535b3876596fc80c45e3de4ce327980SHA-256syncobs.exeChargeur PHANTOMPULL
def66275fa3baffb16e6e4ae0297861d9790ae7161fbc271a2ba05d121f13c70SHA-256Aller à la baliseEnregistrement GTESTIC_WIN
panel.fefea22134[.]netDomainPanneau C2Règle de repli codée en dur pour PHANTOMPULSE
fea22134[.]netDomainC2 domainCrypté en binaire
195.3.222[.]251ipv4-addrServeur de préproductionPowerShell/déploiement du chargeur
0xc117688c530b660e15085bF3A2B664117d8672aAporte-monnaie électroniquePortefeuille Blockchain C2ETH/Base/Optimism
0x38796B8479fDAE0A72e5E7e326c87a637D0Cbc0Eporte-monnaie électroniquePortefeuille de financementFinancement de la résolution C2
eth.blockscout[.]comDomainFournisseur de solutions blockchainRésolution d'URL C2
base.blockscout[.]comDomainFournisseur de solutions blockchainRésolution d'URL C2
optimism.blockscout[.]comDomainFournisseur de solutions blockchainRésolution d'URL C2
hVNBUORXNiFLhYYhmutexExemplaire uniquedécrypté par XOR
svcagent.dllnom-de-fichierDLL de baseCharge utile de persistance
AssetMonrépertoireRépertoire des fichiers DLL de remplacement%ProgramData% ou %APPDATA%
healthmon.exenom-de-fichierCompte-gouttesNom d'origine du fichier exécutable
diagcore.dllnom-de-fichierDLL de chargement latéral héritéeMigré par MigrateSideload
.elevatenom-de-fichierRepère d'altitudeItinéraires du relancement surélevé
DotNetSvcUpdateTasktâche planifiéePersistance primaireIntervalle de 3 minutes
DotNetSvcCoreTasktâche planifiéePersistance du système15 minutes, en mode caché
DotNetSvcUserTasktâche planifiéePersistance des données utilisateurDéclencheur de connexion
EdgeWebViewUpdateTasktâche planifiéeTâche héritéeNettoyé lors de la désinstallation
\Microsoft\Windows\NetFramework\DotNetSvcCoreTasktâchesChemin d'accès aux tâches de démarrageTâche planifiée masquée
Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}com-monikerContournement de l'UACITaskService avec droits étendus
0x666[.]infoDomainmacOS C2programme de distribution pour macOS
t[.]me/ax03botUrlSolution de secours pour TelegramPoint de dépôt sur macOS C2
thoroughly-publisher-troy-clara[.]trycloudflare[.]comDomainPrécédent C2Cloudflare Tunnel

Références

Rapports antérieurs et guides pratiques mentionnés dans la présente analyse :

Partager cet article