1 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • CVE-2024-YIKES é um incidente em que o comprometimento de dependências JavaScript se espalhou para as cadeias de suprimento de Rust e Python
  • O phishing de left-justify vazou credenciais de .npmrc, .pypirc, Cargo e Gem
  • O build.rs malicioso de vulpine-lz4 baixou e executou um script de shell em hosts de CI
  • O malware do snekpack 3.7.0 se espalhou para cerca de 4,2 milhões de máquinas e adicionou chaves SSH e um shell reverso
  • O worm cryptobro-9000 acidentalmente atualizou para snekpack 3.7.1, removendo o malware

Visão geral do incidente

  • CVE-2024-YIKES é um incidente de segurança em que uma dependência comprometida do ecossistema JavaScript levou ao roubo de credenciais, se espalhando depois para um ataque à cadeia de suprimento de uma biblioteca de compressão em Rust e para a distribuição de malware em uma ferramenta de build Python
  • O incidente foi registrado às 03:47 UTC, e o status mudou para “resolvido por acaso”, enquanto a severidade passou de “Critical → Catastrophic → Somehow Fine”
  • A duração foi de 73 horas, e os sistemas afetados continuaram marcados como “Yes”
  • A cadeia de pacotes e ferramentas comprometidos passou por left-justify, vulpine-lz4 e snekpack, distribuindo malware para cerca de 4 milhões de desenvolvedores
  • No fim, um worm separado de mineração de criptomoeda, cryptobro-9000, executou uma atualização nas máquinas infectadas, elevando snekpack para uma versão legítima e removendo o malware por acidente

Evolução do incidente

  • Dia 1: roubo de credenciais em pacote JavaScript

    • Às 03:14 UTC, o mantenedor de left-justify, Marcus Chen, publicou no Twitter que haviam roubado seu cartão de transporte, um notebook antigo e “algo que parecia importante e que o Kubernetes vomitou”, mas isso não foi imediatamente associado a um problema de segurança no pacote
    • Às 09:22 UTC, Chen tentou fazer login no registro nmp e percebeu que não estava com sua chave de 2FA por hardware; o AI Overview no topo dos resultados do Google o direcionou para o site de phishing yubikey-official-store.net, registrado 6 horas antes
    • Às 09:31 UTC, Chen inseriu suas credenciais do nmp no site de phishing, que agradeceu pela compra e prometeu envio em 3 a 5 dias úteis
    • Às 11:00 UTC, [email protected] foi publicado com o changelog “performance improvements”
    • O pacote incluía um script executado após a instalação, que exfiltrava .npmrc, .pypirc, ~/.cargo/credentials e ~/.gem/credentials para um servidor escolhido pelo atacante
    • Às 13:15 UTC, foi aberto um ticket de suporte em left-justify com a mensagem “why is your SDK exfiltrating my .npmrc”, mas ele foi marcado como “low priority - user environment issue” e encerrado automaticamente após 14 dias sem atividade
  • Dia 1: ataque à cadeia de suprimento se espalha para biblioteca Rust

    • Entre as credenciais vazadas estavam as do mantenedor da biblioteca Rust vulpine-lz4
    • vulpine-lz4 é uma biblioteca para “blazingly fast Firefox-themed LZ4 decompression”, tem 12 estrelas no GitHub, mas é uma dependência transitiva do próprio cargo
    • Às 22:00 UTC, vulpine-lz4 0.4.1 foi publicado com a mensagem de commit “fix: resolve edge case in streaming decompression”
    • A mudança real foi a adição de um script build.rs que baixava e executava um script de shell se o hostname contivesse “build”, “ci”, “action”, “jenkins”, “travis” ou “karen”
  • Dia 2: falha na detecção e na resposta

    • Às 08:15 UTC, a pesquisadora de segurança Karen Oyelaran encontrou o commit malicioso depois que o payload foi executado em seu notebook pessoal
    • Karen Oyelaran abriu uma issue dizendo “your build script downloads and runs a shell script from the internet?”, mas não recebeu resposta
    • O mantenedor legítimo havia ganhado €2.3 million na EuroMillions e estava em Portugal pesquisando fazendas de cabras
    • Às 10:00 UTC, o VP de Engenharia de uma empresa da Fortune 500 cliente do snekpack soube do incidente por um post no LinkedIn intitulado “Is YOUR Company Affected by left-justify?” e quis saber por que ninguém o havia incluído antes, embora ele já tivesse sido incluído antes
    • Às 10:47 UTC, o canal #incident-response no Slack desviou brevemente para uma thread de 45 mensagens discutindo se “compromised” deveria ser escrito com “z” no inglês americano
  • Dia 2: infecção da ferramenta de build Python snekpack

    • Às 12:33 UTC, o script de shell mirou especificamente o pipeline de CI do snekpack
    • snekpack é uma ferramenta de build Python usada por 60% dos pacotes do PyPI com “data” no nome
    • snekpack embutia vulpine-lz4 porque “Rust is memory safe”
    • Às 18:00 UTC, snekpack 3.7.0 foi lançado, e o malware começou a ser instalado em máquinas de desenvolvedores no mundo todo
    • O malware adicionava uma chave SSH em ~/.ssh/authorized_keys, instalava um shell reverso que só era ativado às terças-feiras e alterava o shell padrão do usuário para fish
    • A mudança do shell padrão para fish foi tratada como bug
    • Às 19:45 UTC, outro pesquisador de segurança publicou um post de blog de 14.000 palavras intitulado “I found a supply chain attack and reported it to all the wrong people”, contendo a expressão “in this economy?” 7 vezes
  • Dia 3: correção acidental e encerramento do incidente

    • Às 01:17 UTC, um desenvolvedor júnior em Auckland descobriu o malware enquanto depurava um problema não relacionado e abriu um PR revertendo a versão vendorizada de vulpine-lz4 em snekpack
    • Esse PR exigia 2 aprovações, mas os dois aprovadores estavam dormindo
    • Às 02:00 UTC, o mantenedor de left-justify recebeu um YubiKey de yubikey-official-store.net; era um pen drive de 4 dólares com um README escrito “lol”
    • Às 06:12 UTC, um worm separado de mineração de criptomoeda, cryptobro-9000, começou a se espalhar por meio de uma vulnerabilidade em jsonify-extreme
    • jsonify-extreme é descrito como um pacote que “makes JSON even more JSON, now with nested comment support”
    • O payload de cryptobro-9000 em si não tinha nada de especial, mas seu mecanismo de propagação incluía executar npm update e pip install --upgrade em máquinas infectadas para ampliar a superfície de ataque futura
    • Às 06:14 UTC, cryptobro-9000 atualizou acidentalmente snekpack para 3.7.1
    • snekpack 3.7.1 era um release legítimo publicado por um co-mantenedor confuso e revertia a versão vendorizada de vulpine-lz4
    • Às 06:15 UTC, o shell reverso de terça-feira foi ativado, mas o servidor de comando e controle havia sido comprometido por cryptobro-9000 e não conseguia responder
    • Às 09:00 UTC, os mantenedores de snekpack emitiram um aviso de segurança de 4 frases contendo as expressões “out of an abundance of caution” e “no evidence of active exploitation”
    • “no evidence of active exploitation” foi considerado tecnicamente verdadeiro porque ninguém havia procurado evidências
    • Às 11:30 UTC, um desenvolvedor tuitou “I updated all my dependencies and now my terminal is in fish???” e recebeu 47.000 curtidas
    • Às 14:00 UTC, as credenciais comprometidas de vulpine-lz4 foram trocadas
    • O mantenedor legítimo recebeu um e-mail em sua nova fazenda de cabras e respondeu “I haven’t touched that repository in two years” e “I thought Cargo 2FA was optional”
    • Às 15:22 UTC, o incidente foi declarado resolvido, e a retrospectiva foi agendada e depois remarcada três vezes

Designação do CVE e escala do dano

  • Na 6ª semana, CVE-2024-YIKES foi oficialmente designado
  • O aviso ficou sob embargo enquanto MITRE e GitHub Security Advisories discutiam a classificação CWE
  • Quando o CVE foi publicado, 3 artigos no Medium e uma apresentação na DEF CON já haviam detalhado o incidente
  • O dano total permaneceu desconhecido
  • O número de máquinas comprometidas foi estimado em 4,2 milhões
  • O número de máquinas salvas pelo worm de criptomoeda também foi estimado em 4,2 milhões
  • A mudança líquida na postura de segurança permaneceu como “desconforto”

Causa raiz e fatores contribuintes

  • Causa raiz

    • Foi tratado como causa raiz o fato de um cachorro chamado Kubernetes ter comido o YubiKey
  • Fatores contribuintes

    • O registro nmp ainda permite autenticação apenas por senha para pacotes com menos de 10 milhões de downloads semanais
    • O Google AI Overviews apontou com confiança para uma URL que jamais deveria existir
    • A filosofia de “small crates” do ecossistema Rust foi copiada no ecossistema npm, permitindo que pacotes como is-even-number-rs, com 3 estrelas no GitHub, acabem como dependência transitiva a quatro níveis de infraestrutura crítica
    • Ferramentas de build Python vendorizam bibliotecas Rust por “performance” e depois não as atualizam
    • O Dependabot fez merge automático de PRs após o CI passar, e o CI passou porque o malware instalou volkswagen
    • O worm de criptomoeda tem melhores práticas de CI/CD do que a maioria das startups
    • Não houve um único responsável, mas o PR do Dependabot foi aprovado por um contratado cuja sexta-feira era o último dia de trabalho
    • O incidente aconteceu em uma terça-feira

Ações de melhoria e opções restantes

  • A implementação de assinatura de artefatos era um item de ação do incidente do Q3 de 2022, mas continua no backlog
  • A implementação obrigatória de 2FA já havia sido exigida, mas não ajudou
  • A auditoria de dependências transitivas foi riscada porque havia 847 itens no escopo
  • Fixar todas as versões de dependências impede o recebimento de patches de segurança
  • Não fixar versões de dependências abre espaço para ataques à cadeia de suprimento
  • A opção de reescrever em Rust foi riscada e apontava para vulpine-lz4
  • Como ações restantes, sobraram esperar por um worm benevolente ou considerar uma mudança de carreira para fazenda de cabras

Impacto no cliente e resposta organizacional

  • Alguns clientes podem ter sofrido “resultados de segurança não ideais”
  • Houve contato proativo para dar visibilidade da situação às partes interessadas afetadas
  • A confiança do cliente permaneceu como “north star”
  • Foi criado um grupo de trabalho multifuncional para revisar a postura de segurança, mas ele ainda não se reuniu
  • Após revisão jurídica, foi acrescentada a frase de que o shell fish não é malware, embora às vezes pareça ser
  • Este relatório de incidente é o terceiro do trimestre
  • O pedido de reforço de pessoal da equipe de segurança continua no backlog desde o Q1 de 2023

Agradecimentos

  • Karen Oyelaran descobriu o problema porque seu hostname batia com a regex
  • O PR aberto pelo desenvolvedor júnior em Auckland foi aprovado 4 horas depois de o incidente já ter sido resolvido
  • Alguns pesquisadores de segurança encontraram o problema antes, mas o reportaram às pessoas erradas
  • O autor de cryptobro-9000 não quis ter o nome divulgado, mas pediu para mencionarem seu SoundCloud
  • O cachorro Kubernetes recusou comentar
  • Apesar de tudo, a equipe de segurança cumpriu o SLA deste relatório

1 comentários

 
GN⁺ 2 시간 전
Comentários do Hacker News
  • Para quem ficou confuso: este texto é uma ficção, e bem escrita, sobre um incidente na cadeia de suprimentos
    Quando passei o olho por cima, achei que fosse real e fiquei bem preocupado, então acabei lendo com mais atenção :)

    • Eu perdi tudo no left-justify :)
    • No começo, sinceramente, não consegui distinguir, e foi essa a sensação: https://github.com/bitcoin/bips/blob/master/bip-0042.mediawi...
    • Se você pesquisar por CVE-2024-YIKES, também aparecem várias postagens de blog caça-cliques geradas por IA, reescrevendo o conteúdo deste texto e fingindo completa seriedade
    • nmp
  • Fiquei curioso com a parte citada sobre “vulpine-lz4 com 12 estrelas no GitHub ser uma dependência transitiva do próprio cargo”, então puxei rapidamente alguns crates que poderiam se infiltrar em um build do cargo e já ter um build.rs, ficando menos chamativos: flate2, tar, curl-sys, libgit2-sys, openssl-sys, libsqlite3-sys, blake3, libz-sys, zstd-sys, cc
    De quebra, se alguém comprometesse xz2, também poderia contaminar o rustup
    Pelo menos o Cargo.lock é versionado

    • Os crates -sys são só bindings, então fazer qualquer outra coisa ali pareceria bem suspeito
      Pelo que sei, os outros pertencem a mantenedores principais do Rust, como alexcrichton, ou ao próprio rustlang
  • É fácil ficar cínico, porque depois que tudo passa o problema e a solução parecem óbvios demais
    Mas, por muito tempo, e talvez ainda hoje, o credo da cultura hacker foi move fast and break things
    É bom ver crescer o movimento para corrigir os problemas evidentes de sistemas de cadeia de suprimentos como o npm, mas me preocupa estarmos entrando numa era de novos problemas de segurança causados em boa parte pelo desenvolvimento orientado por agentes
    Não só no sentido de Mythos/Glasswing revelar vulnerabilidades em quase tudo em que toca, mas também no modo como estamos criando software, puxando dependências e perdendo nossos modelos mentais humanos sobre sistemas complexos, o que provavelmente vai gerar muito software e infraestrutura improvisados que ninguém entende direito
    Espero que, daqui a alguns anos, ao olharmos para hoje, a gente não se arrependa de ter sido tão ingênuo, sem nos preparar direito para a longa cauda do desenvolvimento com IA, enquanto tentávamos resolver problemas recriando sistemas complexos com IA
    Mesmo assim, o texto foi engraçado

    • Isso foi mesmo um credo por tanto tempo? Eu achava que essa frase horrível tinha sido inventada pelo Zuckerberg
  • Como fã do Fish, essa frase me fez sentir atacado e compreendido ao mesmo tempo: “por favor, deixem claro que o shell fish não é malware, só às vezes parece”
    Independente do shell, a parte dizendo que “o pedido para ampliar a equipe de segurança estava no backlog desde o 1º trimestre de 2023” também pareceu familiar demais

    • Como alternativa, você pode instalar figlet com apt-get ou dnf e então sobrescrever o conteúdo de /etc/motd com all your base are belong to us em uma fonte gigante de arte ASCII
  • Eu realmente ri alto na parte em que o mantenedor do left-justify recebeu uma YubiKey de yubikey-official-store.net, e no fim era um pendrive USB de 4 dólares com “lol” escrito no README
    Trollagem total

    • Sim, foi muito bom
      Gostei do fato de que plugar um dispositivo USB vindo de um site de phishing já é por si só outro vetor de ataque
    • Normalmente se recebe bem menos de sites de phishing. Um pendrive USB que funciona, até que está no lucro!
  • Não era SCP de verdade, mas foi o texto mais SCP que li recentemente

    • Ah, claro, um raríssimo Supply Chain Problem (SCP)
  • Eu ri alto na parte da Karen :D ;)
    Isso me lembrou um script de build baseado em make que recebi ao revisar o projeto de um colega de turma; se o hostname contivesse bpavuk, ele tentava fazer rm -rf na minha pasta home
    Isso foi na 7ª série!!

  • Incidentes de cadeia de suprimentos são realmente complicados, e precisamos fazer melhor
    Pessoalmente, no Rust eu apoio a fundação financiar alguns crates centrais, submetendo-os ao mesmo processo de auditoria do núcleo da linguagem Rust e investindo em projetos para reduzir vulnerabilidades na cadeia de suprimentos
    Não acho que a resposta seja acabar com sistemas como crates ou npm. crates e npm ajudam muito desenvolvedor

    • crates também tem feito esforços para incorporar o rustsec, mas, além disso, eu gostaria de ver a comunidade migrar de muitas dependências pequenas para menos dependências grandes, como tokio
    • Uma parte considerável dos crates mais populares no crates.io já são crates primários fornecidos pela organização Rust
      Isso costuma ser ignorado quando as pessoas se preocupam com o grafo de crates do Rust
      Se você olhar os 10 mais baixados na página inicial do crates.io, o único que não foi feito pela organização Rust ou por mantenedores centrais do Rust é o crate base64
    • Será que não dava para mover crates de alto valor para a biblioteca padrão?
    • Mas será que a gente realmente precisa de npm e nmp ao mesmo tempo?
    • Sinceramente, eu achava que esse era o objetivo final do blessed.rs
  • “O mantenedor oficial ganhou 2,3 milhões de euros na EuroMillions e está pesquisando criação de cabras em Portugal”, e “causa raiz: um cachorro chamado Kubernets comeu a YubiKey”
    Ah, claro. Tão irresponsável cair nesse ataque clássico e famoso
    A famosa técnica de “deixar alguém desnorteado com o prêmio da loteria enquanto o dongle da outra pessoa parece irresistivelmente saboroso para o pet”
    Quando é que as pessoas vão aprender

  • Ainda bem que eu não uso npm nem pip, e sigo o método recomendado de usar só curl ... | bash

    • Isso é curl | sudo bash
      Amadorismo puro