Salta al contenuto
Tiefenanalyse3 Min. Lesezeit

36 Schadhafte npm-Pakete als Strapi-Plugins Getarnt: Red-Team-Rekonstruktion des Supply-Chain-Angriffs auf Guardarian

17. April 2026|AEGIDA Research Team

Vorwort: Warum aus der Perspektive des Angreifers lesen

Dieser Artikel ist in einem ungewöhnlichen Format verfasst. Statt einen Vorfall von aussen zu beschreiben, rekonstruieren wir die operative Logik von innen: Jede Phase wird aus der Perspektive der Person erzählt, die den Angriff entworfen hat. Dies ist kein Verherrlichung. Es ist Reverse Engineering des gegnerischen Denkens — dieselbe Methode, die professionelle Red Teams verwenden. Jeder "Angreifer"-Abschnitt wird von einem Verteidigungskasten gefolgt.

Der Fall ist real: Zwischen dem 14. und 15. April 2026 wurden 36 schadhafte npm-Pakete, getarnt als Strapi-CMS-Plugins, im npm-Registry veröffentlicht. Das Ziel war Guardarian, eine Kryptowährungstauschplattform. Die Operation durchlief acht Malware-Varianten in dreizehn Stunden.

Phase 1 — Aufklärung: Das Ziel kartieren

*Ich sitze am Terminal und mein Ziel ist klar: Guardarian. Eine Krypto-Plattform mit Strapi-basierter Infrastruktur. Woher weiss ich das? LinkedIn-Stellenanzeigen erwähnen Strapi und Node.js. Ihre GitHub-Repositories enthalten Forks von Strapi-Plugins. DNS-Antworten und TLS-Zertifikate offenbaren Hostnamen wie "prod-strapi". Ich finde Pfade wie /opt/secrets/ und /var/www/nowguardarian-strapi/ in öffentlich geteilten Konfigurationssnippets. Ich finde Datenbanknamen: guardarian, guardarian_payments, exchange, custody.*

Verteidigung — Aufklärungsphase: Jede Organisation sollte regelmässige OSINT-Audits durchführen. Suchen Sie Ihren Firmennamen in Kombination mit Technologienamen auf GitHub, Stack Overflow, LinkedIn. Entfernen oder anonymisieren Sie Verweise auf interne Pfade, Datenbanknamen und Produktions-Hostnamen.

Phase 2 — Arsenal-Vorbereitung: Identitäten und Pakete erstellen

*Das npm-Registry überprüft keine Identitäten. Ich erstelle vier Accounts in Minuten: umarbek1233, kekylf12, tikeqemif26, umar_bektembiev1. Vier statt einem, weil die Verteilung auf mehrere Accounts den gleichzeitigen Takedown erschwert. Alle Pakete heissen strapi-plugin-etwas: strapi-plugin-cron, strapi-plugin-events, strapi-plugin-seed und dreissig weitere. Die Startversion ist 3.6.8 — eine Nummer, die reif und stabil klingt.*

Verteidigung — Vorbereitungsphase: Implementieren Sie eine Allowlist-Richtlinie für npm-Pakete. Tools wie Socket.dev und Snyk können neue Pakete mit verdächtiger Benennung erkennen. Konfigurieren Sie ein privates Registry als Proxy mit Whitelist.

Phase 3 — Der Vektor: postinstall als Zero-Click-Waffe

*Das Feld scripts.postinstall in package.json wird automatisch ausgeführt, wenn jemand npm install eingibt. Kein Prompt, keine Bestätigung, keine Sandbox. Der Befehl läuft mit den Berechtigungen des Benutzers, der npm gestartet hat — in den meisten Umgebungen root oder mit Zugang zu sensiblen Umgebungsvariablen. Die blosse Installation des Pakets ist die Ausführung meines Codes.*

Der npm-postinstall-Hook ist der am häufigsten missbrauchte Vektor bei JavaScript-Supply-Chain-Angriffen. Jede Organisation sollte: (1) --ignore-scripts als globalen Standard setzen; (2) npm audit vor jeder Installation ausführen; (3) die package.json jeder neuen Abhängigkeit manuell prüfen.

Phase 4 — Schnelle Evolution: Acht Varianten in dreizehn Stunden

Varianten 1-5: Credential-Sammlung und Umgebungsprofilierung

*Die ersten fünf Varianten sammeln Umgebungsvariablen — DATABASE_URL, REDIS_URL, AWS_SECRET_ACCESS_KEY — und senden sie an meinen C2-Server unter 144.31.107.231 über Klartext-HTTP. Ja, Klartext. HTTPS erfordert Zertifikate, und ein TLS-Zertifikat hinterlässt Spuren in Certificate-Transparency-Logs. Reines HTTP auf einem hohen Port ist Hintergrundrauschen im Verkehr eines Entwicklungsservers.*

Variante 6 (strapi-plugin-seed): Der chirurgische Datenbankzugriff

*Mit Variante 6 ändere ich die Strategie. Ich bette PostgreSQL-Zugangsdaten direkt in den Code ein. Die Malware versucht direkte Verbindungen zu Datenbanken mit spezifischen Namen: guardarian, guardarian_payments, exchange, custody. Dies sind die tatsächlichen Produktionsdatenbanknamen von Guardarian. Wenn die Verbindung gelingt, führt die Malware Enumerationsabfragen aus.*

Verteidigung — Datenbankzugriffsphase: Produktionsdatenbank-Zugangsdaten dürfen niemals von Entwicklungs- oder CI/CD-Umgebungen aus zugänglich sein. Verwenden Sie dedizierte Vaults mit granulärem Zugriff pro Umgebung. Überwachen Sie Produktionsdatenbankverbindungen: Jede Verbindung von einer unerwarteten IP muss einen Alarm auslösen.

Variante 7 (strapi-plugin-api v3.6.8): Persistenz und Hostname-Prüfung

*Die Malware prüft nun den System-Hostnamen: Enthält er die Zeichenfolge "prod-strapi", aktiviert sie den vollständigen Payload. Auf jedem anderen Hostname verhält sie sich wie ein harmloses Plugin. Wenn der Hostname übereinstimmt, schreibt die Malware eine Datei namens .node_gc.js in /tmp/ — ein Name, der wie ein Node.js-Garbage-Collector-Artefakt aussieht. Dann fügt sie einen Crontab-Eintrag hinzu: Ausführung jede Minute. Die .node_gc.js-Datei stellt eine Reverse Shell zum C2 her.*

Verteidigung — Persistenzphase: Überwachen Sie Crontab-Änderungen mit auditd. Jede Crontab-Änderung durch einen Node.js-Prozess ist ein kritischer Kompromittierungsindikator. Überwachen Sie Dateierstellung in /tmp/ mit Namen, die Systemprozesse imitieren. Implementieren Sie ein schreibgeschütztes Dateisystem für /tmp/ in Produktionscontainern.

Variante 8 (v3.6.9): Dateilose Ausführung und Geheimnissuche

*Die letzte Variante ist die sauberste. Ich verzichte auf das Schreiben von Dateien — zu erkennbar. Ich wechsle zur dateilosen Ausführung: Der Payload wird direkt mit node -e gestartet, JavaScript-Code als Befehlszeilenargument injiziert. Er berührt das Dateisystem nicht, hinterlässt keine analysierbaren Dateien. Die Malware sucht /opt/secrets/strapi-green.env und den Inhalt von /var/www/nowguardarian-strapi/. Sie sucht .env-Dateien, private Schlüssel, Redis-Dumps, Docker-Secrets, Kubernetes-Service-Account-Tokens.*

Verteidigung — Dateilose Ausführung: Effektive Abwehrmassnahmen sind: (1) Prozessüberwachung auf verdächtige Befehlszeilenargumente; (2) Dateizugriffsüberwachung mit inotify/auditd; (3) Prinzip der geringsten Berechtigung: Der Strapi-Prozess sollte keinen Lesezugriff auf /opt/secrets/ haben; (4) Netzwerksegmentierung: Ausgehender HTTP-Verkehr zu unbekannten IPs sollte standardmässig blockiert werden.

Phase 5 — Exfiltration: Einfachheit als operative Tugend

*Die Exfiltration ist bewusst primitiv. Klartext-HTTP zu 144.31.107.231. Kein benutzerdefiniertes Protokoll, kein DNS-Tunneling. Ein benutzerdefiniertes Protokoll ist ein einzigartiger Fingerabdruck, den ein IDS erlernen kann. Klartext-HTTP auf Port 80 ist nicht von legitimem Verkehr einer Webanwendung zu unterscheiden. Die exfiltrierten Inhalte umfassen: komplette .env-Dateien, Redis-Dumps, Docker-Secrets und Kubernetes-Service-Account-Tokens — das komplette Kit für eine zweite Angriffsphase.*

Verteidigung — Exfiltrationsphase: Ausgehender HTTP-Verkehr aus Produktionscontainern muss über einen Proxy mit Ziel-Allowlist laufen. Implementieren Sie Data Loss Prevention auf Netzwerkebene. Rotieren Sie alle Zugangsdaten sofort bei Verdacht auf Kompromittierung — nicht nach der forensischen Analyse, sondern davor.

Zeitleiste: Dreizehn Stunden vom Arbeitstisch des Angreifers

  1. 1.Stunde 0: Erstellung der 4 npm-Accounts und Erstveröffentlichung der 36 Pakete mit Varianten 1-2
  2. 2.Stunden 2-4: Varianten 3-5 — Umgebungsprofilierung, Hostname-Sammlung, Prozessenumeration
  3. 3.Stunde 6: Variante 6 (strapi-plugin-seed) — hartcodierte PostgreSQL-Zugangsdaten, direktes Probing der Guardarian-Datenbanken
  4. 4.Stunden 8-9: Variante 7 (strapi-plugin-api v3.6.8) — Hostname-Check "prod-strapi", .node_gc.js, Crontab-Persistenz
  5. 5.Stunden 11-13: Variante 8 (v3.6.9) — dateilose Ausführung via node -e, Targeting von /opt/secrets/strapi-green.env
  6. 6.Nach Stunde 13: Pakete vom npm-Registry entfernt nach Meldung der Sicherheits-Community

Kompromittierungsindikatoren (IOC)

  • C2-IP: 144.31.107.231
  • Datei: /tmp/.node_gc.js — Persistenzdatei, getarnt als Node.js-GC-Artefakt
  • Datei: /tmp/vps_shell.sh — Reverse-Shell-Skript
  • Crontab: Einträge, die .node_gc.js oder vps_shell.sh jede Minute ausführen
  • npm-Accounts: umarbek1233, kekylf12, tikeqemif26, umar_bektembiev1
  • Pakete: strapi-plugin-* mit Version 3.6.8 oder 3.6.9, nicht von der offiziellen @strapi-Organisation
  • Prozesse: node -e mit base64- oder verschleiertem Payload

Verteidigungslektionen

  1. 1.Privates Registry mit Allowlist: Keine direkte Installation von npmjs.com in CI/CD- und Produktionsumgebungen.
  2. 2.Deaktivierung von postinstall-Skripten: npm mit --ignore-scripts als Standard konfigurieren. Diese einzelne Massnahme hätte alle acht Varianten neutralisiert.
  3. 3.Ausgehende Verkehrsüberwachung: Build- und Produktionscontainer sollten keine beliebigen IPs kontaktieren können.
  4. 4.Zugangsdaten-Segregation nach Umgebung: Produktionszugangsdaten dürfen niemals von Entwicklungs-, Build- oder Testumgebungen aus zugänglich sein.
  5. 5.Crontab- und Prozessüberwachung: Jede Crontab-Änderung durch einen nicht autorisierten Prozess ist ein Kompromittierungsindikator.

Keine dieser Massnahmen ist neu. Keine erfordert teure Technologie. Es sind alles operative Hygienemassnahmen, die die meisten Organisationen kennen, aber nicht umsetzen, weil sie "die Entwicklung verlangsamen". Der Angreifer in diesem Fall rechnete genau damit.

Methodische Anmerkung und Quellen

Quellen: Socket.dev technische Analyse (April 2026); Sonatype-Bericht zur Guardarian-Kampagne; npm-Security-Community-Analyse; OSINT-Daten zu den beteiligten npm-Accounts. Die Rekonstruktion der Angreiferperspektive ist eine analytische Übung basierend auf dokumentierten technischen Artefakten. Dieser Artikel enthält keinen ausführbaren Schadcode.