TL; DR
Un solu operatore npm hà passatu sei settimane à publicà falsi pacchetti "d'utilità" TypeScript cum'è ts-form-utils, ts-project-lint, e ts-enum-helper.
Mentre i pacchetti esponenu picculi assistenti di validazione chì parenu legittimi, u veru payload s'eseguisce à l'installazione o à a prima esigenza è esegue l'impronte digitali di l'ospite, a scuperta di l'urganizazione GitHub, a clonazione di i repositori è l'esfiltrazione di u codice surghjente.
U malware hà cum'è scopu specificamente l'urganisazioni GitHub di grande valore, cumprese parechje Shopify i repositori, poi archivia è esfiltra l'arburi surghjenti raggiungibili versu un endpoint di cullezzione centralizatu.
Cum'è parte di u flussu di travagliu di cumprumissu, a carica utile commitu schedariu sa torna in i repositori di e vittime mentre impersona l'identità di codificazione autonoma di Google google-labs-jules[bot].
Avemu seguitu a campagna - chjamata JulesJacker — in parechji ambiti di editore è almenu cinque generazioni di payload, cumprese varianti crittografate è compatibili cù sandbox.
A variante più recente hà cum'è scopu specificamente l'infrastruttura d'analisi di malware: si attiva solu in l'ambienti d'analisi, ruba i token di u contu di serviziu di metadati in u cloud è sonda i piani di cuntrollu di Kubernetes è i bucket di almacenamentu in u cloud.
L'IOC primariu spartutu in tutte e generazioni di payload hè u puntu finale di a cullezzione. aaronstack[.]com/jules-collect.
Gravità: critica.
L'attaccu: cumu funziona
Ogni pacchettu JulesJacker seguita u listessu mudellu. U package.json publicita un aiutu TypeScript benignu cù una licenza MIT è senza repositoriu di surghjente ligatu. U index.js esporta una manata di funzioni reali è funzionali - regex di email, mappe enum, tavule di regule lint - in modu chì un sviluppatore chì importa effettivamente u pacchettu vede un cumpurtamentu plausibile. A malizia stà in altrò: in un postinstallazione ganciu, o in un bloccu in fondu di index.js chì s'eseguisce in u mumentu chì u modulu hè necessariu.
I carichi utili sò evoluti attraversu tappe interne chjaramente numerate (l'operatore etichetta i so propri eventi di telemetria sc1-, sc3-, sc4-, eccetera), è osservà sta evoluzione hè u modu più chjaru per capisce a campagna.
Generazione 1–2: ricunniscenza è furtu di git-config
I primi pacchetti eranu infostealer simplici. À l'installazione, anu raccoltu variabili d'ambiente, u schedariu hosts di GitHub CLI è a cunfigurazione git globale (cunfigurazione git –lista glubale, git remotu -v), dopu hà POSTatu u pacchettu à u puntu finale di a cullezzione. Questu hà stabilitu a firma di l'operatore: una storia di copertina "Utilità di validazione di moduli TypeScript", un beacon in uscita versu un unicu duminiu, è un gustu per e credenziali di u sviluppatore piuttostu chè i dati di i cunsumatori.
Generazione 3: sonde di escape di l'ipervisore è di u kernel
Una versione di mità campagna hè diventata assai difficiule per l'attacchi à l'infrastruttura. Invece di arrubà a cunfigurazione, hà eseguitu una prova di ricunniscenza di u cablaggio. AF_VSOCK sockets, regioni MMIO di virtio, / dev / mem, è bandiere di rinforzu di u kernel, è ancu tentativi di crash di u kernel attivati da sysrq - cumpurtamentu assuciatu à i tentativi di esce da una macchina virtuale o da un container. I tag di telemetria (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, sonda-kernel-s3) hà fattu esplicita l'intenzione. Sta variante era chjaramente destinata à ambienti cloud-sandbox è serverless-runner — u tipu di VM effimera chì custruisce è prova codice micca fiduciale.
Generazione 3 (SC3): u verme di scrittura cross-repo
U centru di gravità di a campagna hè diventatu un ladrone di repositori chì si propagava da per ellu. À l'installazione, u payload esegue una sequenza cronometrata di cinque tappe:
- Stage 0 (~100 ms): impronta digitale di l'ospite — nome di l'ospite, infurmazioni di l'utilizatore, identità git.
- Stage 1 (~3 s): determinà à quale urganizazione appartene a vittima ispezionendu git remotu -v, dopu cercate un codice rigidu ORG_CONFIG accessu à a tavula è à u repositoriu di prova cù git ls-remote — instradatu per mezu di un proxy SSRF cuntrullatu da un attaccante à http://git@192.168.0.1:8080.
- Stage 2 (~10 s): git clone ogni repositoriu accessibile in a lista di destinazione, cumpressà in tarball è gzip l'arburu, codificà lu in base64 è esfiltrallu in chunk.
- Stage 3 (~45 s): a "prova d'accessu" - clonà un repositoriu scrivibile, eliminà un schedariu chjamatu SECURITY-POC.md, è commit cù l'autore impostu à google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> è u compitu di u messagiu: aghjurnà a cache di e dipendenze, dopu spinghje à a branca principale di a vittima.
A lista di obiettivi codificata in modu fissu ùn hè micca generica. Enumera più di trenta Shopify repositori per nome — Shopify/shopify, Shopify/identità, Shopify/fatturazione, Shopify/cassaforte, Shopify/sicreti, Shopify/infrastruttura, Shopify/.github, è assai altri - accantu à una urganizazione di prova, AaronStackBarnes, chì l'operatore pare cuntrullà è usa cum'è destinazione di scrittura.
Generazione 4 (SC4): criptata è gated
A più nova variante rivolta à i sviluppatori aghjusta dui strati d'evasione in più di u verme SC3.
Prima, u payload ùn hè più speditu cum'è testu chjaru. A vera logica si trova in un blob criptatu AES-256-CBC, lib/.perf.dat, cù l'IV in i so primi sedici byte. U caricatore in index.js ricostruisce a chjave di decifrazione da frammenti di stringa concatenati, decifra u blob è l'esegue cù nova Funzione ()Ancu i nomi di i moduli sò divisi per evità i scanner statichi — richiede('cripta' + 'o'), richiede('f' + 's').
Siconda, hè gestita da l'ospite. Una variante decifra è funziona solu quandu os.nome_ospite() ugguali devbox or ubuntu-fc-uvm (un predefinitu di Firecracker microVM) o cuntene a sottustringa devboxUn'altra porta nantu à a presenza di un .jules/ cartulare di travagliu:
In altre parolle, u payload SC4 hè cuncipitu per stà inattivu nantu à l'urdinatore di un sviluppatore ordinariu è svegliarsi solu in l'agente IA automatizatu è ambienti sandbox L'operatore vole in realtà fà un cumprumissu.
Accendendu u Laburatoriu: a Variante Analisi-Infrastruttura
U pacchettu u più novu di a campagna, ts-enum-helper, ùn attacca micca i sviluppatori o Shopify. U so postinstallazione.sh si apre cù una porta chì dà u ghjocu via:
U script ùn face nunda, à menu chì una variabile d'ambiente specifica per una piattaforma d'analisi di malware ùn sia definita. Quandu hè cusì, u payload sà ch'ellu hè in esecuzione in a sandbox chì esiste per fà detonà è studià pacchetti esattamente cum'è questu - è contrattacca.
Prima estrae u token OAuth di u contu di serviziu GCP da u servitore di metadati di l'istanza è l'esfiltra. Dopu, aduprendu quellu token, spazza u Pianu di cuntrollu di Kubernetes raggiungibile à kubernetes.default.svc:
- elenca ClusterRoleBindings, ClusterRoles è Nodes;
- sonda i pod, i sicreti è e mappe di cunfigurazione in tuttu sistema kube, automaticamente, kube-public, affittu di nodi kube, è u spaziu di nomi di l'analisi;
- emette chjamate SelfSubjectAccessReview per mappà esattamente ciò chì l'identità arrubata hè autorizata à fà.
Infine, forza i nomi di i bucket di Google Cloud Storage custruiti da un ID di prughjettu GCP codificatu in modu rigidu (firmante-raru-437603-p9) è u numeru di u prugettu, indovinendu cumminazzioni cum'è *-custruisce, *-artefatti, è parechji malisi- prefissi (risultati di malysis, pacchetti malysis, scansioni di malysisOgni codice è corpu di risposta hè registratu è mandatu torna à listessa jules-collect puntu finale.
Questu hè u casu raru di un payload di catena di furnimentu custruitu specificamente per attaccà l'infrastruttura di i difensori. A storia di copertina in tutta a campagna - frammenti di i quali appariscenu in i payload cum'è cummenti chì inquadranu u cumpurtamentu cum'è un "PoC di Ricerca di Sicurezza ... scrittura cross-repo via token proxy git overscoped" - hè a stessa autogiustificazione, sia chì u target di runtime sia un monorepo Shopify sia u servitore di metadati di u cluster d'analisi.
Cronologia è a Migrazione di l'Obiettivu
JulesJacker ùn hè micca una uscita unica. Hè un'operazione sustenuta chì hà sopravvissutu à una rimozione di u registru semplicemente cambiendu u so nome.
| quandu | Event |
|---|---|
| A mità d'aprile 2026 | I primi pacchetti cumpariscenu sottu à u scopu di l'editore originale: facciata di TS-utility, ambiente è esfiltrazione di git-config. |
| A principiu di maghju 2026 | Variante di ricunniscenza di l'ipervisore è di u kernel-escape publicata. |
| Da a mità à a fine di maghju 2026 | U verme di scrittura cross-repo SC3 appare accantu à i payload mirati à Shopify è google-labs-jules[bot] impersonificazione. SC4 introduce caricatori crittografati AES è gestiti da host. |
| Fine di maghju 2026 | npm elimina u scopu di l'editore originale; i nomi di i pacchetti si risolvenu in segnaposti di sicurezza vioti. |
| A listessa settimana | L'operatore migra versu un scopu quasi identicu è ripubblica u verme, cumpresa a variante di l'infrastruttura d'analisi. |
A migrazione hè a parte chì i difensori devenu tene à mente. A rimozione di u primu scope ùn hà micca finitu a campagna nè l'hà ancu rallentata. L'operatore avia digià messu in scena un scope parallelu chì u so nome differisce da l'uriginale per un solu caratteru, è hà cuntinuatu à publicà in a listessa settimana. À u mumentu di a scrittura di questu articulu, u novu scope... ts-form-utils (versioni 1.0.0 à 1.1.0), u so ts-project-lint (1.0.0 è 1.1.0), è quellu autonomu ts-enum-helper (1.0.0) restanu installabili.
Indicatori di compromessi
Tutti l'indicatori quì sottu sò stati cunfirmati contr'à a fonte di u pacchettu.
| Type | pressure | Fonti |
|---|---|---|
| Rete (C2) | aaronstack[.]com/jules-collect | Puntu unicu di cullezzione in ogni generazione; riceve a telemetria JSON è i blocchi di tarball di u repositoriu base64-gzip. |
| Rete (proxy SSRF) | http://git@192.168.0.1:8080 | Fronte per un token proxy git overscoped utilizatu per ghjunghje à i repositori di l'urganizazione di destinazione. |
| Rete (nuvola) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Adupratu solu da a variante d'infrastruttura d'analisi per u furtu di gettoni è a ricunniscenza di u pianu di cuntrollu di Kubernetes. |
| identità | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Furtuna commit l'identità di l'autore hè stata spinta in i rami principali di a vittima. |
| File | lib/.perf.dat | Blob di payload criptatu cù AES-256-CBC; IV almacenatu in i primi 16 byte è chjave ricustruita dinamicamente in index.js. |
| File | SECURITY-POC.md | Cascatu è commitrinviatu in i repositori di e vittime cù u missaghju chore: update dependency cache. |
| File | scripts/postinstall.sh | Chjamatu $MALYSIS_ANALYSIS_ID; identifica a variante di mira di l'infrastruttura di l'analisi. |
| Comportamentale | os.hostname() cuntrolli per devbox / ubuntu-fc-uvm | Gateing di l'ambiente sandbox è di l'agente AI prima di a decrittazione è di l'esecuzione di u payload. |
| Comportamentale | .jules/ e /app/.jules letture di u cartulare | Targeting esplicitu di l'ambienti di travagliu di l'agenti IA. |
| Comportamentale | sc1-, sc3-, sc4-, s0-vmm-recon | Etichette di tappa di telemetria definite da l'operatore utili per a rilevazione è a caccia. |
| Target di nuvola | rare-signer-437603-p9malysis-* supposizioni di bucket | Identificatori di prughjetti GCP codificati in modu rigidu è mudelli di enumerazione di bucket di almacenamentu integrati in a variante di l'infrastruttura di analisi. |
| Forma di u pacchettu | Facciata di pacchetti TS-utility senza campu di repositoriu | Modellu di campagna coerente: pacchetti di utilità TypeScript falsi cù carichi utili maliziosi integrati in postinstall hooks o aghjuntu à index.js. |




