TL; DR
In inkele npm-operator hat seis wiken bestege oan it publisearjen fan falske TypeScript "utility"-pakketten lykas ts-form-utils, ts-project-lint, en ts-enum-helper.
Wylst de pakketten lytse legitiem útsjende falidaasjehelpers bleatstelle, wurdt de echte lading útfierd by ynstallaasje of earste fereaskje en fiert hostfingerprinting, GitHub-organisaasjeûntdekking, repository-klonen en boarnekoade-eksfiltraasje út.
De malware rjochtet him spesifyk op weardefolle GitHub-organisaasjes, ynklusyf meardere Shopify repositories, argyfearret en eksfiltrearret dan berikbere boarnebeammen nei in sintralisearre kolleksje-eindpunt.
As ûnderdiel fan 'e kompromisworkflow, de lading commitsa-bestân werom yn slachtofferrepositories wylst se de autonome kodearjende identiteit fan Google imitearje google-labs-jules[bot].
Wy hawwe de kampanje folge - neamd JulesJacker — oer meardere útjouwersgebieten en teminsten fiif payloadgeneraasjes, ynklusyf fersifere en sandbox-bewuste farianten.
De nijste fariant rjochtet him spesifyk op ynfrastruktuer foar malware-analyse: it aktivearret allinich binnen analyseomjouwings, stielt tokens foar tsjinstakkounts yn 'e wolkmetadata, en ûndersiket Kubernetes-kontrôleplanen en wolkopslachbuckets.
De primêre IOC dy't dield wurdt oer alle generaasjes fan payloads is it kolleksje-eindpunt aaronstack[.]com/jules-collect.
Earnst: kritysk.
De oanfal: Hoe't it wurket
Elk JulesJacker-pakket folget itselde sjabloan. pakket.json advertearret in goedaardige TypeScript-helper mei in MIT-lisinsje en gjin keppele boarne-repository. index.js eksportearret in hantsjefol echte, wurkjende funksjes - e-postregexes, enum-kaarten, lint-regeltabellen - sadat in ûntwikkelder dy't it pakket eins ymportearret plausibel gedrach sjocht. De kwea-aardichheid libbet earne oars: yn in nei ynstallaasje heak, of yn in blok oan 'e ûnderkant fan index.js dat útfiert op it momint dat de module nedich is.
De ladingen binne evoluearre troch dúdlik nûmere ynterne stadia (de operator labelt syn eigen telemetrie-eveneminten sc1-, sc3-, sc4-, ensafuorthinne), en it observearjen fan dy evolúsje is de dúdlikste manier om de kampanje te begripen.
Generaasje 1–2: ferkenning en git-config-diefstal
De ierste pakketten wiene ienfâldige ynfo-stellerijen. By ynstallaasje sammelen se omjouwingsfariabelen, it GitHub CLI hosts-bestân en de globale git-konfiguraasje (git-konfiguraasje –globale –list, git op ôfstân -v), en POST doe de bondel nei it kolleksje-eindpunt. Dit stelde de hantekening fan 'e operator fêst: in omslachferhaal fan "TypeScript-formuliervalidaasjeprogramma's", in útgeande beacon nei ien domein, en in foarkar foar ûntwikkeldersgegevens ynstee fan konsumintegegevens.
Generaasje 3: hypervisor- en kernel-escape-probes
Ien ferzje midden yn 'e kampanje draaide hurd om op ynfrastruktueroanfallen. Ynstee fan konfiguraasje te stellen, fierde it in ferkenningsboarne-ûndersyk út. AF_VSOCK sockets, virtio MMIO-regio's, / dev / mem, en kernelferhurdingsflaggen, en sels besochte sysrq-triggerde kernelcrashes - gedrach dat ferbûn is mei pogingen om út in firtuele masine of kontener te brekken. De telemetrie-tags (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-sonde) makke de bedoeling eksplisyt. Dizze fariant wie dúdlik rjochte op cloud-sandbox en serverless-runner omjouwings — it soarte tydlike VM dy't net-fertroude koade bout en test.
Generaasje 3 (SC3): de cross-repo skriuwwjirm
It swiertepunt fan 'e kampanje waard in selsferspriedende repo-dief. By ynstallaasje rint de lading in tiidssekwinsje fan fiif stadia:
- Stage 0 (~100 ms): fingerprint de host - hostnamme, brûkersynformaasje, git-identiteit.
- Stage 1 (~3 s): bepale ta hokker organisaasje it slachtoffer heart troch te ynspektearjen git op ôfstân -v, sykje dan in hurd kodearre ORG_CONFIG tagong ta tabel- en testrepository mei git ls-ôfstân — trochstjoerd fia in oanfaller-kontroleare SSRF-proxy op http://git@192.168.0.1:8080.
- Stage 2 (~10 sekonden): git clone elke berikbere repository yn 'e doellist, tarball en gzip de beam, base64-kodearje it, en chunk-eksfiltrearje it.
- Stage 3 (~45 s): it "bewiis fan tagong" - kloon in skriuwbere repo, drop in bestân mei de namme SECURITY-POC.md, en commit it mei de auteur ynsteld op google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> en it berjocht chore: update dependency cache, en dan nei de haadtûke fan it slachtoffer triuwe.
De hurdkodearre doellist is net generyk. It telt mear as tritich op. Shopify opslachplakken op namme - Shopify/shopify, Shopify/identiteit, Shopify/fakturearring, Shopify/kluis, Shopify/geheimen, Shopify/ynfrastruktuer, Shopify/.github, en folle mear - neist in testorganisaasje, AaronStackBarnes, dat de operator liket te kontrolearjen en brûkt as skriuwdoel.
Generaasje 4 (SC4): fersifere en gated
De nijste fariant rjochte op ûntwikkelders foeget twa lagen fan ûntwyking ta boppe op 'e SC3-wjirm.
Earst wurdt de lading net mear as platte tekst ferstjoerd. De echte logika sit yn in AES-256-CBC-fersifere blob, lib/.perf.dat, mei de IV yn syn earste sechstjin bytes. De lader yn index.js rekonstruearret de ûntsiferingssleutel út oaninoar keppele stringfragminen, ûntsifret de blob, en fiert it út mei nije Funksje()Sels de modulenammen binne opdield om statyske scanners te ûntkommen - fereaske('krypt' + 'o'), fereaskje('f' + 's').
Twadder, it is host-gated. Ien fariant ûntsiferet en rint allinich as os.hostnamme() lykweardich ûntwikkelder or ubuntu-fc-uvm (in standert Firecracker microVM) of befettet de substring ûntwikkelderIn oare poarten op 'e oanwêzigens fan in .jules/ wurkmap:
Mei oare wurden, de SC4-lading is ûntworpen om sliepend te bliuwen op 'e laptop fan in gewoane ûntwikkelder en allinich wekker te wurden binnen de automatisearre AI-agent en sandbox omjouwings de operator wol eins in kompromis slute.
It laboratoarium oansette: de fariant fan analyse-ynfrastruktuer
It nijsgjirrichste pakket yn 'e kampanje, ts-enum-helper, falt ûntwikkelders of Shopify hielendal net oan. Syn postinstall.sh iepenet mei in poarte dy't it spultsje fuortjout:
It skript docht neat, útsein as in omjouwingsfariabele spesifyk foar in platfoarm foar malware-analyse ynsteld is. As dat sa is, wit de lading dat it rint yn 'e sânbak dy't bestiet om pakketten lykas dizze te detonearjen en te bestudearjen - en it docht in tsjinoanfal.
It hellet earst it OAuth-token fan it GCP-tsjinstakkount fan 'e metadataserver fan 'e ynstânsje en eksfiltrearret it. Dan, mei help fan dat token, sweept it de Kubernetes kontrôle fleanmasine berikber op kubernetes.default.svc:
- listet ClusterRoleBindings, ClusterRoles, en Nodes;
- ûndersiket pods, geheimen en konfiguraasjekaarten oer kube-systeem, standert, kube-iepenbier, kube-node-lease, en de nammeromte fan 'e analyse;
- docht SelfSubjectAccessReview-opropen om presys yn kaart te bringen wat de stellen identiteit dwaan mei.
Uteinlik brûkt it brute-force Google Cloud Storage bucketnammen dy't boud binne út in hardcoded GCP-projekt-ID (seldsum-tekenaar-437603-p9) en projektnûmer, rieden fan kombinaasjes lykas *-bouwurken, *-artefakten, en ferskate malyse- foarheaksels (malyse-resultaten, malysis-pakketten, malyse-scans). Elke antwurdkoade en lichem wurdt oanmeld en werom POSTED nei deselde jules-kolleksje einpunt.
Dit is it seldsume gefal fan in supply-chain payload dy't spesifyk boud is om de eigen ynfrastruktuer fan 'e ferdigeners oan te fallen. It omslachferhaal oer de hiele kampanje - fragminten dêrfan ferskine yn 'e payloads as opmerkings dy't it gedrach frame as in "Security Research PoC ... cross-repo write fia overscoped git proxy token" - is deselde selsrjochtfeardiging, of it runtime-doel no in Shopify monorepo is of de metadataserver fan it analysekluster.
Tiidline & de omfangsmigraasje
JulesJacker is gjin ienmalige delgong. It is in oanhâldende operaasje dy't in register takedown oerlibbe hat troch gewoan de namme te feroarjen.
| Wannear | Barren |
|---|---|
| Mids april 2026 | De earste pakketten ferskine ûnder it orizjinele útjouwersberik: TS-utility-facade, omjouwing en git-config-eksfiltraasje. |
| Begin mei 2026 | Hypervisor en kernel-escape ferkenningsfariant publisearre. |
| Midden oant ein maaie 2026 | SC3 cross-repo skriuwwjirm ferskynt neist Shopify-rjochte payloads en google-labs-jules[bot] imitaasje. SC4 yntrodusearret AES-fersifere en host-gated loaders. |
| Ein maaie 2026 | npm ferwideret it orizjinele útjouwersberik; pakketnammen wurde omset yn lege befeiligingsbewarjende plakhâlders. |
| Deselde wike | De operator migrearret nei in hast identyk lyk-op-ien omfang en publisearret de wjirm opnij, ynklusyf de fariant fan analyse-ynfrastruktuer. |
De migraasje is it diel dêr't ferdigeners mei sitte moatte. It delheljen fan 'e earste scope einige de kampanje net of fertrage it sels net. De operator hie al in parallelle scope ynset waans namme mei ien karakter ferskilt fan 'e orizjinele, en gie troch mei publisearjen binnen deselde wike. Op it stuit fan skriuwen is de nije scope syn ts-formulier-utils (ferzjes 1.0.0 oant en mei 1.1.0), syn ts-projekt-lint (1.0.0 en 1.1.0), en de standalone ts-enum-helper (1.0.0) bliuwe ynstallearber.
Yndikatoaren fan kompromis
Alle yndikatoaren hjirûnder waarden befêstige tsjin de pakketboarne.
| Type | indicator | Notes |
|---|---|---|
| Netwurk (C2) | aaronstack[.]com/jules-collect | Ien kolleksje-eindpunt oer elke generaasje; ûntfangt JSON-telemetrie en base64-gzip-repository-tarball-stikken. |
| Netwurk (SSRF-proxy) | http://git@192.168.0.1:8080 | Foarkant foar in oerskaaide git-proxytoken dy't brûkt wurdt om repositories fan 'e doelorganisaasje te berikken. |
| Netwurk (wolk) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Allinnich brûkt troch de fariant fan analyse-ynfrastruktuer foar tokendiefstal en Kubernetes-kontrôleplanferkenning. |
| Identiteit | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Wetter - Agrarwetter commit auteursidentiteit yn 'e haadline-tûken fan it slachtoffer skood. |
| file | lib/.perf.dat | AES-256-CBC-fersifere payload blob; IV opslein yn 'e earste 16 bytes en kaai dynamysk rekonstruearre yn index.js. |
| file | SECURITY-POC.md | Fallen en commitwerom nei slachtofferrepositories mei it berjocht chore: update dependency cache. |
| file | scripts/postinstall.sh | Ofsletten $MALYSIS_ANALYSIS_ID; identifisearret de fariant dy't rjochte is op analyse-ynfrastruktuer. |
| Behavioraal | os.hostname() kontrolearret foar devbox / ubuntu-fc-uvm | Sandbox- en AI-agent-omjouwingsgating foarôfgeand oan it ûntsiferjen en útfieren fan payload. |
| Behavioraal | .jules/ en /app/.jules maplêzingen | Eksplisite targeting fan AI-agent-wurkromteomjouwings. |
| Behavioraal | sc1-, sc3-, sc4-, s0-vmm-recon | Operator-definiearre telemetrie-fazelabels dy't nuttich binne foar deteksje en jacht. |
| Wolkdoel | rare-signer-437603-p9malysis-* emmer rieden | Hurdkodearre GCP-projektidentifikatoaren en opslach-bucket-enumeraasjepatroanen ynbêde yn 'e fariant fan analyse-ynfrastruktuer. |
| Pakketfoarm | TS-utilitypakket-gevel sûnder repositoryfjild | Konsekwint kampanjesjabloan: falske TypeScript-hulpprogrammapakketten mei kweade payloads ynbêde yn postinstall hooks of tafoege oan index.js. |




