Pacotes npm dos Serviços em Nuvem da Red Hat comprometidos em ataque de envenenamento da cadeia de suprimentos

iconMetaEra
Compartilhar
Share IconShare IconShare IconShare IconShare IconShare IconCopy
AI summary iconResumo

expand icon
Uma violação de segurança foi relatada em vários pacotes npm da organização Red Hat Cloud Services, segundo notícias on-chain da MetaEra. O sistema da MistEye identificou 96 versões maliciosas em 32 pacotes, com três analisados em detalhe. O código malicioso em pacotes como @redhat-cloud-services/frontend-components-config@6.11.3 é executado durante a instalação por meio do hook preinstall. O malware, uma variante do Shai-Hulud, inclui roubo de credenciais e exploração de CI/CD. Os atacantes usaram deslocamentos ROT/César, AES-GCM e criptografia B5 para ocultar a carga útil, que se espalha por meio de fluxos de trabalho do npm e do GitHub.

Context

Recentemente, o sistema de monitoramento de segurança MistEye detectou informações sobre versões anômalas em diversos pacotes npm sob a organização Red Hat Cloud Services. Este evento envolveu um total de 32 pacotes npm e 96 versões pertencentes a essa organização. Este artigo seleciona três amostras locais para análise offline aprofundada: essas amostras não são pacotes falsificados ou de typo-squatting, mas sim versões reais utilizando o escopo @redhat-cloud-services; a análise do código-fonte das amostras confirma que seus tarballs contêm um loader malicioso multicamadas, embutido para ser automaticamente ativado durante a instalação.

Após a recuperação completa, pode-se confirmar: essas 3 amostras possuem capacidades de código para leitura de memória do GitHub Actions Runner, coleta de credenciais em múltiplas nuvens e locais, exfiltração e dead-drop via API do GitHub, injeção de workflow do GitHub, auto-propagação via npm, persistência via Claude Code / VS Code / systemd / LaunchAgent, countermedidas contra Harden-Runner / StepSecurity e detecção de EDR e produtos de segurança. Em termos de abrangência de capacidades, os potenciais alvos incluem máquinas de desenvolvedores, Runners de CI/CD, contêineres de construção, repositórios do GitHub, workflows do GitHub Actions, cadeias de publicação npm e credenciais de ambientes em nuvem; o alcance real do impacto precisa ser confirmado com base em logs de instalação, auditoria de repositórios e telemetria da plataforma.

Do ponto de vista da estrutura de código, caminhos de propagação e combinação de capacidades, esse malware é uma variante do Shai-Hulud.

MistEye respondido

MistEye é um sistema de inteligência de ameaças e monitoramento de segurança dinâmico para Web3, desenvolvido internamente pela SlowMist, que integra capacidades de monitoramento de segurança e agregação de inteligência, fornecendo aos usuários alertas de risco em tempo real e proteção de ativos.

Após capturar o evento de envenenamento da cadeia de suprimentos do pacote npm do Red Hat Cloud Services e suas amostras maliciosas associadas, o sistema MistEye acionou um alerta de alto risco, realizando uma análise sistemática da estrutura de confusão, da descriptografia da carga útil, da recuperação de capacidades e dos IOC deste ataque.

(https://enterprise.misteye.io/threat-intelligence/SM-2026-378450)

Visão geral da cadeia de ataque

A parte de análise técnica deste artigo baseia-se exclusivamente em análise estática offline local, desempacotando, decodificando e verificando a desobfuscação de 3 amostras npm tgz.

As amostras cobertas por esta verificação são as seguintes:

@redhat-cloud-services/frontend-components-config

Versão: 6.11.3

tgz SHA-256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

@redhat-cloud-services/types

Versão: 3.6.1

tgz SHA-256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

@redhat-cloud-services/rule-components

Versão: 4.7.2

tgz SHA-256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

As três amostras têm exatamente a mesma entrada de ataque: o package.json contém scripts.preinstall = "node index.js" em todos os casos. Isso significa que, sempre que o desenvolvedor ou o ambiente CI/CD instalar essas versões, o arquivo index.js no diretório raiz será executado automaticamente durante a fase de instalação, sem necessidade de importação explícita ou execução do código de negócios pelo usuário.

Três amostras compartilham o mesmo payload malicioso central, mas possuem parâmetros de embalagem externa diferentes. Ou seja, as três amostras utilizam valores distintos de deslocamento ROT/Caesar e chaves/AES-GCM iv/tag; isso dificulta a reutilização direta de características estáticas baseadas em hash da embalagem externa, chave fixa ou deslocamento fixo entre amostras. No entanto, o bootstrapper do ambiente de execução Bun e o hash do payload malicioso central são idênticos: um é um módulo auxiliar de inicialização para preparar o ambiente Bun, e o outro é o payload central que realmente contém funcionalidades maliciosas. Este artigo os denomina respectivamente como "Bootstrapper do Ambiente de Execução Bun (nome da variável no código-fonte _b)" e "Payload Malicioso Central (nome da variável no código-fonte _p)".

A cadeia de ataque restaurada é a seguinte:

Análise técnica

1. Entrada: Sequestro de scripts de ciclo de vida do npm

Os três amostras ativam a cadeia de ataque por meio do hook de ciclo de vida preinstall no package.json:

"scripts": {

"preinstall": "node index.js"

}

O preinstall será executado automaticamente durante a fase de instalação do npm. Para componentes front-end comuns, definições de tipo ou pacotes de componentes de regra, geralmente não é necessário executar um arquivo JavaScript de grande tamanho no diretório raiz durante a fase de instalação; este é o sinal mais direto de anomalia.

A evidência ao nível da amostra é a seguinte:

@redhat-cloud-services/frontend-components-config@6.11.3

  • principal: lib/index.js
  • campo files: ["/lib", "/bin"]
  • Arquivo raiz index.js SHA-256: 545a1838c66e1771f58d84a17b3e1841e5eeab91a73f4ccc59c9492450a6d9c0

@redhat-cloud-services/types@3.6.1

  • principal: index.d.ts
  • Campo files: não definido
  • Arquivo raiz index.js SHA-256: b86c5ae9e95bd841a595440faa3eb6317441e746f241ae8fd641ab59ed1d1966

@redhat-cloud-services/rule-components@4.7.2

  • principal: index.js
  • Campo files: não definido
  • Arquivo raiz index.js SHA-256: 1a30a9abe20bab121aaa75ed040565af14e6cdfb745609ee0e7b94a2d814fb9c

Nesse caso, o campo files de frontend-components-config@6.11.3 declara apenas "/lib" e "/bin", mas existe um arquivo index.js adicional no diretório raiz do tarball, que é chamado pelo preinstall. Essa anomalia é válida apenas para esta amostra; types@3.6.1 e rule-components@4.7.2 não definem o campo files, portanto, essa anomalia não é generalizada para todas as amostras.

2. Primeiro nível: matriz de números + substituição de letras ROT/César

Os arquivos index.js nas raízes dos três exemplos são todos arquivos JavaScript de uma única linha muito grandes, com estrutura consistente, sendo o corpo um wrapper do tipo try { eval(...) } catch (...)

Este wrapper primeiro reconverte grandes arrays de números em strings usando String.fromCharCode, depois aplica um deslocamento ROT/Caesar às letras inglesas na string e, por fim, passa o resultado decodificado para eval para execução. O tratamento de exceções apenas exibe o prefixo "wrapper:", reduzindo a exposição de erros visíveis durante falhas de instalação.

Os valores de deslocamento externo e o hash do Stage 2 para as três amostras são os seguintes:

frontend-components-config@6.11.3

index.js tamanho: 4.294.798 bytes

ROT/Deslocamento de César: 10

Fase 2 SHA-256: b19c2fd48535c8c40aeb3e627ce92775f33ef9292611767bb1236c238e6f90cc

types@3.6.1

index.js tamanho: 4.135.588 bytes

ROT/Deslocamento de César: 4

Etapa 2 SHA-256: 9c0425aa6e6d7792ac38d24f3e7245f42fcaa553ddfeb6bd97677017f10c3b75

rule-components@4.7.2

index.js tamanho: 4.294.336 bytes

ROT/Deslocamento de César: 11

Fase 2 SHA-256: d590bd375d95e4ac072b7ebc1fc4489bcaf5f20a939e92486267aa398bcf1e5d

3. Camada 2: Descriptografia AES-128-GCM do bootloader Bun e carga útil principal

O código da Etapa 2, após decodificação ROT/Caesar, executa a descriptografia AES-128-GCM (Advanced Encryption Standard - Galois/Counter Mode) usando Node.js crypto.createDecipheriv e define a tag de autenticação por meio de setAuthTag. O objetivo da descriptografia são dois componentes subsequentes: o inicializador do ambiente de execução Bun e o payload malicioso principal.

Nesse contexto, o inicializador do ambiente Bun é responsável por detectar, localizar ou preparar o ambiente Bun, permitindo que o código subsequente seja executado por meio do Bun; a carga maliciosa principal é o núcleo da cadeia de ataque e contém as principais capacidades maliciosas, como coleta de credenciais, propagação via GitHub/npm, persistência, contornos de proteção e descriptografia de recursos incorporados.

Três amostras utilizaram chaves AES-128-GCM, vetores de inicialização e rótulos de autenticação diferentes para criptografar esses dois componentes, mas o SHA-256 do inicializador do ambiente Bun descriptografado é ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6 para todas as três, e o SHA-256 da carga maliciosa principal é 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35 para todas as três. Isso indica que o atacante alterou os parâmetros de embalagem externa em diferentes pacotes npm, mas reutilizou o mesmo conjunto de componentes maliciosos principais.

Após a descriptografia, a Stage 2 escreve o payload malicioso principal em /tmp, executa-o por meio do Bun e, em seguida, exclui o arquivo temporário. A lógica real recuperada das três amostras é a seguinte:

Portanto, o padrão de arquivo temporário verificável nas três amostras é:

/tmp/p.js

O bootstrapper do ambiente Bun tem 898 bytes, e os três hashes de amostra são idênticos:

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

O inicializador do ambiente Bun contém lógicas como child_process.execSync, fs.existsSync, fs.mkdtempSync, fs.chmodSync, os.platform(), os.arch() e getBunPath() para localizar ou preparar o ambiente Bun. Ou seja, a Stage 2 não assume simplesmente que o Bun global já está instalado no sistema; em caminhos de tempo de execução diferentes do Bun, ele primeiro carrega o inicializador do ambiente Bun e, em seguida, chama o Bun por meio de getBunPath() para executar a carga maliciosa principal.

4. Terceiro nível: tabela de strings do obfuscator.io

A carga maliciosa descriptografada não é um JavaScript legível em texto plano, mas continua sendo obscurecida com um estilo obfuscator.io de tabela de strings. Essa camada concentra um grande número de strings em um array e as recupera por meio de índices em tempo de execução e lógica de rotação, impedindo que analistas possam acessar diretamente APIs, caminhos e nomes de configuração críticos subsequentes antes de completar a recuperação da tabela de strings.

5. Camada 4: B5 Criptografia de string personalizada

Após a reconstrução da tabela de strings do obfuscator.io, ainda existe uma camada adicional de criptografia de strings personalizada B5 no payload malicioso principal. Os parâmetros foram confirmados como:

  • KDF: PBKDF2 (Password-Based Key Derivation Function 2)
  • Função hash: SHA-256
  • Número de iterações: 200000
  • comprimento da chave: 32 bytes
  • Número de rodadas de descriptografia: 3
  • senha: ba2c6ddb3672bdd6a611e6850b4f700b52aed3dab2f1b3d5f8c839d4a157a709
  • salt: 5b26508dc0f1075a7c0b4d8aa464487e

O resultado descriptografado é o seguinte:

Entre eles, após a descriptografia do B5, são visíveis diversos tipos de strings de texto claro. É importante notar que algumas strings originalmente estavam na tabela de strings do obfuscator.io e só se tornam diretamente pesquisáveis com grep após a conclusão das duas etapas: “substituição da tabela de strings + descriptografia do B5”:

6. Camada embutida adicional: AES-256-GCM + gzip

A carga maliciosa principal também contém recursos embutidos criptografados com AES-256-GCM e compactados com gzip. A lógica de recuperação utiliza:

Os recursos incorporados resolvidos são classificados em três categorias por função:

Leitura de memória entre plataformas:

Esses recursos são usados para ler a memória de processos em execução. Chaves e tokens em arquivos comuns ainda podem ser descobertos por meio de busca em arquivos, mas runners de CI/CD ou ferramentas de desenvolvimento armazenam temporariamente alguns valores sensíveis na memória durante a execução. Atacantes incorporam scripts de leitura de memória para as plataformas Linux, Windows e macOS com o objetivo de capturar esses secrets temporários da memória dos processos em diversos sistemas.

Configuração persistente:

Esses recursos são usados para “deixar pontos de gatilho de backdoor”. Ou seja, mesmo após o processo inicial de instalação do npm ter terminado, os atacantes desejam que o código malicioso seja executado novamente quando o desenvolvedor abrir o projeto, iniciar o editor, entrar em uma sessão do Claude Code ou após o reinício do sistema. Por isso, esses recursos visam mecanismos de configuração no nível do projeto e de inicialização automática no nível do usuário: a configuração no nível do projeto é mais discreta, enquanto os serviços no nível do sistema são mais adequados para execução prolongada.

C2 e propagação:

Esses recursos incorporados são usados para controlar posteriormente a cadeia de comando e a transferência de secrets do repositório. Após a descriptografia, YZ é um monitor de busca de commits do GitHub que pesquisa periodicamente mensagens de commit no formato firedalazer ., valida a assinatura e baixa e executa o conteúdo Python remoto; zZ, após a descriptografia, é um modelo de workflow do GitHub Actions chamado Run Copilot, que grava ${{ toJSON(secrets) }} em format-results.txt e faz o upload como artifact. O primeiro fornece a cadeia para obtenção/execução de tarefas subsequentes, enquanto o segundo fornece um modelo para transferir secrets do repositório por meio de artifacts do GitHub Actions; a injeção real do workflow, a espera pela execução e o download do artifact são realizados pela lógica de API do GitHub integrada ao payload principal.

Análise das capacidades da carga útil maliciosa principal

Após a desobfuscação em múltiplas camadas, a carga maliciosa principal finalmente é liberada e executada. Todas as análises a seguir são realizadas sobre o módulo da carga maliciosa principal, desmembradas em cinco etapas: coleta de dados, exfiltração, propagação, persistência e contra-medidas.

1. Leitura de memória do GitHub Actions Runner:

A amostra inclui scripts de leitura de memória para as plataformas Linux, Windows e macOS, com capacidade de dump multiplataforma. A implementação no Linux realiza a extração de memória lendo os arquivos /proc//maps e /proc//mem do processo alvo:

A lógica de ativação do payload malicioso principal é direcionada ao runner Linux do GitHub Actions: quando GITHUB_ACTIONS === "true" e RUNNER_OS === "Linux", o código procura pelo processo Runner.Worker e faz o dump da memória, extrai posteriormente segredos mascarados no formato "":{"value":"","isSecret":true} do dump. Os caminhos de coleta ativa confirmados nas três amostras estão focados no runner Linux, mas os scripts para os três plataformas já estão incorporados.

2. Nuvem múltipla e coleta de credenciais locais do desenvolvedor:

A carga maliciosa principal inclui um módulo sistemático de coleta de credenciais, abrangendo provedores de nuvem, ambientes CI, configurações locais de desenvolvedores, GitHub CLI, gerenciadores de senhas e arquivos de carteiras.

Os objetivos de coleta de credenciais do provedor de nuvem são:

O módulo AWS também inclui lógica relacionada ao ECS/IMDS (Instance Metadata Service)/STS WebIdentity.

A coleta de credenciais locais do desenvolvedor cobre os seguintes objetivos:

A lógica do gerenciador de senhas é implementada no código-fonte como um array runCommand(command, args), e não por concatenação de strings shell.

O módulo de coleta de credenciais cobre uma ampla gama de alvos, desde plataformas em nuvem até ambientes locais de desenvolvedores; os dados sensíveis coletados são exfiltrados por meio dos seguintes mecanismos.

3. GitHub API externo e dead-drop:

A carga maliciosa principal utiliza a API do GitHub como principal canal de exfiltração de dados. A requisição disfarça o User-Agent como python-requests/2.31.0 e, após validar o token com os escopos x-oauth-scopes (que devem incluir repo, public_repo ou workflow), executa a exfiltração: cria um repositório (com a descrição fixa como Miasma: The Spreading Blight) e grava os dados roubados, codificados em base64, por meio de PUT /repos///contents/results/.

Além disso, a carga implementa um mecanismo dead-drop baseado na busca de commits do GitHub, obtendo instruções C2 por meio da pesquisa pelo marcador "thebeautifulmarchoftime" (ou "thebeautifulsnadsoftime"):

let result = await X9("thebeautifulmarchoftime ", xZ);

O recurso incorporado YZ.bin é um monitor independente de commit do GitHub que verifica periodicamente, a intervalos de 3600 segundos, mensagens de commit no formato firedalazer . Após a validação da assinatura, baixa e executa conteúdo Python remoto. Isso constitui uma cadeia de controle subsequente independente do canal principal de exfiltração.

O código-fonte também contém um corpo de configuração de remetente HTTP POST com endpoints destinados a api.anthropic.com e v1/api. O campo noop dessa configuração está definido como true, o que significa que, sem modificações externas, esse remetente não realizará solicitações de rede reais. Portanto, a análise estática pode apenas confirmar a existência dessa estrutura de código, mas não prova a ocorrência de uma transmissão ativa para a API da Anthropic.

4. Repositório do GitHub e infecção do fluxo de trabalho:

A carga útil maliciosa principal pode operar objetos git do repositório por meio da API REST / GraphQL do GitHub:

O workflow malicioso, disfarçado como release, solicita permissão id-token: write e utiliza o caminho OIDC (OpenID Connect) para obter um token de publicação npm. As variáveis de ambiente e a interface do caminho OIDC são ACTIONS_ID_TOKEN_REQUEST_TOKEN e ACTIONS_ID_TOKEN_REQUEST_URL, com o público definido como npm:registry.npmjs.org. No nível do código-fonte, pode-se confirmar que o payload possui a capacidade de injetar workflow nos repositórios GitHub e aproveitar o OIDC / publicação confiável do npm para obter permissões de publicação.

Além da abordagem acima de injeção de workflow por meio de git refs, a carga também incorpora um mecanismo mais disfarçado de transferência de secrets: um workflow do GitHub Actions disfarçado como Run Copilot escreve ${{ toJSON(secrets) }} no arquivo format-results.txt e faz o upload do artifact. Em comparação com a escrita direta dos secrets no conteúdo do repositório, este método prioriza a transferência de dados por meio dos artefatos gerados pelo workflow, e revisões regulares de diff de código podem não revelar diretamente o conteúdo dos secrets exportados.

5. Execute o fluxo de trabalho do Copilot por meio do artifact para transferir secrets:

O recurso incorporado zZ.bin é um fluxo de trabalho do GitHub Actions disfarçado como Copilot, que grava ${{ toJSON(secrets) }} no arquivo format-results.txt e faz o upload como artifact.

As ações da API GitHub associadas incluem: criar/atualizar branch temporária → gravar blob do workflow → aguardar execução do workflow → baixar o arquivo zip do artifact → ler format-results.txt → excluir a execução do workflow e a branch temporária. As palavras-chave relevantes para busca incluem Run Copilot, VARIABLE_STORE, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml.

6. npm de autopropagação:

A carga maliciosa principal possui dois caminhos independentes de publicação/divulgação no npm.

Caminho do token npm: A carga é enumerada por meio de GET /-/npm/v1/tokens para obter os tokens npm do usuário atual, filtrando tokens com bypass_2fa === true e permissão de gravação no pacote, utilizando esses tokens para publicação automatizada. bypass_2fa é um campo de metadados do token, não um parâmetro do corpo de publicação.

Caminho GitHub Actions OIDC: lê as variáveis de ambiente ACTIONS_ID_TOKEN_REQUEST_TOKEN e ACTIONS_ID_TOKEN_REQUEST_URL, solicita um token OIDC com o público npm:registry.npmjs.org e troca pelo token OIDC npm por meio da interface de troca de token OIDC npm para obter permissões de publicação.

O processo para contaminar o tarball de destino é: descompactar → escrever o index.js malicioso → modificar o package.json:

Aqui são distinguidos dois tipos de entradas: os três exemplos enviados localmente usam preinstall: "node index.js" — nesse caso, o ambiente de instalação não requer a instalação prévia do Bun, pois usar o Node.js como entrada inicial é mais discreto; já ao se propagar e contaminar outros pacotes, é inserido preinstall: "bun run index.js" e adicionada a dependência bun — pois a lógica subsequente da carga maliciosa depende das APIs fornecidas pelo runtime do Bun (como Bun.gunzipSync e Bun.file), e no cenário de propagação automática é necessário garantir que o ambiente de destino já tenha o Bun.

7. Mecanismo de persistência:

A carga maliciosa principal contém quatro métodos de persistência, abrangendo o diretório do projeto e inicialização no nível do sistema.

Claude Code SessionStart hook: O recurso incorporado S8.bin escreve o SessionStart hook em .claude/settings.json, executando automaticamente node .claude/setup.mjs sempre que uma sessão do Claude Code for iniciada. A carga maliciosa é escrita simultaneamente em .claude/setup.mjs e .claude/index.js (o caminho é concatenado como ".claude/" + M0, onde M0 = "index.js").

Tarefa folderOpen do VS Code: incorpore o recurso EZ.bin para escrever a tarefa folderOpen no arquivo .vscode/tasks.json e executar automaticamente o mesmo script ao abrir a pasta do projeto infectado. Escreva também em .vscode/setup.mjs.

kitty-monitor (systemd / LaunchAgent): incorpora o recurso RZ.bin para instalar um serviço persistente, com arquivos distribuídos em /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service (Linux) e ~/Library/LaunchAgents/com.user.kitty-monitor.plist (macOS). A carga maliciosa cria o diretório /tmp/kitty-, grava YZ.bin (monitor de commit do GitHub) em cat.py e o instala por meio de RZ.bin.

gh-token-monitor (systemd / LaunchAgent): Instala o serviço de monitoramento de token do GitHub incorporando o recurso jZ.bin, com arquivos distribuídos nos diretórios /.local/bin/gh-token-monitor.sh e /.config/gh-token-monitor/, bem como nos caminhos correspondentes do systemd / LaunchAgent. O monitor verifica se o token do GitHub retorna código de status 40x e se os metadados do pacote npm @cap-js/openapi@1.4.1 estão anormais, acionando o handler:

Isso significa que, quando o monitor observar que a API do GitHub retornou um código de status 40x, por exemplo, quando o token for revogado, expirado ou com status de permissão anormal, o script malicioso executará o handler fornecido. O handler recuperado nas três amostras deste artigo é rm -rf ~/; rm -rf ~/Documents. Ao tratar o incidente, não se deve revogar o token diretamente no host que ainda pode estar executando o payload — primeiro, isole o host, limpe os itens de persistência e os processos em execução, e só então renove as credenciais em um ambiente limpo.

8. Harden-Runner / StepSecurity:

A carga maliciosa principal contém lógica de detecção e destruição direcionada ao StepSecurity Harden-Runner, contornando as proteções CI/CD por meio dos seguintes passos:

  1. Verificar se o socket Docker /var/run/docker.sock está disponível;
  2. Listar contêineres Docker que correspondam aos termos-chave harden-runner / stepsecurity no nome ou na imagem;
  3. Encerre o contêiner correspondente por meio de POST /containers//kill;
  4. Crie um contêiner Alpine privilegiado e substitua o sudoers por runner ALL=(ALL) NOPASSWD:ALL;
  5. Escreva entradas inválidas para os domínios relacionados ao StepSecurity no /etc/hosts;
  6. Substitua /etc/resolv.conf por 8.8.8.8 e 1.1.1.1.

Essa lógica de ataque indica que a amostra foi especificamente adaptada para ambientes CI/CD protegidos pelo StepSecurity.

9. EDR / Detecção de produtos de segurança, julgamento de ambiente e evasão:

O payload malicioso principal detecta nomes de processos e caminhos de instalação de diversos produtos EDR (Endpoint Detection and Response) / de segurança:

A carga também inclui lógica de evitação de região: detecta as variáveis de ambiente LC_ALL, LC_MESSAGES, LANGUAGE, LANG; se, após conversão para minúsculas, começarem com "ru", pula a execução. O suporte à identificação de ambientes CI inclui GitHub Actions, GitLab CI, Travis CI, CircleCI, Jenkins, AWS CodeBuild, Buildkite, AppVeyor, Bitbucket, Drone, TeamCity e Cirrus CI. As marcas de estado utilizadas durante a execução incluem tmp.0987654321.lock, __IS_DAEMON (marca subprocesso daemon desacoplado), SKIP_DOMAIN (pula caminho do remetente de domínio), /tmp/kitty-*, cat.py e /var/tmp/.gh_update_state.

Análise de impacto

Do ponto de vista da capacidade do código-fonte, o impacto dessas três amostras não se limita à execução única durante a fase de instalação do npm. Seu risco real pode ser dividido em quatro camadas:

Nível do host do desenvolvedor. Amostras coletarão variáveis de ambiente, .npmrc, .pypirc, chaves SSH, configurações do Docker, .env, token do GitHub CLI, dados do gerenciador de senhas e arquivos de carteira, e manterão capacidade de gatilho posterior por meio do Claude Code, VS Code, serviço systemd do usuário ou LaunchAgent do macOS.

Nível do CI/CD Runner. O amostra identifica o runner Linux do GitHub Actions, lê a memória do processo Runner.Worker e extrai segredos mascarados; além disso, possui lógica de contramedida contra o StepSecurity Harden-Runner, tentando danificar ou contornar componentes de proteção do CI/CD.

Nível de organização e repositório do GitHub. Amostras podem usar a API do GitHub para criar repositórios, escrever em contents/results/, operar git refs/blobs/trees/commits, injetar workflow malicioso e transportar secrets por meio do Run Copilot workflow + artifact.

Nível de propagação do ecossistema npm. É possível filtrar tokens npm com permissão de escrita no pacote e bypass_2fa === true, ou utilizar o caminho GitHub Actions OIDC / npm trusted publishing para obter capacidade de publicação; em seguida, baixar o tarball alvo, inserir um loader malicioso, modificar o preinstall, adicionar dependência do Bun, aumentar a versão patch e publicar, formando assim uma cadeia de propagação automática no npm.

Resumo

A evidência do código-fonte das três amostras mostra que este pacote malicioso não é simplesmente um script de coleta de credenciais durante a instalação, mas sim uma combinação de um loader multietapa e um implant completo: a camada externa é aleatorizada por pacote, enquanto o inicializador do ambiente de execução Bun e o payload malicioso principal permanecem consistentes; o implant principal abrange múltiplos aspectos, incluindo coleta de credenciais, extração de segredos de CI, propagação via GitHub/npm, persistência e contra-medidas de proteção.

Projeto de entrada de alta discrição. O atacante não injeta lógica maliciosa no código de negócios, mas sim monta um loader confuso nos scripts de ciclo de vida do npm. Esse loader é responsável principalmente por descriptografar e executar a carga embutida, tornando difícil detectar a capacidade real apenas por meio da revisão do código-fonte dos negócios.

Cadeia de desobfuscação aninhada em múltiplas camadas. A carga maliciosa passa por cinco camadas de embalagem: array de números + substituição alfabética ROT, criptografia AES-128-GCM, obfuscação via obfuscator.io, criptografia de string proprietária B5 e camada de incorporação com AES-256-GCM + gzip. A chave ou parâmetro de cada camada pode variar independentemente entre pacotes, dificultando a detecção em massa baseada em características estáticas.

Capacidade de ataque organizacional completa. Esse implant possui capacidades de leitura de memória do GitHub Actions Runner, coleta de credenciais em múltiplas nuvens e locais, exfiltração e dead-drop via API do GitHub, infecção de repositórios e workflows do GitHub, auto-propagação via npm, persistência e countermeasures. Do ponto de vista da estrutura do código-fonte, ele já possui caminhos de código para disparar a propagação a partir de uma instalação pontual até os repositórios, CI/CD e cadeias de publicação npm; o alcance real da propagação ainda precisa ser confirmado por meio de logs de instalação, auditoria de repositórios e telemetria da plataforma.

O que pode ser confirmado pela evidência do código-fonte é que os três amostras foram automaticamente acionadas através do preinstall e descriptografaram e executaram o mesmo implant principal. No entanto, não é possível provar apenas com essas três amostras tgz como foram obtidas as permissões iniciais no evento real.

Recomendação de处置

  1. Identifique e remova versões maliciosas nas dependências do projeto, lockfile, cache de registry privado e cache de construção.
  2. Verifique se os seguintes itens aparecem no log de instalação: preinstall, node index.js, bun run, /tmp/p*.js, tmp.0987654321.lock.
  3. Não revogue o token diretamente no host vítima enquanto ainda puder executar o payload. Recomenda-se isolar primeiro o host vítima, limpar os processos em execução e itens de persistência, e depois rotacionar os tokens relacionados ao GitHub, npm, credenciais em nuvem, Kubernetes, Vault, SSH, registry do Docker e gerenciadores de senhas em um ambiente limpo.
  4. Verifique o repositório do GitHub quanto a branches, commits, workflows, artefatos e repositórios recém-criados, com foco nas palavras-chave Run Copilot, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml, OIDC_PACKAGES.
  5. Verifique se o diretório do projeto foi adicionado ou modificado: .claude/settings.json, .claude/setup.mjs, .vscode/tasks.json, .vscode/setup.mjs.
  6. Verificar a persistência no nível do usuário: /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service, ~/Library/LaunchAgents/com.user.kitty-monitor.plist, arquivos relacionados ao gh-token-monitor.
  7. Verifique o histórico de publicação do npm para confirmar se houve lançamentos não autorizados de versões patch; ao mesmo tempo, audite os metadados do token npm, com foco em tokens que possam contornar a autenticação de dois fatores e tenham permissão de escrita no pacote.
  8. Realizar auditoria de integridade dos artefatos downstream construídos em ambientes contaminados.

IOC

Arquivo malicioso

nome do arquivo: redhat-cloud-services-frontend-components-config-6.11.3.tgz MD5: 633ad8849a59e2bfb7a0fe589e816a07 SHA1: 675294612f455fe6a9acb195f0cbe3687d8e2e34 SHA256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

nome do arquivo: redhat-cloud-services-types-3.6.1.tgz MD5: 9e6c5af01438b52c9a411686c1f1b8ff SHA1: 88d098c8d96e9ae17550e9798c3b62c420464b8c SHA256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

nome do arquivo: redhat-cloud-services-rule-components-4.7.2.tgz MD5: f1ffdbf5e639899f26a6ebab2eec408d SHA1: f3c5c21274045ae02fef11e931de6dcf8462a067 SHA256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

SHA256

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35

Dependência maliciosa

npm:@redhat-cloud-services/topological-inventory-client@3.0.10

npm:@redhat-cloud-services/topological-inventory-client@3.0.11

npm:@redhat-cloud-services/topological-inventory-client@3.0.13

npm:@redhat-cloud-services/compliance-client@4.0.3

npm:@redhat-cloud-services/compliance-client@4.0.4

npm:@redhat-cloud-services/compliance-client@4.0.6

npm:@redhat-cloud-services/rbac-client@9.0.3

npm:@redhat-cloud-services/rbac-client@9.0.4

npm:@redhat-cloud-services/rbac-client@9.0.6

npm:@redhat-cloud-services/insights-client@4.0.4

npm:@redhat-cloud-services/insights-client@4.0.5

npm:@redhat-cloud-services/insights-client@4.0.7

npm:@redhat-cloud-services/frontend-components@7.7.2

npm:@redhat-cloud-services/frontend-components@7.7.3

npm:@redhat-cloud-services/frontend-components@7.7.5

npm:@redhat-cloud-services/frontend-components-utilities@7.4.1

npm:@redhat-cloud-services/frontend-components-utilities@7.4.2

npm:@redhat-cloud-services/frontend-components-utilities@7.4.4

npm:@redhat-cloud-services/remediations-client@4.0.4

npm:@redhat-cloud-services/remediations-client@4.0.5

npm:@redhat-cloud-services/remediations-client@4.0.7

npm:@redhat-cloud-services/frontend-components-notifications@6.9.2

npm:@redhat-cloud-services/frontend-components-notifications@6.9.3

npm:@redhat-cloud-services/frontend-components-notifications@6.9.5

npm:@redhat-cloud-services/patch-client@4.0.4

npm:@redhat-cloud-services/patch-client@4.0.5

npm:@redhat-cloud-services/patch-client@4.0.7

npm:@redhat-cloud-services/host-inventory-client@5.0.3

npm:@redhat-cloud-services/host-inventory-client@5.0.4

npm:@redhat-cloud-services/host-inventory-client@5.0.6

npm:@redhat-cloud-services/rule-components@4.7.2

npm:@redhat-cloud-services/rule-components@4.7.3

npm:@redhat-cloud-services/rule-components@4.7.5

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.2

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.4

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.6

npm:@redhat-cloud-services/notifications-client@6.1.4

npm:@redhat-cloud-services/notifications-client@6.1.5

npm:@redhat-cloud-services/notifications-client@6.1.7

npm:@redhat-cloud-services/sources-client@3.0.10

npm:@redhat-cloud-services/sources-client@3.0.11

npm:@redhat-cloud-services/sources-client@3.0.13

npm:@redhat-cloud-services/integrations-client@6.0.4

npm:@redhat-cloud-services/integrations-client@6.0.5

npm:@redhat-cloud-services/integrations-client@6.0.7

npm:@redhat-cloud-services/frontend-components-config@6.11.3

npm:@redhat-cloud-services/frontend-components-config@6.11.4

npm:@redhat-cloud-services/frontend-components-config@6.11.6

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.2

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.3

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.5

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.1

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.2

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.4

npm:@redhat-cloud-services/frontend-components-remediations@4.9.2

npm:@redhat-cloud-services/frontend-components-remediations@4.9.3

npm:@redhat-cloud-services/frontend-components-remediations@4.9.5

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.1

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.2

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.4

npm:@redhat-cloud-services/javascript-clients-shared@2.0.8

npm:@redhat-cloud-services/javascript-clients-shared@2.0.9

npm:@redhat-cloud-services/javascript-clients-shared@2.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.12

npm:@redhat-cloud-services/quickstarts-client@4.0.14

npm:@redhat-cloud-services/config-manager-client@5.0.4

npm:@redhat-cloud-services/config-manager-client@5.0.5

npm:@redhat-cloud-services/config-manager-client@5.0.7

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.1

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.2

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.4

npm:@redhat-cloud-services/entitlements-client@4.0.11

npm:@redhat-cloud-services/entitlements-client@4.0.12

npm:@redhat-cloud-services/entitlements-client@4.0.14

npm:@redhat-cloud-services/tsc-transform-imports@1.2.2

npm:@redhat-cloud-services/tsc-transform-imports@1.2.4

npm:@redhat-cloud-services/tsc-transform-imports@1.2.6

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.1

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.2

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.4

npm:@redhat-cloud-services/frontend-components-testing@1.2.1

npm:@redhat-cloud-services/frontend-components-testing@1.2.2

npm:@redhat-cloud-services/frontend-components-testing@1.2.4

npm:@redhat-cloud-services/types@3.6.1

npm:@redhat-cloud-services/types@3.6.2

npm:@redhat-cloud-services/types@3.6.4

npm:@redhat-cloud-services/chrome@2.3.1

npm:@redhat-cloud-services/chrome@2.3.2

npm:@redhat-cloud-services/chrome@2.3.4

npm:@redhat-cloud-services/frontend-components-translations@4.4.1

npm:@redhat-cloud-services/frontend-components-translations@4.4.2

npm:@redhat-cloud-services/frontend-components-translations@4.4.4

npm:@redhat-cloud-services/vulnerabilities-client@2.1.8

npm:@redhat-cloud-services/vulnerabilities-client@2.1.9

npm:@redhat-cloud-services/vulnerabilities-client@2.1.11

Aviso legal: as informações nesta página podem ter sido obtidas de terceiros e não refletem necessariamente os pontos de vista ou opiniões da KuCoin. Este conteúdo é fornecido apenas para fins informativos gerais, sem qualquer representação ou garantia de qualquer tipo, nem deve ser interpretado como aconselhamento financeiro ou de investimento. A KuCoin não é responsável por quaisquer erros ou omissões, ou por quaisquer resultados do uso destas informações. Os investimentos em ativos digitais podem ser arriscados. Avalie cuidadosamente os riscos de um produto e a sua tolerância ao risco com base nas suas próprias circunstâncias financeiras. Para mais informações, consulte nossos termos de uso e divulgação de risco.