TL; DR
Een enkele npm-beheerder heeft zes weken lang nep-TypeScript-"hulpprogramma's" gepubliceerd, zoals: ts-form-utils, ts-project-linten ts-enum-helper.
Hoewel de pakketten kleine, legitiem ogende validatiehulpmiddelen bevatten, wordt de werkelijke lading uitgevoerd bij installatie of de eerste keer dat deze wordt geladen. Deze voert host-fingerprinting, het opsporen van GitHub-organisaties, het klonen van repositories en het exfiltreren van broncode uit.
De malware is specifiek gericht op waardevolle GitHub-organisaties, waaronder meerdere. Shopify repositories, archiveert vervolgens en exfiltreert bereikbare broncodebomen naar een gecentraliseerd verzamelpunt.
Als onderdeel van het compromitteringsproces wordt de payload commitsa-bestanden terugplaatsen in de opslagplaatsen van het slachtoffer, terwijl de identiteit van Google voor autonoom coderen wordt geïmiteerd. google-labs-jules[bot].
We hebben de campagne gevolgd — genaamd JulesJacker — verspreid over meerdere uitgeversbereiken en ten minste vijf payloadgeneraties, inclusief versleutelde en sandbox-bewuste varianten.
De nieuwste variant richt zich specifiek op infrastructuur voor malware-analyse: hij wordt alleen geactiveerd binnen analyseomgevingen, steelt service-accounttokens voor cloudmetadata en onderzoekt Kubernetes-control planes en cloudopslagbuckets.
De primaire IOC die door alle payloadgeneraties wordt gedeeld, is het verzamel-eindpunt. aaronstack[.]com/jules-collect.
Ernst: kritiek.
De aanval: hoe werkt het?
Elk JulesJacker-pakket volgt hetzelfde sjabloon. package.json Het programma adverteert een goedaardige TypeScript-helper met een MIT-licentie en zonder gekoppelde broncode-repository. index.js Het exporteert een handvol echte, werkende functies — e-mailreguliere expressies, enum-mappings, lint-regeltabellen — zodat een ontwikkelaar die het pakket daadwerkelijk importeert, plausibel gedrag ziet. De boosdoener zit echter elders: in een na installatie haak, of in een blok onderaan index.js die wordt uitgevoerd op het moment dat de module nodig is.
De payloads zijn geëvolueerd via duidelijk genummerde interne fasen (de operator labelt zijn eigen telemetriegebeurtenissen). sc1-, sc3-, sc4-, enzovoort), en het volgen van die ontwikkeling is de duidelijkste manier om de campagne te begrijpen.
Generatie 1–2: verkenning en diefstal van git-config
De eerste pakketten waren rechtstreekse informatiedieven. Bij installatie verzamelden ze omgevingsvariabelen, het hosts-bestand van de GitHub CLI en de globale git-configuratie (git config –global –list, git afstandsbediening -vVervolgens verstuurde de operator het pakket via POST naar het collectie-eindpunt. Hiermee werd de signatuur van de operator vastgelegd: een dekmantel van "TypeScript-formuliervalidatieprogramma's", een uitgaand signaal naar één enkel domein en een voorkeur voor ontwikkelaarsgegevens in plaats van consumentengegevens.
Generatie 3: ontsnappingssondes voor hypervisor en kernel
Een van de varianten halverwege de campagne maakte een radicale koerswijziging richting infrastructuuraanvallen. In plaats van configuratiegegevens te stelen, voerde deze een verkenningsaanval uit. AF_VSOCK sockets, virtio MMIO-regio's, / dev / memen kernelbeveiligingsvlaggen, en zelfs pogingen tot sysrq-getriggerde kernelcrashes — gedrag dat geassocieerd wordt met pogingen om uit een virtuele machine of container te breken. De telemetrietags (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-probe) maakte de intentie expliciet. Deze variant was duidelijk gericht op cloud-sandbox- en serverless-runner-omgevingen — het soort vluchtige VM dat onbetrouwbare code bouwt en test.
Generatie 3 (SC3): de cross-repo write worm
Het zwaartepunt van de campagne werd een zichzelf verspreidende repository-dief. Na installatie voert de payload een getimede reeks van vijf stappen uit:
- Stage 0 (~100 ms): maak een vingerafdruk van de host — hostnaam, gebruikersinformatie, git-identiteit.
- Stage 1 (~3 s): bepaal tot welke organisatie het slachtoffer behoort door inspectie git afstandsbediening -v, zoek dan een hardgecodeerde waarde op ORG_CONFIG tabel- en testrepositorytoegang met git ls-remote — gerouteerd via een door de aanvaller beheerde SSRF-proxy op http://git@192.168.0.1:8080.
- Stage 2 (~10 s): git clone Van elke bereikbare repository in de doellijst, de boomstructuur in een tarball en gzip-bestand uitpakken, deze base64-coderen en de chunks exfiltreren.
- Stage 3 (~45 s): het "bewijs van toegang" — kloon een beschrijfbare repository, plaats een bestand met de naam SECURITY-POC.md erin, en commit Het bericht bevat de volgende tekst: `choice`, waarbij de auteur is ingesteld op `google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>` en de tekst: `choice: update dependency cache, then push to the victim's mainline branch.`
De vastgelegde doellijst is niet generiek. Hij bevat meer dan dertig opties. Shopify repositories op naam — Shopify/shopify, Shopify/identiteit, Shopify/facturering, Shopify/vault, Shopify/geheimen, Shopify/infrastructuur, Shopify/.githuben nog veel meer — samen met een testorganisatie, AaronStackBarnes, dat de operator lijkt te besturen en gebruikt als schrijfdoel.
Generatie 4 (SC4): versleuteld en beveiligd
De nieuwste variant, bedoeld voor ontwikkelaars, voegt twee extra beveiligingslagen toe aan de SC3-worm.
Ten eerste wordt de payload niet langer als platte tekst verzonden. De eigenlijke logica bevindt zich in een met AES-256-CBC versleutelde data. lib/.perf.dat, met de IV in de eerste zestien bytes. De loader in index.js Het programma reconstrueert de decryptiesleutel uit aaneengesloten tekenreeksfragmenten, decodeert de blob en voert deze uit met nieuwe functie()Zelfs de modulenamen zijn opgesplitst om statische scanners te omzeilen. require('crypt' + 'o'), vereisen('f' + 's').
Ten tweede is het host-afhankelijk. Eén variant decodeert en voert het alleen uit wanneer os.hostname() is gelijk aan ontwikkelbox or ubuntu-fc-uvm (een standaardinstelling van Firecracker microVM) of bevat de substring ontwikkelboxEen andere poort wijst op de aanwezigheid van een .jules/ werkmap:
Met andere woorden: de SC4-payload is ontworpen om inactief te blijven op een gewone laptop van een ontwikkelaar en pas te ontwaken binnen de geautomatiseerde AI-agent. sandbox-omgevingen De operator wil eigenlijk een compromis sluiten.
Het lab inschakelen: de analyse-infrastructuurvariant
Het meest vernieuwende pakket in de campagne. ts-enum-helperHet valt ontwikkelaars of Shopify helemaal niet aan. postinstall.sh opent met een poort die het geheim verraadt:
Het script doet niets tenzij een omgevingsvariabele die specifiek is voor een malware-analyseplatform is ingesteld. Wanneer dit het geval is, weet de payload dat deze draait binnen de sandbox die is bedoeld om pakketten zoals deze te testen en te bestuderen — en voert deze een tegenaanval uit.
Het haalt eerst het GCP-serviceaccount OAuth-token op van de instantie-metadataserver en onderschept het. Vervolgens gebruikt het dat token om de gegevens te scannen. Kubernetes-besturingsvlak bereikbaar op kubernetes.default.svc:
- Geeft een overzicht van ClusterRoleBindings, ClusterRoles en Nodes;
- scant pods, secrets en configmaps in verschillende omgevingen. kube-systeem, verzuim, kube-public, kube-node-leaseen de analyse-naamruimte;
- De SelfSubjectAccessReview-aanroepen worden gebruikt om precies in kaart te brengen wat de gestolen identiteit wel en niet mag doen.
Ten slotte probeert het met brute force de namen van Google Cloud Storage-buckets te achterhalen die zijn opgebouwd uit een hardgecodeerde GCP-project-ID (zeldzame-ondertekenaar-437603-p9) en projectnummer, waarbij combinaties worden geraden zoals *-bouwt, *-artefactenen meerdere malysis- voorvoegsels (malysis-resultaten, malysis-pakketten, malysis-scansElke responscode en -body wordt geregistreerd en teruggestuurd naar dezelfde server. jules-collect eindpunt.
Dit is een zeldzaam geval van een payload in de toeleveringsketen die specifiek is ontworpen om de eigen infrastructuur van de verdedigers aan te vallen. Het dekmantelverhaal van de hele campagne – waarvan fragmenten in de payloads verschijnen als commentaar waarin het gedrag wordt omschreven als een "PoC voor beveiligingsonderzoek ... cross-repo schrijfbewerking via een te grote git-proxytoken" – is steeds dezelfde zelfrechtvaardiging, of het doelwit nu een Shopify-monorepo is of de metadataserver van het analysecluster.
Tijdlijn en de Scope-migratie
JulesJacker is geen eenmalige actie. Het is een aanhoudende operatie die een verwijdering uit een register heeft overleefd door simpelweg de naam te veranderen.
| . | Evenementen |
|---|---|
| Midden april 2026 | De eerste pakketten verschijnen onder de oorspronkelijke uitgeversscope: TS-utility façade, environment en git-config exfiltration. |
| Begin mei 2026 | Variant voor verkenning van hypervisor- en kernel-escape-aanvallen gepubliceerd. |
| Midden tot eind mei 2026 | De SC3 cross-repo write worm verschijnt samen met payloads die gericht zijn op Shopify. google-labs-jules[bot] Identiteitsvervalsing. SC4 introduceert AES-versleutelde en host-gated loaders. |
| Eind mei 2026 | npm verwijdert het oorspronkelijke publisher-bereik; pakketnamen worden omgezet naar lege, beveiligingsplaceholders. |
| Dezelfde week | De operator migreert naar een vrijwel identieke omgeving en publiceert de worm opnieuw, inclusief de variant met analyse-infrastructuur. |
De migratie is het onderdeel waar verdedigers zich op zouden moeten concentreren. Het uitschakelen van de eerste scope maakte geen einde aan de campagne en vertraagde deze zelfs niet. De operator had al een parallelle scope opgezet, waarvan de naam slechts één teken verschilde van het origineel, en bleef binnen dezelfde week publiceren. Op het moment van schrijven is de nieuwe scope... ts-form-utils (versies 1.0.0 tot en met 1.1.0), de ts-project-lint (1.0.0 en 1.1.0), en de zelfstandige ts-enum-helper (1.0.0) blijft installeerbaar.
Indicatoren van compromis
Alle onderstaande indicatoren zijn geverifieerd aan de hand van de bron van het pakket.
| Type | Indicator | Notes |
|---|---|---|
| Netwerk (C2) | aaronstack[.]com/jules-collect | Eén centraal verzamelpunt voor elke generatie; ontvangt JSON-telemetrie en base64-gecomprimeerde repository-tarball-chunks. |
| Netwerk (SSRF-proxy) | http://git@192.168.0.1:8080 | Frontend voor een overscoped git proxy token dat wordt gebruikt om toegang te krijgen tot de repositories van de doelorganisatie. |
| Netwerk (cloud) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Wordt uitsluitend gebruikt door de analyse-infrastructuurvariant voor tokendiefstal en verkenning van het Kubernetes-controlepaneel. |
| Identiteit | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Gesmeed commit De identiteit van de auteur werd doorgedrukt naar de hoofdlijnen van het slachtoffer. |
| Dien in | lib/.perf.dat | AES-256-CBC-versleutelde payloadblob; IV opgeslagen in de eerste 16 bytes en sleutel dynamisch gereconstrueerd in index.js. |
| Dien in | SECURITY-POC.md | Gedropt en commitTed keerde terug naar de slachtofferarchieven met het bericht. chore: update dependency cache. |
| Dien in | scripts/postinstall.sh | Afgesloten op $MALYSIS_ANALYSIS_ID; identificeert de variant die gericht is op de analyse-infrastructuur. |
| Behavioral | os.hostname() cheques voor devbox / ubuntu-fc-uvm | Toegang tot de sandbox- en AI-agentomgeving wordt beperkt voordat de payload wordt ontsleuteld en uitgevoerd. |
| Behavioral | .jules/ en /app/.jules map leest | Expliciete targeting van de werkomgevingen van AI-agenten. |
| Behavioral | sc1-, sc3-, sc4-, s0-vmm-recon | Door de operator gedefinieerde labels voor telemetriefasen zijn nuttig voor detectie en opsporing. |
| Cloud-doelwit | rare-signer-437603-p9malysis-* emmer schattingen | In de variant voor analyse-infrastructuur zijn vastgelegde GCP-project-ID's en opsommingspatronen voor opslagbuckets opgenomen. |
| Pakket vorm | TS-utility pakket façade zonder repository veld | Consistent campagnesjabloon: nep TypeScript-hulpprogrammapakketten met daarin ingebedde kwaadaardige payloads. postinstall hooks of eraan toegevoegd index.js. |




