PRIDELOCKER – UM NOVO FORK DO CRIPTOGRAFADOR BABUK ESX.

Alguns meses após o vazamento do código-fonte do Babuk em setembro de 2021, novas famílias de ransomware com recursos muito semelhantes já parecem surgir. Durante uma resposta a um incidente, o CSIRT da Synacktiv detectou um novo criptografador ESX chamado PrideLocker, baseado no criptografador Babuk ESX, com novas adições. Este artigo fornece uma análise aprofundada do PrideLocker e um método usando IDAPython para descriptografar suas strings, bem como dicas para detectar seus recursos de criptografia.
Alguns meses após o vazamento do código-fonte do Babuk em setembro de 2021, novas famílias de ransomware com recursos muito semelhantes já parecem surgir. Durante uma resposta a um incidente, o CSIRT da Synacktiv detectou um novo criptografador ESX chamado PrideLocker, baseado no criptografador Babuk ESX, com novas adições. Este artigo fornece uma análise aprofundada do PrideLocker e um método usando IDAPython para descriptografar suas strings, bem como dicas para detectar seus recursos de criptografia.
Compartilhe

Alguns meses após o vazamento do código-fonte do Babuk em setembro de 2021, novas famílias de ransomware com recursos muito semelhantes já parecem surgir. Durante uma resposta a um incidente, o CSIRT da Synacktiv detectou um novo criptografador ESX chamado PrideLocker, baseado no criptografador Babuk ESX, com novas adições. Este artigo fornece uma análise aprofundada do PrideLocker e um método usando IDAPython para descriptografar suas strings, bem como dicas para detectar seus recursos de criptografia.

INTRODUÇÃO

Durante uma resposta a um incidente ocorrido há alguns meses, envolvendo um ataque de ransomware, encontramos vários malwares.

  • Dagon Locker 1 , um ransomware direcionado a ativos do Windows. Parece ser a nova variante do MountLocker. Sua análise revela que a amostra do Dagon Locker envolvida neste caso é bastante semelhante à análise feita pelo SecurityScorecard no Quantum Locker (a versão baseada no MountLocker que precede o Dagon). 2
  • Vários beacons CobaltStrike e ferramentas personalizadas,
  • E um ransomware ELF direcionado a servidores ESXi chamado PrideLocker, no qual nos concentramos neste artigo.

Após análise, concluímos que o PrideLocker é provavelmente um derivado do ransomware Babuk ESX, cujo código-fonte vazou em setembro de 2021 4 . Em maio de 2022, TrendMicro descreveu outro ransomware ESX chamado CheersCrypt que é ainda mais semelhante ao código-fonte vazado Babuk ESX 5 .

Portanto, o objetivo deste artigo é descrever as novas adições trazidas pelo PrideLocker. Outra finalidade também é ajudar a detectar o PrideLocker e variantes com base no código-fonte Babuk, a fim de melhorar a qualificação desse ransomware durante a resposta a incidentes.

INFORMAÇÃO BÁSICA

Nome do arquivocriptografador.esx.bin
MD52dbf12d19306611b8deeb708bc61c18c
SHA1a0e29552db15adc29ac60dc7e5fe757b42e07a76
SHA256a312fef3873b96ce5829cc00b724291ece7a0fd238a007c52695dc4a3268e3c1
Tipo de arquivoELF 64-bit LSB executável x86_64 removido
Tamanho do arquivo165928
AmeaçaRansomware ESX

BILHETE DE RESGATE

What happened?
 All your files are encrypted on all devices across the network
 Huge volume of your data including financial, customer, partner and employees data was downloaded to our internal servers

What's next?
 If you don't get in touch with us next 48 hours, we'll start publishing your data

How do I recover?
 There is no way to decrypt your files manually unless we provide a special decryption tool
 Please download TOR browser (https://www.torproject.org/) and CONTACT US (http://<redacted>.onion/?cid=<redacted>) for further instructions

Bilhete de resgate

Suporte de bate-papo seguro Quantum
Figura 1 – Suporte de bate-papo seguro Quantum

O Quantum Locker é a versão anterior ao Dagon Locker, portanto, não é surpreendente vê-lo aparecendo no bate-papo *seguro* vinculado a esta nota de resgate de exemplo do PrideLocker, já que o Dagon Locker foi implantado para criptografar ativos do Windows neste ataque de ransomware.

ANÁLISE DE CÓDIGO

Ofuscação de String

A amostra do PrideLocker que encontramos ofuscou suas strings. Vamos cobrir em detalhes seu mecanismo de ofuscação.

A figura abaixo descreve o início do código assembly da função principal. O padrão de carregamento da string é sempre o mesmo:

  1. Chame uma função que carrega uma string de pilha criptografada
  2. Chame uma função contendo uma chave exclusiva para descriptografar a string
Padrão de carregamento de strings
Figura 2 – Padrão de carregamento de strings

Abaixo está uma função que carrega uma string de pilha criptografada. O primeiro byte é o comprimento da string criptografada.

Carregamento de cadeia de pilha criptografada
Figura 3 – Carregamento de cadeia de pilha criptografada

Em seguida, a função de descriptografia dessa sequência criptografada carrega uma QWORD exclusiva (8 bytes) como uma chave e chama outra função que é a rotina de descriptografia real.

Carregamento e descriptografia de chaves
Figura 4 – Carregamento e descriptografia da chave

A rotina de descriptografia é bastante simples. Cada byte da string criptografada é xor-ed com a chave shifted.

Rotina de descriptografia
Figura 5 – Rotina de descriptografia

Abaixo está a rotina de descriptografia traduzida em Python:

def decrypt_string(enc_str, qword_key):
    dec_str = bytearray(len(enc_str))
    for i in range(0, len(enc_str)):
        tmp = (qword_key >> (8 * (i&7)))&0xff
        dec_str[i] = enc_str[i] ^ tmp
    return dec_str

Como analisar tal programa com este tipo de ofuscação? Cada string tem suas próprias funções de carregamento: uma carregando a string da pilha criptografada e outra descriptografando-a. Portanto, existem centenas de funções envolvidas no carregamento e na descriptografia das strings. No entanto, o padrão permanece semelhante e a mesma rotina de descriptografia ( sub_408D0C) é usada.

Eu queria descriptografar todas as strings para ter uma boa compreensão desse malware, sem gastar muito tempo depurando-o. Portanto, optei por desenvolver um script IDA Python, pois estou mais acostumado com esse framework. Para ajudar a desenvolver tal script, eu recomendo ler a folha de dicas IDA Python 6 do icecr4ck  e, claro, a documentação oficial 7 .

O script completo está disponível na organização Github da Synacktiv: https://github.com/synacktiv/pridelocker-analysis

A abordagem desse script é primeiro obter todas as referências cruzadas ( XrefsTo) da rotina de descriptografia exclusiva. Dessa forma, para cada referência cruzada, podemos buscar a chave exclusiva e o comprimento da string criptografada. Em seguida, o ponteiro de instrução é movido para trás até que a função Stack string loader seja encontrada (verifique get_function_with_encrypted_stringa função no script). Uma vez que esta função é encontrada, ela é navegada até que a string da pilha seja carregada ( get_encrypted_stringfunção). Por fim, a string da pilha é coletada, descriptografada e adicionada como um novo comentário IDA nas exibições de desmontagem e descompilador. Além disso, as funções de ofuscação que foram atendidas no processo são renomeadas. Dessa forma, posso me concentrar no código relevante do ransomware e deixar a parte de ofuscação para trás.

Você pode ver abaixo o início da função main nas visualizações do desmontador e do descompilador, após a execução do script.

Visualização IDA após a execução do script
Figura 6 – Visualização do IDA após a execução do script

Como você pode ver na Figura 6, todas as strings foram recuperadas corretamente. Além disso, cerca de 280 funções foram renomeadas no processo, então é muito código que eu poderia pular. 😃

Como lembrete, fiz uma lista de algumas funções do IDA Python que são úteis na maioria das vezes:

  • Movendo-se pela assembléia:
    • percorrendo uma lista de instruções com base nos endereços inicial e final: idautils.Heads,
    • referências cruzadas de um endereço: idautils.XrefsTo,
    • obter a função que possui um endereço específico: ida_funcs.get_func.
  • Instruções de decodificação:
    • instrução atual apontada por um endereço: idautils.DecodeInstruction,
    • obter a instrução anterior: idautils.DecodePreviousInstruction,
    • obter a representação de texto do mnemônico (mov, call, etc.): idc.print_insn_mnem,
    • obter o tipo de operando (o_reg, o_displ, o_imm): idc.get_operand_type,
    • obtenha o valor do operando: idc.get_operand_value,
    • obtenha a representação de texto do operando: idc.print_operand.
  • Obtendo dados:
    • obter bytes (por exemplo, um bloco de dados para descriptografar): idc.get_bytes,
    • obtenha o conteúdo da string apontado por um endereço: idc.get_strlit_contents.
  • Comentários de configuração:
    • Na desmontagem:idc.set_cmt
    • No descompilador é um pouco mais complicado, recomendo ler a função setCommentToDecompilationdo meu script, que na verdade tirei do repositório gdataadvancedanalytics ‘ida-python GitHub 8 .

Argumentos da linha de comando

O Babuk ESX Locker precisa ser executado com o caminho de destino para criptografar como um argumento de linha de comando. Não exigia outros argumentos.

Pelo contrário, o PrideLocker pode ser executado sem nenhum argumento. Vários argumentos opcionais também podem ser especificados na linha de comando. A seguinte nota de ajuda é impressa quando executada com o -hsinalizador:

PrideLocker ESX Encryptor (HYDRA-220218) started

Usage: ./encryptor.esx.bin <arguments>

Arguments:
    -h, --help       Show this help message and exit
    -v, --verbose    (OPTIONAL) Verbose encryptor output
    -p, --path       (OPTIONAL) Path to encrypt (/vmfs/volumes by default)
    -d, --dryrun     (OPTIONAL) Run in dryrun mode (i.e. no real encryption)
    -n, --nostop     (OPTIONAL) Do not stop VMs
    -t, --threads    (OPTIONAL) Set number of threads

Nota de ajuda

Como você pode ver na nota de ajuda, a primeira linha PrideLocker ESX Encryptor (HYDRA-220218) startedindica o nome do ransomware “PrideLocker ESX Encryptor” e provavelmente algum tipo de versão de compilação “HYDRA-220218”.

O caminho padrão para criptografar é /vmfs/volumes. Na verdade, é o caminho padrão onde as máquinas virtuais são armazenadas no ESXi (o armazenamento de dados pesquisável do cliente vSphere). Entre os argumentos opcionais, é possível especificar o caminho para criptografar, optar por não parar as máquinas virtuais antes da criptografia, especificar um número de threads, habilitar o modo detalhado ou até mesmo executar no modo dry-run. O modo de simulação não para as máquinas virtuais e não criptografa os arquivos.

Licença por tempo limitado

Logo no início da execução, a hora atual é verificada em relação a uma armazenada e criptografada no .datasegmento. Você pode ver abaixo um script Python mínimo para recuperá-lo:

Se o carimbo de data/hora atual estiver 14 dias atrasado ou adiantado em relação ao armazenado no segmento .data, o criptografador sairá com o seguinte erro:

Err: LICEXPR => <c>1668595744 <l>[encrypted hardcoded timestamp] <d>[hardcoded timestamp]

<c>1668595744sendo o timestamp atual.

Como você provavelmente adivinhou, é um mecanismo muito simples para impedir que essa amostra específica seja executada fora do período esperado de execução planejado pelos invasores.

Essa funcionalidade não está presente no código-fonte do Babuk ESX. Portanto, achamos que é específico do PrideLocker.

Grupo de discussão

A manipulação do encadeamento é a mesma do código-fonte do Babuk ESX, exceto que o número de encadeamentos pode ser personalizado na linha de comando com a opção -t.

Desligamento de máquinas virtuais

O PrideLocker cria um arquivo temporário chamado /tmp/stopall.sh. Ele contém o seguinte script de shell:

for i in $(esxcli vm process list 2>/dev/null| grep 'World ID:' | grep -o '[0-9]*'); do esxcli vm process kill --type=force --world-id=$i; done;

Este script é executado e removido.

É comum ver o uso de esxclicomandos em criptografadores ESXi para desligar as máquinas virtuais antes de criptografá-las 9 . No entanto, essa funcionalidade não estava presente no código-fonte do Babuk ESX. A propósito, tanto o caminho do script /tmp/stopall.shquanto o escxlicomando estão em texto não criptografado no segmento de dados do ransomware, então podemos usá-lo para a detecção!

Processo de criptografia

A nota de resgate é criada no caminho especificado para criptografar (o padrão é /vmfs/volumes). O nome do arquivo é HOW TO RECOVER YOUR FILES.txt. Seu conteúdo foi detalhado na seção Nota de resgate.

Em seguida, o PrideLocker verifica recursivamente o caminho para criptografar. Somente arquivos com as seguintes extensões de nome de arquivo são direcionados:

.log
.vmdk
.vmem
.vswp
.vmsn
.vib
.vbm
.vbk

Ao contrário do criptografador Babuk ESX, o PrideLocker adiciona três novas extensões de nome de arquivo que visam os arquivos de backup do Veeam Agent 10 :

  • .vib: arquivos de backup incremental que armazenam alterações incrementais de imagens VM,
  • .vbm: arquivos de metadados de backup que armazenam informações sobre a tarefa de backup,
  • .vbk: os arquivos de backup completos que armazenam cópias de imagens VM completas.

Quando um arquivo corresponde a uma dessas extensões, ele é criptografado em um novo thread.

Algoritmo de criptografia

A rotina de criptografia usada pelo PrideLocker é a mesma do Babuk ESX e do CheersCrypt 5 , então não darei uma descrição completa do algoritmo. Ele usa a cifra de fluxo SOSEMANUK para criptografar arquivos. O algoritmo ECDH (X25519), combinado com SHA256, é usado para gerar a chave SOSEMANUK. Na figura abaixo, o lado esquerdo é a rotina de criptografia conforme descrito no código-fonte Babuk ESX, e o lado direito é a versão descompilada da rotina de criptografia PrideLocker.

Rotina de criptografia PrideLocker vs Babuk
Figura 7 – Rotina de criptografia PrideLocker vs Babuk

Os arquivos criptografados são renomeados com a .encryptedextensão.

A amostra foi removida, portanto, quando analisei esse malware pela primeira vez, foi difícil reconhecer os algoritmos SOSEMANUK e ECDH. Por isso, dei esse malware ao meu colega Eloi Benoist-vanderbeken, que conseguiu determinar a rotina de criptografia completa. Graças a isso, a semelhança com Babuk ESX tornou-se óbvia. A seção de detecção fornece dicas e regras para ajudar a detectar esses algoritmos de criptografia.

Estatísticas

Ao final da execução são impressas as estatísticas de como ela foi executada, indicando alguns números. Abaixo está um exemplo do que é impresso, se o modo detalhado -vestiver habilitado:

Stats:
        found files:             142
        encrypted files:         54
        skipped files:           72
        failed files:            06

Total encrypted volume: 123.0 GiB

Essa funcionalidade já estava presente no Babuk ESX, as strings são apenas um pouco diferentes.

DETECÇÃO

O seguinte padrão ajuda a detectar o algoritmo ECDH (ou Curve25519):

u_priv[0] &= 248;
u_priv[31] &= 127;
u_priv[31] |= 64;

Essas instruções limpam os bits 0, 1, 2 do primeiro byte, limpam o bit 7 do último byte e ativam o bit 6 do último byte da chave secreta gerada. Sua finalidade é por motivos de segurança do algoritmo Curve25519, conforme definido no artigo de David Bernstein 11 .

Com relação à detecção de SOSEMANUK, a constante 0x54655307 é utilizada para atualizar sua máquina de estados finitos 12 . 0x54655307 é a representação hexadecimal das primeiras dez casas decimais de π. Não encontrei nenhum uso dessa constante além de SOSEMANUK. Além disso, existem arrays de dois bytes, que – creio eu – estão relacionados à multiplicação polinomial usada para atualizar o registrador de deslocamento 13 . De qualquer forma, eles são ótimos para detectar a capacidade de criptografia SOSEMANUK.

Regra PrideLocker Yara

Abaixo está uma regra da Yara cujo objetivo é detectar amostras semelhantes do PrideLocker:

rule Linux_Ransomware_PrideLocker 
{
    meta:
        author = "Theo Letailleur, Synacktiv"
        source = "Synacktiv"
        status = "RELEASED"
        sharing = "TLP:WHITE"
        category = "MALWARE"
        malware = "PrideLocker"
        description = "Yara rule that detects PrideLocker ransomware"

    strings:
        // for i in $(esxcli vm process list 2>/dev/null| grep 'World ID:' | grep -o '[0-9]*'); do esxcli vm process kill --type=force --world-id=$i; done;
        $shut_down_esxi = {
            66 6F 72 20 69 20 69 6E 20 24 28 65 73 78 63 6C 69 20 76 6D 20 70 72 6F 63 65 73 
            73 20 6C 69 73 74 20 32 3E 2F 64 65 76 2F 6E 75 6C 6C 7C 20 67 72 65 70 20 27 57 
            6F 72 6C 64 20 49 44 3A 27 20 7C 20 67 72 65 70 20 2D 6F 20 27 5B 30 2D 39 5D 2A 
            27 29 3B 20 64 6F 20 65 73 78 63 6C 69 20 76 6D 20 70 72 6F 63 65 73 73 20 6B 69 
            6C 6C 20 2D 2D 74 79 70 65 3D 66 6F 72 63 65 20 2D 2D 77 6F 72 6C 64 2D 69 64 3D 
            24 69 3B 20 64 6F 6E 65 3B
        }
        // Load "/tmp/stopall.sh" string
        $shut_down_esxi_load_filename = {
            48 B? 2F 74 6D 70 2F 73 74 6F // mov     r64, 6F74732F706D742Fh
            48 89 ?? ??                   // mov     qword ptr [rbp+?], r64
            48 B? 70 61 6C 6C 2E 73 68 00 // mov     r64, 68732E6C6C6170h
            48 89 ?? ??                   // mov     [rbp+?], r64
        }
        $x25519_clear_set_bits = {
            0F B6 ?? [1-4]  // movzx   r32, [rbp+?]
            83 ?? F8        // and     r32, 0FFFFFFF8h
            88 ?? [1-4]     // mov     [rbp+?], r8
            0F B6 ?? [1-4]  // movzx   r32, [rbp+?]
            83 ?? 7F        // and     r32, 7Fh
            88 ?? [1-4]     // mov     [rbp+?], r8
            0F B6 ?? [1-4]  // movzx   r32, [rbp+?]
            83 ?? 40        // or      r32, 40h
            88 ?? [1-4]     // mov     [rbp+?], r8
            ??
        }
        // Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
        $sosemanuk_encrypt_mul_a = {
            00 00 00 00 E1 9F CF 13 6B 97 37 26 8A 08 F8 35 D6 87 6E 4C 37 18 A1 5F BD 10 59 
            6A 5C 8F 96 79 05 A7 DC 98 E4 38 13 8B 6E 30 EB BE 8F AF 24 AD D3 20 B2 D4 32 BF 
            7D C7 B8 B7 85 F2 59 28 4A E1 0A E7 11 99 EB 78 DE 8A 61 70 26 BF 80 EF E9 AC DC 
            60 7F D5 3D FF B0 C6 B7 F7 48 F3 56 68 87 E0 0F 40 CD 01 EE DF 02 12 64 D7 FA 27 
            85 48 35 34 D9 C7 A3 4D 38 58 6C 5E B2 50 94 6B 53 CF 5B 78
        }
        // DWORD array version
        $sosemanuk_encrypt_mul_a_4byte_array_le = {
            00 00 00 00 13 CF 9F E1 26 37 97 6B 35 F8 08 8A 4C 6E 87 D6 5F A1 18 37 6A 59 10 
            BD 79 96 8F 5C 98 DC A7 05 8B 13 38 E4 BE EB 30 6E AD 24 AF 8F D4 B2 20 D3 C7 7D 
            BF 32 F2 85 B7 B8 E1 4A 28 59 99 11 E7 0A 8A DE 78 EB BF 26 70 61 AC E9 EF 80 D5 
            7F 60 DC C6 B0 FF 3D F3 48 F7 B7 E0 87 68 56 01 CD 40 0F 12 02 DF EE 27 FA D7 64 
            34 35 48 85 4D A3 C7 D9 5E 6C 58 38 6B 94 50 B2 78 5B CF 53
        }
        // Multiplication by 1/alpha: 1/alpha * x = (x >> 8) ^ mul_ia[x & 0xFF]
        $sosemanuk_encrypt_mul_ia = {
            00 00 00 00 18 0F 40 CD 30 1E 80 33 28 11 C0 FE 60 3C A9 66 78 33 E9 AB 50 22 29 
            55 48 2D 69 98 C0 78 FB CC D8 77 BB 01 F0 66 7B FF E8 69 3B 32 A0 44 52 AA B8 4B 
            12 67 90 5A D2 99 88 55 92 54 29 F0 5F 31 31 FF 1F FC 19 EE DF 02 01 E1 9F CF 49 
            CC F6 57 51 C3 B6 9A 79 D2 76 64 61 DD 36 A9 E9 88 A4 FD F1 87 E4 30 D9 96 24 CE 
            C1 99 64 03 89 B4 0D 9B 91 BB 4D 56 B9 AA 8D A8 A1 A5 CD 65
        }
        // DWORD array version
        $sosemanuk_encrypt_kk_mul_ia_4byte_array_le = {
            00 00 00 00 CD 40 0F 18 33 80 1E 30 FE C0 11 28 66 A9 3C 60 AB E9 33 78 55 29 22 
            50 98 69 2D 48 CC FB 78 C0 01 BB 77 D8 FF 7B 66 F0 32 3B 69 E8 AA 52 44 A0 67 12 
            4B B8 99 D2 5A 90 54 92 55 88 31 5F F0 29 FC 1F FF 31 02 DF EE 19 CF 9F E1 01 57 
            F6 CC 49 9A B6 C3 51 64 76 D2 79 A9 36 DD 61 FD A4 88 E9 30 E4 87 F1 CE 24 96 D9 
            03 64 99 C1 9B 0D B4 89 56 4D BB 91 A8 8D AA B9 65 CD A5 A1
        }

    condition:
        uint32(0) == 0x464C457F and
        (
            $shut_down_esxi and $shut_down_esxi_load_filename
            and $x25519_clear_set_bits 
            and 2 of ($sosemanuk_encrypt_*)
        )
}

Você pode encontrar a regra Yara em nosso repositório Github: https://github.com/synacktiv/pridelocker-analysis

As condições podem ser um pouco mais flexíveis (por exemplo, entre as regras $shut_down e as regras criptográficas) para detectar mais variantes.

Regras ECDH e SOSEMANUK CAPA

CAPA 14 é uma ferramenta desenvolvida pela equipe Mandiant FLARE que detecta recursos em arquivos executáveis.

Para detectar o algoritmo ECDH, já existe uma regra CAPA da Mandiant nomeada encrypt data using Curve25519por Dimiter Andonov 15 que ajuda a detectar a função de criptografia.

Para detectar o algoritmo Sosemanuk, há também uma regra CAPA da Mandiant nomeada encrypt data using Sosemanukpor Andrew Williams 16 que faz um bom trabalho detectando a função de criptografia. Novas regras de CAPA para detectar sosemanuk_schedulesosemanuk_initfuncionar podem ser adicionadas.

CONCLUSÃO

O criptografador PrideLocker ESX é um fork do criptografador Babuk ESX que traz novos recursos: ofuscação de string, desligamento de máquinas virtuais usando esxcli, argumentos de linha de comando opcionais e uma “licença” limitada por tempo. A nota de resgate mostra que o afiliado usando o Dagon Locker e envolvido em nossa resposta a incidentes também está usando o PrideLocker para atingir os servidores ESXi, mas não podemos dizer se há um link entre os desenvolvedores de ambos os criptografadores.

Com base nessa análise de amostra do PrideLocker, uma metodologia usando IDAPython para automatizar a descriptografia de strings foi detalhada.

Por fim, as dicas para detectar os algoritmos ECDH e Sosemanuk abordados neste artigo podem ajudar a detectar outras famílias recentes de ransomware baseadas nos criptografadores vazados do Babuk.