Auf dem Python-Paketmanager PyPI sind über 450 Pakete mit Schadcode aufgetaucht, die darauf ausgelegt sind, Kryptowährung abzugreifen. Das auf Sicherheit in der Software Supply Chain ausgerichtete Unternehmen Phylum hat die Pakete analysiert, die unter Windows eine Extension für Chromium installieren, welche Wallet-Adressen in der Zwischenablage austauscht. Der Angriff setzt auf Typosquatting: Die Namen der Pakete ähneln regulären Python-Paketen, bringen aber kleine Änderungen wie fehlende Buchstaben oder zusätzliche Zeichen in die Schreibweise ein. Alleine für das vyper
-Paket zu der Programmiersprache für die Ethereum Virtual Machine (EVM) hat Phylum dreizehn Pakete von vypr
bis vyperr
gefunden. Für längere Paketnamen wie beim Paket cryptocompare
für Preisvergleiche von Kryptowährung über die CryptoCompare-API sind wohl 38 Varianten mit absichtlichen Tippfehlern auf PyPI aufgetaucht. Alle PyPI-Pakete setzen auf denselben Angriffsvektor, den bereits eine im November entdeckte Welle nutzte, die aus ein paar Dutzend Packages auf PyPI bestand: Die Schadsoftware legt unter Windows eine JavaScript-Extension für Chromium an. Anschließend sucht sie nach Links zu den Browsern, die die Engine verwenden – Google Chrome, Microsoft Edge, Opera und Brave – und erweitert die gefundenen Verknüpfungen mit dem Parameter --load-extension
und dem Pfad zur Extension, um sie beim Start des jeweiligen Browsers auszuführen. Der JavaScript-Code in der Extension ersetzt Wallet-Adressen für Kryptowährungen in der Zwischenablage mit fest vorgegebenen Wallet-Adressen, um Transaktionen umzuleiten. Während der Code in der abgelegten Extension gut lesbar ist und beispielsweise den offensichtlichen Funktionsnamen checkWalletAddresses()
verwendet, ist der Python-Code in den PyPI-Paketen, der die Extension anlegt und die Browser-Verknüpfungen manipuliert, aufwendig verschleiert. Zunächst verwendet er für die Variablen- und Funktionsnamen chinesische Ideogramme: Die Namen setzen sich aus jeweils 16 scheinbar zufällig zusammengewürfelten Ideogrammen zusammen. Der eigentliche Code entsteht durch das Zusammensetzen einzelner Zeichen, die wiederum durch Methoden wie __str__
verschleiert sind. Letztere Methode wandelt Python-Objekte in Strings um. Daraus greift der Schadcode einzelne Buchstaben über den Index ab, der durch bitweise Operationen zusätzlich schwerer lesbar ist.
''.join(map(getattr(__builtins__, oct.__str__()[-3 << 0] + hex.__str__()[-1 << 2] + copyright.__str__()[4 << 0]), [(((1 << 4) - 1) << 3) - 1, ((((3 << 2) + 1)) << 3) + 1, (7 << 4) - (1 << 1), ((((3 << 2) + 1)) << 2) - 1, (((3 << 3) + 1) << 1)]))
Der Buchstabe c ist am Anfang der obigen Codezeile als oct.__str__()[-3 << 0]
geschrieben: Python wandelt oct.__str__()
in die Zeichenkette <built-in function oct>
um, deren drittletzter Buchstabe (an dieser Stelle ist die bitweise Verschiebung 0) das c ist. Dieses ist wiederum der Start für den Befehl chr
, um eine Zahl in ein Zeichen zu wandeln. Die umzuwandelnden Zahlen sind ihrerseits mit bitweisen Operationen verschleiert. Nach deren Auflösung führt obige Zeile den chr
-Befehl auf die Zahlenfolge [119, 105, 110, 51, 50]
aus, was letztlich win32
ergibt. Weitere Details zum Angriff lassen sich dem Phylum-Blog entnehmen, der die Namen der gefundenen Pakete auflistet, die zu einem großen Teil auf PyPI-Pakete rund um Kryptowährungen zielen. Ein Update des Beitrags weist darauf hin, dass die Attacke wohl weiter läuft und zusätzliche Typosquatting-Pakete auf PyPI aufgetaucht sind, die denselben Angriffsvektor verwenden.