2 pontos por GN⁺ 2024-04-13 | 1 comentários | Compartilhar no WhatsApp
  • Linha do tempo dos eventos:

    • 2024.01.19: o site do XZ foi movido para GitHub Pages por um novo mantenedor (jiaT75)
    • 2024.02.15: build-to-host.m4 é adicionado ao .gitignore
    • 2024.02.23: dois "arquivos de teste" contendo estágios de script malicioso são introduzidos
    • 2024.02.24: XZ 5.6.0 é lançado
    • 2024.02.26: commit em CMakeLists.txt sabotando o recurso de segurança Landlock
    • 2024.03.04: o backdoor causa problemas com o Valgrind
    • 2024.03.09: dois "arquivos de teste" são atualizados, funções de CRC são modificadas, problema com o Valgrind é "corrigido"
    • 2024.03.09: XZ 5.6.1 é lançado
    • 2024.03.28: bug descoberto, Debian e RedHat são notificadas, Debian faz rollback do XZ
    • 2024.03.29: e-mail publicado na mailing list OSS-security, RedHat confirma envio de XZ com backdoor
    • 2024.03.30: Debian interrompe builds e inicia processo de rebuild
    • 2024.04.02: principal desenvolvedor do XZ reconhece o incidente do backdoor
  • Valores de hash das distribuições do XZ que incluíam o backdoor malicioso:

    • xz-5.6.0: valores de hash MD5, SHA1 e SHA256 fornecidos
    • xz-5.6.1: valores de hash MD5, SHA1 e SHA256 fornecidos

Análise inicial da infecção

  • Estágio 1 - script build-to-host adulterado:

    • os arquivos-fonte de release eram inicialmente inofensivos, mas incluíam um arquivo build-to-host.m4 que executava código malicioso quando baixado de uma URL controlada pelo invasor
    • esse arquivo .m4 era executado durante o build, modificando e descompactando o primeiro arquivo adicionado à pasta de testes
  • Estágio 2 - script shell injetado:

    • o script malicioso injetado pelo arquivo .m4 verifica se está rodando dentro do processo de build pretendido no Linux
    • ele usa o arquivo good-large_compressed.lzma para executar o próximo estágio; ele está compactado normalmente, mas os dados descompactados contêm dados lixo internamente
    • extrai 33.492 bytes com comandos head/tail e remove a ofuscação aplicando uma substituição básica com o comando tr
  • Estágio 3 - extração do backdoor:

    • o script shell da etapa final realiza várias verificações para confirmar se está sendo executado no ambiente esperado
    • ele extrai o próprio código binário do backdoor, escondido em outro offset do mesmo arquivo good-large_compressed.lzma
    • extrai o arquivo com a ferramenta XZ e descriptografa os dados binários com uma série de chamadas head, usando um algoritmo semelhante ao RC4
    • extrai o arquivo compactado com XZ, remove os bytes iniciais com base em valores predefinidos e o salva como liblzma_la-crc64-fast.o
    • modifica a função is_arch_extension_supported de crc_x86_clmul.h, trocando a chamada __get_cpuid por _get_cpuid

Análise do backdoor binário

  • Cenário de carregamento furtivo:

    • o XZ usa as funções lzma_crc32 e lzma_crc64 para cálculo de CRC, e elas são armazenadas na tabela de símbolos ELF como tipo IFUNC
    • IFUNC é usado para decidir dinamicamente se deve usar a versão otimizada
    • o backdoor é armazenado como arquivo-objeto, e o principal objetivo é ser vinculado ao executável main no momento da compilação
    • o arquivo-objeto inclui o símbolo _get_cpuid; ao remover um sublinhado do código-fonte original, quando o código chama _get_cpuid, na prática passa a chamar a versão do backdoor
  • Análise do código do backdoor:

    • o código inicial do backdoor é chamado duas vezes, e a atividade maliciosa real começa quando o IFUNC lzma_crc64 chama _get_cpuid
    • ele encontra o endereço da GOT, localiza a posição do ponteiro cpuid e o substitui pelo ponteiro da função maliciosa principal
    • o objetivo principal é fazer hook de funções específicas para poder monitorar todas as conexões com o sistema infectado
  • Comportamentos principais:

    • tem como alvos de hook funções de libcrypto como RSA_public_decrypt, EVP_PKEY_set1_RSA e RSA_get0_key
    • verifica se o processo atual atende aos critérios de execução e se existe um kill switch
    • usa uma estrutura Trie para realizar operações com strings
    • usa três ou mais rotinas de symbol resolver para encontrar a posição das estruturas ELF Symbol
    • obtém o hook de funções abusando do recurso rtdl-audit para sequestrar as rotinas de resolução de símbolos

Opinião do GN⁺

  • Este artigo mostra muito bem um caso extremamente sofisticado de injeção de malware em software open source. Ele traz a lição de que as vantagens do open source também podem ser exploradas de forma maliciosa.

  • Ataques cibernéticos e backdoors voltados a sistemas Linux estão ficando cada vez mais sofisticados. Em especial, ataques por meio de servidores SSH podem se tornar uma séria ameaça de segurança.

  • Por outro lado, isso também mostra a capacidade de autocorreção do ecossistema open source. No fim, o backdoor foi descoberto pela comunidade e houve uma resposta rápida. Transparência é essencial.

  • O uso de técnicas como estrutura de dados Trie avançada, Symbol Resolver e hooking via dl_audit mostra a evolução técnica do malware para Linux. Também é preciso dar atenção redobrada à segurança de sistemas Linux.

  • Ao adotar software open source em empresas, é essencial verificar não apenas a licença, mas também os aspectos de segurança. É preciso confirmar se a distribuição é confiável e se há monitoramento contínuo do código.

1 comentários

 
GN⁺ 2024-04-13
Comentários do Hacker News

Resumo:

  • Considerando o quanto o invasor se esforçou em scripts e código para evitar detecção, este projeto como um todo pode servir como alternativa para distrações ou vários esforços ocorrendo ao mesmo tempo
  • É preciso considerar que focar no SSHD pode fazer com que outras partes do sistema inteiro, ou aspectos técnicos e sociais, sejam afetados
  • Pode ser uma etapa útil de hardening fazer com que cada biblioteca de ligação dinâmica tenha sua própria GOT e marcar a tabela como somente leitura quando a ligação dinâmica for concluída
  • O código-fonte parece ter sido gerado executando um disassembler, entendendo o que o código faz e depois renomeando tudo com nomes descritivos
  • A lentidão e o atraso no SSH causados por um bug no backdoor acabaram levando à sua exposição, e fica a curiosidade se houve alguma análise sobre isso
  • O repositório do xz reapareceu no GitHub, e os mantenedores estão fazendo uma limpeza, incluindo commits que removem o suporte a ifunc e o código que gera arquivos de teste
  • A ideia de que deve haver muitos backdoors que as pessoas ainda não descobriram, junto do desejo de que não exista nada tão discreto quanto este