
Un rootkit per kernel Linux in Rust che utilizza un ipervisore di tipo 2 personalizzato, programmi eBPF XDP e TC
BlackPill è un rootkit Linux furtivo realizzato in Rust.
Il rootkit è composto da più moduli (parlando di moduli Rust, non moduli del kernel):
L'architettura appare come segue:

Ed ecco come il codice malevolo viene eseguito dal C2 all'ospite VM:

Il C2 invia mnemonici x86_64 assemblati al rootkit, che poi li invia all'ospite VM per eseguirli. L'ospite VM è isolato dall'host e può essere utilizzato per eseguire codice malevolo.
Il kernel non vede i pacchetti malevoli in arrivo poiché vengono filtrati dal programma eBPF XDP e inviati al modulo LKM, mentre i pacchetti in uscita vengono modificati dal programma eBPF TC.
[!IMPORTANTE]
Questo progetto è ancora in fase di sviluppo. Non tutte le funzionalità sono funzionanti!
Sentiti libero di segnalare problemi o inviare richieste pull.
L'hooking è una capacità fondamentale del rootkit, implementata utilizzando kprobes nel kernel Linux. Questa tecnica intercetta e reindirizza l'esecuzione delle funzioni di sistema per monitorare o modificare il loro comportamento. Nel contesto di questo rootkit, kprobes fornisce un potente meccanismo per interagire con le funzioni del kernel senza alterare direttamente il codice sorgente.
Per garantire la furtività, il rootkit impiega due meccanismi primari anti-rilevamento:
Rimozione del Modulo dalla Lista dei Moduli del Kernel
Quando un modulo del kernel viene caricato, viene aggiunto alla lista dei moduli del kernel, visibile tramite strumenti come lsmod o /proc/modules. Per prevenire il rilevamento:
Hooking della funzione filldir64 per Nascondere una Directory Specifica
Per nascondere i file utilizzati dal rootkit, viene implementato un hook sulla funzione filldir64. Questa funzione viene invocata quando un processo legge il contenuto di una directory (ad es. tramite le syscall getdents o readdir).
filldir64 utilizzando kprobes./BLACKPILL-BLACKPILL (utilizzata per memorizzare file critici del rootkit), viene filtrata e non restituita all'utente.Utilizzo di programmi eBPF XDP e TC per Modificare il Traffico di Rete In entrata e In uscita
Per normalizzare le nostre comunicazioni di rete malevole, utilizziamo programmi eBPF XDP (eXpress Data Path) e TC (Traffic Control). In questo modo, possiamo:
Il nostro semplice hypervisor è stato implementato seguendo questi passaggi:
Configurazione iniziale del sistema
Entrata in modalità VMX o SVM
Gestione delle transizioni tra Host e Ospite
Creazione del Sistema Ospite
Comunicazione
La persistenza è una capacità critica di qualsiasi rootkit, che gli consente di mantenere il controllo sul sistema di destinazione anche dopo un riavvio.
Nella sua implementazione attuale, il meccanismo di persistenza dimostra la sua funzionalità creando un file di prova nel filesystem utilizzando il comando /bin/touch. Questa azione placeholder mostra la capacità del rootkit di eseguire operazioni privilegiate e può essere estesa per implementare strategie di persistenza più avanzate.
Ora è inutile poiché non è la nostra priorità creare un rootkit di livello APT, ma piuttosto fare più ricerca su concetti meno visti.
Prima di compilare il nostro rootkit sono necessari diversi passaggi. L'ambiente di sviluppo è composto da:
Inizia clonando il repository e i suoi sottomoduli shallow:
git clone [email protected]:DualHorizon/blackpill.git --recursive --depth 1
Su una distribuzione basata su Arch:
sudo pacman -S qemu-base qemu-desktop docker grub
Su una distribuzione Linux basata su Arch, installa Rust e altre dipendenze:
sudo pacman -S rust rust-src rust-bindgen
sudo pacman -S clang lld llvm
Poi avremo bisogno dei sorgenti Rust e di bindgen:
rustup component add rust-src clippy rustfmt
cargo install --locked bindgen-cli
Assicurati di poter iniziare a compilare il tuo kernel con Rust eseguendo nella cartella linux/:
$ cd blackpill
$ pushd linux
$ make LLVM=1 rustavailable
Rust is available!
$ popd
Avvia l'attività di configurazione iniziale che configura e compila il kernel:
make first-time-setup
[!IMPORTANTE]
Se ti vengono chieste opzioni personalizzate, premi Invio ogni volta.
Puoi compilare il modulo del kernel Rust (out-of-tree) con:
make