TL; DR
En enda npm-operatör spenderade sex veckor med att publicera falska TypeScript-"verktygspaket" som ts-form-utils, ts-project-lintoch ts-enum-helper.
Medan paketen exponerar små valideringshjälpprogram som ser legitima ut, körs den verkliga nyttolasten vid installation eller första krav och utför värdfingeravtryck, GitHub-organisationsidentifiering, kloning av arkiv och källkodsexfiltrering.
Skadlig kod riktar sig specifikt mot värdefulla GitHub-organisationer, inklusive flera Shopify arkiver, arkiverar och exfiltrerar sedan nåbara källträd till en centraliserad samlingsslutpunkt.
Som en del av kompromissarbetsflödet, nyttolasten commitsa-filen tillbaka till offerdatabaser medan den utger sig för att vara Googles autonoma kodande identitet google-labs-jules[bot].
Vi följde kampanjen — namngiven JulesJacker — över flera utgivaromfång och minst fem nyttolastgenerationer, inklusive krypterade och sandlådemedvetna varianter.
Den senaste varianten riktar sig specifikt mot infrastruktur för analys av skadlig kod: den aktiveras endast inuti analysmiljöer, stjäl tokens för molnmetadatatjänstkonton och undersöker Kubernetes kontrollplan och molnlagringsbuckets.
Den primära IOC som delas mellan alla nyttolastgenerationer är insamlingsslutpunkten aaronstack[.]com/jules-collect.
Allvarlighetsgrad: kritisk.
Attacken: Hur den fungerar
Varje JulesJacker-paket följer samma mall. package.json annonserar en oskadlig TypeScript-hjälp med en MIT-licens och inget länkat källkodsarkiv. index.js exporterar en handfull verkliga, fungerande funktioner – e-postregexer, enum-mappningar, lint-regeltabeller – så att en utvecklare som faktiskt importerar paketet ser rimligt beteende. Illviljan finns någon annanstans: i en efterinstallation krok, eller i ett block längst ner på index.js som körs i det ögonblick modulen behövs.
Nyttolasterna har utvecklats genom tydligt numrerade interna steg (operatören märker sina egna telemetrihändelser sc1-, sc3-, sc4-, och så vidare), och att följa den utvecklingen är det tydligaste sättet att förstå kampanjen.
Generation 1–2: rekognoscering och git-config-stöld
De tidigaste paketen var enkla informationsstjälare. Vid installationen samlade de in miljövariabler, GitHub CLI-hosts-filen och den globala git-konfigurationen (git config –global –list, git remote -v), POSTADE sedan paketet till samlingsslutpunkten. Detta etablerade operatörens signatur: en huvudartikel om "TypeScript-formulärvalideringsverktyg", en utgående beacon till en enda domän och en smak för utvecklaruppgifter snarare än konsumentdata.
Generation 3: hypervisor- och kernel escape-prober
En version mitt i kampanjen riktade sig kraftigt mot infrastrukturattacker. Istället för att stjäla konfiguration körde den en rekognoseringsbaserad undersökning av attackerna. AF_VSOCK sockets, virtio MMIO-regioner, / dev / mem, och flaggor för kärnhärdning, och till och med försök till sysrq-utlösta kärnkrascher — beteende som är associerat med försök att bryta sig ut ur en virtuell maskin eller container. Telemetri-taggarna (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kärnsond) gjorde avsikten tydlig. Denna variant var tydligt avsedd att moln-sandbox- och serverlösa runner-miljöer — den typen av kortlivad virtuell maskin som bygger och testar otillförlitlig kod.
Generation 3 (SC3): masken för att skriva över flera lager
Kampanjens tyngdpunkt blev en självspridande repotjuv. Vid installationen kör nyttolasten en tidsbestämd sekvens i fem steg:
- Steg 0 (~100 ms): fingeravtryck av värden — värdnamn, användarinformation, git-identitet.
- Steg 1 (~3 s): avgör vilken organisation offret tillhör genom att inspektera git remote -v, slå sedan upp en hårdkodad ORG_CONFIG åtkomst till tabell och testrepositori med git ls-remote — dirigeras via en angriparstyrd SSRF-proxy på http://git@192.168.0.1:8080.
- Steg 2 (~10 sekunder): git klon varje nåbar arkiv i mållistan, tarball och gzip-arkivet, base64-koda det och chunk-exfiltrera det.
- Steg 3 (~45 s): "beviset för åtkomst" — klona ett skrivbart repo, släpp en fil med namnet SECURITY-POC.md, och commit den med författaren inställd på google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> och meddelandet chore: update dependency cache, och skicka sedan till offrets huvudgren.
Den hårdkodade mållistan är inte generisk. Den räknar upp mer än trettio Shopify arkiv med namn — Shopify/Shopify, Shopify/identitet, Shopify/fakturering, Shopify/valv, Shopify/hemligheter, Shopify/infrastruktur, Shopify/.githuboch många fler — tillsammans med en testorganisation, AaronStackBarnes, som operatorn verkar kontrollera och använder som skrivmål.
Generation 4 (SC4): krypterad och gatad
Den senaste utvecklarvänliga varianten lägger till två lager av undvikande åtgärder ovanpå SC3-masken.
För det första skickas nyttolasten inte längre som klartext. Den verkliga logiken finns i en AES-256-CBC-krypterad blob, lib/.perf.dat, med IV i sina första sexton byte. Laddaren i index.js rekonstruerar dekrypteringsnyckeln från sammanfogade strängfragment, dekrypterar blobben och kör den med ny funktion()Även modulnamnen är uppdelade för att undvika statiska skannrar — require('crypt' + 'o'), kräver('f' + 's').
För det andra är den värdstyrd. En variant dekrypterar och körs bara när os.hostname() är lika med utvecklarlåda or ubuntu-fc-uvm (en Firecracker microVM-standard) eller innehåller delsträngen utvecklarlådaEn annan grind på närvaron av en .jules/ arbetskatalog:
Med andra ord är SC4-nyttolasten utformad för att förbli vilande på en vanlig utvecklares bärbara dator och bara vakna upp inuti den automatiserade AI-agenten. sandlådemiljöer operatören vill faktiskt kompromissa.
Att slå på labbet: varianten analys-infrastruktur
Det mest nyskapande paketet i kampanjen, ts-enum-hjälpare, attackerar inte utvecklare eller Shopify alls. Dess postinstall.sh öppnas med en grind som avslöjar spelet:
Skriptet gör ingenting om inte en miljövariabel specifik för en plattform för analys av skadlig kod är inställd. När den är det vet nyttolasten att den körs inuti sandlådan som finns för att detonera och studera paket exakt som det här – och den motattackar.
Den hämtar först OAuth-token för GCP-tjänstkontot från instansens metadataserver och exfiltrerar den. Sedan, med hjälp av den token, sveper den Kubernetes kontrollplan nås på kubernetes.default.svc:
- listar ClusterRoleBindings, ClusterRoles och Nodes;
- undersöker poddar, hemligheter och konfigurationsmappningar över kubsystem, standard, kub-offentlig, kube-nod-leasingoch analysnamnrymden;
- utfärdar SelfSubjectAccessReview-anrop för att kartlägga exakt vad den stulna identiteten har tillåtelse att göra.
Slutligen bruteforcerar den Google Cloud Storage-bucketnamn byggda från ett hårdkodat GCP-projekt-ID (sällsynt-signerare-437603-p9) och projektnummer, gissa kombinationer som *-byggen, *-artefakteroch flera malys- prefix (malysresultat, malysis-paket, malys-skanningar). Varje svarskod och -text loggas och POSTAS tillbaka till samma Jules-collect slutpunkt.
Detta är det sällsynta fallet av en nyttolast i leveranskedjan som är specifikt byggd för att attackera försvararnas egen infrastruktur. Huvudhistorien genom hela kampanjen – fragment av vilka visas inuti nyttolasterna som kommentarer som ramar in beteendet som en "Security Research PoC ... cross-repo write via overscoped git proxy token" – är samma självrättfärdigande, oavsett om körningsmålet är ett Shopify-monorepo eller analysklustrets metadataserver.
Tidslinje och omfattningsmigrering
JulesJacker är inte en engångsoperation. Det är en långvarig operation som överlevde en borttagning från registret genom att helt enkelt byta namn.
| När | Event |
|---|---|
| Mitten av april 2026 | De första paketen dyker upp under det ursprungliga utgivaromfånget: TS-utility facade, environment och git-config exfiltration. |
| Början av maj 2026 | Hypervisor och kernel-escape-rekognoseringsvariant publicerad. |
| Mitten till slutet av maj 2026 | SC3-korsrepo-skrivmasken dyker upp tillsammans med Shopify-riktade nyttolaster och google-labs-jules[bot] imitation. SC4 introducerar AES-krypterade och värdstyrda laddare. |
| Sent i maj 2026 | npm tar bort det ursprungliga utgivarens omfattning; paketnamn tolkas som tomma säkerhetsinnehållande platshållare. |
| Samma vecka | Operatören migrerar till ett nästan identiskt liknande omfång och publicerar masken igen, inklusive varianten analysinfrastruktur. |
Migreringen är den del försvararna bör förhålla sig till. Nedtagningen av det första scopet avslutade inte kampanjen eller saktade den ens ner. Operatören hade redan iscensatt ett parallellt scope vars namn skiljer sig från originalet med ett enda tecken, och fortsatte att publicera inom samma vecka. I skrivande stund är det nya scopets ts-formulär-verktyg (versionerna 1.0.0 till 1.1.0), dess ts-projekt-lint (1.0.0 och 1.1.0), och den fristående ts-enum-hjälpare (1.0.0) kan fortfarande installeras.
Indikatorer för kompromiss
Alla indikatorer nedan bekräftades mot paketets källa.
| Typ | Indikator | Anmärkningar |
|---|---|---|
| Nätverk (C2) | aaronstack[.]com/jules-collect | En enda samlingsslutpunkt för varje generation; tar emot JSON-telemetri och base64-gzip-arkivets tarball-block. |
| Nätverk (SSRF-proxy) | http://git@192.168.0.1:8080 | Front för en överskriden git-proxytoken som används för att nå målorganisationens arkiv. |
| Nätverk (moln) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Används endast av analysinfrastrukturvarianten för tokenstöld och Kubernetes kontrollplansrekognoscering. |
| Identitet | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Smitt commit författaridentitet trycktes in i offrets huvudgrenar. |
| Fil | lib/.perf.dat | AES-256-CBC-krypterad nyttolastblob; IV lagras i de första 16 byten och nyckeln rekonstrueras dynamiskt i index.js. |
| Fil | SECURITY-POC.md | Tappade och committillbaka till offerdatabaser med meddelandet chore: update dependency cache. |
| Fil | scripts/postinstall.sh | Spärrad på $MALYSIS_ANALYSIS_ID; identifierar varianten som är inriktad på analysinfrastruktur. |
| Behavioral | os.hostname() kontrollerar för devbox / ubuntu-fc-uvm | Sandbox- och AI-agentmiljögrindning före dekryptering och exekvering av nyttolasten. |
| Behavioral | .jules/ och /app/.jules katalogläsningar | Explicit inriktning på arbetsytemiljöer för AI-agenter. |
| Behavioral | sc1-, sc3-, sc4-, s0-vmm-recon | Operatörsdefinierade telemetri-etiketter som är användbara för detektion och jakt. |
| Molnmål | rare-signer-437603-p9malysis-* gissningar i hinkformat | Hårdkodade GCP-projektidentifierare och uppräkningsmönster för lagringsbuckets inbäddade i varianten analysinfrastruktur. |
| Paketform | TS-verktygspaketfasad utan förvaringsfält | Konsekvent kampanjmall: falska TypeScript-verktygspaket med skadliga nyttolaster inbäddade i postinstall hooks eller bifogad till index.js. |




