🔍 Contexte

Publié le 26 septembre 2026 sur opensourcemalware.com, cet article présente une analyse technique approfondie de l’évolution du malware PolinRider, attribué à la Corée du Nord (DPRK), ciblant des développeurs via des dépôts GitHub infectés.

🎯 Mécanisme d’infection initial

L’attaque repose sur deux fichiers clés dans des projets VS Code :

  • .vscode/tasks.json : contient une tâche qui s’exécute automatiquement à l’ouverture du dossier et lance le payload
  • public/fonts/fa-solid-400.woff2 : fichier contenant un payload JavaScript obfusqué, dissimulé par des espaces blancs

Le vecteur d’infection initial est vraisemblablement une attaque Contagious Interview (fausse interview d’embauche demandant de cloner et exécuter un projet).

🔄 Évolution des variantes (tests A/B)

L’organisation GitHub Binary-Mindz (3 dépôts TypeScript backend) a été infectée pendant 8 mois, portant successivement toutes les variantes :

Variante Date d’apparition Taille Particularité
fa-solid-400.woff2 25 avril 2026 5,5 KB Payload avec 421 tabulations de padding
fa-solid-500.woff2 3 septembre 2026 ~32 KB Marqueur global.i = 'A8', obfuscateur _0x
fa-solid-900.woff2 25 septembre 2026 37,5 KB Nom de fichier Font Awesome légitime, chemin variable par repo

🛠️ Techniques d’exécution multiples

Quatre chemins d’exécution ont été identifiés dans agimtula_server :

  1. Tâche curl dans tasks.json (non obfusquée) vers 260120.vercel[.]app
  2. Tâche cachée (hide: true) exécutant le faux fichier .woff2 via Node.js
  3. Payload appendé à eslint.config.mjs (s’exécute via npm run lint, hooks pre-commit, CI)
  4. Loader dans prisma.config.ts récupérant le stage suivant depuis une URL encodée en base64 dans une variable d’environnement

📡 Infrastructure C2 (variante 500)

  • Technique NullReceiver : lecture de la dernière transaction d’un wallet Ethereum fixe pour décoder l’IP du C2
  • Wallet Ethereum : 0xa322e5f3d311d3080e6f0121063e9adc2490ef1a
  • RPC Ethereum : 1rpc.io/eth, eth.drpc.org, ethereum-rpc.publicnode.com, eth-mainnet.public.blastapi.io
  • Chemins C2 : :443/0x/cls, :443/0x/ls
  • En-tête de réponse : X-Payload-B64
  • Clés XOR : q4FZkxX{!h,Sr3=@ et y-p_>d$0B&@^1aQk
  • Le build envoie son marqueur (Sec-V) au C2, permettant aux opérateurs de tracker quelle variante est la plus efficace

🔑 Empreinte sur les machines infectées

Entrées caractéristiques dans .gitignore :

  • config.bat
  • temp_auto_push.bat
  • temp_interactive_push.bat
  • branch_structure.json

📊 Type d’article

Analyse technique et de threat intelligence, basée sur des preuves publiques (logs GitHub). But principal : documenter l’évolution des variantes de PolinRider et fournir des indicateurs de détection mis à jour.

🧠 TTPs et IOCs détectés

Acteurs de menace

  • PolinRider (state-sponsored) —

TTP

  • T1195.001 — Supply Chain Compromise: Compromise Software Dependencies and Development Tools (Initial Access)
  • T1566 — Phishing (Initial Access)
  • T1059.007 — Command and Scripting Interpreter: JavaScript (Execution)
  • T1059.001 — Command and Scripting Interpreter: PowerShell (Execution)
  • T1053 — Scheduled Task/Job (Execution)
  • T1027 — Obfuscated Files or Information (Defense Evasion)
  • T1036.005 — Masquerading: Match Legitimate Name or Location (Defense Evasion)
  • T1102 — Web Service (Command and Control)
  • T1568 — Dynamic Resolution (Command and Control)
  • T1098 — Account Manipulation (Persistence)
  • T1505 — Server Software Component (Persistence)

IOC

  • Domaines : 260120.vercel.app — VT · URLhaus · ThreatFox
  • URLs : https://260120.vercel.app/settings/linux?flag=9-test — URLhaus
  • URLs : https://260120.vercel.app/settings/win?flag=9-test — URLhaus
  • Fichiers : fa-solid-400.woff2
  • Fichiers : fa-solid-500.woff2
  • Fichiers : fa-solid-900.woff2
  • Fichiers : tasks.json
  • Fichiers : eslint.config.mjs
  • Fichiers : prisma.config.ts
  • Fichiers : config.bat
  • Fichiers : temp_auto_push.bat
  • Fichiers : temp_interactive_push.bat
  • Fichiers : branch_structure.json
  • Chemins : prisma/generated/prisma/internal/public/fonts/fa-solid-900.woff2
  • Chemins : src/main/admin/admin-ad/dto/public/fonts/fa-solid-900.woff2
  • Chemins : src/module/content-master/category/dto/public/fonts/fa-solid-900.woff2
  • Chemins : public/fonts/fa-solid-400.woff2
  • Chemins : public/fonts/fa-solid-500.woff2
  • Chemins : .vscode/tasks.json

⚠️ À propos de ces IOC — ils sont extraits automatiquement de l’article original le 27 septembre 2026 et n’ont pas fait l’objet d’une vérification externe. Un indicateur peut avoir été réattribué depuis : une IP de C2 peut redevenir un service légitime, un domaine sinkholé peut changer de propriétaire. Aucune garantie d’exactitude ni d’actualité — contrôlez leur validité avant tout usage opérationnel, en particulier avant de les injecter dans une blocklist ou un SIEM.

Malware / Outils

  • PolinRider (other)

🟢 Indice de vérification factuelle : 83/100 (haute)

  • ✅ opensourcemalware.com — source reconnue (liste interne) (20pts)
  • ✅ 15000 chars — texte complet (fulltext extrait) (15pts)
  • ✅ 19 IOCs (IPs/domaines/CVEs) (10pts)
  • ✅ 1/3 IOC(s) confirmé(s) (ThreatFox, URLhaus, VirusTotal) (8pts)
  • ✅ 11 TTPs MITRE identifiées (15pts)
  • ✅ date extraite du HTML source (10pts)
  • ✅ acteur(s) identifié(s) : PolinRider (5pts)
  • ⬜ pas de CVE à vérifier (0pts)

IOCs confirmés externellement :

  • 260120.vercel.app (domain) → VT (12/91 détections) + ThreatFox (Unknown malware)

🔗 Source originale : https://opensourcemalware.com/blog/polinrider-is-a-b-testing-its-way-past-your-detections