Im Axios-Lieferkettenkompromittierung – eine Verräterin, die sie alle beherrscht

Elastic Security Labs analysiert eine Kompromittierung der Lieferkette des axios npm-Pakets, das eine einheitliche plattformübergreifende RAT (Remote Access Trojan) bereitstellt.

Elastic Security Labs hat erste Triage- und Erkennungsregeln für die Axios-Lieferkettenkompromittierung veröffentlicht. Dies ist eine detaillierte Analyse der Funkzugangstechnologie und der Nutzlasten.

Einführung

Elastic Security Labs hat eine Gefährdung der Lieferkette des axios npm-Pakets festgestellt, eines der meistgenutzten Pakete im JavaScript-Ökosystem mit etwa 100 Millionen wöchentlichen Downloads. Der Angreifer kompromittierte ein Wartungskonto und veröffentlichte mit einer Hintertür versehene Versionen, die über einen bösartigen Postinstall-Hook einen plattformübergreifenden Remote-Access-Trojaner auf macOS-, Windows- und Linux-Systemen einschleusten.

Wichtigste Erkenntnisse

  • Ein kompromittiertes npm-Maintainer-Konto (jasonsaayman) wurde verwendet, um zwei schädliche Versionen des weit verbreiteten Axios-HTTP-Clients zu veröffentlichen – 1.14.1 (als „latest“ gekennzeichnet) und 0.30.4 (als „legacy“ gekennzeichnet) – was bedeutet, dass ein standardmäßiges „npm install axios“ zu einem Paket mit Hintertür führte.
  • Das bösartige JavaScript installiert plattformspezifische Stage-2-Implantate für macOS, Windows und Linux.
  • Alle drei Stage-2-Payloads sind Implementierungen desselben RAT – identisches C2-Protokoll, Befehlssatz, Beacon-Kadenz und gefälschter User-Agent, geschrieben in PowerShell (Windows), C++ (macOS) und Python (Linux).
  • Der Dropper führt eine forensische Bereinigung durch, indem er sich selbst löscht und seine package.json-Datei durch eine saubere Kopie ersetzt, wodurch Spuren des Postinstall-Triggers beseitigt werden. node_modules

Präambel

Am 30 März 2026 entdeckte Elastic Security Labs durch automatisierte Lieferkettenüberwachung eine Kompromittierung der Lieferkette, die auf das axios npm-Paket abzielte. Der Angreifer erlangte die Kontrolle über den npm-Account von jasonsaayman, einem der Hauptverantwortlichen des Projekts, und veröffentlichte innerhalb von 39 Minuten zwei Versionen mit Hintertüren.

Das axios-Paket ist eine der am weitesten verbreiteten HTTP-Client-Bibliotheken im JavaScript-Ökosystem. Zum Zeitpunkt der Entdeckung wiesen sowohl die neuesten als auch die älteren Dist-Tags auf kompromittierte Versionen hin, sodass die Mehrheit der Neuinstallationen eine Version mit Hintertür erhielt.

Die bösartigen Versionen führten eine einzige neue Abhängigkeit ein: plain-crypto-js, ein eigens dafür entwickeltes Paket, dessen Postinstall-Hook stillschweigend plattformspezifische Stage-2-RAT-Implantate von sfrclak[.]com:8000 herunterlud und ausführte.

Was diese Kampagne über ihren Wirkungsradius hinaus bemerkenswert macht, ist die Werkzeugausstattung der zweiten Phase. Der Angreifer setzte drei parallele Implementierungen desselben RAT ein – jeweils eine für Windows, macOS und Linux –, die alle ein identisches C2-Protokoll, eine identische Befehlsstruktur und ein identisches Beacon-Verhalten aufwiesen. Es handelt sich hierbei nicht um drei verschiedene Tools, sondern um ein einziges plattformübergreifendes Implantat-Framework mit plattformspezifischen Implementierungen.

Elastic Security Labs hat am 31. März 2026 um 01:50 Uhr UTC eine Sicherheitswarnung auf GitHub für das axios-Repository eingereicht, um die Offenlegung zu koordinieren und sicherzustellen, dass die Maintainer und die npm-Registry auf die kompromittierten Versionen reagieren können.

Nachdem die Community den Sicherheitsverstoß in den sozialen Medien gemeldet hatte, veröffentlichte Elastic Security Labs erste Erkenntnisse, um den Verteidigern eine Reaktion in Echtzeit zu ermöglichen.

Dieser Beitrag behandelt die gesamte Angriffskette: von der Kompromittierung der Lieferkette auf npm-Ebene über den verschleierten Dropper bis hin zur Architektur des plattformübergreifenden RAT und den wesentlichen Unterschieden zwischen seinen drei Varianten.

Kampagnenübersicht

Der Kompromiss wird in den Metadaten der npm-Registry deutlich. Die E-Mail-Adresse des Maintainers änderte sich von jasonsaayman@gmail[.]com – die bei allen vorherigen legitimen Versionen vorhanden war – zu ifstap@proton[.]me bei den bösartigen Versionen. Auch die Veröffentlichungsmethode änderte sich:

VersionHerausgegeben vonMethodHerkunft
axios@1.14.0 (legitim)jasonsaayman@gmail[.]comGitHub Actions OIDCSLSA-Herkunftsnachweise
axios@1.14.1 (kompromittiert)ifstap@proton[.]meDirekte CLI-VeröffentlichungKein Schutz
axios@0.30.4 (kompromittiert)ifstap@proton[.]meDirekte CLI-VeröffentlichungKein Schutz

Der Wechsel von einem vertrauenswürdigen OIDC-Publisher-Flow mit SLSA-Provenienz zu einem direkten CLI-Publish mit geänderter E-Mail-Adresse ist ein klares Indiz für unautorisierten Zugriff.

Zeitleiste

  • 2026-02-18 17:19 UTCaxios@0.30.3 rechtmäßig veröffentlicht von jasonsaayman@gmail[.]com
  • 2026-03-27 19:01 UTCaxios@1.14.0 Rechtmäßig veröffentlicht über GitHub Actions OIDC
  • 2026-03-30 05:57 UTCplain-crypto-js@4.2.0 veröffentlicht von nrwise (nrwise@proton.me) — Bereinigen des Köders zum Aufbau des Registrierungsverlaufs
  • 30.03.2026 23:59 UTCplain-crypto-js@4.2.1 veröffentlicht von nrwise — bösartige Version mit postinstall Hintertür
  • 2026-03-31 00:21 UTCaxios@1.14.1 veröffentlicht von einem kompromittierten Konto — markiert mit latest
  • 2026-03-31 01:00 UTCaxios@0.30.4 veröffentlicht von einem kompromittierten Konto — markiert mit legacy

Betroffene Pakete

  • axios@1.14.1 — Böswillig, zum Zeitpunkt der Entdeckung mit latest gekennzeichnet
  • axios@0.30.4 — Böswillig, zum Zeitpunkt der Entdeckung mit legacy gekennzeichnet
  • plain-crypto-js@4.2.0 — Saubere Täuschung, veröffentlicht, um die Registerhistorie aufzubauen
  • plain-crypto-js@4.2.1 — Böswilliges Nutzlasttransportfahrzeug (postinstall Hintertür)

Sichere Versionen: axios@1.14.0 (letzte legitime 1.x-Version mit SLSA-Herkunft) und axios@0.30.3 (letzte legitime 0.30.x -Version).

Der Angreifer markierte sowohl die neuesten als auch die älteren Kanäle und maximierte so den Wirkungsradius über Projekte hinweg, die entweder die aktuelle oder die ältere Axios-API verwendeten.

Code-Analyse

Phase 1: Der Plain-Crypto-JS-Dropper

Die gesamte Auslieferungskette hängt vom Postinstall-Lifecycle-Hook von npm ab. Die Installation einer der beiden kompromittierten Axios-Versionen zieht plain-crypto-js@^4.2.1 als Abhängigkeit nach sich, welche Folgendes deklariert:

"scripts": {
  "postinstall": "node setup.js"
}

Dies bewirkt, dass setup.js während npm install automatisch ausgeführt wird – eine Benutzerinteraktion ist nicht erforderlich.

Die setup.js-Datei verwendet ein zweischichtiges Kodierungsschema, um ihr Verhalten zu verbergen:

  • Schicht 1: Stringumkehrung gefolgt von Base64-Dekodierung
  • Schicht 2: XOR-Verschlüsselung mit dem Schlüssel OrDeR_7077 und einem positionsabhängigen Index (7 * i² % 10)

Alle kritischen Zeichenketten, Modulnamen, URLs und Shell-Befehle werden in einem kodierten Array stq[] gespeichert und zur Laufzeit dekodiert. Die entschlüsselten Inhalte offenbaren die operative Infrastruktur:

Plattformspezifische Auslieferung

Nach dem Dekodieren seiner Stringtabelle prüft der Dropper os.platform() und verzweigt sich in eine von drei Zustellungsroutinen. Jeder sendet einen HTTP-POST-Request an http://sfrclak[.]com:8000/6202033 mit einem plattformspezifischen Body — packages.npm.org/product0 (macOS), packages.npm.org/product1 (Windows), packages.npm.org/product2 (Linux) — ermöglicht es dem C2-Server, die korrekte Nutzlast von einem einzigen Endpunkt aus zu liefern. Die packages.npm.org/ Das Präfix ist ein bewusster Versuch, ausgehenden Datenverkehr in Netzwerkprotokollen als harmlose npm-Registry-Kommunikation erscheinen zu lassen:

PlattformLiefermethodeStandort Phase 2Verkleidung
macOSAppleScript lädt über osascript eine Binärdatei mit curl herunter./Library/Caches/com.apple.act.mondApple-Systemdaemon
WindowsVBScript-Downloads .ps1 via curl, ausgeführt über umbenanntes PowerShell (%PROGRAMDATA%\wt.exe)%TEMP%\6202033.ps1 (vorübergehend)Windows Terminal
LinuxDirekter curl-Download und Python3-Ausführung/tmp/ld.pyKein Schutz

Anti-Forensik

Die Pipette führt zwei Aufräumaktionen durch:

  1. Selbstlöschung: setup.js entfernt sich selbst mittels fs.unlink(__filename)
  2. Paketmanifest-Tausch: Eine saubere Datei namens package.md (die eine unproblematische Versionskonfiguration 4.2.0 ohne Postinstall-Hook enthält) wird in package.json umbenannt. die schädliche Version überschreiben

Eine nach dem Vorfall durchgeführte Überprüfung der Datei node_modules/plain-crypto-js/package.json ergab keine Hinweise auf den Postinstall-Trigger. Die schädliche setup.js-Datei ist verschwunden. Lediglich die Sperrdatei und die npm-Audit-Logs enthalten noch Beweise.

Phase 2: Plattformübergreifende RAT

Die drei Stage-2-Payloads: PowerShell für Windows, kompiliertes C++ für macOS und Python für Linux sind keine drei verschiedenen Tools. Es handelt sich um drei Implementierungen derselben RAT-Spezifikation, die ein identisches C2-Protokoll, einen identischen Befehlssatz, ein identisches Nachrichtenformat und ein identisches Betriebsverhalten aufweisen. Die Konsistenz deutet stark darauf hin, dass es sich um einen einzelnen Entwickler oder ein eng abgestimmtes Team handelt, das mit einem gemeinsamen Designdokument arbeitet.

Gemeinsame Architektur

Folgende Eigenschaften sind bei allen drei Varianten identisch:

  • C2-Transport: HTTP POST
  • Body-Kodierung: Base64-kodiertes JSON
  • User-Agent: mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)
  • Beacon-Intervall: 60 Sekunden
  • Sitzungs-UID: 16-stellige zufällige alphanumerische Zeichenfolge, die pro Ausführung generiert wird
  • Ausgehende Nachrichtentypen: FirstInfo, BaseInfo, CmdResult
  • Eingehende Befehlstypen: kill, peinject, runscript, rundir
  • Antwortbefehlstypen: rsp_kill, rsp_peinject, rsp_runscript, rsp_rundir

Besonders auffällig ist die gefälschte User-Agent-Zeichenfolge für IE8/Windows XP; sie ist auf allen drei Plattformen anachronistisch, und ihr Vorhandensein auf einem macOS- oder Linux-Host ist ein starkes Erkennungsmerkmal.

Initialisierung und Aufklärung

Beim Startvorgang jeder Variante:

  1. Generiert eine Sitzungs-UID – 16 zufällige alphanumerische Zeichen, die in jede nachfolgende C2-Nachricht eingefügt wird.
  2. Erkennt Betriebssystem und Architektur – meldet plattformspezifische Kennungen (z. B. windows_x64, macOS, linux_x64)
  3. Listet die relevanten Anfangsverzeichnisse auf (Benutzerprofil, Dokumente, Desktop, Konfigurationsverzeichnisse)
  4. Sendet ein FirstInfo-Beacon mit der UID, der Betriebssystemkennung und dem Verzeichnis-Snapshot.

Nach der Initialisierung tritt das Implantat in den Hauptkreislauf ein. Der erste BaseInfo-Heartbeat enthält ein umfassendes Systemprofil. Auf allen Plattformen werden dieselben Datenkategorien erfasst, obwohl sich die zugrunde liegenden APIs unterscheiden:

Gesammelte DatenWindows-QuellemacOS-QuelleLinux-Quellcode
Hostname%COMPUTERNAME% Umgebungsvariablegethostname()/proc/sys/kernel/hostname
Nutzername%USERNAME% Umgebungsvariablegetuid() + getpwuid()os.getlogin()
Version des BetriebssystemsWMI / Registrierungsysctlbyname("kern.osproductversion")platform.system() + platform.release()
ZeitzoneSystemzeitzonelocaltime_r()datetime.timezone
BootzeitSystemverfügbarkeitsysctl("kern.boottime")/proc/uptime
InstallationsdatumRegistry / WMIstat("/") oder sysctlZeitstempel von /var/log/installer oder /var/log/dpkg.log
HardwaremodellWMIsysctlbyname("hw.model")/sys/class/dmi/id/product_name
CPU-TypWMIsysctlbyname()platform.machine()
Process listVollständige Prozess-ID, Sitzung, Name, Pfadpopen("ps") (bis zu 1000)Vollständige /proc-Aufzählung (PID, PPID, Benutzer, Befehlszeile)

Die nachfolgenden Herzschläge sind leicht und enthalten lediglich einen Zeitstempel, um zu bestätigen, dass das Implantat funktioniert.

Befehlsausgabe

Die C2-Antwort wird als JSON analysiert, und das Feld „type“ bestimmt die auszuführende Aktion. Alle drei Varianten implementieren dieselben vier Befehle:

kill — Selbstbeendigung. Sendet eine rsp_kill-Bestätigung und beendet sich. Der Persistenzmechanismus der Windows-Variante (Registry-Schlüssel + Batch-Datei) bleibt nach dem Kill-Befehl erhalten, sofern er nicht explizit gelöscht wird; die macOS- und Linux-Varianten verfügen über keinen eigenen Persistenzmechanismus.

runscript — Skript-/Befehlsausführung. Der primäre Interaktionsbefehl des Bedieners. Akzeptiert ein Script-Feld (auszuführender Code) und ein Param-Feld (Argumente). Wenn das Skript leer ist, wird der Parameter direkt als Befehl ausgeführt. Der Ausführungsmechanismus ist plattformnativ:

PlattformAusführungsmechanismus
WindowsPowerShell mit -NoProfile -ep Umgehung
macOSAppleScript über /usr/bin/osascript
LinuxShell via subprocess.run(shell=True) oder Python über python3 -c

peinject – Zustellung binärer Nutzdaten. Trotz der Windows-zentrierten Bezeichnung („PE inject“) implementieren alle drei Plattformen dies als Methode zum Ablegen und Ausführen binärer Nutzdaten:

PlattformImplementation
WindowsReflektierendes Laden der .NET-Assembly über [System.Reflection.Assembly]::Load()
macOSBase64-dekodiert und verwirft eine Binärdatei und führt sie mit vom Operator bereitgestellten Parametern aus.
LinuxBase64-dekodiert eine Binärdatei nach /tmp/.<random 6-Zeichenkette> (versteckte Datei), startet über subprocess.Popen().

Die Windows-Implementierung verfügt über eine In-Memory-Ausführung ohne Dateispeicherung, jedoch ohne AMSI zu deaktivieren, was beim Laden der Assembly sicherlich zu einer Fehlermeldung führen wird. Die macOS- und Linux-Varianten verfolgen den einfacheren Ansatz, eine Binärdatei auf die Festplatte zu schreiben und diese direkt auszuführen.

rundir — Verzeichnisaufzählung. Akzeptiert Pfade und gibt detaillierte Dateilisten zurück (Name, Größe, Typ, Erstellungs-/Änderungszeitstempel, Anzahl der Unterverzeichnisse). Ermöglicht dem Benutzer das interaktive Durchsuchen des Dateisystems.

Zusammenfassung der Fähigkeiten

FunktionalitätWindows (PowerShell)macOS (C++)Linux (Python)
PersistenzRegistry-Schlüssel „Run“ + versteckte .bat-DateiKein SchutzKein Schutz
SkriptausführungPowerShellAppleScript via osascriptShell- oder Python-Inline-Code
Binäre InjektionReflective .NET-Lasteinspeisung in cmd.exeBinärdatei ablegen + ausführenBinärdatei nach /tmp/ ablegen + ausführen
Anti-ForensikBereinigung versteckter Fenster und temporärer DateienVersteckte temporäre .scpt-DateiVersteckte /tmp/.XXXXXX-Dateien

Quellenangabe

Die über den plain-crypto-js Postinstall-Hook ausgelieferte macOS Mach-O Binärdatei weist erhebliche Überschneidungen mit WAVESHAPER auf, einer von Mandiant verfolgten C++-Backdoor, die UNC1069, einem mit Nordkorea in Verbindung stehenden Bedrohungscluster, zugeordnet wird.

Fazit

Diese Kampagne beweist die anhaltende Attraktivität des npm-Ökosystems als Angriffsvektor für Lieferketten. Durch die Kompromittierung eines einzigen Maintainer-Kontos eines der am häufigsten genutzten Pakete im JavaScript-Ökosystem erlangte der Angreifer einen Verbreitungsmechanismus mit potenzieller Reichweite in Millionen von Umgebungen.

Der zuverlässigste Erkennungsindikator des Toolkits ist gleichzeitig seine kurioseste Designentscheidung: die identische, fest codierte User-Agent-Zeichenfolge für IE8/Windows XP auf allen drei Plattformvarianten. Während es einen konsistenten Protokoll-Fingerabdruck für das serverseitige Routing von C2 liefert, ist es auf jedem modernen Netzwerk trivial erkennbar – und stellt auf macOS- und Linux-Hosts eine sofortige Anomalie dar.

Elastic Security Labs wird diese Aktivitätsgruppe weiterhin überwachen und diesen Beitrag mit allen weiteren Erkenntnissen aktualisieren.

MITRE ATT&CK

Elastic verwendet das MITRE ATT&CK-Framework , um gängige Taktiken, Techniken und Verfahren zu dokumentieren, die von Advanced Persistent Threats gegen Unternehmensnetzwerke eingesetzt werden.

Taktiken

Taktiken stellen das Warum einer Technik oder Untertechnik dar. Es ist das taktische Ziel des Gegners: der Grund für die Ausführung einer Aktion.

Techniken

Techniken stellen dar, wie ein Angreifer ein taktisches Ziel erreicht, indem er eine Aktion ausführt.

Beobachtungen

Die folgenden Observablen wurden in dieser Studie diskutiert.

ÜberwachbarTypNameReferenz
617b67a8e1210e4fc87c92d1d1da45a2f311c08d26e89b12307cf583c900d101SHA-2566202033.ps1Windows-Nutzlast
92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645aSHA-256com.apple.act.mondMacOS-Nutzlast
fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cfSHA-256ld.pyLinux-Nutzlast
sfrclak[.]comDomainC2
142.11.206[.]73IPv4-ADDRC2

Referenzen

In der obigen Studie wurde auf Folgendes Bezug genommen: