visão geral
Em 25 de março de 2021, o sistema BotMon da 360 NETLAB sinalizou um arquivo SUSPEITOELF (MD5=64f6cfe44ba08b0babdd3904233c4857) com detecção de 0 VT, a amostra se comunica com 4 domínios no TCP 443 (HTTPS), mas o tráfego não é de TLS/SLS. Uma olhada de perto na amostra revelou que é um backdoor voltado para sistemas Linux X64, uma família que existe há pelo menos 3 anos.
Nós o chamamos de RotaJakiro com base no fato de que a família usa criptografia rotatina e se comporta de forma diferente para quando executada.root/non-root accounts
RotaJakiro
presta bastante atenção para esconder suas trilhas, usando vários algoritmos de criptografia, incluindo: o uso de algoritmo AES para criptografar as informações de recursos dentro da amostra; Comunicação C2 usando uma combinação de e .AES, XOR, ROTATE encryption
ZLIB compression
RotaJakiro
suporta um total de 12 funções, três das quais estão relacionadas à execução de Plugins específicos. Infelizmente, não temos visibilidade para os plugins e, portanto, não sabemos seu verdadeiro propósito. De uma perspectiva ampla de backdoor, as funções podem ser agrupadas nas quatro categorias seguintes.
- Relatar informações do dispositivo
- Roubando informações confidenciais
- Gerenciamento de arquivos/plugin (consulta, download, exclusão)
- Execução de Plugin específico
Mais alguma coisa lá fora?
Com a amostra que temos, descobrimos as seguintes 4 amostras, todas com 0 detecções em VT, e a primeira vez vista em VT é em 2018.
FILENAME | MD5 | DETECÇÃO | VISTO PELA PRIMEIRA VEZ EM VT |
---|---|---|---|
sistemad-daemon | 1d45cd2c1283f927940c099b8fab593b | 0/61 | 2018-05-16 04:22:59 |
sistemad-daemon | 11ad1e9b74b144d564825d65d7fb37d6 | 0/58 | 2018-12-25 08:02:05 |
sistemad-daemon | 5c0f375e92f551e8f2321b141c15c48f | 0/56 | 2020-05-08 05:50:06 |
gvfsd-helper | 64f6cfe44ba08b0babdd3904233c4857 | 0/61 | 2021-01-18 13:13:19 |
Todas essas amostras têm os seguintes 4 C2s incorporados. Esses 4 domínios C2 têm tempo muito próximo, os leitores notarão que os dados de classificação foram em dezembro de 2015, há 6 anos.Crteated,Updated and Expired
DOMÍNIO | DETECÇÃO | CRIADO | ÚLTIMA ATUALIZAÇÃO | EXPIRADO |
---|---|---|---|---|
news.thaprior.net | 0/83 | 2015-12-09 06:24:13 | 2020-12-03 07:24:33 | 2021-12-09 06:24:13 |
blog. eduelects. com | 0/83 | 2015-12-10 13:12:52 | 2020-12-03 07:24:33 | 2021-12-10 13:12:52 |
cdn.mirror-codes.net | 0/83 | 2015-12-09 06:24:19 | 2020-12-03 07:24:32 | 2021-12-09 06:24:19 |
status.sublineover.net | 0/83 | 2015-12-09 06:24:24 | 2020-12-03 07:24:32 | 2021-12-09 06:24:24 |
Análise Reversa
As 4 amostras do RotaJakiro, com distribuição de tempo de 2018 a 2021, estão muito próximas de suas funções, e a amostra de 2021 é selecionada para análise neste blog, que possui as seguintes informações básicas:
MD5:64f6cfe44ba08b0babdd3904233c4857
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, stripped
Packer:No
At the coding level
, o RotaJakiro utiliza técnicas como AES dinâmicos, protocolos de comunicação criptografados de duas camadas para neutralizar a análise binária e de tráfego de rede.
, o RotaJakiro primeiro determina se o usuário é raiz ou não no tempo de execução, com diferentes políticas de execução para diferentes contas, em seguida, descriptografa os recursos sensíveis relevantes usando AES& ROTATE para posterior , e uso, e finalmente estabelece comunicação com C2 e aguarda a execução de comandos emitidos pelo C2.At the functional level
persistence
process guarding
single instance
A seguir, analisará a implementação específica do RotaJakiro na perspectiva acima.
0x00: Truques usados pela amostra
- Gere dinamicamente uma tabela de constantes exigidas pelo algoritmo de criptografia AES para evitar que o algoritmo seja diretamente identificado
- Use a técnica de ofuscação de strings de pilha para armazenar informações de recursos confidenciais criptografadas
- Comunicação de rede usando criptografia de camada dupla
0x01: Algoritmo de criptografia
Todos os recursos sensíveis no RotaJakiro são criptografados, e no IDA podemos ver que o método de descriptografia dec_proc é chamado 60 vezes, que é composto por AES e Rotate. A entrada de descriptografia AES
é a seguinte: Onde está o AES-256, o modo CBC, a chave e o iv são codificados.aes_dec
- chave
14 BA EE 23 8F 72 1A A6 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- Iv
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A entrada de descriptografia rotata é mostrada abaixo:
A chamada Rotação é uma mudança cíclica, podemos ver que o número de turnos é determinado pelo valor de .plain_len(length of plaintext) &7
Tome o seguinte texto de cifra C2 como exemplo.
ff ba a2 3b cd 5b 7b 24 8c 5f e3 4b fc 56 5b 99
ac 91 cf e3 9a 27 d4 c9 6b 39 34 ce 69 ce 18 60
Os vários parâmetros relacionados à descriptografia são mostrados abaixo, o comprimento do texto cifrado é de 32 bytes e o comprimento do texto simples é de 26 bytes. Primeiro, descriptografando com AES, temos o seguinte “sub-cifra”.
Em seguida, o texto de cifra válido é extraído do texto sub-cifra, onde o texto de cifra válido começa a partir do 8º byte, e o comprimento é o comprimento do texto simples menos 8, que é 26-8=18 bytes aqui.
98 1B DB D9 8B 59 19 5D 59 1B 59 D8 1D DC 8B D8
DB 5B
Finalmente,podemos calcular 26 (o comprimento do texto simples é 26)&7=2, e obter o número de turnos, e mudar o texto de cifra acima válido byte byte por 2 bits para obter c2 plaintext.
blog.eduelects.com
0x02: Persistência
O RotaJakiro faz uma distinção entre os usuários ao implementar recursos de persistência, e diferentes técnicas são usadas para diferentes contas.root/non-root
conta raiz
- Dependendo da distribuição Linux, crie o script de auto-partida correspondente ou .
/etc/init/systemd-agent.conf
/lib/systemd/system/sys-temd-agent.service
Content of systemd-agent.conf ----------------------------- #system-daemon - configure for system daemon #This service causes system have an associated #kernel object to be started on boot. description "system daemon" start on filesystem or runlevel [2345] exec /bin/systemd/systemd-daemon respawn
Content of systemd-agent.service ----------------------------- [Unit] Description=System Daemon Wants=network-online.target After=network-online.target [Service] ExecStart=/usr/lib/systemd/systemd-daemon Restart=always [Install]
- O nome do arquivo usado para o disfarce é um dos dois seguintes.
/bin/systemd/systemd-daemon /usr/lib/systemd/systemd-daemon
conta não raiz
- Crie script de inicialização automática para ambiente de desktop
$HOME/.config/au-tostart/gnomehelper.desktop
[Desktop Entry] Type=Application Exec=$HOME/.gvfsd/.profile/gvfsd-helper
- Modifique o arquivo para criar o script de inicialização automática para o ambiente shell
.bashrc
# Add GNOME's helper designed to work with the I/O abstraction of GIO # this environment variable is set, gvfsd will not start the fuse filesystem if [ -d ${HOME} ]; then ${HOME}/.gvfsd/.profile/gvfsd-helper fi
- O nome do arquivo usado para o disfarce, ambos existem ao mesmo tempo
$HOME/.dbus/sessions/session-dbus $HOME/.gvfsd/.profile/gvfsd-helper
0x03:Guarda de processos
O RotaJakiro implementa a guarda de processos para proteger sua própria operação, e como a persistência, existem diferentes implementações para os usuários.root/non-root
conta raiz
Ao ser executado sob a conta raiz, dependendo da distribuição Linux, um novo processo é criado automaticamente quando o processo de serviço é encerrado escrevendo para o arquivo de configuração do serviço.
O resultado real é mostrado na figura abaixo, onde você pode ver que um novo processo é criado imediatamente após o processo de sistema-daemon ser
encerrado.Restart=always or respawn
conta não raiz
Ao executar sob uma conta não raiz, o RotaJakiro gera dois processos e , que monitoram a sobrevivência um do outro e os restauram quando um deles é encerrado, o que é muito típico da proteção de dois processos.session-dbus
gvfsd-helper
Como a proteção de dois processos do RotaJakiro é implementada?
Primeiro,ele cria um pedaço de memória compartilhada com o , e session-dbus e gvfsd-helper se comunicam entre si através desta memória compartilhada, dizendo uns aos outros seus PIDs.
Então,dinamicamente buscando a sobrevivência do processo através do diretório. Quando o outro processo é encontrado morto, o processo é criado pela API execvp para ajudar o processo morto a “ressuscitar”, como mostrado no diagrama a seguir.
O efeito real é mostrado na figura abaixo, você pode ver que depois que session-dbus e gvfsd-helper são terminados por kill -9, novos processos são criados
imediatamente.shmget API
/proc/[PID]
0x04: Instância única
RotaJakiro implementa uma única instância por bloqueio de arquivos, como mostrado abaixo.
O arquivo de bloqueio usado neste difere sob a conta raiz/não-raiz.
- O arquivo de bloqueio sob raiz, um será criado.
/usr/lib32/.X11/X0-lock /bin/lib32/.X11/X0-lock
- O arquivo de bloqueio sob não-raiz, ambos serão criados.
$HOME/.X11/X0-lock $HOME/.X11/.X11-lock
Na conta real não raiz, por exemplo, os processos e travas de arquivo podem ser combinados com , e, em seguida, a amostra rotaJakiro correspondente é executada./proc/locks
0x05: Comunicação em rede
RotaJakiro estabelece comunicação com C2 através do seguinte trecho de código, aguardando a execução de comandos subsequentes.
Este processo pode ser dividido em 2
etapas
- Estágio 1, fase
de inicialização Descriptografar a lista C2, estabelecer uma conexão com C2, enviar as informações on-line, receber e descriptografar as informações devolvidas pelo C2. - Estágio 2, aguarde
chamadas C2 Verifique as informações devolvidas pelo C2, caso passe na verificação, execute as instruções subsequentes enviadas pelo C2.
Estágio 1: Inicialização
A lista C2 é descriptografada pelo algoritmo de descriptografia descrito na seção anterior, e os quatro C2s a seguir são incorporados na amostra no momento.
news.thaprior.net
blog.eduelects.com
cdn.mirror-codes.net
status.sublineover.net
RotaJakiro primeiro tentará estabelecer uma conexão com eles e, em seguida, construirá a mensagem golive pelo trecho de código a seguir. Em seguida, ele criptografa as informações golive e envia-as para os C2s
Finalmente, ele recebe o pacote de volta do C2, descriptografa-o e verifica sua legitimidade, e se ele passa a verificação, ele vai para o Estágio 2.
Estágio 2: Operações específicas
Receba e execute o comando a partir do C2 através do seguinte codesnippet.
Atualmente, o RotaJakiro suporta um total de 12 instruções, e a correspondência entre o código de instrução e a função é mostrada na tabela a
seguir.
CMDID | FUNÇÃO |
---|---|
0x138E3E6 | sair |
0x208307A | teste |
0x5CCA727 | batimento cardíaco |
0x17B1CC4 | Defina o tempo de tempo limite de C2 |
0x25360EA | Roubar informações sensuais |
0x18320e0 | Enviar informações do dispositivo |
0x2E25992 | Entregar arquivo/plugin |
0x2CD9070 | Status de arquivo/plugin de consulta |
0x12B3629 | Excluir arquivo/plugin ou dir |
0x1B25503 | Executar Plugin_0x39C93E |
0x1532E65 | Executar Plugin_0x75A7A2 |
0x25D5082 | Executar Plugin_0x536D01 |
A função Executar Plugin reutiliza o mesmo código e implementa a chamada de função através da lógica a seguir.
No momento, não estamos capturando tais cargas, por isso usamos o formulário para representar diferentes tarefas.Plugin_"parameter"
análise do pacote de 0x06
O pacote de comunicação de rede do RotaJakiro consiste em três partes: .
é obrigatório e 82 bytes de comprimento, e as peças são opcionais.
são criptografados com XOR & Rotate, e é criptografado com Compressão AES & ZLIB.
A seguir, ilustraremos a composição do tráfego de rede e o processo de descriptografia através de uma rodada de interação entre Bot e C2.Head, Key, Payload
Head
Key & Payload
Head & Key
Payload
head&key&payload
C2 -> Bot
Os primeiros 0x52 bytes são o conteúdo do Cabeça. Como decifrar a cabeça? Muito simples, . Depois da descriptografia, podemos obter o seguinte conteúdo.shift 3 bits left byte by byte, and then XOR with 0x1b
00000000 16 11 10 b9 03 b1 0c fb 04 20 00 00 00 08 00 e0 |...¹.±.û. .....à|
00000010 20 83 01 c2 20 64 20 01 e2 00 00 00 00 c2 0c 00 | .. d .â....Â..|
00000020 00 00 32 42 36 39 33 33 34 46 38 34 31 44 30 44 |..2B69334F841D0D|
00000030 39 46 41 30 36 35 38 45 43 33 45 32 39 46 41 44 |9FA0658EC3E29FAD|
00000040 34 39 c8 53 e6 9c 48 c4 8b 77 24 2e 02 1c 96 d9 |49ÈSæ.HÄ.w$....Ù|
00000050 81 28
------------filed parse------------------
offset 0x09, 4 bytes--->payload length
offset 0x0d, 2 bytes--->body length
offset ox0f, 4 bytes--->cmdid
Através da análise de campo, podemos saber que o comprimento da chave é 0x8 bytes, o comprimento da carga é 0x20 bytes, e o código de instrução a ser executado é 0x18320e0, ou seja, o . Ler 8 bytes de offset 0x52 dá à Chave, e usando o mesmo método de descriptografia que a cabeça, nós recebemos , que é usado como a chave AES para descriptografar a Carga Útil.report device information
ea 9a 1a 18 18 44 26 a0
4c cf cb dbdb 39 2a 1e
Ler 32 bytes de offset 0x5a nos dá a seguinte carga útil.
54 c1 c3 69 00 18 31 e4 a2 5b 10 7f 67 ab d1 4b
b2 7b 3d 3f b3 bc 66 6a 26 f6 f6 b3 f7 2e 66 6d
Usando a chave descriptografada como a tecla AES-256, descriptografe os dados acima no modo CBC para obter o seguinte conteúdo.
3b c7 f8 9b 73 2b d1 04 78 9c e3 60 60 60 d8 df d9 c1 71 56 f7 6f 00 00 13 80 04 28
O 8º byte em diante são dados compactados ZLIB, descomprimidos para obter o seguinte conteúdo.
08 00 00 00 bf 89 88 08 cd 2d fd 50
------------filed parse------------------
offset 0, 4 bytes--->length
Qual é o uso da Carga Útil descomprimida? Ele é usado como uma nova chave AES para descriptografar algumas informações confidenciais de recursos.bf 89 88 08 cd 2d fd 50
Por exemplo, quando o Bot coleta informações do dispositivo, uma das informações é a distribuição atual do SO, que é implementada pelo comando.cat /etc/*release | uniq
root@debian:~# cat /etc/*release | uniq
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
O comando é o resultado do seguinte texto cifradocat /etc/*release | uniq
"cat /etc/*release | uniq" cmd_ciphertxt
---------------------------
74 00 dd 79 e6 1e aa bb 99 81 7e ca d9 21 6b 81
6b d9 9d 14 45 73 6a 1c 61 cc 28 a3 0f 2b 41 5a
6b 33 8c 37 25 89 47 05 44 7e f0 6b 17 70 d8 ca
descriptografado com a figura a seguir.new AES key and the parameters
Bot -> C2
Quando o BOT receber o comando “informações do dispositivo de relatório” do C2, ele enviará os seguintes dados para C2, e você poderá ver que o valor da parte chave ainda está .
O valor-chave descriptografado é
. Depois de descriptografar e descomprimir a carga enviada pelo Bot para C2, obtemos os seguintes dados, que são as várias informações do dispositivo, incluindo as informações obtidas pelo mencionado anteriormente, o que verifica que nossa análise está correta.ea 9a 1a 18 18 44 26 a0
4c cf cb db db 39 2a 1e
cat /etc/*release | uniq
Relacionamento com o Botnet Torii
A botnet Torii foi exposta pela Avast em 20 de setembro de 2018, e notamos que existem algumas semelhanças entre os dois, por exemplo:
1: Semelhança de cordas
Depois de descriptografar os recursos sensíveis do RotaJakiro & Torii, descobrimos que eles reutilizam muitos dos mesmos comandos.
1:semanage fcontext -a -t bin_t '%s' && restorecon '%s'
2:which semanage
3:cat /etc/*release
4:cat /etc/issue
5:systemctl enable
6:initctl start
...
2: Similaridade do tráfego
No processo de construção do fluxo, um grande número de constantes são utilizadas e os métodos de construção estão muito próximos.
3: Similaridade funcional
Do ponto de vista da engenharia reversa, a RotaJakiro & Torii compartilham estilos semelhantes: o uso de algoritmos de criptografia para ocultar recursos sensíveis, a implementação de um estilo de persistência bastante antiquado, tráfego de rede estruturado, etc.
Não sabemos exatamente a resposta, mas parece que RotaJakiro e Torii têm algumas conexões.
A ponta do iceberg
Enquanto isso conclui nossa análise do RotaJakiro, o verdadeiro trabalho está longe de acabar, e muitas perguntas permanecem sem resposta: “Como o RotaJakiro se espalhou, e qual era o seu propósito?” , “O RotaJakiro tem um alvo específico?”, Adoraríamos saber se a comunidade tem pistas relevantes.
Entre em contato conosco
Os leitores são sempre bem-vindos para nos contatar no twitter, ou e-mail para netlabat[at]360.cn.
coi
Amostra MD5
1d45cd2c1283f927940c099b8fab593b
11ad1e9b74b144d564825d65d7fb37d6
5c0f375e92f551e8f2321b141c15c48f
64f6cfe44ba08b0babdd3904233c4857
C2
news.thaprior.net:443
blog.eduelects.com:443
cdn.mirror-codes.net:443
status.sublineover.net:443
IP
176.107.176.16 Ukraine|Kiev|Unknown 42331|PE_Freehost
FONTE: NETLAB