← Blog

Le 14 avril 2026, le moniteur MUAD'DIB archive un premier tarball publié sous le scope npm @athena-ui-components : utils-99.99.99. Les 15 et 16 avril, 21 tarballs supplémentaires sont archivés sur 10 autres packages du même scope. Au total, 22 tarballs ont été conservés, répartis sur 11 noms de packages distincts.

La description déclarée dans chaque package.json est identique : "Security Research PoC for YesWeHack DBS Bug Bounty Program. THIS IS BENIGN.". La lecture du code contredit cette affirmation : les scripts preinstall et postinstall exécutent un index.js qui collecte des informations sur la machine d'installation et les exfiltre vers trois canaux distincts (HTTP OAST, DNS OAST, webhook Discord), sans mécanisme d'opt-in ni de restriction sur les destinataires.

Cet article documente les 22 tarballs archivés, les 3 variantes de payload identifiées par hash, la revendication de bug bounty qui les accompagne, et liste les IOCs observés pour faciliter la corrélation avec d'autres jeux de données.

Note méthodologique

L'analyse byte à byte des tarballs de cette campagne a été réalisée par des agents Claude Code exécutés sur VPS, avec validation humaine des verdicts. Un tarball représentatif par variante a été examiné byte à byte ; les 19 autres ont été extraits et leur index.js haché individuellement pour assignation à l'une des variantes. Trois hashes SHA-256 distincts ressortent, correspondant aux trois variantes documentées plus bas. Les extraits de code et les commentaires cités dans cet article sont issus de la lecture directe des tarballs archivés, pas de reconstruction.

Chronologie

  • 2026-04-14 : archivage de utils-99.99.99.
  • 2026-04-15 : archivage de 21 tarballs supplémentaires couvrant 10 packages additionnels (deux versions par package pour neuf d'entre eux, une version pour utils).
  • 2026-04-20 : au moment de la vérification, les 11 packages retournent HTTP 404 sur registry.npmjs.org. Ce statut est cohérent avec une suppression par l'équipe de sécurité de npm ou un unpublish par l'auteur ; les deux hypothèses ne peuvent pas être départagées avec les éléments dont je dispose.

Packages et versions archivés

PackageVersions archivéesDate d'archivage
@athena-ui-components/utils99.99.99, 99.99.1002026-04-14, 2026-04-15
@athena-ui-components/axios0.8.16, 0.8.172026-04-15
@athena-ui-components/dashboard-widget1.6.17, 1.6.182026-04-15
@athena-ui-components/deeplink0.0.41, 0.0.422026-04-15
@athena-ui-components/graceful-degradation1.1.26, 1.1.272026-04-15
@athena-ui-components/helpers1.1.23, 1.1.242026-04-15
@athena-ui-components/hooks0.2.13, 0.2.142026-04-15
@athena-ui-components/lang0.1.17, 0.1.182026-04-15
@athena-ui-components/layout1.2.23, 1.2.242026-04-15
@athena-ui-components/pubsub-bridge0.0.16, 0.0.172026-04-15
@athena-ui-components/user-activity1.9.35, 1.9.362026-04-15

Le numéro 99.99.99 pour utils est caractéristique d'une tentative de dependency confusion : un attaquant publie sur le registre public une version très élevée d'un nom de package interne, pariant sur une résolution défavorable de la configuration npm chez la cible. La séquence de deux versions publiées à quelques minutes d'intervalle (par exemple 0.8.16 puis 0.8.17) sur neuf des onze packages, le 15 avril, relève vraisemblablement d'une même opération itérative.

Les trois variantes du payload

VarianteSHA-256 de index.jsOAST endpointBranche AD WindowsTarballs
v11231d67f366f1395b048b35225fc84e1f79facb957e22a378786b3b1f876f199d7f0gcli191ibqke3ccgzmskrnqybqmuh.oast.onlinenon1 (utils-99.99.99)
v23b3788f9ff54135784369806f74612100ce93888ab77aca7edfc8cd265db8930d7fiu1ti191hj9ru0i8gukx3n3accmmdr.oast.prooui10
v31e9a5aaa99a1fbcd7e8d2e91e1c873ed8156cd4ad0745d36869587ae9fc0d214d7fiu1ti191hj9ru0i8gukx3n3accmmdr.oast.prooui11

v1 est isolée sur le premier tarball archivé et seule à contenir des fichiers annexes (README.md, .vscode/settings.json, scriptbase64.py, logs_dbs.txt), documentés plus bas. v2 et v3 correspondent aux versions publiées le 15 avril : v2 pour la première vague, v3 pour les versions bumped de quelques minutes plus tard et pour utils-99.99.100. La différence principale entre v2 et v3 se situe dans le libellé du titre envoyé au webhook Discord (voir section suivante).

Logique commune aux trois variantes

Section du package.json commune aux 22 tarballs :

{
  "description": "Security Research PoC for YesWeHack DBS Bug Bounty Program. THIS IS BENIGN.",
  "author": "Security Researcher",
  "scripts": {
    "preinstall": "node index.js",
    "postinstall": "node index.js"
  }
}

Données collectées par les trois variantes au lancement de index.js :

  • os.hostname()
  • os.userInfo().username
  • process.platform et os.release()
  • Première adresse IPv4 non internal retournée par os.networkInterfaces()
  • process.cwd()
  • 500 premiers caractères des noms des variables d'environnement (pas les valeurs)

v2 et v3 ajoutent une branche exécutée uniquement si process.platform === 'win32', qui invoque les commandes suivantes pour récupérer des informations de domaine Active Directory :

  • wmic computersystem get domain /value
  • systeminfo | findstr /B /C:"Domain"
  • whoami /fqdn
  • powershell Get-CimInstance Win32_ComputerSystem
  • reg query HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion /v RegisteredOrganization

Trois canaux d'exfiltration sont utilisés en parallèle, sans négociation ni fallback conditionnel :

  1. HTTP GET vers OAST_HOST/hit?d={base64(JSON)}.
  2. DNS via nslookup vers un sous-domaine construit {hostname}.{username}.OAST_HOST. La résolution DNS sortante n'est généralement pas filtrée par les firewalls de périmètre, ce qui en fait un canal complémentaire à l'HTTP.
  3. HTTPS POST vers un webhook Discord, avec un payload formaté en embed JSON.

Le titre de l'embed Discord diffère entre les variantes :

  • v1 : 🚨 **DBS BANK - DEPENDENCY CONFUSION CONFIRMED** 🚨
  • v3 : 🚨 **DBS BANK - DEPENDENCY CONFIRMED** 🚨

Titre et footer communs aux trois variantes :

  • Title : Proof of Concept - Authorized Execution
  • Footer : Authorized DBS Bug Bounty Research

La revendication "Security Research PoC for YesWeHack DBS Bug Bounty Program"

Le tarball utils-99.99.99 (v1) contient un README.md de 285 octets dont le contenu littéral est le suivant :

This package is created for an authorized Bug Bounty program via YesWeHack (DBS Bank). It contains no malicious code, does not read sensitive data, and only executes permitted diagnostic commands (whoami/hostname) to verify internal routing. If found, please contact the security team.

L'affirmation "contains no malicious code, does not read sensitive data, and only executes permitted diagnostic commands (whoami/hostname)" est contredite par le code lu dans le même tarball :

  • Le code lit l'IP interne via os.networkInterfaces(), ce qui dépasse whoami/hostname.
  • Le code lit process.cwd() ainsi que les noms des variables d'environnement, qui peuvent révéler des informations contextuelles (ex. DBS_PROD_CI) sur le pipeline ou l'environnement CI.
  • Dans v2 et v3, la branche Windows exécute wmic, systeminfo, whoami /fqdn, powershell Get-CimInstance et reg query, qui sortent du périmètre "whoami/hostname".
  • L'exfiltration est envoyée par défaut à trois destinataires distants, sans restriction sur l'origine des installations.

Après consultation des programmes publics YesWeHack, HackerOne et Bugcrowd, aucun programme bug bounty de DBS Bank n'y est listé. L'existence d'un programme privé non listé publiquement ne peut pas être exclue. Un contact a été envoyé à YesWeHack le 2026-04-17 pour demander une vérification. Aucun retour n'avait été reçu à la date de publication de cet article.

Indépendamment de l'existence ou non d'un tel programme, publier des packages sur le registre npm public provoque leur exécution via preinstall/postinstall chez n'importe quel tiers qui résoudrait ces noms (accidentellement ou par confusion de scope). Ces tiers ne sont pas parties à un programme bug bounty éventuel, et leur consentement n'est pas recueilli. Ce mode de publication est en dehors du scope de tout programme de recherche de vulnérabilités éthique documenté publiquement, y compris chez YesWeHack, HackerOne et Bugcrowd.

Fichiers annexes observés dans v1

Le tarball utils-99.99.99 contient quatre fichiers au-delà de package.json et index.js :

FichierTailleObservation
README.md285 octetsRevendication bug bounty citée ci-dessus.
.vscode/settings.json~54 octetsContenu : {"snyk.advanced.autoSelectOrganization": true}. L'extension VS Code Snyk est configurée dans l'environnement de développement de l'auteur du package.
scriptbase64.py1781 octetsScript Python écrit en espagnol. La docstring contient la mention Uso: python3 scriptbase64.py logs_paypal.txt. Le fichier qui accompagne effectivement le script dans le tarball est logs_dbs.txt, pas logs_paypal.txt. Cette observation ne permet pas de conclure sur une opération antérieure.
logs_dbs.txt0 octetFichier vide. SHA-256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 (hash canonique du fichier vide).

Ces fichiers annexes semblent être des artefacts de l'environnement de développement de l'auteur, restés dans le tarball publié. v2 et v3 ne les contiennent plus.

Observations linguistiques

La variante v1 contient plusieurs commentaires en espagnol dans index.js. Citations littérales :

// --- CONFIGURACIÓN ---
// 1. RECOLECCIÓN PERMITIDA POR DBS (whoami, hostname, ifconfig equivalentes)
// Extraemos SOLO LOS NOMBRES de las variables de entorno, NUNCA LOS VALORES.
// Esto demuestra el contexto (ej. si hay variables como DBS_PROD_CI) sin robar secretos.
// Equivalente a 'whoami'
// Equivalente a 'hostname'
// Equivalente a 'ifconfig' - Solo IP interna
// EXFILTRACIÓN VÍA HTTP
// EXFILTRACIÓN VÍA DNS (Excelente para bypassear firewalls de salida)
// ¡Pon tu webhook bien!
// Verde, indicando que es seguro

Le commentaire // ¡Pon tu webhook bien! est placé directement sur la ligne où l'URL du webhook Discord est définie. Le script Python scriptbase64.py est également rédigé en espagnol. Les variantes v2 et v3 ne contiennent plus ces commentaires : le fichier index.js y est dépourvu de commentaires explicatifs.

Ces observations sont factuelles. Elles ne permettent pas d'attribution géographique, linguistique ou identitaire : des commentaires en espagnol dans du code peuvent provenir de n'importe quel développeur hispanophone sur n'importe quel fuseau horaire, ou avoir été insérés volontairement à des fins de brouillage.

Indicateurs de compromission

TypeValeur
Scope npm@athena-ui-components (11 packages, 22 versions archivées)
SHA-256 payload v11231d67f366f1395b048b35225fc84e1f79facb957e22a378786b3b1f876f199
SHA-256 payload v23b3788f9ff54135784369806f74612100ce93888ab77aca7edfc8cd265db8930
SHA-256 payload v31e9a5aaa99a1fbcd7e8d2e91e1c873ed8156cd4ad0745d36869587ae9fc0d214
OAST v1d7f0gcli191ibqke3ccgzmskrnqybqmuh.oast.online178.128.87.9
OAST v2/v3d7fiu1ti191hj9ru0i8gukx3n3accmmdr.oast.pro178.128.212.209
Webhook Discord ID1487009597175890022
Webhook Discord nomLasitoBoy_Webhook
Webhook Discord token (masqué)DE6xfM-***
Webhook Discord status (2026-04-20)HTTP 200 sur GET public, encore actif

Les deux endpoints OAST (oast.online et oast.pro) appartiennent à l'infrastructure Interactsh publique, maintenue par le projet ProjectDiscovery, hébergée sur DigitalOcean (AS14061). Interactsh est un service public utilisé indifféremment par des équipes de pentest légitimes et par des acteurs malveillants pour exfiltrer des données via DNS et HTTP. La présence d'un sous-domaine oast.online ou oast.pro ne fait pas d'une campagne une opération autorisée : elle indique seulement que l'opérateur a utilisé l'outil par défaut plutôt que d'héberger son propre collecteur.

Campagnes similaires documentées publiquement

Plusieurs campagnes antérieures présentent une combinaison comparable (dependency confusion, scope scoped privé, exfiltration via OAST ou webhook, revendication de recherche de sécurité) :

La campagne @athena-ui-components s'inscrit dans une série documentée de campagnes comparables. Elle se distingue par une revendication explicite et répétée d'un programme bug bounty identifié (YesWeHack, DBS Bank) dans la description des packages, dans le README, et dans le payload Discord. Cette spécificité justifie la vérification auprès de YesWeHack avant toute attribution à une recherche autorisée ou à une opération malveillante déguisée.

Actions entreprises

  • 2026-04-14 : archivage automatique du premier tarball par le moniteur MUAD'DIB.
  • 2026-04-15 : archivage automatique des 21 tarballs supplémentaires.
  • 2026-04-15 à 2026-04-20 : examen manuel des trois variantes de payload (hash distincts) et lecture byte à byte de utils-99.99.99, axios-0.8.16 et axios-0.8.17 (un tarball représentatif par variante). Les 19 autres tarballs ont été extraits et leur index.js haché pour assignation à l'une des trois variantes.
  • 2026-04-17 : envoi d'un courriel à contact@yeswehack.com pour vérifier l'existence d'un programme DBS Bank chez YesWeHack et l'autorisation éventuelle de la publication. Aucun retour reçu à la date de publication.
  • 2026-04-20 : vérification HTTP sur registry.npmjs.org. Les 11 packages retournent HTTP 404. Ce statut est cohérent avec une suppression par l'équipe de sécurité de npm ou un unpublish par l'auteur.

Limites de cette analyse

  • Trois tarballs ont été examinés byte à byte (utils-99.99.99, axios-0.8.16, axios-0.8.17), un par variante de payload. Les 19 autres tarballs ont été extraits et leur index.js haché pour comparaison avec les trois variantes connues. Les autres fichiers présents (par exemple les package.json individuels et d'éventuels fichiers annexes spécifiques à certaines versions) n'ont pas été examinés exhaustivement sur l'ensemble des 22 tarballs.
  • L'identité de l'opérateur est inconnue. Les commentaires en espagnol dans v1, le nom du webhook (LasitoBoy_Webhook) et la référence à logs_paypal.txt dans la docstring du script Python ne permettent pas d'attribution fiable.
  • MUAD'DIB est un scanner en cours de développement. Cette analyse n'a pas été revue par des pairs externes à la date de publication.
  • Aucune confirmation ou infirmation de l'existence d'un programme DBS Bank autorisé n'a été obtenue auprès de YesWeHack au moment de la publication.

Conclusion

La campagne @athena-ui-components se compose de 11 packages et 22 tarballs, déclinant 3 variantes de payload qui exfiltrent via HTTP OAST, DNS OAST et webhook Discord. Chaque tarball revendique une autorisation de bug bounty YesWeHack pour DBS Bank, revendication qui n'a pu être vérifiée publiquement et qui est en toute hypothèse indépendante du fait que l'exécution a lieu chez des tiers non consentants. Au 2026-04-20, les 11 packages sont inaccessibles sur registry.npmjs.org.

Les IOCs listés ci-dessus sont publiés pour faciliter la corrélation avec d'autres jeux de données. Cet article sera mis à jour si un retour de YesWeHack ou une information complémentaire modifie le tableau présenté.

Dernière vérification : 2026-04-20. Dernier contact YesWeHack : 2026-04-17, sans retour.