- A campanha de confusão de repositório (repo confusion), iniciada em meados de 2023, voltou a se espalhar, e mais de 100 mil repositórios com payloads maliciosos semelhantes foram detectados no GitHub
- Os atacantes criam clones maliciosos parecidos com repositórios legítimos para induzir desenvolvedores ao erro, combinando clonagem, inserção de loader, reenvio, forks em massa e promoção discreta
- Ao executar o repositório malicioso, após uma ofuscação em 7 etapas, são baixados código Python e binários, e dados sensíveis como credenciais de login, senhas de navegador e cookies são roubados
- Mesmo que o GitHub remova automaticamente a maioria dos forks, repositórios que escapam da detecção e uploads manuais permanecem; mesmo que apenas 1% sobreviva, milhares de repositórios maliciosos continuam ativos
- O fluxo de ataque está migrando de pacotes maliciosos no PyPI para repositórios no GitHub, tornando também a cadeia de suprimentos de software fora dos gerenciadores de pacotes uma superfície de ataque direta
Como funciona o ataque de confusão de repositório
- A confusão de repositório se parece com dependency confusion no sentido de induzir o usuário a baixar um repositório malicioso em vez do legítimo
- A diferença está no ponto explorado
- dependency confusion explora o funcionamento do gerenciador de pacotes
- confusão de repositório depende de uma situação em que a pessoa escolhe por engano um repositório parecido
- Nesta campanha, repositórios maliciosos foram espalhados em massa no GitHub para aumentar a chance de infecção
- clona repositórios existentes como
TwitterFollowBot,WhatsappBOT,discord-boost-tool,Twitch-Follow-Bot - insere um loader de malware no clone
- reenvia para o GitHub com o mesmo nome
- faz fork automático de cada repositório milhares de vezes
- promove discretamente em fóruns e no Discord
- clona repositórios existentes como
Fluxo após executar o repositório malicioso
- Quando o usuário utiliza o repositório malicioso, o payload oculto desfaz uma ofuscação em 7 etapas
- Em seguida, baixa código Python malicioso e executáveis binários
- O código malicioso é baseado principalmente em uma versão modificada do BlackCap-Grabber
- Os alvos da coleta incluem credenciais de login de vários apps, senhas e cookies de navegador, além de outros dados confidenciais
- Os dados roubados são enviados ao servidor de C&C (command-and-control) do atacante, e outras atividades maliciosas continuam em seguida
- A análise do código relacionado pode ser vista na análise técnica da Trend Micro
Remoção automática do GitHub e repositórios que permanecem
- O GitHub identifica a automação e remove rapidamente a maior parte dos repositórios forkados
- Ainda assim, muitos repositórios escapam da detecção automatizada, e os enviados manualmente sobrevivem
- Como a cadeia de ataque é automatizada em larga escala, mesmo que apenas 1% permaneça, isso ainda representa milhares de repositórios maliciosos
- Ao pesquisar
🔥 2024 language:pythonno GitHub, é possível ver parte dos repositórios atualmente em disseminação - Incluindo os repositórios já removidos, a escala total chega à casa dos milhões
- a remoção normalmente acontece algumas horas após o upload, o que dificulta a documentação
- muitos repositórios de origem continuam disponíveis, e a remoção mira principalmente o fork bomb
- por exemplo, na lista de repositórios de Mattia69 o resumo mostra milhares de forks, mas eles não aparecem no detalhe dos forks
- Alguns usuários fazem fork de repositórios maliciosos sem saber, criando também um efeito de rede secundário de engenharia social
Linha do tempo da campanha
- Maio de 2023: a Phylum relatou pacotes maliciosos publicados no PyPI
- esses pacotes continham a parte inicial do payload atual
- a disseminação ocorria por chamadas
os.system("pip install package")embutidas em forks de repositórios populares do GitHub, comochatgpt-api
- Julho a agosto de 2023: vários repositórios maliciosos foram publicados no GitHub e passaram a entregar o payload diretamente, em vez de buscar pacotes no PyPI
- foi uma mudança após o PyPI remover os pacotes maliciosos e a comunidade de segurança aumentar a atenção sobre o caso
- Aliakbar Zahravi e Peter Girnus, da Trend Micro, publicaram a análise técnica
- Novembro de 2023 até agora: mais de 100 mil repositórios contendo payloads maliciosos semelhantes foram detectados, e o número continua crescendo
- É claro por que esse método é vantajoso para os atacantes
- a escala do GitHub é tão grande que mesmo muitas instâncias ainda parecem poucas em termos relativos, dificultando a detecção
- diferentemente de antes, não há participação do gerenciador de pacotes, então não fica um nome explícito de pacote malicioso como indicador
- como os repositórios visados ocupam nichos pequenos e têm baixa popularidade, fica mais fácil para desenvolvedores clonarem por engano um repositório impostor malicioso
Migração de gerenciadores de pacote para SCM
- A migração de pacotes maliciosos no PyPI para repositórios maliciosos no GitHub acompanha um movimento observado em vários gerenciadores de pacote e plataformas de SCM
- À medida que a comunidade de segurança passou a focar mais nos gerenciadores de pacote, o caminho do ataque foi deslocado para outro lugar
- O GitHub e plataformas semelhantes facilitam a criação automatizada de contas e repositórios, além de oferecer APIs convenientes e rate limits frouxos que são fáceis de contornar
- Como é possível se esconder entre inúmeros repositórios, o SCM se torna um alvo ideal para infectar discretamente a cadeia de suprimentos de software
- Campanhas de dependency confusion, código malicioso em registros de pacote e disseminação de malware via SCM mostram que, mesmo com muitas ferramentas e mecanismos de segurança, a segurança da cadeia de suprimentos de software continua frágil
Indicadores para verificar infecção
- No código Python, é preciso procurar os seguintes padrões e investigar qualquer correspondência
exec(Fernetexec(requestsexec(__importexec(bytesexec("""\nimportexec(compile__import__("builtins").exec(
- É preciso verificar se há repositórios locais ligados a automação de plataformas sociais, bots e jogos, e removê-los
- Se for realmente necessário usá-los, reinstale apenas após validar cuidadosamente a origem ou executá-los em um sandbox
- Se houver possibilidade de ter clonado esse tipo de repositório, deve-se assumir que os seguintes cookies, credenciais e chaves foram roubados e agir de acordo
- navegadores: serviços financeiros, serviços de e-mail, serviços de criptomoedas, Amazon, eBay, AliExpress, Facebook, Instagram, Twitter, Youtube, Discord, TikTok, Telegram, Twitch, Steam, Yahoo, ExpressVPN, Spotify, serviços de streaming
- apps: Exodus, Atomic Wallet, Guarda, Coinomi, Ethereum
- Uma lista completa de checksums de arquivos é impraticável de tratar, mas alguns itens comuns podem ser vistos no gráfico do VirusTotal
- Após ser notificada, a Cloudflare desativou os registros DNS dos endereços maliciosos encontrados
Defesa e resposta
- O GitHub foi notificado e removeu a maior parte dos repositórios maliciosos, mas a campanha continua em andamento
- Ataques que tentam injetar código malicioso na cadeia de suprimentos estão se tornando cada vez mais comuns
- Existem muitas soluções para detectar malware em nível de sistema e rede, mas a cadeia de suprimentos continua sendo uma superfície de ataque grande e lucrativa para os atacantes
- Ao encontrar um repositório malicioso, independentemente de fazer parte desta campanha, é possível denunciá-lo pelo relatório de abuso ou spam do GitHub
- A Apiiro construiu um sistema de detecção de malware para monitorar codebases conectadas
- análise de código baseada em LLM
- decomposição do código em um grafo completo de fluxo de execução
- mecanismo heurístico
- decodificação, descriptografia e desofuscação dinâmicas
- Sem monitorar payloads maliciosos injetados, a segurança da organização passa a depender de condições como a capacidade dos desenvolvedores de não escolherem o repositório errado quase idêntico, configuração perfeita de CI/CD sem erros e código de terceiros 100% seguro
- É necessária uma abordagem que vá além da detecção e coleta tradicional de vulnerabilidades, revelando os riscos de próxima geração na cadeia de suprimentos de software e em aplicações
1 comentários
Comentários do Hacker News
Indo além do alerta geral de que é preciso ter cuidado com código vindo de repositórios públicos ou fontes externas e fazer verificação da árvore de dependências, fica a dúvida sobre que impacto haveria em LLMs e ferramentas de automação treinados com esse conteúdo se houver código malicioso em massa em repositórios públicos
Parece possível que, quando ferramentas como o Copilot geram respostas longas de código, partes maliciosas acabem entrando por acaso
Coisas como vulnerabilidades simples de injeção já são vistas com frequência
Talvez não agora, mas parece bem plausível dentro de alguns anos
IA não dá nenhuma garantia de precisão
Foi demonstrado que um atacante pode assumir o controle de um bot de serviço conectado ao espaço de conversão Hugging Face Safetensors, que é um serviço popular para converter modelos de machine learning inseguros no ecossistema em versões mais seguras
Para usar LLMs, é preciso investir mais esforço em revisão de código, e acho que esse compromisso vale a pena
Ainda assim, para virar um incidente real, há principalmente duas barreiras: o gerador recebe instruções internas para evitar esse tipo de código, e, pela natureza dos LLMs, é pouco provável que repita exatamente o endereço do atacante real
Mesmo assim, vários vetores de ataque, como bind shell, negação de serviço e exfiltração local, ainda permanecem
O GitHub está fracassando de modo parecido com o fracasso da Usenet
Qualquer um pode criar um repositório, e não há nada que diferencie repositórios oficiais de repositórios de spam
Assim como a Amazon mirou ser “a loja de tudo” e acabou esbarrando em “90% de tudo é lixo”, tornando-se uma loja em que a maior parte é lixo, o GitHub precisa decidir se seu produto é “repositórios para todos” ou “código confiável”
Por exemplo, no PG JDBC oficial não parece haver nenhum elemento que um spammer não consiga reproduzir; então como confiar que isto não é um repositório infectado: https://github.com/pgjdbc
A Sonatype exige comprovação de propriedade do domínio reverso usado no
groupId, que neste caso éorg.postgresqlO método está aqui: https://central.sonatype.org/faq/how-to-set-txt-record/
Para mais tranquilidade, como todos os artefatos publicados no Maven Central são assinados, também é possível verificar a assinatura GPG, mas a desvantagem é que seria preciso obter a chave que o Postgres usa para assinatura por um caminho independente da Sonatype
No caso do PG, uma busca rápida não encontrou a chave
O GitHub tem cerca de 500 milhões de repositórios, então isso na verdade é bem bom
Um desenvolvedor que usaria um repositório infectado encontraria muitos outros meios de criar um produto inseguro mesmo que tais repositórios não existissem no GitHub
A organização usada como exemplo simplesmente parece não ter feito isso
Problemas de cadeia de suprimentos são realmente uma dor de cabeça
Não miro diretamente os releases do npm, mas estou criando releases no npm para monitorar, usando o socket.dev, um projeto de navegador web com virtualização leve chamado BrowserBox
Mesmo esse projeto tem cerca de 800 dependências contando todas as dependências transitivas, embora use apenas 19 dependências de nível superior; ainda assim, no contexto da stack inteira, é relativamente leve
Agora estou pensando em tirar snapshots de todas as 800 dependências no namespace
@browserboxdo npm, acompanhar as vulnerabilidades encontradas e aplicar patchesParece coisa de doido, mas é a situação atual; pelo menos assim dá para garantir diretamente, dentro do nível de segurança da empresa, as vulnerabilidades de cadeia de suprimentos do lado de Node/JS
https://socket.dev
https://github.com/BrowserBox/BrowserBox
Como o arquivo de lock mantém o sha256 de toda a árvore, não é necessário espelhar para evitar alterações mesmo que o repositório seja hackeado
Fixar em uma versão alguns meses atrás da mais recente parece um bom equilíbrio para evitar CVEs novas sem ficar preso a versões velhas demais e acabar tendo de fazer uma grande correção de uma vez
O número de downloads parece uma métrica razoável quando comparado a dependências de nível superior com propósito parecido, mas é um julgamento subjetivo
Austral usa tipos lineares para conceder permissões granulares às dependências
Algo como: uma biblioteca gráfica não precisa de E/S de arquivos, e uma biblioteca de transporte de rede não precisa de acesso ao microfone
É apenas uma mitigação, mas eu gostaria de ver isso em outras linguagens também
Depois de sair de .NET para Java uns 10 anos atrás, fiquei surpreso com o quanto aumentou o tempo gasto em inferno de dependências; hoje, tanto em projetos Java quanto Python, a quantidade de tempo dedicada a atualizações de vulnerabilidades e problemas de dependências é assustadora
Acho que esse problema era menor em .NET porque a adoção de gerenciamento automático de pacotes foi relativamente tardia e o NuGet também era bastante novo; na época, muitos projetos ainda não o tinham adotado, então havia uma cultura forte de evitar árvores enormes de dependências transitivas
Os problemas recentes da Boeing parecem parecidos
Nas últimas décadas, ao transferir cada vez mais a produção para fornecedores externos e focar em otimização de custos, o gerenciamento da cadeia de suprimentos ficou cada vez mais difícil; em uma visão mais ampla, isso se parece com a cultura de cadeia de suprimentos da engenharia de software moderna
Quando trabalhei em uma instituição financeira que proibiu gerenciadores de pacotes por causa da segurança da cadeia de suprimentos, o gerenciamento de dependências foi o menos incômodo e também foi onde houve menos problemas de qualidade
Há vantagens em código que nunca muda a menos que você o altere explicitamente
Implementávamos internamente muita coisa que outros usariam via pacotes, mas, como fazíamos apenas o necessário e aplicávamos padrões de código mais altos, era mais fácil entender, depurar e modificar
O custo de escrever pela primeira vez é único e se amortiza bem, mas o custo recorrente de lidar com código que tenta fazer tudo para todos fica maior no longo prazo e normalmente se acumula
“Simple Made Easy”, de Rich Hickey, mostrou bem esse fenômeno: simples e fácil são coisas diferentes, e opções simples podem parecer mais difíceis no começo, mas ficam mais fáceis no longo prazo quando os efeitos de segunda ordem se acumulam
Eu já tinha percebido isso por acaso ao ver repositórios parecidos
Eu já não executava código de qualquer repositório aleatório, mas agora, mesmo confiando no repositório e no dono, abro uma VM em sandbox
Parece que, hoje, como desenvolvedor, você precisa separar claramente pelo menos três ambientes: trabalho, hobby e uso pessoal
Há projetos que, mesmo não sendo maliciosos, são mal projetados ou escritos de forma idiota
Um programa que executei há pouco tempo adicionou 3 linhas ao meu
~/.bashrcantes mesmo de eu pedir qualquer coisa, e só percebi alguns dias depoisNão consigo entender que tipo de desenvolvedor acha isso uma boa ideia; por isso, agora uso sandbox sempre que executo código externo
É meu OS do dia a dia
Existem mesmo empregadores que permitem isso?
Fico curioso para saber quais ferramentas vocês usam no trabalho para evitar esse tipo de problema e se estão satisfeitos com a configuração atual
Estou desenvolvendo um SDK com muitos downloads semanais em uma equipe bem pequena, e avaliamos soluções baseadas em snyk, aikido.dev, renovate etc., mas não está claro se elas ajudam nesse tipo de problema
Como ainda somos uma equipe pequena, também é pesado lidar com ferramentas com muitos falsos positivos, como o snyk
A Sonatype analisa todos os pacotes, adiciona vários metadados e define políticas que podem ser usadas no Firewall para filtrar o restante
Só funciona para dependências públicas, mas, depois de alguns anos de uso, funciona muito bem
Até agora não tivemos problemas com malware, pacotes com vulnerabilidades conhecidas não entram na base de código e recebemos alertas quando uma vulnerabilidade é encontrada em algo que estamos usando
Ele separa as vulnerabilidades de cadeia de suprimentos encontradas em alcançáveis, não alcançáveis e indeterminadas, o que tornou a triagem muito mais fácil e reduziu bastante o tempo para avaliar novas vulnerabilidades
Os fornecedores mencionados não detectam código malicioso; detectam apenas vulnerabilidades
Mesmo que sejam bons em detectar vulnerabilidades, você ainda não fica protegido contra código malicioso inserido na base de código
Ela realiza análises estática, dinâmica e de metadados, e marca pacotes perigosos verificando mais de 40 atributos, como execução de shell, uso de chaves SSH, comunicação de rede e uso de decode+eval
https://github.com/ossillate-inc/packj
Até agora tem funcionado muito bem
https://trivy.dev/
Fico me perguntando se a prática de baixar scripts de instalação de shell com
curle executá-los comsudovai acabar em breveAlgo como “para instalar nosso software, execute
curl [https://somesite/install.sh](<https://somesite/install.sh>)' | sudo sh” parece se encaixar muito bem com o código infectado mencionado no artigoNosso sistema lista cerca de 100 ocorrências por semana do padrão mencionado, e cerca de 3% delas são maliciosas
Eu gostaria de ver essa prática acabar
npm item as mesmas permissõesEntre as ferramentas comuns atuais para baixar dependências, a única que conheço em que código hostil não é executado no momento da instalação ou do build é mais ou menos
go getNo mínimo, precisamos de ferramentas melhores para trabalhar em sandbox, para compartimentalizar a explosão
A forma do ChromeOS de “uma máquina virtual poder abrir janelas Wayland no desktop principal” é elegante, mas, da última vez que vi, aquele código não era muito limpo nem reutilizável
É um domínio reservado para esse fim: https://www.rfc-editor.org/rfc/rfc2606.html#section-3
.deb/.rpm/instalador” ou, na pior das hipóteses, “confie em algo empacotado por terceiros, não pelo publicador”No npm, é possível mitigar a execução de malware com
--ignore-scriptshttps://blog.uirig.com/getting-rid-of-npm-scripts
Com sorte, ele pode apresentar algum comportamento estranho no CI e ser pego
A solução real é um sistema de reputação como https://github.com/crev-dev/cargo-crev, mas infelizmente quase não é usado
Também vale prestar atenção ao comentário de que um Makefile é necessário
Com a continuidade desses relatórios, venho melhorando aos poucos a segurança do ambiente de desenvolvimento nos últimos meses
Uso dev containers do VSCode para desenvolvimento: https://code.visualstudio.com/docs/devcontainers/create-dev-...
Depois de criar uma vez, é fácil de usar mesmo sem muito conhecimento de Docker, e é bom para subir apps web/de console, mas coisas como Flutter ou Electron foram difíceis
Também me acostumei com o GitHub Codespaces para projetos pequenos: https://github.com/codespaces
No passado, em uma entrevista, já fiz live coding para modificar um projeto Node simples; hoje em dia, em uma situação dessas, acho que certamente usaria contêineres ou Codespaces: https://www.welivesecurity.com/en/eset-research/lazarus-luri...
Para boas práticas de npm, Node e Docker, leio regularmente as diretrizes da OWASP e aplico coisas como usar imagens Docker tão pequenas quanto possível e tags de imagem explícitas: https://cheatsheetseries.owasp.org/cheatsheets/NodeJS_Docker...
Para pacotes npm/python, antes de instalar, verifico no socket.dev acesso a variáveis de ambiente, chamadas de rede, ataques à cadeia de suprimentos, mudanças recentes de propriedade do código etc.; e, como a OWASP recomenda, também é possível desativar globalmente scripts postinstall: https://cheatsheetseries.owasp.org/cheatsheets/NPM_Security_...
Houve, há menos de um ano, um caso de repositório com vírus cavalo de Troia: https://github.com/orgs/community/discussions/63603
Ele apenas funcionou exatamente como o repositório dizia
Só indicar que é um repositório oficial já poderia chamar alguma atenção
O que poderia dar errado /s
Ainda assim, concordo que o GitHub deveria mostrar melhor qual repositório é o oficial de um projeto