Source: tip-o-deincognito (write-up technique). Contexte: analyse statique et surveillance live (57 h) d’une variante GlassWorm macOS distribuée via des extensions Open VSX compromises, avec mise en évidence d’un C2 résilient (BitTorrent DHT + Solana), d’un stealer multi-cibles et d’un RAT persistant.

• Infection supply chain via extensions VS Code (compte “oorzc” — ssh-tools, i18n-tools-plus, mind-map, scss-to-css-compile, 22k+ téléchargements). Le package npm injecte un preinstall.js contenant une stéganographie Unicode (sélecteurs de variation) pour dissimuler le blob AES-256-CBC menant au loader Stage 1. Exclusion CIS via détection de locale russe + fuseau/offset. Un kill switch base64 de 20 caractères est géré côté Stage 1 (eval), mais échoue côté RAT persistant.

• Chaîne d’exécution: Stage 1 récupère la charge sur C2 (clé/IV AES-256-CBC via en-têtes HTTP) après résolution via Solana, puis évalue le Stage 3. Stage 3 (macOS) comporte 2 voies: AppleScript (extraction de trousseaux/Chrome, cookies, logins, autofill, extensions dont 150 IDs crypto, portefeuilles desktop, SSH, AWS, Apple Notes, Safari, documents <10 Mo, FortiVPN; trojanisation de Ledger/Trezor si détectés) et Node.js (tokens GitHub/NPM avec validation API, module extracteur de trousseau natif téléchargé, éventuel sudo). Exfiltration vers deux serveurs distincts (Vultr). Métadonnées de campagne dans les en-têtes HTTP.

• Persistance et C2: installation d’un LaunchAgent pointant vers une Node.js cachée (~/.config/system/.data/.nodejs/), qui charge un RAT v2.27 via Socket.IO sur le port 4789. Capacités: exécution de commandes arbitraires (eval base64), start_socks/stop_socks (proxy TCP), téléchargement/évaluation périodiques de stealer, dropper natif. Résilience: interception de signaux, auto-redémarrage (21 s), relance par launchd (KeepAlive.SuccessfulExit:false). Découverte C2 décentralisée: priorité au BitTorrent DHT (enregistrement mutable signé ed25519, auto-republication par les bots), repli via memos Solana (11 RPCs, API keys; historique de 47 transactions).

• Observations live (57 h): endpoints payload/“env”/“wrtc” tour à tour désactivés/0-octet/500, Socket.IO C2 fonctionnel en continu (inventaire via check_version). À T+31 h, réactivation de /module/wrtc livrant un module proxy TCP/UDP/dns cache en Node pur (≈700 lignes), suggérant un pivot vers proxy résidentiel; re-désactivé ensuite. Serveur exfil AppleScript arrêté à T+57 h; C2 Socket.IO toujours actif au-delà de T+60 h.

• Particularités: kill switch inefficace côté RAT (20 chars ignorés + fenêtre 7 jours + relance launchd). Alternance d’IPs Vultr (217.69.11.x France, 45.32.150-151.x) pilotées via DHT/Solana. Corrélation avec vagues GlassWorm précédentes (URLs, infra Vultr, modules), mais wallet Solana distinct.

IoCs 🔎

  • Réseau (Vultr/AS20473)
    • C2/payload: 217.69.11.99:80 (actuel)
    • C2 Socket.IO: 217.69.11.99:4789 (actuel)
    • Inconnu: 217.69.11.99:5000 (404)
    • DHT: 217.69.11.99:10000
    • Exfil AppleScript: 208.76.223.59:80 /p2p [OFFLINE]
    • Exfil Node.js: 208.85.20.124:80 /wall, /log
    • Historiques C2: 45.32.150.97; 217.69.11.57; 45.32.151.157; 217.69.11.60
  • Chemins URL C2
    • GET /<encrypted_id> (stealer)
    • GET /get_arhive_npm/ (archive binaire)
    • GET /get_encrypt_file_exe/ (binaire)
    • GET /env/ (addon keychain)
    • GET /darwin-universal/?wallet= (apps wallet trojanisées)
    • GET /module/wrtc (module proxy TCP)
  • Blockchain
    • Wallet C2 (Solana): BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC
    • Funder: G2YxRa6wt1qePMwfJzdXZG62ej4qaTC7YURzuh2Lwd3t
    • Fee payer: E9vf42zJXFv8Ljop1cG68NAxLDat4ZEGEWDLfJVX38GF
    • DHT pubkey: ea1b4260a83348243387d6cdfda3cd287e323958
    • Wallet publié (vagues antérieures): 28PKnu7RzizxBzFPoLp69HLXp9bJL3JFtT2s5QzHsEA2
  • Hashes (post-décryptage)
    • stage1_loader.js (SHA256): fe06f0d6…e128097f6
    • stage2_darwin_encrypted.bin (SHA256): 7fb54d95…4ce9d431
    • stage3_darwin_decrypted.js (SHA256): d72c1c75…fa06a51a
    • hidden_blob_1.js (RAT v2.27, SHA256): 41caca39…a6b9e1a7
  • Identifiants de campagne
    • _partner: mulKRsVtolooY8S; UUID: 7c102363-8542-459f-95dd-d845ec5df44c; Version RAT: 2.27; Build stealer: 2026-03-10T21:58:46.968Z
  • Artéfacts macOS
    • ~/Library/LaunchAgents/com.user.nodestart.plist
    • ~/.config/system/.data/.nodejs/node-v23.5.0-darwin-x64/
    • ~/.config/system/.data/.nodejs/webrtc/index.js
    • ~/init.json
    • /tmp/ijewf/ ; error_wsXkrnQlLAXsage.txt ; errorXkrnQlLAXsage.txt

TTPs 🧰

  • Compromission de la chaîne d’approvisionnement (extensions VS Code/Open VSX)
  • Obfuscation/stéganographie Unicode pour payload chiffré (AES-256-CBC)
  • Évasion géopolitique: détection locale/langue russe + fuseau/offset
  • Découverte C2 décentralisée: BitTorrent DHT (mutable signé) avec auto-republication; repli via memos Solana (transactions immuables)
  • Persistance: LaunchAgent + Node.js cachée; redémarrage automatique et gestion de signaux
  • Contrôle: Socket.IO (port 4789), exécution de JS arbitraire (eval base64), SOCKS/proxy TCP à la demande
  • Vol d’identifiants/données: navigateurs Chromium/Firefox/Safari, 150 ID d’extensions crypto, portefeuilles desktop (Ledger/Trezor trojanisés), SSH, AWS, Apple Notes, documents <10 Mo, FortiVPN
  • Exfiltration vers 2 serveurs dédiés; métadonnées de campagne via en-têtes HTTP
  • Kill switch inopérant sur bots persistants (longueur 20, cooldown 7 j, KeepAlive)

Conclusion: write-up d’« analyse technique » visant à documenter en détail une variante de GlassWorm sur macOS (chaîne d’infection, persistance, C2 décentralisé), avec surveillance live et publication d’IoCs/TTPs.

🧠 TTPs et IOCs détectés

TTP

[‘Compromission de la chaîne d’approvisionnement (extensions VS Code/Open VSX)’, ‘Obfuscation/stéganographie Unicode pour payload chiffré (AES-256-CBC)’, ‘Évasion géopolitique: détection locale/langue russe + fuseau/offset’, ‘Découverte C2 décentralisée: BitTorrent DHT (mutable signé) avec auto-republication; repli via memos Solana (transactions immuables)’, ‘Persistance: LaunchAgent + Node.js cachée; redémarrage automatique et gestion de signaux’, ‘Contrôle: Socket.IO (port 4789), exécution de JS arbitraire (eval base64), SOCKS/proxy TCP à la demande’, ‘Vol d’identifiants/données: navigateurs Chromium/Firefox/Safari, 150 ID d’extensions crypto, portefeuilles desktop (Ledger/Trezor trojanisés), SSH, AWS, Apple Notes, documents <10 Mo, FortiVPN’, ‘Exfiltration vers 2 serveurs dédiés; métadonnées de campagne via en-têtes HTTP’, ‘Kill switch inopérant sur bots persistants (longueur 20, cooldown 7 j, KeepAlive)’]

IOC

{‘hashes’: [‘fe06f0d6…e128097f6’, ‘7fb54d95…4ce9d431’, ‘d72c1c75…fa06a51a’, ‘41caca39…a6b9e1a7’], ‘ips’: [‘217.69.11.99’, ‘208.76.223.59’, ‘208.85.20.124’, ‘45.32.150.97’, ‘217.69.11.57’, ‘45.32.151.157’, ‘217.69.11.60’], ‘domains’: [], ‘blockchain’: [‘BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC’, ‘G2YxRa6wt1qePMwfJzdXZG62ej4qaTC7YURzuh2Lwd3t’, ‘E9vf42zJXFv8Ljop1cG68NAxLDat4ZEGEWDLfJVX38GF’, ’ea1b4260a83348243387d6cdfda3cd287e323958’, ‘28PKnu7RzizxBzFPoLp69HLXp9bJL3JFtT2s5QzHsEA2’]}


🔗 Source originale : https://codeberg.org/tip-o-deincognito/glassworm-writeup