"Windigo" ainda está vivo: uma atualização do Linux/Ebury

“Windigo” ainda está vivo: uma atualização do Linux/Ebury

Fornecemos alguns detalhes técnicos e novos IoCs para a versão 1.6 do Ebury, um malware que estamos analisando desde 2014.

Fornecemos alguns detalhes técnicos e novos IoCs para a versão 1.6 do Ebury, um malware que estamos analisando desde 2014.

Em fevereiro de 2014, pesquisadores da ESET escreveram uma postagem sobre um backdoor de OpenSSH chamado Linux/Ebury. A pesquisa extra mostrou que este componente era o núcleo de uma operação que evolvia várias famílias de malware, que chamamos de “Operação Windigo“. Isso levou à publicação de um white paper que analisou a operação completa.

Em fevereiro de 2017 encontramos uma nova amostra do Ebury, que apresenta um número significativo de novas características. O número da versão subiu para 1.6.2a. No momento dessa descoberta, as versões mais recentes que vimos foram 1.5.x, meses antes. Após uma pesquisa mais aprofundada, percebemos que sua infraestrutura para vazar credenciais ainda estava operacional e que Ebury ainda estava sendo ativamente usada pela quadrilha Windigo.

Os IoCs originais que fornecemos em 2014 são para a versão 1.4 do Ebury. Em seu site, o CERT-Bund atualizou os IoCs para a versão 1.5. Neste post, fornecemos detalhes técnicos sobre a versão 1.6, que descobrimos em fevereiro de 2017. Também compartilhamos IoC atualizados para as versões 1.5 e 1.6.

Um algoritmo de geração de domínio para extrair credenciais

O Ebury v1.4 usa um algoritmo de geração de domínio (domain generation algorithm ou DGA), quando o cibercriminoso não se conecta ao sistema infectado através do backdoor do OpenSSH por três dias. Nestas condições, o Ebury irá filtrar os dados coletados usando o domínio gerado.

O Ebury v1.6 tem o mesmo mecanismo, mas há uma pequena alteração no próprio DGA. Somente as constantes mudaram entre essas duas versões, como mostrado na figura 2.

Figura 1: O novo DGA do Ebury v1.6 implementado no Python.

Figura 2: Diferenças entre o DGA na v1.4 e v1.6 implementado no Python.

Os primeiros dez domínios gerados pelo DGA são:

  • larfj7g1vaz3y.net
  • idkff7m1lac3g.biz
  • u2s0k8d1ial3r.info
  • h9g0q8a1hat3s.net
  • f2y1j8v1saa3t.biz
  • xdc1h8n1baw3m.info
  • raj2p8z1aae3b.net
  • o9f3v8r1oaj3p.biz
  • tav4h8n1baw3r.info
  • hdm5o8e1tas3n.net

O Ebury tenta sequencialmente os nomes de domínio gerados até encontrar um que tenha um registro TXT definido pelo operador. Para verificar a propriedade do domínio, o Ebury verifica se o registro TXT pode ser descriptografado usando uma chave pública RSA embutida em seu código:

Figura 3: Registros de DNS para larfj7g1vaz3y[.]net.

O registro A no domínio é ignorado pelo Ebury.

Os dados descriptografados possuem três campos separados por vírgulas. Aqui está um exemplo dos dados armazenados na entrada do DNS para larfj7g1vaz3y[.]net em agosto de 2017:

O primeiro campo contém o nome do domínio para que os dados assinados não possam ser reutilizados para outro domínio. O segundo campo é o endereço IP do servidor C&C e o terceiro campo contém uma marca de tempo UNIX utilizada como a data de validade dos dados assinados.

A data de validade é um novo campo adicionado como um mecanismo anti-sinkhole na v1.6. Se alguém tentasse apropriar-se do domínio e do endereço IP do servidor de filtração, só seria possível reutilizar os dados assinados por um período de tempo limitado, reduzindo o impacto de uma tentativa exitosa de sinkhole: algo que aconteceu para quase todas as versões anteriores do DGA.

Tabela 1. Informações descodificadas armazenadas no registro TXT

Domain nameIP AddressExpiration date
larfj7g1vaz3y[.]net0xc6697959 ⇒ 198[.]105.121.892018-01-30 @ 9:00pm (UTC)

Não acreditamos que os operadores do Ebury estejam realmente pensando em usar este mecanismo. Nas amostras que analisamos, foram encontrados vários bugs que evitavam que a execução ocorresse normalmente, o que indica que o código não passou por uma fase de testes completa.

Por este motivo, suspeitamos que seja bastante estranho que os operadores percam o acesso às máquinas infectadas. Também é possível que eles não se importem de perder o acesso a algumas máquinas de vez em quando, considerando que controlam tantos sistemas comprometidos. No entanto, a razão pela qual dedicam tantos esforços em um mecanismo que já não funciona, não é algo tão claro.

Resumo das mudanças

  • DGA ligeiramente modificado (constantes modificadas)
  • Foi adicionada uma data de expiração para a validade da entrada DNS do servidor de filtração
  • Novo domínio registrado: larfj7g1vaz3y[.]net
  • Novo endereço IP do servidor de infiltração: 198[.]105.121.89

Novas funcionalidades

Foram adicionadas novas funcionalidades à versão 1.6. Por razões desconhecidas, não estavam disponíveis em todas as amostras da v1.6 que analisamos.

O Ebury agora implementa técnicas para se esconder, geralmente descritas como um “userland rootkit“. Para isso, gera um hook para a função readdir o readdir64, cada uma das quais é usada para listar as entradas do diretório. Se a próxima estrutura de diretório para retornar é o arquivo de biblioteca compartilhado do Ebury, o hook a ignora e retorna para a entrada subsequente.

Figura 4: Saída Hex-Raios do hook readdir do Ebury

A ativação desses hooks é feita pelo Ebury injetando sua biblioteca dinâmica em cada processo descendentes do sshd. Para injetar-se em subprocessos, o Ebury produz hook e usa a variável LDLPRELOAD do linker dinâmico. Toda vez que um novo processo é criado, o Ebury adiciona LD_PRELOAD = <Ebury_filename> ao seu ambiente. Uma vez que o novo processo é executado, a biblioteca dinâmica do Ebury é carregada e seu construtor é chamado, executando as rotinas de hook.

Como mencionado em um artigo no srvfail.com, existe um tópico no StackExchange de um usuário que afirma que o Ebury comprometeu sua máquina. O comportamento descrito corresponde às técnicas de auto ocultação que presenciamos no Ebury v1.6.2a.

As versões anteriores do Ebury costumavam funcionar apenas em versões muito específicas do OpenSSH e eram específicas para a distribuição do Linux. Normalmente, as amostras anteriores do Ebury funcionariam para três a cinco compilações do OpenSSH para uma determinada distribuição do Linux. Este já não é o caso. A maioria das rotinas de correções do OpenSSH foram substituídas pelo hooking de funções. Não há mais compensações hardcodeadas. Tentamos instalar a Ebury nas máquinas que executam Debian Jessie, CentOS 7 e Ubuntu Artful com a mesma amostra e funcionou em todos os casos.

Para injetar a configuração do servidor OpenSSH diretamente na memória, o Ebury analisa a seção de código do binário sshd mapeada no mesmo processo procurando duas funções diferentes. Ele tenta encontrar o endereço de parse_server_config ou process_server_config_line.

Caso falhe, ele degrada as caraterísticas de segurança ao desativar o controle de acesso baseado na função SELinux e ao desativar os módulos PAM. Quando uma das funções é resolvida com êxito, o Ebury aproveitará isso quando o backdoor for usado para alterar a configuração do sshd.

Figura 5: Configuração usada pelo backdoor do Ebury.

Os autores do Ebury também endureceram seu mecanismo de backdoor. Em vez de confiar apenas em uma senha codificada na string da versão do cliente SSH, a ativação agora requer uma chave privada para se autenticar. É possível que esta verificação extra tenha sido adicionada para evitar que outras pessoas que tenham encontrado a senha do backdoor possam usá-la para obter acesso ao servidor comprometido do Ebury.

Figura 6: Chave pública de RSA das operações do Ebury.

Quando há uma tentativa de conexão ao backdoor, o Ebury modifica a opção AuthorizedKeysFile para apontar para /proc/self/environ. Produz hook  para open ou open64 e comprova se existe uma tentativa de abrir  / proc / self / environ ou uma caminho que contenha .ssh / authorized_keys. A segunda verificação pode ser usada como um retorno no caso do Ebury não conseguir resolver parse_server_config e process_server_config_line para enviar sua própria configuração.

O Ebury também produz hook para fgets que é chamado pelo sshd para ler o conteúdo do arquivo authorized_keys. Uma variável global é usada para garantir que fgets seja chamado depois que o arquivo authorized_keys for aberto. Logo depois, o hook preenche o buffer do fgets com a chave pública dos operadores do Ebury para que a chave do cibercriminoso seja usada para a autenticação.

Figura 7: Saída Hex-Rays do hook fgets

Algo que continua sendo um mistério para nós é o propósito deste hook memcpy:

Figura 8: Saída Hex-Rays do hook memcpy

Até onde sabemos, o hook é usado para remover o algoritmo chacha20-poly1305 durante a troca de chaves SSH, não compreendemos por que os autores do Ebury não querem que esse algoritmo seja usado.

Novos métodos de instalação

Anteriormente, o Ebury adicionou seu payload dentro da biblioteca libkeyutils.so. O arquivo conteria as funções legítimas do libkeyutils e o código malicioso do Ebury, que é iniciado durante o carregamento. Quando comprometido, o arquivo foi maior do que o habitual, um sinal de compromisso que compartilhamos em 2014.

Embora tenhamos visto esta técnica usada pela versão 1.6, os autores do Ebury criaram novos truques para enganar nossos IOCs. Eles ainda usam o arquivo libkeyutils.so, mas de forma diferente.

Segundo o que temos visto, as sequências de comandos e as técnicas de implantação parecem diferir em função da distribuição do Linux do sistema de destino.

Debian/Ubuntu

Nos sistemas Debian/Ubuntu, o Ebury se implementa atualmente usando um novo método. Considerando que o libkeyutils.so é carregado pelo cliente OpenSSH e os executáveis ​​do servidor OpenSSH, continua sendo um alvo interessante para os cibercriminosos.

Anteriormente vimos o Ebury instalado mudando o link simbólico libkeyutils.so.1 para apontar para a versão maliciosa da biblioteca. A biblioteca alterada teria um construtor onde o código de inicialização da Ebury é armazenado. Toda vez que o libkeyutils.so é carregado, o construtor é chamado. Assim, sempre que o cliente ou servidor OpenSSH é iniciado, o Ebury é injetado no processo.

O último método de implantação no Debian/Ubuntu agora depende do patch do libkeyutils.so para forçá-lo a carregar o Ebury, que é armazenado em um arquivo .so separado. Comparando uma versão original e uma parcheada, percebemos que há uma entrada adicional na seção .dynamic do cabeçalho ELF. Esta entrada é do tipo NEEDED (0x01), o que significa que é uma dependência deste executável e que será carregado em tempo de execução. No script de implantação que analisamos, a biblioteca que será carregada se chama libsbr.so e contém o código malicioso do Ebury.

Figura 9: Diferença entre seção dinâmica de uma versão original e uma parcheada do libkeyutils.so.

O processo de atualização tem duas etapas. Primeiro, a cadeia “libsbr.so” deve ser armazenada na tabela de strings do binário. Em segundo lugar, uma nova entrada do tipo 0x1 (DT_NEEDED) deve ser adicionada à seção dinâmica dos cabeçalhos ELF. Esta entrada deve apontar para a string da biblioteca com um deslocamento na tabela de strings. Os autores do Ebury substituem a cadeia “__bss_start” por “_ \ x00libsbr.so”. Como __bss_start não é usado pelo vinculador dinâmico, a modificação deste símbolo não tem impacto na execução da biblioteca. A Figura 10 mostra a diferença entre o original e a tabela de strings alteradas do libkeyutils.so.

Figura 10: Diferenças entre uma tabela de strings originais e uma parcheada.

Agora que a cadeia “libsbr.so” é armazenada na tabela de strings, uma nova entrada deve ser adicionada na seção .dynamic. A Figura 11 mostra a diferença entre a seção .dynamic do original e do parcheado libkeyutils.so.

Figura 12: Estruturas relacionadas à seção .dynamic

Na figura 13, temos uma versão para 64 bits do libkeyutils.so. Portanto, a nova entrada na seção .dynamic pode ser escrita como:

Figura 13: Nova entrada .dynamic

O primeiro campo é 0x1, o que se traduz para a etiqueta DT_NEEDED. O segundo campo é o deslocamento para a string libsbr.so na tabela de strings: 0x3F8.

Para ser ainda mais sigiloso, os operadores do Ebury se preocupam em corrigir as somas do pacote libkeyutils1 da MD5. Portanto, não é possível verificar se um sistema está infectado examinando a integridade do pacote – um comando para tal finalidade não apresentaria erros:

Diversos nomes de arquivos são usados ​​pelo Ebury quando ele é implantado como uma biblioteca autônoma. Aqui está a lista dos nomes de arquivos que conhecemos:

  •     libns2.so
  •     libns5.so
  •     libpw3.so
  •     libpw5.so
  •     libsbr.so
  •     libslr.so

CentOS

No CentOS são usadas técnicas semelhantes às descritas para implantação do Debian/Ubuntu. Os cibercriminosos parcheariam libkeyutils.so para forçá-lo a carregar uma biblioteca extra. Além disso, percebemos uma nova técnica utilizada para a implantação do Ebury nos sistemas CentOS/RedHat.

Ainda não conhecemos todos os detalhes sobre o funcionamento do processo de instalação. A análise de vários relatórios online nos ajudou a organizar algumas suposições sobre como ocorre a implantação.

Sabemos que o Ebury está sendo implantado como um objeto compartilhado separado carregado por libkeyutils de forma semelhante à implantação do Debian. No entanto, também testemunhamos outro método de instalação, que acreditamos ser o método de implantação para v1.6.

Como foi o caso em lançamentos anteriores do Ebury, as operadoras constroem sua própria versão do libkeyutils.so ao qual adicionam um construtor que contém o código malicioso. Em vez de alterar o libkeyutils.so.1 desde /lib/ou/lib64 / usam a pasta /lib {, 64}/tls/ para carregar seu arquivo porque o vinculador dinâmico parece primeiro neste diretório quando as dependências são resolvidas.

Acreditamos que o processo de implantação para esta versão é carregar o Ebury no / lib / tls / ou / lib64 / tls / dependendo da arquitetura do sistema da vítima. Em seguida, ao executar ldconfig se criará automaticamente um link simbólico /lib{,64}/tls/libkeyutils.so.1 que aponta para o objeto compartilhado malicioso.

Figura 14: Uso de ldconfig para implantar o Ebury no / lib64 / tls /

Além disso, cria um sistema de desinstalação simples que não requer manipular links simbólicos e mantém algumas cópias de backup do objeto compartilhado original do libkeyutils no caso de algo dar errado durante o processo de implantação. É necessário apenas apagar o arquivo malicioso libkeyutils.so na pasta / lib {, 64} / tls /, em seguida, executar o ldconfig novamente e o sistema volta ao seu estado original.

Figura 15: Uso do ldconfig para desinstalar o Ebury.

O subdiretório tls é usado em conjunto com uma funcionalidade do loder do Linux no qual se a CPU suporta um conjunto de instruções extras, o que nesse diretório tem precedência sobre o “regular”. O diretório tls é na realmente um pseudo-hwcap do “TLS support” que está sempre presente atualmente.

Conclusão

Mesmo após a prisão de Maxim Senakh, o núcleo da Windigo ainda continua em funcionamento. O Ebury, o principal componente da botnet do Linux, passou por atualizações significativas.

Agora usa técnicas para se esconder e novas formas de injeção em processos relacionados ao OpenSSH. Além disso, usa um novo algoritmo de geração de domínio (DGA) para encontrar qual registro de TXT de domínio deve ser buscado. O endereço IP do servidor de infiltração está escondido nestes dados, assinado com a chave privada dos cibercriminosos.

Uma data de validade foi adicionada aos dados assinados para se defender contra a reutilização das assinaturas, mitigando possíveis tentativas do sinkhole. Os operadores da Windigo monitoram regularmente os IoCs compartilhados publicamente e se adaptam rapidamente aos indicadores tolos disponíveis. Mantenha isso em mente ao tentar determinar se um sistema está infectado usando IOCs públicos. Quanto mais velhos forem, é mais provável que sejam obsoletos.

Indicadores de Compromisso (IoCs)

Nesta seção, compartilhamos os IoCs que podem ajudar a identificar as últimas variantes do Ebury. Fornecemos estes dados para ajudar a comunidade a detectar se seus sistemas estão comprometidos, mas não devem ser considerados perfeitos.

O Ebury agora usa um conector UNIX abstrato para se comunicar com um processo externo que será responsável pela infiltração de dados. Na maioria dos casos, o nome começa com “/ tmp / dbus-“. O dbus verdadeiro pode criar um conector usando o mesmo padrão. No entanto, o Ebury faz isso com processos não relacionados ao dbus legítimo. Se o comando a seguir emitir o socket, deve ser considerado suspeito:

Aqui está uma lista dos processos que conhecemos que o Ebury usa como agente de infiltração:

  • auditd
  • crond
  • anacron
  • arpd
  • acpid
  • rsyslogd
  • udevd
  • systemd-udevd
  • atd
  • hostname
  • sync

No CentOS/Redhat, ter um arquivo libkeyutils.so * em / lib / tls / ou / lib64 / tls / é suspeito.

Executando objdump -x libkeyutils.so.1 (ou readelf -d libkeyutils.so.1) imprimirá a seção dinâmica do cabeçalho ELF. Qualquer coisa NECESSÁVEL (tipo 1) que não seja libc ou libdl é suspeito.

No caso de sua máquina estar infectada com uma versão do Ebury userland rootkit, há várias maneiras de detectá-lo. Como o Ebury se injeta usando a variável de ambiente LDLPRELOAD do vinculador dinâmico, podemos usar alguma outra variável de ambiente para rastrear o processo de vinculação dinâmica. Se o libkeyutils é carregado em algum processo onde não deveria, é muito provável que o sistema esteja infectado com uma versão habilitada para o rootkits. Se o seguinte comando aumento o resultado, deve ser considerado muito suspeito:

Se você detectar máquinas comprometidas, sugerimos que seja realizada a reinstalação completa porque o Windigo, às vezes, instala malware extra. Portanto, é provável que uma máquina comprometida pelo Ebury esteja contaminada por outras ameaças.

Além disso, considere todas as credenciais do usuário e todas as chaves SSH comprometidas. Garanta a troca de todas.

Hashes relacionados ao Ebury

Table 2. Ebury-related hashes

   
SHA-1FilenameVersionDetection Name
5c796dc566647dd0db74d5934e768f4dfafec0e5libns2.so1.5.0Linux/Ebury.B
615c6b022b0fac1ff55c25b0b16eb734aed02734Unknown1.5.1Linux/Ebury.E
d4eeada3d10e76a5755c6913267135a925e195c6libns5.so1.5.1cLinux/Ebury.E
27ed035556abeeb98bc305930403a977b3cc2909libpw3.so1.5.1dLinux/Ebury.E
2f382e31f9ef3d418d31653ee124c0831b6c2273libpw5.so1.5.1eLinux/Ebury.E
7248e6eada8c70e7a468c0b6df2b50cf8c562bc9libpw5.so1.5.1fLinux/Ebury.I
e8d3c369a231552081b14076cf3eaa8901e6a1cdlibkeyutils lib1.5.5Linux/Ebury.F
1d3aafce8cd33cf51b70558f33ec93c431a982eflibkeyutils lib1.5.5Linux/Ebury.F
a559ee8c2662ee8f3c73428eaf07d4359958cae1libkeyutils lib1.5.5cLinux/Ebury.F
17c40a5858a960afd19cc02e07d3a5e47b2ab97alibslr.so1.5.6dpLinux/Ebury.I
eb352686d1050b4ab289fe8f5b78f39e9c85fb55libkeyutils.so.1.51.5.6dLinux/Ebury.F
44b340e90edba5b9f8cf7c2c01cb4d45dd25189elibkeyutils.so.1.51.6.2aLinux/Ebury.I
e8d392ae654f62c6d44c00da517f6f4f33fe7fedlibsbr.so1.6.2gpLinux/Ebury.I
b58725399531d38ca11d8651213b4483130c98e2libsbr.so1.6.2gpLinux/Ebury.I

Discussão