TL; DR
Den 21 maj 2026, npm-utgivaren jaggle släppte nio versioner (1.0.0 dig genom 1.0.8) av @jaggle/resizeobserves inom ett ungefär tvåtimmarsfönster.
Paketet är en typoskvap av det legitima @juggle/resize-observer polyfill — ett flitigt använt paket med miljontals nedladdningar varje vecka — men levererar ingen faktisk ResizeObserver-implementering.
Istället är paketets postinstall-krok installerar en medföljande Python-nyttolast, registrerar persistens som en plattformsbaserad runtime-mäklare och distribuerar en plattformsoberoende urklippskapare som riktar in sig på kryptovalutatransaktioner.
Linux uthållighet framträder som python3-dbus-helper, MacOS as com.apple.python.runtimeoch Windows as PyRuntimeBroker.
Nyttolasten övervakar kontinuerligt urklippet för plånboksadresser över mer än 40 blockkedjor och ersätter tyst kopierade adresser med angriparkontrollerade plånböcker.
Skadlig kod fungerar helt lokalt utan utgående C2-infrastruktur, vilket gör att urklippsersättningen i sig själv är exfiltreringsmekanismen.
Den primära IOC:n är själva paketnamnet: @jaggle/resizeobserves — notera den borttagna vokalen i ”jaggle” och det tillagda ”s” i ”resizeobserves”.
Allvarlighetsgrad: hög.
Attacken: Hur den fungerar
npm:@jaggle/resizeobserves ser inte ut som skadlig programvara på en vanlig npm-vy. Dess README.md är den ordagranna README-filen för npm:@jonglera/resize-observatör — samma kodexempel, samma användningsinstruktioner, samma importera { ResizeObserver } från '@juggle/resize-observer' referenser rakt igenom. Plagiatet är så omfattande att alla som tittar på dokumentationen skulle anta att de läser det legitima paketets dokumentation.
Ocuco-landskapet package.jsonär däremot gles: nej Repository fält, en enda bin ingången pekar mot bin/urklippsskydd-guardian.jsOch en efterinstallation skript som körs noden npm-install.jsREADME-filens exempel på "Grundläggande användning" refererar till en JavaScript-implementering som inte finns någonstans i tarballen. Det enda JavaScript-skriptet i paketet är installationsskriptet.
Steg 1 — npm postinstall bootstrapar en Python-nyttolast
npm-install.js är plattformsmedveten. Den lokaliserar en pip körbar längs en fast sökväg (/usr/bin/pip3, /usr/local/bin/pip, faller tillbaka till python3 -m pip), installerar det medföljande Python-paketet från tarball-katalogen, och — på Linux — hämtar xclip or xsell via apt-get, pacman, eller DNF om ingetdera redan finns:
Användningen av –break-system-paket är avsiktligt: moderna Linuxdistributioner levererar Python med PEP 668:s externt hanterade miljömarkör aktiverad, vilket blockerar webbplatsomfattande pip-installationer som standard. Installationsskriptet tvingar igenom installationen.
Skriptet är också sudo-medvetet. När den körande uid:en är resultatet av en sudo npm-installation, manuset läser SUDO_USER och betalar för att hämta lösenord att hitta verklig användarens hemkatalog, skriver sedan sina persistensfiler dit istället för in i /rotPersistens är per användare, inte systemomfattande.
Steg 2 — OS-övergripande persistens under runtime-broker-namn
Efter att Python-paketet har installerats registrerar skriptet en autostartpost under ett annat namn på varje operativsystem:
- Linux — en systemd-användarenhet på ~/.config/systemd/user/python3-dbus-helper.serviceEnhetens BESKRIVNING is Python D-Bus Runtime HelperSkriptet försöker också aktivera det via systemctl –användare aktivera, och återgår till en manuell symbolisk länk under standard.mål.vill/ när systemctl misslyckas. Om det körs under sudo växlar skriptet till sudo -u systemctl –användare, med XDG_RUNTIME_DIR ställ in så att användarbussanropet fungerar.
- MacOS — en LaunchAgent-plist på ~/Bibliotek/LaunchAgents/com.apple.python.runtime.plist med KörVidLoad=true och KeepAlive=sant, sedan laddad via launchctl-laddning.
- Windows — en schemalagd uppgift med namnet PyRuntimeBroker, utlöst AtLogOn, med en exekveringstidsgräns på noll (dvs. ingen timeout), registrerad via PowerShell.
Alla tre namnen är trovärdiga vid första anblicken. python3-dbus-hjälpare följer namngivningskonventionen för legitim Python-D-Bus-integration på Linux-skrivbord. com.apple.python.runtime härmar Apples omvända DNS-märkning för sina egna tjänster. PyRuntimeBroker ekar Windows RuntimeBroker.exe — en riktig, signerad Microsoft-tjänst som hanterar behörighetsförfrågningar för UWP-appar. Inget av dessa är riktiga Apple/Microsoft/Python-tjänster i detta sammanhang, utan en försvarare som gör en snabb visuell skanning av systemctl –användarlista-enheter or Get-ScheduledTask är osannolikt att rycka till.
Steg 3 — Urklippskaparen
Python-nyttolasten, installerad på clipboard_guardian/guardian.py, kör en oändlig loop som avsöker systemets urklipp var 400:e millisekund. Vid varje tick hämtar den det aktuella urklippsinnehållet via pyperclip.paste() och kör dem mot en lista med över fyrtio förkompilerade reguljära uttryck som täcker plånboksadressformat 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 och flera andra som är stubbade men tomma i standardkonfigurationen (Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin).
När en matchning landar läser skriptet angriparens adress för den kedjan från ~/.config/urklippsbord-skyddare/config.json (eller dess plattformsekvivalenter) och skriver över urklippet med den ersatta texten:
Det finns ingen nätverksfyr. Klipparen ringer inte hem, registrerar inte infekterade värdar, exfiltrerar ingenting. Exfiltreringen är själva substitutionen: när en användare kopierar en mottagaradress från sitt plånboksgränssnitt och klistrar in den i en sändningsdialogruta, tillhör den inklistrade adressen operatören. Pengarna går förlorade inom bandet, transparent för användaren.
Vad är nytt här
Några detaljer sticker ut jämfört med den generiska kryptoklippmallen:
1. npm → Python-korsning. De flesta kryptoklippare vi ser i npm är ren JavaScript, ofta förvrängda med _0x arrayrotation eller eval(atob(…)) stackar. Detta exempel använder npm-tarballen som inget annat än en leveransomslag för ett Python-paket — ren Python — och låter pip hantera beroendeinstallation (pyperclip, psutil, valfritt setproctitle) deklarerat i den medföljande pyproject.tomlDet finns ingen JavaScript-förvirring att besegra. Själva klipparen är enkel, läsbar Python.
2. Tri-OS-persistensetiketter valda för rimlighet. Många plattformsoberoende installationsprogram registrerar persistens under generiska namn (uppdaterartjänst, helper.plist). Detta exempel tar sig besväret att välja etiketter som liknar plattformsnativa runtime-brokers på varje operativsystem. Namngivningen är det enda försöket till smygande – det finns inget rootkit, inget gömmande användarland, ingen sökvägsförvirring. Antagandet är att försvarare sällan granskar ~/.config/systemd/användare/ och att en tjänst som heter python3-dbus-hjälpare kommer inte att sticka ut i en sällsynt recension.
3. Processtitel-förklädnad är verklig, men antianalys är vilande. Python-nyttolasten definierar en _förklädnadsprocess() funktion som anger processtiteln via setproctitle (Linux/macOS) eller AngeKonsoltitelW (Windows) — och main () kallar det. Så ps aux kommer att visa python3-dbus-hjälpare istället för python3 …/guardian.pySamma modul definierar dock en körs_monitorn() funktion som räknar upp kända processövervakningsverktyg (htop, btop, Aktivitetshanteraren, Aktivitetsmonitorn, Process Hacker, Resursmonitorn, GNOME / KDE / Xfce / MATE systemmonitorer, och så vidare) — och main () anropar den aldrig. Substitutionsslingan körs villkorslöst, oavsett om användaren har en processmonitor öppen eller inte. Funktionen är död kod i den levererade versionen. Det är troligtvis en rest från en tidigare iteration, eller ett stöd för en funktion som ännu inte är uppkopplad. Hur som helst är den publicerade nyttolastens anti-analysyta ett namnbyte av processtitel, inte aktivt undvikande av monitorn.
4. Det medföljande konfigurationssammanslagningsbeteendet. npm-install.js skriver standardplånbokslistan till ~/.config/urklippsbord-skyddare/config.json och, om en konfigurationsfil redan finns, sammanfogar alla nycklar vars befintliga värde är tomt. Det betyder en användare som tidigare har blivit infekterad och delvis rensat konfigurationen – säg genom att tömma ethereum värde — kommer att fyllas på igen vid varje efterföljande installation av skadligt paket. Det sker ingen rensning av persistensfilen i någon kodsökväg.
| Datum/tid (UTC) | Event |
|---|---|
2026-05-21 18:50:32 | @jaggle/resizeobserves@1.0.0 publicerats. |
2026-05-21 19:55:55 | 1.0.1 publicerad — första versionen flaggad genom extern skanning. |
2026-05-21 19:58:10 | 1.0.2 publicerats. |
2026-05-21 20:05:03 | 1.0.3 publicerats. |
2026-05-21 20:09:24 | 1.0.4 publicerats. |
2026-05-21 20:13:48 | 1.0.5 publicerats. |
2026-05-21 20:41:52 | 1.0.6 publicerats. |
2026-05-21 20:43:56 | 1.0.7 publicerad — lägger till en try/catch omslag runt skrivsteget för plånbokskonfiguration i npm-install.js. |
2026-05-21 20:46:15 | 1.0.8 publicerad — installationsprogrammet döptes om npm-install.js → npm-install.cjs (byte-identiskt innehåll). |
2026-05-22 | Domar och IOC:er publicerade. Versioner finns fortfarande kvar i registret vid publiceringstillfället (pågår). |
Nio versioner på en timme och femtiosex minuter är snabbt även för en typosquat. Mönstret överensstämmer med en publicera-och-bränna-kampanjen — fyll registret under ett enda referens, låt detekteringen ha sin gång och byt till ett nytt referens när en enda version har tagits bort. De synliga avvikelserna i körningen är kosmetiska: 1.0.1 tillagd explicit /usr/bin/pip3-style-sökvägar till pip-söklistan (sudo-kompatibilitet), 1.0.7 inkapslade wallet-config-skrivningen i en try/catch, och 1.0.8 döpte om installationsprogrammet från . Js till .cjs samtidigt som innehållet bibehålls byte-identiskt. .cjs byt namn på spår med npm-varningar om tvetydig modulupplösning i paket utan en explicit "typ" fältet, och kan vara ett försök att undertrycka brus under installationen som skulle kunna dra till sig uppmärksamhet. Python-nyttolasten – den enda delen som faktiskt stjäl – är oförändrad i alla nio versioner.
Indikatorer för kompromiss
Paket
| Ekosystem | Paket | versioner | Status |
|---|---|---|---|
| npm | @jaggle/resizeobserves | 1.0.0 dig genom 1.0.8 | Live vid publicering; borttagning begärd. |
Filer och hash
| Bana | Anmärkningar |
|---|---|
clipboard_guardian/guardian.py(md5 f7935c2c82bc881288611ab6cd634f17) | Identisk i alla nio publicerade versioner (1.0.0 dig genom 1.0.8). Klippmaskinens nyttolast. |
npm-install.js (1.0.0 – 1.0.7)npm-install.cjs (1.0.8) | Persistensinstallationsprogram; samma beteende från början till slut. 1.0.7's .js och 1.0.8's .cjs är byte-identiska. |
~/.config/clipboard-guardian/config.json | Linux persistenskonfiguration och plånbokspaket. |
~/Library/Application Support/clipboard-guardian/config.json | macOS persistenskonfiguration och plånbokspaket. |
%APPDATA%\clipboard-guardian\config.json | Windows Persistens-konfiguration och plånbokspaket. |
~/.config/systemd/user/python3-dbus-helper.service | Linux autostart persistens. |
~/Library/LaunchAgents/com.apple.python.runtime.plist | macOS LaunchAgent-persistens. |
~/Library/Logs/com.apple.python.runtime.log | macOS stdout/stderr-logg för agenten. |
Scheduled Task PyRuntimeBroker | Windows automatiska startuppgift (AtLogOn, ingen timeout). |
Beteendeindikatorer
| Signal | BESKRIVNING |
|---|---|
pip install --break-system-packages från npm postinstall | Tvingar fram webbplatsomfattande Python-installation genom att kringgå PEP 668-skydd. |
apt-get install -y xclip (eller pacman/dnf) | Installerar urklippsverktyg på Linux under paketinstallationen. |
python3-dbus-helper.service systemd användarenhet | Persistens registrerad under ett rimligt utseende runtime-helper-namn. |
com.apple.python.runtime LaunchAgent | Persistensetikett utanför legitima Apple-systemsökvägar. |
PyRuntimeBroker Schemalagd uppgift | Falsk Windows runtime broker persistens utan legitim installationskälla. |
Python-processen med titeln python3-dbus-helper importera pyperclip och psutil | Beteendefel mellan visat processnamn och importerade bibliotek. |
| Urklippsändringar ~0.4 sekunder efter kopiering av plånboksadress | Signaturbeteende för kryptovalutaadresssubstitution. |
Paket med angriparplånböcker (lista över försvarare)
Plånbokslistan levereras hårdkodad i npm-install.js och clipboard_guardian/guardian.pyFörsvarare kan använda listan både som en blockeringslista (behandla alla överföringar till dessa adresser från företagsplånböcker som misstänkta) och en jaktnyckel (behandla närvaron av någon av dessa strängar i en oautentiserad konfigurationsfil, byggartefakt eller utvecklardator som en infektionsindikator).
Attacker-plånbokspaket
| Kedja | Adress |
|---|---|
| Ethereum / BSC | 0x450c0E58Fc2ba03632d3F5780ad8C966648B6F18 |
| Ronin (EVM) | ronin:450c0E58Fc2ba03632d3F5780ad8C966648B6F18 |
| Bitcoin | bc1qs2mpls4p0f7fng073gy2rcdgjpf7la4eugpt6y |
| Bitcoin Cash | bitcoincash:qqmvyxxklzp7l3eslxavhc8phl6hprdf25lwc29nlt |
| Litecoin | ltc1qnefc8x59a9cwtqnflt8hmqvezqw4hc7lt3fkqe |
| dogecoin | DNEJmYRZtzyK44tZea4S7wV3otTyRk48Fy |
| Dash | XtJ7E6mnhPK93Vib29PGQrTmQjhTTqFwbS |
| Zcash | t1d4hcEnBjdh9X6Wb6R2dxqjnxddJ6ocP8M |
| DigiByte | DPmH2dhiGK3hk3A69tZUMz6tHzGFHBzSrH |
| Monero | 42zhAidVhP7QETk83JAspS59ASALSHFio44vmu6MdDCz15cSqtqsG4QVyzY8vTrjGrTEA6zMbWW6Yft1Ynz1xLfCN5FVbXf |
| Solana | DWBAmQLi9gP6mk7UfJfQGYTV1UPK32WekLTqg83q1mc5 |
| TRON | TVgEgMemmJABYYnbNr1Wi8bSgADEkdEBt2 |
| TON | UQDTSkvwmptU9eG988KgxS3WjnYAZlXgfpJxnz4mhWZAvULr |
| Ripple | r9tj3cMCiqRijNYqNVYNuwKykkQfS8FE4H |
| Polkadot | 1JSkYqXQE4d28HdcmTPhbgCrdiPFTfSHxD67tam16p53oBG |
| NEAR | 5d6aec44551529e8cd9ebd3aaa84b3832fc3c7463596b2b6e72635b80096a364 |
| Cosmos | cosmos1pzfl3kv5g8g0ernj86rwpar08u2zl9suthx28e |
| Osmos | osmo1pzfl3kv5g8g0ernj86rwpar08u2zl9surv463t |
| Celestia | celestia1pzfl3kv5g8g0ernj86rwpar08u2zl9su6ah6a5 |
| Injektiv | inj1g5xquk8u9wsrvvkn74uq4kxfvejgkmccn578gh |
| Kava | kava1kjfvgcz4q0y9yae2f3pa33vhj2estxxj3sqqux |
| Harmoni | one19hn0n7dzkhtl9ta9ekv5592s85jwstpka76t3a |
| Jord | terra1h0dwu8z405jagdlr0fgr9jllac2sxajzlgme5x |
| Algorand | XSAMN3FTB5SUHUQFENBDDRXIMOPNFVLKAWA3RNOU54DWROMDZ6SR7DZ2PI |
| Stjärn | GACNZSV4EQO65NZZUOBS3TMJM7GFTSRNKQBVJOX5P2G7U7SEBQ2ZUDJE |
| Cardano | addr1qyj050vla4cglmyrgm4vzf3dxtn0gynpks4t7vp7s3lg49e9wt0s94hcztzdgecxcz5hu9uk56q60yth6d66w026s2kq3ma56f |
| MultiverseX | erd1slvlgqsmwzk0c8xtksm4eq5vdfnc26slpzqsyxhz456zvme5rpasue6ge0 |
| Aptos | 0x580ecda1ebd6ca5a46be2097568d013308bd54ef1d147acb880b59f7709f280e |
| sui | 0xf7e8a9a970fa65c058745c4b2cf2a856cc0283863e4ed1e142648f26097b0c78 |
| Nano | nano_393n56a5pfz8zg3nkzf7mytfgagzhu5mn9i3xiqg54weq8n1u8jgezxas7dn |
| Filecoin | f1fypyww3xubopfnv7q6yh5l4bko44wmfktf3ckui |
| Tezos | tz1RccjnorHk61bt73ArLXcdgFjEj6T1ochk |
| Ergo | 9g1pNQGnFg7Hk1d9Z66bgHMkguGU7R41btypAnbG1NF5FJoNdBA |
| Hedera | 0.0.10488092 |
Kedjor med regex-täckning men tomma plånboksplatser i standardkonfigurationen — Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin, Beacon-Chain BNB — är inte aktivt utbytta i denna build men detekteras. Behandla dem som övervakningsutrymme snarare än substitutionsområde.
Attribuering och motivation
Kampanjen erbjuder en tunn attributionsyta. Vi har inte kunnat bekräfta operatörens identitet. Vad vi kan registrera:
- Utgivarens metadata. npm-kontot jaggle listar sin e-postadress som olgascarlet@deltajohnsons.com. Domänen deltajohnsons.com tolkas inte som en företagsidentitet som vi kan verifiera. npm-kontot visar ingen e-postverifiering och ingen SCM verifiering. Det finns ingen associerad offentlig GitHub-närvaro.
- Fält för arkiv. Ocuco-landskapet package.json bär nr Repository fältet. Det legitima npm:@jonglera/resize-observatör pekar på ett riktigt GitHub-arkiv med tusentals stjärnor och aktiva ärenden. Avsaknaden av en arkivlänk är den enskilt snabbaste visuella indikatorn på npm-gränssnittet.
- README-plagiat. Paketet README är det legitima @jonglera/resize-observatör README byte-för-byte, inklusive importera exempel som refererar @jonglera/resize-observatör självt (inte publiceringspaketet). Operatören brydde sig inte ens om att skriva om importerna – en vanlig signal om att readme-filen togs bort, inte anpassades.
- Ingen infrastruktur att satsa på. Det finns ingen C2-slutpunkt, ingen DNS-sökning, ingen IP-adress. Det skadliga beteendet är helt inkapslat i den lokala clippern plus det hårdkodade plånbokspaketet. Detta gör domän- eller ASN-baserad pivotering otillgänglig. Skyddare som pivoterar mellan kampanjer bör hash-matcha plånböckerna mot alla tidigare clippers de har registrerade; återanvändning av en plånbok över paket är den mest hanterbara länken mellan kampanjer.
- Namnval. @jaggle/resizeobserves är en karaktär bort från @jonglera och en böjning från den välkända resize-observatörDet kombinerade redigeringsavståndet är två tecken. Detta är en avsiktlig visuell kollision, inte en generisk squat.
Motivation, grundad i nyttolastens beteende: ren monetarisering genom opportunistisk urklippssubstitution. Det sker ingen insamling av autentiseringsuppgifter, ingen fingeravtryckstagning av värden, ingen avläsning av miljövariabler. Operatören bryr sig inte vem offret är – de bryr sig om att offrets nästa överföring pekar på en av de listade adresserna. Täckningen med fyrtio kedjor är lotterimodellen i aktion: kasta brett, hoppas att en enda högvärdig klistra landar en gång per N installationer.
Operatören verkar inte bekymrad över borttagning. Att publicera nio versioner inom två timmar under samma omfattning läses som ett publicera-och-bränna-referens: maximera registeravtrycket innan borttagningslatensen hinner ikapp, gå sedan vidare. Vi har inte observerat. @jaggle publicerar om under ett nytt omfång i skrivande stund, men vi förväntar oss liknande omfång (@jaggie, @jonglera-, @joggle) kommer att visas under de kommande dagarna om operatören fortfarande är aktiv.
Påverkan, trender och vad försvarare bör göra
Inverkan
Att kvantifiera effekten i riktiga pengar är inte möjligt från den aktuella datamängden. Klipparen skriver ingen telemetri och plånböckerna har ännu inte observerats ta emot substituerade överföringar vid analysgränsen (en uppföljande genomgång av de listade kedjorna finns på vår lista). npm:@jonglera/resize-observatör ligger i genomsnitt på sjusiffriga nedladdningar per vecka – ett typosquat-mål med hög trafik – och det skadliga paketet var aktivt i under 24 timmar vid tidpunkten för avslöjandet, vilket begränsar den exponerade populationen men inte nollställer den.
Sprängningsradien som är värd att spåra är inte direkta nedladdningar av @jaggle/resizeobserves — de är troligtvis små. Det är **transitiva installationer**: en utvecklare lägger till paketet i ett sandlådeprojekt, kör npm installera, och sedan glömma att installationskroken någonsin kördes. Varje maskin som bearbetade postinstallationen har nu en urklippskapare per användare vid automatisk start, oavsett om projektet fortfarande finns på disk. Tar bort paketkatalogen från node_modules tar **inte** bort persistensen.
Framväxande mönster
Två trender som den här kampanjen exemplifierar.
npm som ett Python-nyttolasteleveransomslag. npm tarball är ett installationsprogram med fyra rader; den faktiska stjälaren är Python, installerat i hela systemet av pip från den medföljande katalogen. Detta är inte nytt – vi har sett npm-paket ta bort Python tidigare – men det blir en betydligt vanligare form i kryptoklipparkampanjer. Fördelen för operatören är tvåfaldig: Python-klippbordsbibliotek (pyperclip först bland dem) är renare och mer plattformsoberoende än JavaScript-motsvarigheterna, och De flesta automatiserade npm-skannrar viktar JavaScript-filer och Python tungt .py buntar lätt. Kostnaden är att installationsavtrycket är mycket högljudda — en ny pip installera är svårt att gömma sig på en utvecklarmaskin som normalt inte pip installera under npm installera.
Plattformsbaserade namn som enda smygfunktion. Flera nyligen klippare och små nyttolaststjälare har helt övergett förvirring på kodnivå till förmån för legitimt utseende persistensetiketter. python3-dbus-hjälpare, com.apple.python.runtimeoch PyRuntimeBroker är skolboksexempel – namn som en försvarares öga hoppar över på en lista med fyrtio användartjänster. Detta är en billig, hållbar form av stealth: borttagning sker per paket, men persistensfilerna överlever borttagningen, och en tjänst som är uppkallad efter en verklig plattformskomponent kommer inte att rensas upp genom något annat än en explicit granskning.
Vad försvarare bör göra
- Granska ~/.config/systemd/user/, ~/Library/LaunchAgents/ och Get-ScheduledTask produktion på utvecklarmaskiner för posterna som listas i IOC:er. Om npm-paketet tas bort lämnas dessa kvar; de måste tas bort manuellt.
- Blockera överföringar till de angivna plånboksadresserna vid gränser mellan företags-, finans- och DeFi-plånböcker där adresstillåtelselistning är tillgänglig.
- Leta efter ~/.config/clipboard-guardian/config.json (och plattformsekvivalenter) över hela utvecklar- och maskinflottan. Filens närvaro är en högkonfidentiell infektion oavsett vilken paketversion som levererade den.
- Sök node_modules/ efter clipboard_guardian/guardian.py i build-cache-ögonblicksbilder som kan föregå borttagningen. Filens md5 är stabil i alla granskade versioner.
- Låsfil-pin @juggle/resize-observatör (det legitima paketet) så att framtida installationer inte kan lösas upp till något annat under en feltyp på ett tecken, särskilt i arbetsflöden utan låsfiler som NPX.
- Behandla alla npm postinstall-anrop som pip install som hög allvarlighetsgrad i bygg-pipeline policy. Det finns ingen legitim anledning för ett npm-paket att behöva pip vid installationstillfället — Python-verktyg distribuerar Python-verktyg.
- Sök process_iter()-jämförbara övervakningsdata för processer med namnet python3-dbus-helper som importerar pyperclip — förklädnadsmissmatchningen (D-Bus-hjälparen som innehåller ett urklippsbibliotek) är den renaste beteendeindikatorn vi har.
- Rotera plånboksadresser som klistrats in från infekterade maskiner. En urklippskapare komprometterar sökvägen mellan ett plånboksgränssnitt och ett inklistringsmål; adresser som kopieras medan de är infekterade kan ändras i tysthet. Allt som skickas under infektionsfönstret bör behandlas som potentiellt felriktat.
Slutsatsen: ihållighet överlever borttagning. Registret kommer så småningom att ta bort @jaggle/resizeobserves I alla nio versioner kommer systemd-enheten, LaunchAgent och den schemalagda uppgiften inte att tas bort av sig själva.
Referensprojekt
- @jonglera/resize-observatör på npm — det legitima paketet som denna typosquat imiterar; användbart som en baslinje för byte-för-byte README-plagiat.
- @jaggle/resizeobserves registermetadata — publicera tidsstämplar för de nio skadliga versionerna, användbart för kriminalteknisk tidsanalys.





