TL; DR
Njëzet paketa npm të publikuara gjatë dy ditëve në fund të korrikut dhe fillim të gushtit 2026 paraqiten si biblioteka të komponentëve të brendshëm të ndërfaqes së përdoruesit dhe shërbime të përbashkëta të backend-it. Asnjëra prej tyre nuk e zbaton funksionalitetin që reklamojnë. Secila prej tyre ofron një klasë stub, një README që e përshkruan paketën si të brendshme dhe një skedar të quajtur _polyfill.js.
Pjesa interesante është se nga thirret ai skedar. Nuk është një grep instalimi — manifestet nuk deklarojnë asnjë parainstalim, instalim ose postinstalim. Në vend të kësaj, rreshti i fundit i index.js thotë: try { require("./_polyfill"); } catch (_) {}Ngarkesa ekzekutohet herën e parë që kodi i aplikacionit importon paketën. Instalimi me --ignore-scripts, standard këshilla për uljen e ekspozimit ndaj zinxhirit të furnizimit në kohën e instalimit, nuk e pengon.
Çfarë _polyfill.js Bëhet fjalë për marrjen e një skedari ekzekutues specifik për platformën nga një prej tre hosteve Cloudflare Workers, shkrimin e tij në një drejtori të përkohshme nën një emër të rastësishëm, shënimin e tij si të ekzekutueshëm dhe nisjen e tij të shkëputur nga procesi prind. Ky skedar ekzekutues është vetë një ngarkues: ai numëron produktet e sigurisë së pikës fundore sipas emrit të procesit, kontrollon emrin aktual të përdoruesit kundrejt llogarive të njohura të mjedisit të analizës, përditëson ndërfaqet e telemetrisë AMSI dhe ETW në memorie, instalon persistencën nën emrin e një komponenti audio të Windows dhe merr një skedar të tretë binar me madhësi disa megabajt. Faza e tretë arrin e enkriptuar dhe është deshifrohet dhe ekzekutohet në memorie në vend që të shkruhet në disk.
Më 1 gusht, afërsisht katër orë pasi paketat u konfirmuan si keqdashëse gjatë shqyrtimit manual, nëntëmbëdhjetë nga njëzet emrat u hoqën nga npm nga botuesi i tyre në një sekuencë prej njëzet e pesë sekondash. Më 2 gusht, një nga këto emra u regjistrua përsëri — nga një llogari tjetër, me të njëjtin kod. Infrastruktura e shpërndarjes i shërbente të tre fazave kur u shkrua kjo.
| Paketat | 20 emra npm, ~74 versione të publikuara |
| Emërtimi i temave | beaver-ui-* (13), accounts-* (3), plus afisha-storybook-default, bcore-bravo-eslint-config, arbocrate-sla-prober-arbocrate-sla-prober-core, a.poltoradnev-package-c |
| shkrehës | Importimi i modulit (require), jo një skript i ciklit jetësor të npm-së |
| Faza 1 | _polyfill.js — rikuperimi dhe lëshimi |
| Faza 2 | Ngarkues i lidhur statikisht, i paketuar me UPX në Linux; numërim i sigurisë së pikës fundore, patching AMSI/ETW, vazhdimësi |
| Faza 3 | beacon_linux.bin / beacon_mac.bin / update_win.exe, 4–13 MB; dorëzuar i enkriptuar, ekzekutuar në memorie |
| Platformat | Linux x64 dhe arm64, macOS universal, Windows x64 |
| Botuesit | Dy llogari, një bazë kodi |
| Statusi | 19 nga 20 emra të pabotuar nga operatori; 1 ribotuar dhe drejtpërdrejt; infrastruktura e shpërndarjes drejtpërdrejt |
Anatomia e sulmit
Faza 1 — paketa
Çdo anëtar dërgon të njëjtën formë me tre skedarë. indeks.js eksporton një klasë me një init () që vendos një vlerë booleane, një versioni()Dhe a konfiguro() që bashkon një objekt opsionesh. Asgjë tjetër. LEXONI.md jep një linjë instalimi, një kërkojnë rreshti dhe fjalia “Paketë e brendshme. Shih CONTRIBUTING.md për udhëzime” — CONTRIBUTING.md nuk është në tarball.
_polyfill.js është pak më pak se 5 KB dhe lexohet si kod i zakonshëm i infrastrukturës. Hapet me tre kontrolle mjedisore:
if (process.env.DISABLE_TELEMETRY ||
process.env.ANALYTICS_OPT_OUT ||
process.env.DO_NOT_TRACK)
return; Këto variabla janë kontrolle konvencionale të privatësisë. Këtu ato kontrollojnë nëse një skedar binar shkarkohet dhe ekzekutohet. Një makinë që vendos MOS_GJURMO anashkalohet tërësisht.
Më pas vjen një pullë që ekzekutohet vetëm një herë: një skedar në /tmp/.analytics_stateose gjendja_e_analytics sipas % TEMP% në Windows, koha e modifikimit të të cilit krahasohet me një dritare prej 20,357 sekondash. Brenda asaj dritareje moduli kthehet menjëherë, kështu që importet e përsëritura gjatë një ndërtimi prodhojnë një përpjekje rikuperimi në vend të dhjetëra.
Host-et e destinacionit nuk janë të pranishëm si literal-e. Ato mblidhen në kohën e ekzekutimit nga fragmente:
["oob-worker.cf102-","baf.workers.d","ev"].join("") Tre hostë janë ndërtuar në këtë mënyrë dhe përzihen para përdorimit, kështu që rendi ndryshon në varësi të ekzekutimit. Marrja është një HTTPS GET i lidhur me IPv4 me një Agjenti i përdoruesit of nyja-marrje/2.6 — një vlerë e besueshme që një proces Node duhet të emetojë. Një përgjigje nën 1,000 bajt hidhet poshtë dhe provohet hosti tjetër.
Nëse të tre dështojnë, moduli kthehet përsëri te DNS. Ai lëshon një pyetje TXT për c. për të marrë një numërim të pjesëve, pastaj kërkon 0. përmes n. në grupe prej dhjetë, bashkon përgjigjet dhe base64-dekodon rezultatin. Kjo rrugë mbart të njëjtin skedar ekzekutues mbi regjistrimet DNS TXT, i cili mbijeton në mjedise ku HTTP-ja dalëse filtrohet, por zgjidhja e DNS-së jo.
Bajtet e marra shkruhen në /var/tmp/.cache_<8-heksador> në Unix, ose %TEMP%\dotnet_diag_<8-hex>.exe në Windows — një emër skedari që lexohet si një objekt diagnostikues .NET. Në Unix, skedarit i jepet modaliteti 0755. Nisja është pjellem me i shkëputur: i vërtetë, stdio: “injoro”dhe unref(), kështu që fëmija jeton më gjatë se procesi Node që e nisi atë; në Windows thirrja shton windowsHide: e vërtetë.
Dy detaje e plotësojnë pamjen. Një ndihmës i përcaktuar si const _l = (…a) => process.stderr.write("") thirret në çdo hap të rikthimit — shkruan një varg bosh dhe i hedh poshtë argumentet e tij, duke zënë pozicionin ku do të ndodhej regjistrimi. Dhe çdo paketë dërgon një skedar 81 KB në lib/telemetry.js komenti i kokës së të cilit përshkruan një “SDK të Analitikës” me “transport HTTPS me rotacion dhe riprovë të pikës fundore” dhe “zbulim shërbimi të bazuar në DNS për failover”. Në versionin aktual asgjë nuk e kërkon këtë.
Faza 2 — ngarkuesi
Skedari binar Linux x64 është një ELF i lidhur statikisht i kompresuar me UPX 3.96. Ndërtimi i macOS është një skedar binar universal që mbulon x86_64 dhe arm64; ndërtimi i Windows është një ekzekutues i zhveshur i konsolës PE32+. Të katër u gjetën dhe u ekzaminuan statikisht; asnjë nuk u ekzekutua.
Importet dhe tabela e vargjeve të ndërtimit të Windows përshkruajnë sjelljen e tij qartë. Ai zgjidh problemin IsDebuggerPresent, CheckRemoteDebuggerPresentdhe NtQueryInformationProcess, dhe lexon SYSTEM\CurrentControlSet\Services\Disk\Enum — një shteg regjistri vlerat e të cilit identifikojnë kontrolluesit e diskut virtual. Ai thërret GetDiskFreeSpaceExW GlobalMemoryStatusEx, në përputhje me kontrollin nëse burimet e hostit përputhen me një instancë analize jetëshkurtër.
Ai përmban një listë të emrave të përdoruesit: Përdoruesi Aktual, Administratori i IT, Hong Lee, KUTIA E TESTIMIT, hapubws, milozs, Timmy, admin, malware, mostër, virus, mjedisDisa prej këtyre janë artefakte të mjediseve të analizës të dokumentuara publikisht.
Gjithashtu përmban një listë të produkteve të sigurisë së pikave fundore dhe emrat e proceseve të tyre, të numëruara përmes CreateToolhelp32Snapshot Process32FirstW/Process32NextW:
- CrowdStrike Falcon (
csfalconservice,CSFalconContainer) - Karboni i zi (
cb.exe) - Cylance (
cylancesvc.exe) - BitDefender (
bdagent.exe) - Kaspersky (
avp.exe,kavfs.exe) - Trend Micro dhe Deep Security (
coreServiceShell,ds_agent.exe) - FireEye/Trellix (
xagt.exe) - Taniium (
taniumclient.exe) - Hitman Pro (
hmpalert.exe) - Elastik (
elastic-agent.exe,elastic-endpoint,filebeat.exe,winlogbeat.exe) - Wazuh dhe OSSEC (
wazuh-agent.exe,ossec-agent.exe) - Kontrollo Point
- Windows Defender
Janë të pranishme dy simbole të tjera: AmsiScanBuffer, pika e hyrjes që Windows ekspozon për skanimin e përmbajtjes në memorie, dhe EtwEventWrite, funksioni përmes të cilit Event Tracing për Windows regjistron ngjarjet. Të dyja janë objektiva të zakonshëm për modifikim gjatë procesit që shtyp telemetrinë që këto ndërfaqe do të prodhonin përndryshe.
Persistenca shfaqet dy herë në Windows. Skedari binar kopjohet në %APPDATA%\Microsoft\Windows\Themes\SystemSoundsService.exe, dhe dy mekanizma e referojnë atë: një vlerë nën PROGRAME\Microsoft\Windows\Versioni i Tanishëm\Run, dhe një detyrë e planifikuar e regjistruar si
schtasks /Create /F /SC ONLOGON
/TN "\Microsoft\Windows\Multimedia\SystemSoundsService"
/TR "\"%s\""
/RL HIGHEST Shtegu i detyrës, emri i detyrës dhe emri i ekzekutueshëm pasqyrojnë të gjitha një komponent audio të vërtetë të Windows. /RL MË I LARTË kërkon nivelin më të lartë të privilegjit të disponueshëm.
Ndërtimi i macOS ndjek të njëjtin model me emra të përshtatshëm për platformën: shkruan një listë vetish në ~/Library/LaunchAgents/com.apple.windowserver.helper.plist dhe e vendos ekzekutuesin e tij në ~/.local/share/runtime/com.apple.runtimeKontrollon për /Aplikacionet/VMware Fusion.app /Biblioteka/Mbështetja e Aplikacioneve/Mjetet VMware.
Kapaciteti i rrjetit përfshin tre transporte: WININET.dll për HTTPS me një https://%s:%d%s formato vargun, WS2_32.dll prizat, dhe DNSAPI.dll me DnsQuery_A së bashku me një rreth%s.%s format string — e njëjta formë pyetësori për numërimin e pjesëve që përdor faza e parë.
Përshkrimi i mësipërm është ajo që tregojnë importet, vargjet dhe shtigjet e regjistrit të skedarit binar gjatë inspektimit. Analiza publike me shumë motorë e të njëjtit shembull të Windows shton detaje që një lexim statik i një tabele importi nuk mund t'i përcaktojë më vete, dhe i atribuohet këtu në vend që të riparaqitet si vëzhgim i dorës së parë. Kjo analizë raporton se referencat AMSI dhe ETW jo vetëm që janë zgjidhur, por edhe janë rregulluar — AmsiScanBuffer in amsi.dll EtwEventWrite in ntdll.dll — e cila pengon skanimin e përmbajtjes në memorie dhe gjurmimin e ngjarjeve për procesin. Ai raporton kontrollet kundër analizës si të bazuara në kohë përveç CheckRemoteDebuggerPresent, dhe identifikon GetThreadContext thirrja si një kontroll i pikës së ndërprerjes së harduerit duke lexuar regjistrat e debugimit. Gjithashtu raporton një mutex me një instancë të vetme, Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9}, dhe emrat Shërbimi i Tingujve të Sistemit si vlera Run-key. Ajo vlerë mutex nuk ishte midis vargjeve të gjetura këtu - filtri i nxjerrjes i përdorur përjashtoi tokenët heksadeksadorë me shkronja të mëdha të mbështetura në mbërthime - dhe është regjistruar në tabelën e treguesve në bazë të forcës së asaj analize publike në vend të vëzhgimit të drejtpërdrejtë.
Faza 3
Ngarkuesi i referohet një grupi të mëtejshëm shtigjeve në të njëjtat hostë. Të gjitha ishin të arritshme gjatë analizës: beacon_linux.bin në 5.3 MB, beacon_mac.bin në 13.3 MB, update_win.exe në 10.3 MB, dhe krah.bin në 4.3 MB. Këto nuk u gjetën dhe sjellja e tyre është e panjohur.
Për shtegun e Windows, analiza publike e ngarkuesit përshkruan se si trajtohet ajo fazë e tretë: ajo merret nëpërmjet WinINet, mbërrin e enkriptuar dhe dekriptohet në memorie dhe ekzekutohet në mënyrë reflektive — alokohet memoria, zgjidhen importet, përpunohen zhvendosjet dhe kontrolli i kalohet një fije të re nëpërmjet KrijoFijePër këtë arsye, faza e tretë nuk shkruhet kurrë në sistemin e skedarëve, kështu që zbulimi i bazuar në skedarë dhe forenzika e diskut pas incidentit nuk kanë asgjë për të rikuperuar prej tij. Kjo gjithashtu do të thotë që marrja e bajteve nga hosti i dorëzimit do të jepte tekst të koduar, jo një skedar të ekzekutueshëm të analizueshëm.
Kohështrirje
Të gjitha vulat kohore janë UTC dhe vijnë nga meta të dhënat e regjistrit npm, i cili regjistron krijimin dhe mospublikimin e paketave në mënyrë të pavarur nga çdo vëzhgues.
| Kur | Çfarë |
|---|---|
| 2026-07-31 09:25:05 → 09:29:56 | Dhjetë emra të krijuar, secili duke filluar nga versioni 0.0.1, afërsisht trembëdhjetë sekonda larg. |
| 2026-08-01 09:38 → 11:29 | Emrat ekzistues ngjiten përmes numrave të fryrë të versioneve, 6.1.9 përmes 6.1.12, 9.9.9 përmes 9.9.12, 8.9.3 përmes 8.9.6, 5.4.6 përmes 5.4.9. |
| 2026-08-01 13:04:14 → 13:04:18 | Nëntë të tjerë beaver-ui-* emra të krijuar në një shpërthim katër-sekondash, secili i publikuar direkt në një version 12.x pa historik paraprak. |
| 2026-08-01 ~13:00–14:30 | Versione të klasifikuara si keqdashëse në shqyrtimin manual. |
| 2026-08-01 17:39:49 → 17:40:14 | Nëntëmbëdhjetë nga njëzet emrat u pabotuan në njëzet e pesë sekonda, radhazi, me një interval prej rreth 1.2 sekondash nga njëri-tjetri. |
| 2026-08-02 18:58:41 | a.poltoradnev-package-c krijuar përsëri nën një llogari mirëmbajtëse të ndryshme, version 0.0.2. |
| 2026-08-02 19:20:28 | Version 33.9.5 botuar me të njëjtin emër. |
| 2026-08-02 20:14 | Të tre hostet e shpërndarjes shërbejnë në fazat dy dhe tre; rezerva e DNS-it përgjigjet me numërimin e pjesëve të caktuara. |
Dy nga këto shënime ia vlen të ndalemi.
Shpërthimi i orës 13:04 vendosi nëntë paketa në regjistër në katër sekonda, secila me një version të vetëm në dymbëdhjetëshe dhe asnjë 0.0.1 poshtë saj. Numrat e versioneve në këtë shkallë, për emra një ditë më të vjetër, nuk përshkruajnë një histori publikimesh.
Sekuenca e mospublikimit është po aq mekanike: nëntëmbëdhjetë emra, njëzet e pesë sekonda, hapësira të barabarta. npm i regjistron këto si ngjarje të zakonshme mospublikimi në vend të vendit që lë pas një heqje e iniciuar nga regjistri, e cila e vendos veprimin në llogarinë e botimit në vend të regjistrit.
Treguesit e kompromisit
Host-et dhe shtigjet janë të çaktivizuara. Mos i zgjidhni ose mos i merrni ato nga një sistem prodhimi.
| Tipi | vlerë |
|---|---|
| Pritës i dorëzimit | oob-worker[.]cf99-9b3[.]workers[.]dev |
| Pritës i dorëzimit | oob-worker[.]cf102-baf[.]workers[.]dev |
| Pritës i dorëzimit | oob-worker[.]cf103-070[.]workers[.]dev |
| Transporti i DNS-së | tin[.]dl[.]well1[.]site (Linux x64), tina[.] (krahu 64), ldr[.] (macOS), win[.] (Windows) — numri i pjesëve në c.<domain>, të dhënat në <n>.<domain> |
| Shtigjet e Fazës 2 | /pkg/package, /pkg/package-arm64, /pkg/loader_mac, /pkg/package.exe |
| Shtigjet e Fazës 3 | /pkg/beacon_linux.bin, /pkg/beacon_mac.bin, /pkg/update_win.exe, /pkg/arm.bin |
| Shtegu i lëshimit (Unix) | /var/tmp/.cache_<8-hex> |
| Shtegu i lëshimit (Windows) | %TEMP%\dotnet_diag_<8-hex>.exe |
| Qëndrueshmëria (Windows) | %APPDATA%\Microsoft\Windows\Themes\SystemSoundsService.exedetyrë \Microsoft\Windows\Multimedia\SystemSoundsServiceVlera e çelësit të ekzekutimit SOFTWARE\Microsoft\Windows\CurrentVersion\Run\SystemSoundsService |
| Mutex (Windows) | Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9} |
| Qëndrueshmëria (macOS) | ~/Library/LaunchAgents/com.apple.windowserver.helper.plist; binar në ~/.local/share/runtime/com.apple.runtime |
| Vulë që përsëritet një herë | /tmp/.analytics_state, %TEMP%\analytics_state (dritare 20,357 s) |
| Kërkesë për nënshkrim | HTTPS GET, i lidhur me IPv4, Agjent Përdoruesi: node-fetch/2.6 |
| Skedari i Fazës 1 | _polyfill.js, SHA-256 392dc9ec85042ce1796bfa9b8c7bf6e05c7710579aab8b7b1eb73788683883af |
| Skedar i pareferuar | lib/telemetry.js, SHA-256 2266c9b8e199daebe31a9afcb61d9b0d76706b63c92312fc8223d22de42e63c7 |
| Faza 2 (Linux x64) | SHA-256 7e486657f30594afda379b97030252a09a19fe8055e25c9e371544f59bd8e9e3 |
| Faza 2 (Linux arm64) | SHA-256 aafc37589c0d21fb729761a1579ca3b278b95bce152aacfa29243ffd27f5eeb7 |
| Faza 2 (macOS) | SHA-256 c214746c74cae8ece8bdaf69aa05da4db6ce013f9e77452d1eed1a002fd9ba00 |
| Faza 2 (Windows) | SHA-256 d632c2c0c7801c3da57cf849fe4b4ca8351d9a7fe73c31050bf5dbcc96a16791 |
Emrat e paketave
Atribuimi dhe sjellja e vëzhguar
Janë të përfshira dy llogari të npm. Nëntëmbëdhjetë emrat e pabotuar u publikuan nga një llogari; paketa-a.poltoradnev-c u riregjistrua më 2 gusht me një emër llogarie dhe një domen email-i të ndryshëm. Kodi është i njëjtë në të dyja, dhe regjistrimi i dytë mbart të njëjtat host-e shpërndarjeje, të njëjtat domene rezervë DNS, të njëjtën ndërtim të shtegut të lëshimit dhe të njëjtën vulë ekzekutimi një herë.
Dyshja e ribotuar tregon gjithashtu se si u mblodh. Versionet 0.0.2 33.9.5 janë identike me bajt përveç vargut të versionit në package.json, dhe indeks.js dërguar si 0.0.2 i deklaruar const VERSION = "33.9.5"Të dy artefaktet u prenë nga një pemë burimore dhe u numëruan më pas. Nuk ka 0.0.2 historia e zhvillimit për 0.0.2 lirim për të përfaqësuar.
Numërimi i versioneve në të gjithë grupin ndjek të njëjtën logjikë. Emrat e paketave në këtë fushatë lexohen si gjëra që do të ekzistonin brenda një organizate dhe jo në një regjistër publik: një grup komponentësh UI, një konfigurim ESLint, një prober SLA, një paketë e emëruar sipas një personi. Kur një ndërtim zgjidh një varësi me emër dhe konsultohet me një regjistër publik së bashku me një privat, numri më i lartë i versionit është ai që fiton. Një emër i krijuar në 0.0.1 të hënën dhe duke mbajtur 12.9.6 të martën është pozicionuar për atë krahasim.
Dy valët e publikimit ndryshojnë gjithashtu në një mënyrë që sugjeron përsëritje. Kodi i mëparshëm e quajti skedarin e ngarkesës së tij setup.js dhe renditi pesë hoste shpërndarjeje; skedari aktual është emëruar _polyfill.js dhe rendit tre. Versioni i mëparshëm e hoqi skedarin e hequr pesë sekonda pas nisjes, duke e lënë procesin të ekzekutohet nga një inode e fshirë; versioni aktual nuk e bën këtë. I pari referencuar lib/telemetry.js mbetet në tarball nëpër të dyja, ende i transportuar, jo më i lidhur me tela.
Një vëzhgim në lidhje me ndërprerësit e fikjes ia vlen të përmendet paraprakisht.cisely, sepse bie ndesh me një lexim të zakonshëm. Çaktivizo_Telemetrinë, ANALYTICS_OPT_OUTdhe MOS_GJURMO respektohen dhe kontrollohen para se të ndodhë ndonjë gjë tjetër. Një studiues, mjedisi i analizës së të cilit vendos ndonjë prej tyre, vëren një paketë që nuk bën asgjë.
Ndikimi dhe çfarë mund të bëjnë mbrojtësit
Pasoja praktike e shkaktarit të kohës së importit është e ngushtë dhe ia vlen të thuhet më vete. instalimi i npm –injorimi i skripteve parandalon ekzekutimin e skripteve të ciklit jetësor dhe është një këshillë e shëndoshë. Nuk ka efekt këtu, sepse ky kod nuk përdor një skript të ciklit jetësor. Ngarkesa ekzekutohet kur kodi i aplikacionit, një ekzekutim prove, një program paketimi ose një program linter importon së pari modulin. Në një program ekzekutimi CI që instalon dhe pastaj ndërton menjëherë, të dyja janë me një diferencë sekondash.
Për gjueti, sinjalet e qëndrueshme janë strukturore dhe jo të drejtpërdrejta. Hostët, emri i skedarit dhe shtigjet e lëshimit do të ndryshojnë; këto forma janë më të vështira për t'u ndryshuar:
- Një pikë hyrjeje e modulit, deklarata përfundimtare e së cilës është një provo { kërkoj("./x"); } kap (_) {} rreth një skedari që nuk është pjesë e API-t të eksportuar. Një paketë me një polyfill të vërtetë e importon atë në krye dhe përdor rezultatin e tij. Gëlltitja e çdo gabimi nga një importim nga fundi i skedarit nuk është trajtim gabimesh.
- Vargjet pritëse të mbledhura nga .bashko("") nga një mori fragmentesh. Kodi legjitim nuk ka arsye për të ndarë një emër host-i nëpër elementët e vargut.
- Një paketë varësitë e deklaruara të së cilës janë bosh, por që kërkon https, dnsdhe proces_fëmijë në kohën e importit. Rikthimi plus ekzekutimi në një paketë që reklamon një komponent të ndërfaqes së përdoruesit është i gjithë zbulimi.
- Numrat e versioneve nuk përputhen me moshën e një pakete. Një emër i publikuar për herë të parë ditë më parë në një version kryesor me dy shifra, pa publikime ndërmjetëse, përshkruan diçka tjetër përveç zhvillimit të tij.
- Shkruan për / var / tmp or % TEMP% e ndjekur nga a chmod deri në 07:55 dhe një pjellje e shkëputur. Sekuenca është e shkurtër, e renditur dhe rrallë beninje së bashku.
Në hostet e Windows ekzistojnë dy kontrolle të lira dhe me besim të lartë. Artefaktet e persistencës janë vargje të fiksuara dhe asnjëra prej tyre nuk i përket një sistemi të pastër: një detyrë e planifikuar në \Microsoft\Windows\Multimedia\SystemSoundsService, një vlerë e çelësit Run me emrin Shërbimi i Tingujve të Sistemit, dhe një skedar ekzekutues me atë emër nën %APPDATA%\Microsoft\Windows\Temat\Shërbimi i vërtetë audio i Windows nuk ndodhet në asnjë nga këto vende. Së dyti, ngarkuesi përdor një mutex të fiksuar me një instancë të vetme, Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9}; prania e tij në një host është një tregues, dhe meqenëse ngarkuesi e trajton një mutex ekzistues si "tashmë në funksion", krijimi paraprak i tij është një inokulim afatshkurtër i zbatueshëm ndërsa është planifikuar ndreqja.
Zbulimi në fazën e tretë është një problem më i vështirë dhe ia vlen të sqarohet. Sipas shpjegimit të dhënë nga analiza publike, ai deshifrohet dhe hartëzohet në memorie në vend që të shkruhet në disk, kështu që skanimi i skedarëve dhe forenzika e diskut nuk do ta shohin atë. Ajo që mbetet e vëzhgueshme është gjurma e vetë ngarkuesit - hyrjet e këmbënguljes, mutex dhe kërkesat dalëse për hostet e shpërndarjes ose domenet DNS-TXT.
Për mjediset që zgjidhin varësitë si nga një regjistër privat ashtu edhe nga një publik, zbutja nuk ndryshon nga asgjë këtu: emrat e brendshëm të fushëveprimit, kështu që një emër publik nuk mund t'i plotësojë ato, dhe fiksimi i rezolucionit në regjistrin e brendshëm për ato fusha. Sjellja e rritjes së versionit e përshkruar më sipër funksionon vetëm aty ku një version publik më i lartë mund të fitojë një emër.
Së fundmi, ia vlen të lexohet me kujdes pabotimi dhe jo si një përfundim. Nëntëmbëdhjetë emra dolën nga regjistri në njëzet e pesë sekonda dhe një u kthye një ditë më vonë nën një llogari të re, me infrastrukturën e shpërndarjes të paprekur gjatë gjithë kohës. Heqja e paketave nuk është heqje e operacionit; hostet vazhduan të shërbenin në çdo fazë ndërsa kjo po shkruhej. Çdo pemë varësie që zgjidhi një nga këto emra midis 31 korrikut dhe 1 gushtit duhet të trajtohet sikur ka pasur mundësinë të ekzekutojë fazën e parë, pavarësisht nëse emri ekziston ende apo jo.
Referencat
- Analiza e ngarkuesit të Windows me shumë motorë — burim për patch-in AMSI/ETW, ekzekutimin reflektues në memorie dhe detajet mutex të atribuara më sipër.
- dokumentacioni i skripteve npm — ngjarjet e ciklit jetësor që kjo fushatë nuk i përdor.
- dokumentacioni i instalimit të npm — mbulesa - Injoro-skenaret dhe fushëveprimi i saj.




