Analisando Malware ELF Linux
Quando Usar
- Um servidor Linux ou contêiner foi comprometido e binários ELF suspeitos foram encontrados
- Analisando botnets Linux (Mirai, Gafgyt, XorDDoS), criptomineradores ou ransomware
- Investigando malware que ataca infraestrutura em nuvem, contêineres Docker ou pods Kubernetes
- Engenharia reversa de rootkits Linux e módulos de kernel
- Analisando malware multiplataforma compilado para Linux x86_64, ARM ou MIPS
Não use para análise de binários PE do Windows; use PEStudio, Ghidra ou IDA para malware Windows.
Pré-requisitos
- Ghidra ou IDA com suporte a ELF Linux para desmontagem e descompilação
- VM de análise Linux (Ubuntu 22.04 recomendado) com ferramentas de desenvolvimento instaladas
- strace, ltrace e GDB para análise dinâmica e depuração
- readelf, objdump e nm do GNU binutils para inspeção estática
- Radare2 para triagem rápida de binários e análise scriptada
- Docker para execução isolada de malware em contêiner
Fluxo de Trabalho
Passo 1: Identificar Propriedades do Binário ELF
Examine o cabeçalho ELF e as propriedades básicas:
# Identificação do tipo de arquivo
file binario_suspeito
# Análise detalhada do cabeçalho ELF
readelf -h binario_suspeito
# Cabeçalhos de seção
readelf -S binario_suspeito
# Cabeçalhos de programa (segmentos)
readelf -l binario_suspeito
# Tabela de símbolos (se não removido)
readelf -s binario_suspeito
nm binario_suspeito 2>/dev/null
# Informações de vinculação dinâmica
readelf -d binario_suspeito
ldd binario_suspeito 2>/dev/null # Apenas na arquitetura correspondente!
# Calcular hashes
md5sum binario_suspeito
sha256sum binario_suspeito
# Verificar empacotamento/UPX
upx -t binario_suspeito
# Análise ELF baseada em Python
from elftools.elf.elffile import ELFFile
import hashlib
with open("binario_suspeito", "rb") as f:
dados = f.read()
sha256 = hashlib.sha256(dados).hexdigest()
with open("binario_suspeito", "rb") as f:
elf = ELFFile(f)
print(f"SHA-256: {sha256}")
print(f"Classe: {elf.elfclass}-bit")
print(f"Endianness: {'Little' if elf.little_endian else 'Big'}")
print(f"Máquina: {elf.header.e_machine}")
print(f"Tipo: {elf.header.e_type}")
print(f"Ponto de Entrada: 0x{elf.header.e_entry:X}")
# Verificar se foi removido
symtab = elf.get_section_by_name('.symtab')
print(f"Removido: {'Sim' if symtab is None else 'Não'}")
# Análise de entropia das seções
import math
from collections import Counter
for secao in elf.iter_sections():
dados = secao.data()
if len(dados) > 0:
entropia = -sum((c/len(dados)) * math.log2(c/len(dados))
for c in Counter(dados).values() if c > 0)
if entropia > 7.0:
print(f" [!] Seção de alta entropia: {secao.name} ({entropia:.2f})")
Passo 2: Extrair Strings e Indicadores
Procure por IOCs incorporados e pistas de funcionalidade:
# Strings ASCII
strings binario_suspeito > strings_output.txt
# Procurar indicadores de rede
grep -iE "(http|https|ftp)://" strings_output.txt
grep -iE "([0-9]{1,3}\.){3}[0-9]{1,3}" strings_output.txt
grep -iE "[a-zA-Z0-9.-]+\.(com|net|org|io|ru|cn)" strings_output.txt
# Procurar comandos de shell
grep -iE "(bash|sh|wget|curl|chmod|/tmp/|/dev/)" strings_output.txt
# Procurar indicadores de criptomineração
grep -iE "(stratum|xmr|monero|pool\.|mining)" strings_output.txt
# Procurar roubo de SSH/credenciais
grep -iE "(ssh|authorized_keys|id_rsa|shadow|passwd)" strings_output.txt
# Procurar mecanismos de persistência
grep -iE "(crontab|systemd|init\.d|rc\.local|ld\.so\.preload)" strings_output.txt
# FLOSS para strings ofuscadas (se disponível)
floss binario_suspeito
Passo 3: Analisar Chamadas de Sistema e Uso de Bibliotecas
Identifique quais chamadas de sistema e bibliotecas o malware usa:
# Listar funções importadas (vinculação dinâmica)
readelf -r binario_suspeito | grep -E "socket|connect|exec|fork|open|write|bind|listen"
# Rastrear chamadas de sistema durante execução (apenas em VM isolada)
strace -f -e trace=network,process,file -o strace_output.txt ./binario_suspeito
# Rastrear chamadas de biblioteca
ltrace -f -o ltrace_output.txt ./binario_suspeito
# Principais chamadas de sistema a observar:
# Rede: socket, connect, bind, listen, accept, sendto, recvfrom
# Processo: fork, execve, clone, kill, ptrace
# Arquivo: open, read, write, unlink, rename, chmod
# Persistência: inotify_add_watch (monitoramento de arquivo)
Passo 4: Análise Dinâmica com GDB
Depure o malware para observar o comportamento em tempo de execução:
# Iniciar GDB com o binário
gdb ./binario_suspeito
# Definir breakpoints em funções-chave
(gdb) break main
(gdb) break socket
(gdb) break connect
(gdb) break execve
(gdb) break fork
# Executar e analisar
(gdb) run
(gdb) info registers # Visualizar estado dos registradores
(gdb) x/20s $rdi # Examinar argumento de string
(gdb) bt # Backtrace
(gdb) continue
# Para binários removidos, quebrar no ponto de entrada
(gdb) break *0x400580 # Ponto de entrada do readelf
(gdb) run
# Monitorar conexões de rede durante execução
# Em outro terminal:
ss -tlnp # Listar sockets em escuta
ss -tnp # Listar conexões estabelecidas
Passo 5: Engenharia Reversa com Ghidra
Realize análise profunda de código no binário ELF:
Análise Ghidra para ELF Linux:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Importar: File -> Import -> Selecionar binário ELF
- Ghidra detecta automaticamente o formato ELF e arquitetura
- Aceitar opções de análise padrão
2. Alvos-chave de análise:
- Função main() (ou ponto de entrada se removido)
- Funções de criação e conexão de socket
- Lógica de despacho de comandos (switch/case nos dados recebidos)
- Rotinas de criptografia/codificação
- Código de instalação de persistência
- Funções de auto-propagação/varredura
3. Para botnets do tipo Mirai, procure por:
- Lista de credenciais para força bruta (telnet/SSH)
- Seleção de módulo de ataque (UDP flood, SYN flood, ACK flood)
- Módulo de varredura (port scanning para dispositivos vulneráveis)
- Módulo exterminador (eliminando botnets concorrentes)
4. Para criptomineradores, procure por:
- Conexão com pool de mineração (protocolo stratum)
- Strings de endereço de carteira
- Funções de utilização de CPU/GPU
- Técnicas de ocultação de processo
Passo 6: Analisar Persistência Específica do Linux
Verifique mecanismos de persistência:
# Verificar rootkit via LD_PRELOAD
strings binario_suspeito | grep "ld.so.preload"
# Malware escrevendo em /etc/ld.so.preload pode interceptar todas as chamadas de biblioteca dinâmica
# Verificar persistência via crontab
strings binario_suspeito | grep -i "cron"
# Verificar criação de serviço systemd
strings binario_suspeito | grep -iE "systemd|\.service|systemctl"
# Verificar criação de script init
strings binario_suspeito | grep -iE "init\.d|rc\.local|update-rc"
# Verificar injeção de chave SSH
strings binario_suspeito | grep -i "authorized_keys"
# Verificar carregamento de módulo de kernel (rootkit)
strings binario_suspeito | grep -iE "insmod|modprobe|init_module"
# Verificar ocultação de processo
strings binario_suspeito | grep -iE "proc|readdir|getdents"
Conceitos-chave
| Termo | Definição |
|---|---|
| ELF (Formato Executável e Vinculável) | Formato binário padrão para executáveis Linux, bibliotecas compartilhadas e core dumps contendo cabeçalhos, seções e segmentos |
| Binário Removido | Binário ELF com símbolos de depuração removidos, tornando a engenharia reversa mais difícil, pois nomes de funções são perdidos |
| LD_PRELOAD | Variável de ambiente Linux que especifica bibliotecas compartilhadas a serem carregadas antes de todas as outras; abusada por rootkits para interceptar chamadas de biblioteca do sistema |
| strace | Rastreador de chamadas de sistema do Linux que registra todas as chamadas de sistema e sinais feitos por um processo, revelando operações de arquivo, rede e processo |
| GOT/PLT | Tabela de Deslocamento Global e Tabela de Vinculação de Procedimento; estruturas ELF para vinculação dinâmica que podem ser sequestradas para hooking de funções |
| Vinculação Estática | Binário compilado com todo o código de biblioteca incluído; comum em malware IoT para executar em sistemas sem bibliotecas compartilhadas correspondentes |
| Mirai | Botnet Linux prolífica que ataca dispositivos IoT via força bruta telnet; código-fonte vazado, levando a muitas variantes |
Ferramentas e Sistemas
- Ghidra: Ferramenta de engenharia reversa da NSA com suporte completo a ELF para x86, x86_64, ARM, MIPS e outras arquiteturas Linux
- Radare2: Framework de engenharia reversa de código aberto com interface de linha de comando para análise rápida de binários e scriptação
- strace: Ferramenta de rastreamento de chamadas de sistema do Linux para observar comportamento do binário, incluindo operações de arquivo, rede e processo
- GDB: Depurador GNU para definir breakpoints, examinar memória e percorrer a execução de binários Linux
- pyelftools: Biblioteca Python para analisar arquivos ELF programaticamente, útil para pipelines de análise automatizada
Cenários Comuns
Cenário: Analisando um Criptominerador Encontrado em um Servidor Linux Comprometido
Contexto: Um servidor em nuvem mostra 100% de uso de CPU. A investigação revela um binário desconhecido sendo executado a partir de /tmp com um nome suspeito. O binário precisa de análise para confirmar que é um criptominerador e identificar a carteira e o pool do invasor.
Abordagem:
- Copie o binário para uma VM de análise e calcule o hash SHA-256
- Execute
fileereadelfpara identificar a arquitetura e o tipo de vinculação - Extraia strings e procure por endereços de pool de mineração (stratum+tcp://) e endereços de carteira
- Execute com strace em um sandbox para observar conexões de rede (conexão com pool de mineração)
- Importe para o Ghidra para identificar o algoritmo de mineração e extração de configuração
- Verifique mecanismos de persistência (crontab, serviço systemd, chaves SSH)
- Documente todos os IOCs, incluindo endereço do pool, carteira, C2 para atualizações e artefatos de persistência
Armadilhas:
- Executar
lddno malware fora de um sandbox (ldd pode executar código no binário) - Não verificar arquitetura ARM/MIPS antes de tentar execução x86_64
- Ignorar scripts complementares (.sh) que podem lidar com persistência e limpeza
- Desconsiderar o vetor de acesso inicial (como o minerador foi implantado: força bruta SSH, exploração web, escape de contêiner)
Formato de Saída
RELATÓRIO DE ANÁLISE DE MALWARE ELF LINUX
============================================
Arquivo: /tmp/.X11-unix/.rsync
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Tipo: ELF 64-bit LSB executable, x86-64
Vinculação: Estática (todas as bibliotecas incorporadas)
Removido: Sim
Tamanho: 2.847.232 bytes
Empacotador: UPX 3.96 (descompactado para análise)
CLASSIFICAÇÃO
Família: Criptominerador XMRig (modificado)
Variante: Build personalizado com mecanismo de atualização C2
FUNCIONALIDADE
[*] Mineração de XMR (Monero) via algoritmo RandomX
[*] Conexão com pool Stratum para submissão de trabalho
[*] Check-in com C2 para atualizações de configuração
[*] Disfarce de nome de processo (argv[0] = "[kworker/0:0]")
[*] Eliminação de processos concorrentes (mata outros mineradores)
[*] Injeção de chave SSH para reacesso
INDICADORES DE REDE
Pool de Mineração: stratum+tcp://pool.minexmr[.]com:4444
Servidor C2: hxxp://update.malicious[.]com/config
Carteira: 49jZ5Q3b...Monero_Wallet_Address...
PERSISTÊNCIA
[1] Entrada crontab: */5 * * * * /tmp/.X11-unix/.rsync
[2] Chave SSH adicionada a /root/.ssh/authorized_keys
[3] Serviço systemd: /etc/systemd/system/rsync-daemon.service
[4] /etc/ld.so.preload modificado para ocultação de processo
OCULTAÇÃO DE PROCESSO
LD_PRELOAD: /usr/lib/.libsystem.so
Hook: readdir() para ocultar /tmp/.X11-unix/.rsync do ls
Hook: fopen() para ocultar da leitura de /proc/*/maps