Riskabla affärer: Förklaring av självborttagande npm-paket

Riskabla affärer: Anti-Proctoring-paketen som tar bort sig själva

TL; DR

Paketen raderar sig själva. Under femton dagar i augusti publicerade en npm-operatör nio paket under nio namn från sju konton och drog tillbaka åtta av dem personligen. Fönstret som var och en lämnades stående minskade från tretton timmar till sjutton minuter. Tekniken är inte bara deras: sju ytterligare paket från oberoende operatörer, med helt olika nyttolaster, drogs tillbaka av sina egna utgivare med en mediantid på 37.8 minuter. Artefakten är borta innan de flesta defensiva processer körs, och installationen har redan skett.

Allt som registret exponerar roterar; nyttolasten gör det inte. Alla nio levererade en byte-identisk bin/ katalogen, samma SHA-256-sammanfattningar över tre paketnamn och två konton, med femton dagars mellanrum. Innehållsidentitet är den enda spårningssignalen som den här operatören inte knäckte, och det enda paketet de aldrig drog tillbaka är anledningen till att något av det överhuvudtaget kunde undersökas.

De som installerar det är inte offer, och är ändå allvarligt utsatta. Det här verktyget är inte riktat mot utvecklare: det eliminerar fjärrövervakning av prov genom dold skärmdumpning, textutvinning på skärmen och att svaren returneras till ett överlägg, så vem som än springer npm install är den avsedda mottagaren snarare än målet. De kör också en osignerad binärfil som dekrypterar deras webbläsarens cookie-arkiv, från ett konto som raderar sig självt inom en timme. De kan inte få en åtgärd, kan inte senare granska vad de körde och kan inte rapportera skada utan att avslöja varför de installerade den.

Ekosystem: npm, samma mönster observerat på PyPI. Period: Juni–augusti 2026.

Mätningen

Uppehållstiden är intervallet mellan att ett paket dyker upp och försvinner, beräknat från registrets egna metadata. Dessa är mått, inte uppskattningar.

PaketPublicerad (UTC)Vänsterstående
moidev2026-08-16 16:315h 58m
moidevx2026-08-17 03:2413h 23m
moidevz2026-08-26 03:3812h 56m
moideva2026-08-26 18:581h 33m
amicat2026-08-28 20:48Ner till 17m
bmcat2026-08-28 21:17Ner till 47m
eyevox2026-08-28 21:44Ner till 21m
moidevh2026-08-31 03:22Ner till 47m

Läst i publiceringsordning krymper fönstret med mer än en faktor fyrtio – från 13 timmar och 23 minuter som bredast till 17 minuter som smalast. De fyra första paketen är i genomsnitt åtta och en halv timme långa; de fyra sista är i genomsnitt trettiotre minuter långa. Den 28 augusti publicerades och drogs tre paket tillbaka inom loppet av 77 minuter.

Nedgången är inte en gradvis avdrift. Den är koncentrerad mellan 26 och 28 augusti, och det som förändrades var operatörens uppskattning av hur länge ett paket säkert kan stå.

Varje uttag här initieras av utgivaren. Registerdokumentet för varje uttag visar en tom lista över ansvariga bredvid en tid.opublicerad register — signaturen för en avpublicering snarare än en borttagning. Ett nionde paket, ögon, drogs aldrig tillbaka alls; det är anledningen till att allt detta kunde granskas.

Ett andra uttagssystem finns och bör inte förväxlas med detta. Där endast nyttolastversion dras tillbaka och paketet överlever, är medianen ungefär 73 timmar fördelat på 31 paket. Dessa ersättningar anländer i skriptade omgångar och lämnar ett tomt skal — en package.json deklarera en huvudsakliga som inte skickar någon fil — vars enda funktion är att hålla namnet kvar. Den regimen är schemalagd städning. Den här är ett justerat exponeringsfönster.

Vad som överlever borttagningen

Nio av dessa paket är en operatör: moidev, moidevx, moidevz, moideva, moidevh, amicat, bmcat, eyevox och ögonNamnen delar ingen konvention — någon som spårar moidev stem skulle ha missat mer än hälften av dem – och de publicerades från sju separata konton, nästan alla registrerade på domäner för engångs-e-post.

Det de delar är en manifest post utan anledning att existera:

"brickan": { "": "bin/kalamasha-tool.js" } }

Vi behöll kopior av fem innan vi tog bort dem. För alla fem, hela soptunna / katalogen är byte-identisk:

FilSHA-256
bin/kalamasha-tool.js0c293be90c10c8a7618d25f4c4811fa63612b7bc5199b86e10bb31eb36c716dd
bin/uia_extract.exee2fda5aa8397799669f29258f69e803cf05d322c1d93269eef6754ca024c3865
bin/chrome_cookies.ps121b61ec810331850d72423c40c5448e6cd310c4cfad6aed54f92cd7e7cac5f3a
bin/stealth_capture.ps1c9baf5897c03b941c54f736df5af9243ad28794a9e69746d41d4f4a34065589c
bin/uia_extract.pyc20b38c63efd9221930095c54b42cdd5adffa1972c44c4578226cbe1e4dbac3e
bin/uia_get_text.ps14a3f3ada0bdf13aa8e89edb8af817c7816296147dae5be25f169ff960d28a87c

Två ytterligare signaler stämmer överens. Tre av paketen publicerades kl. 03:24, 03:38 och 03:22 UTC den 17 augusti, 26 augusti och 31 augusti – ett sextonminutersband över femton dagar och tre separata konton. Och två av dessa konton var registrerade på samma engångs-e-postdomän, vilket kopplade dem samman oberoende av koden.

Räkenskaperna

Dessa är npm-utgivarekontona som levererade nyttolasten, med varje paket som laddades upp och hur länge det fick stå:

UtgivarkontoPaketE-postdomänVänsterstående
letol39119moidev:1.0.0hutdot.com (engångs)5h 58m
so1d1a7i27moidevx:1.0.0ogzmail.com (engångs)13h 23m
lololololol435678eyiouss:3.0.21, 3.0.22, 4.0.1ogzmail.com (engångs)fortfarande publicerad
tagadob568moidevz:1.0.0ebflyai.com (engångs)12h 56m
tayihim489moideva:1.0.0prodbits.com (engångs)1h 33m
sahihai123amicat:1.0.0, bmcat:2.0.9, eyevox:1.0.0konsumentwebbpost17m / 47m / 21m
heytoshanmoidevh:1.0.0konsumentwebbpostNer till 47m

so1d1a7i27 och lololololol435678 dela ogzmail.com registreringsdomän — länken som kopplar kontot som fortfarande är värd för en aktiv kopia till kontot som publicerades under moidev stam två veckor tidigare. sahihai123 publicerade och drog tillbaka tre separata paketnamn inom ett enda 77-minutersfönster den 28 augusti. heytoshan registrerad, publicerad moidevh, och drog tillbaka den 47 minuter senare; det är fortfarande den enda publiceringen från den berättelsen.

Vart och ett av dessa konton är e-post-overifierade, har ingen verifierad källkontrolllänk och har inte publicerat något orelaterat projekt. Sex av sju är inte längre värdar för något.

Ett paket togs aldrig tillbaka. eyiouss:4.0.1 har publicerats sedan den 16 augusti och var fortfarande lösbar i skrivande stund. Åtta artefakter var oåterkalleliga; kampanjen rekonstruerades helt från den som fanns kvar. En operator som raderar reflexmässigt kommer ändå, så småningom, att lämna en kvar.

Vad verktyget gör

eyiouss:4.0.1 beskriver sig själv på npm som ett "högpresterande DOM-verktyg och diagnostisk brygga för moderna webbapplikationer". Det är ett verktyg för skärmdumpning och svarshämtning som är byggt för att köras under fjärrkontroll av tentamensövervakning, och källan säger det med sina egna ord.

Startprogrammet kopierar Electron-körtiden under ett falskt filnamn innan det körs, och namnger vad det undviker:

// 🛡️ STEALTH BINÄRNAMN: Får INTE kollidera med riktig Testpad! const STEALTH_NAME = 'SearchApp.exe';

Samma fils rubrik kallar det en Anti-Proctor spökvakthund och implementerar en återupplivningsloop som backar längre ju snabbare den dödas. På andra ställen höjer processen sin egen prioritet. för att bekämpa CPU-begränsning vid proctoring, flyttar provapplikationen från förgrunden när den tar fokus och avslutar en underprocess i Safe Exam Browser med taskkill /F /T.

Capture körs via ett medföljande PowerShell-skript som anropas med exekveringspolicyn inaktiverad och fönstret undertryckt, med text på skärmen som samlas in parallellt via Windows UI Automation. De köade bilderna och texten skickas till en språkmodellsession i en inbäddad webbläsare och svaret återges i ett alltid-överst-överlägg. Den anslutningen skjuts upp avsiktligt, och koden anger orsaken: för att undvika permanent NETSTAT-exponering.

Paketet skickas även chrome_cookies.ps1, på väg KROM KAKEXTRAKTOR, som dekrypterar Chrome- och Edge-cookies via DPAPI och läser cookiedatabasen från upp till fyra webbläsarprofiler. Anges förecisely: Vi hittade inte det skriptet som anropades med namn från någon levererad JavaScript-fil. Det som finns och är tillgängligt är den konsumerande halvan, som injicerar lagrade sessionscookies i den inbäddade webbläsaren.

Placeringen för de personer som installerar det

Ingen installerar detta av misstag. Det har ingen funktion utanför en övervakad tentamen, och dess utdata är ett svar som visas på användarens egen skärm. Den vilseledande paketbeskrivningen är inte alls riktad mot installationsprogrammet – det är en omslagsbild riktad mot registret och mot alla som granskar maskinen efteråt. Installationsprogrammet vet vad de får; beskrivningen finns så att... post av installationen återspeglar det inte.

De parter som drabbas är tredje parter som aldrig har berört npm: institutionen som genomför provet, de andra kandidaterna och alla nedströms som förlitar sig på att referenserna betyder något.

Men installationsprogrammet är därför inte säkert, och det är den delen som är värd att förklara, eftersom det är själva modellen med det försvinnande paketet som skapar exponeringen.

De kör en osignerad binärfil från nobody. uia_extract.exe Skepp kompilerade, utan källa och utan byggproveniens, från ett konto som inte längre existerar. Samma fil, via hash, har publicerats på nytt av letol39119, so1d1a7i27, lololololol435678, tagadob568, tayhim489, sahihai123 och heytoshan över femton dagar. Det finns ingen ansvarsansvarig att fråga, inget arkiv att läsa och ingen historik att kontrollera – varje identitet som skickade den raderade sig själv.

De har gett den exakt de funktioner som skadlig programvara behöver. En dold process, som körs under ett falskt namn, som dekrypterar webbläsarens cookie-arkiv, läser skärmen kontinuerligt, avslutar säkerhetsprogramvara och återuppstår när den avslutas. Idag är cookie-dekrypteringen begränsad till en leverantörs domäner och betjänar användarens egen session. Den omfattningen är en ändring på en rad, och ingenting i leveransmodellen skulle visa det om den ändrades – ett nytt namn, ett nytt konto, en ny uppladdning.

De kan inte få en åtgärd. Paketet avpubliceras inom en timme. Det finns ingen uppdateringsväg, ingen rekommendation och inget sätt att senare få veta att versionen de installerade skilde sig från den som deras vän installerade. Det som finns på maskinen stannar där.

De kan inte granska vad de körde. Deras låsfil refererar nu till ett paket som inte längre kan lösas. Om de senare ville fastställa vad som fanns på deras maskin – efter en incident eller en tvist – har registret ingen post att ge dem.

Och de kan inte rapportera skada. En användare som komprometterats av det här verktyget kan inte lämna in en missbruksrapport utan att avslöja varför de installerade det. Det är ingen slumpmässig händelse. Rapporter om missbruk av register är en viktig kanal genom vilken kortlivade paket fångas upp, och den här operatörens användarbas är strukturellt oförmögen att använda den. Den enda återstående motståndaren är automatiserad skanning – som ett sjuttonminutersfönster kalibreras mot.

Offerstrukturen och uppehållstiden är samma faktum som ses två gånger. Det förklarar också anomalin i tidslinjen: om tillbakadragandet drevs av rädsla för klagomål, skulle det långlivade populära paketet gå först. Det gjorde det inte, eftersom klagomålen aldrig kommer.

Samma mönster, en annan operator

Övervakningsoperatören är inte ensam om detta, och den tydligaste parallellen löper på en orelaterad nyttolast.

Mellan den 24 och 27 augusti dök fyra npm-paket upp under namn lånade från tvåfaktorsautentiseringsverktyg — autentiserings-OTP, hemlig nyckel-2fa, secretkey2fa och 2fa-hemlig nyckel — med sexton versioner mellan sig. Varje version publicerades från ett eget, nyligen registrerat konto (beyilol, jeanpaul686g, zzalipay, dluuuuu), alla e-postadresser är overifierade, ingen har en verifierad källkontrolllänk, ingen publicerar något annat. Var och en drogs tillbaka av sin egen utgivare.

Nyttolasten har ingenting att göra med testprogramvaran. Den läser webbläsarens autentiseringsuppgifter och Discord-tokens, och kör en Xbox Live-autentiseringsstege mot Minecraft-startaren för att hämta en uppdateringstoken. Här är installationsprogrammet. is offret i vanlig bemärkelse – vilket är det som gör jämförelsen användbar, eftersom leveransbeteendet är identiskt oavsett.

De fyra cyklerna löpte i publiceringsordning på 274.9, 37.8, 37.6 och 35.7 minuter: ett långt första försök, sedan konvergens mot en siffra som håller. Tre ytterligare paket tillhör återigen andra operatörer och visar samma uttagsbeteende.

PaketOperatörVänsterstående
octopus-actionrekognoseringsfyr2.5 min
mt-ts-serverless-starterrekognoseringsfyr9.6 min
2fa-secretkey2FA-täcknamn35.7 min
secretkey2fa2FA-täcknamn37.6 min
secretkey-2fa2FA-täcknamn37.8 min
auth-otp2FA-täcknamn274.9 min
hex-encode-utils Övrigt724.2 min

Sju paket, median 37.8 minuter, inget av dem relaterat till examensprogram.

Tre orelaterade nyttolaster, tre orelaterade uppsättningar konton, en delad teknik.

Varför fönstret stängs

Något förändrades i registrets miljö under 2026, och den uppenbara anledningen är att skanningen blev snabbare.

Fram tills nyligen upptäcktes skadliga paket huvudsakligen i efterhand: genom att en användare märkte något, genom en rapport nedströms eller genom en periodisk genomsökning. Detekteringslatens mättes i dagar. Det är inte längre den enda metoden. Analys i nära realtid av nyligen publicerade paket — Xygenis egen tidiga varning om skadlig kod bland en växande uppsättning sådana system inom branschen — minskar klyftan mellan publicering och inspektion till något mycket kortare.

En operator som har två alternativ. Göra nyttolasten svårare att känna igen, eller förkorta den tid den är tillgänglig för granskning. Det andra är billigare, kräver ingen ingenjörskonst, och registret tillhandahåller mekanismen gratis: inom npm:s 72-timmars avpubliceringsfönster kan en utgivare ensidigt ta bort ett paket, och namnet kan återanvändas efteråt. Återkallelse kostar ingenting för operatören.

Tidpunkten passar. Båda operatorerna ovan konvergerar mot en siffra och håller den snarare än att driva, vilket är hur en avstämd parameter ser ut snarare än en fråga om bekvämlighet. Och parametern de konvergerade mot – tiotals minuter – sitter förecisprecis där den skulle behöva sitta för att klara en automatiserad inspektion samtidigt som paketet fortfarande är installerbart tillräckligt länge för att nå sin publik.

Detta förblir en hypotes. Tidsdata kan inte separera ett svar på skanning från ett svar på registertillämpning, eller från vanlig operationell mognad eftersom dessa operatorer lär sig av varandra. Det som kan sägas utan slutledning är snävare och fortfarande användbart: Exponeringsfönstret är nu tillräckligt kort för att all kontroll som är beroende av att inspektera ett paket efter publicering tävlar mot en klocka som operatören ställer in. Kontroller som inte är beroende av inspektion – karantän efter ålder, inaktiverade installationsskript – påverkas inte av den rasen, vilket är den praktiska anledningen till att föredra dem.

Vad man ska göra åt det

Karantän efter ålder. Ingenting i tabellen över uppehållstid överlevde tretton timmar. En policy som säger att ingen beroendeversion är installerbar förrän den har funnits i 72 timmar skulle ha uteslutit varenda en av dem utan att upptäcka något.

Inaktivera installationsskript som standard. --ignorera-skript tar bort leveransmekanismen som paketen som stjäl autentiseringsuppgifter i denna korpus är beroende av. Det hjälper inte mot ett verktyg som användaren kör avsiktligt, vilket är precisverkligen skillnaden värd att förstå.

Behandla försvinnandet som en säkerhetshändelse. Avisering när ett installerat beroende slutar fungera. Det är din låsfil, inte registret, som fortfarande innehåller bevisen.

Spåra innehåll, inte namn. De sex sammanfattningarna ovan matchar oavsett paketnamn, utgivarkonto eller versionssträng — varje fält som den här operatorn visade kommer att ändras. En regel på registersidan som säger att ett nyregistrerat konto återkallar sitt enda paket inom en timme är ett rapporterbart mönster skulle ha aktiverats på varje paket här, enbart på metadata.

Och om du funderar på att installera något i den här kategorin: De egenskaper som gör det svårt för ett register att upptäcka är samma egenskaper som gör att du inte har någon möjlighet att få hjälp. Det finns ingen utgivare att hålla ansvarig, ingen uppdateringssökväg och ingen registrering av vad du körde.

indikatorer

TypVärderar
Filbin/kalamasha-tool.js — icke-standard inmatningspunkt för soptunna
SHA-2560c293be90c10c8a7618d25f4c4811fa63612b7bc5199b86e10bb31eb36c716dd
SHA-256e2fda5aa8397799669f29258f69e803cf05d322c1d93269eef6754ca024c3865
BehandlaSearchApp.exe skriven bredvid en legitim Electron-körningstid
Beteendepowershell -ExecutionPolicy Bypass -File med windowsHide: true
Beteendetaskkill /F /T inriktning på en Safe Exam Browser-process
metadataTom underhållslista bredvid en time.unpublished post
kontonletol39119, so1d1a7i27, lololololol435678, tagadob568, tayihim489, sahihai123, heytoshan
Registreringogzmail.com, hutdot.com, ebflyai.com, prodbits.com — domäner för engångspost

Referensprojekt

  • npm avpublicera policy — den 72-timmarsperiod inom vilken en utgivare får ta bort ett paket utan ingripande.
sca-tools-programvara-verktyg-för-kompositionsanalys
Prioritera, åtgärda och säkra dina programvarurisker
Skaffa ditt gratiskonto.
Inga kreditkort krävs.

Säkra din programvaruutveckling och leverans

med Xygeni-produktsviten