# Rootkit linux 5.6+ ## Fonctionnalités * Hook les appels systèmes `write`, `openat`, `getdents64` * Canal de communication dans `/dev/null` * Élévation des privilèges (devenir root) * Cacher le LKM (Linux Kernel Module) * Révéler le LKM * Cacher plusieurs PID * Script de persistance du LKM ## Explication de fonctionnement 1. Hook des appels systèmes Les appels systèmes sont hook à l'aide de `ftrace` où on attache une fonction callback dans une partie de kernel, notamment dans les registres des appels systèmes qu'on veut hook. 2. Canal de communication Dans le hook de l'appel système `openat` on vérifie quel fichier à été ouvert. Si le fichier est `/dev/null` on retient le `file descriptor` et le `pid` du procès appelant. Puis, dans le hook de l'appel système `write` on vérifie si le `pid` et le `file descriptor` correspond à celui que on a retenu, afin de ne pas faire des vérification inutiles. Si c'est le cas, on compare ce qui est écrit dans le fichier. Les commandes acceptées sont `root`, `hideme`, `reveal` et `hide$` avec un préfixe `secret`. Le moyen de communication se fait par l'outil standard `echo`. 3. Élévation de privilèges Pour devenir root, d'abord je récupère la structure `pid` du processus qui écrit dans `/dev/null`. Puis, on récupère la tâche qui correspond à ce `pid`. À la suite, on change les accréditations de la tâche pour celle du root (`0`). 4. Cacher LKM Pour cacher le LKM, on récupère la liste des modules chargées et on supprime le rootkit. 5. Révélation de LKM Pour révéler le LKM, on ajoute mon module dans la liste des modules chargées. 6. Cacher PID Les _pid_ sont stocké dans la structure `_hidden_pids` qui peut contenir au plus 200 `pid`, et qui contient le nombre de `pid` cachés. Puis, dans le hook de l'appel système `write`, le `pid` avec la phrase `secrethide$PID$,` où **PID** est le `pid` donné, est retenu. Après, dans l'appel système `getdents64` on vérifie si le dossier dont une tache essaye d'accéder correspond aux `pid`s retenus. Si c'est le cas, on l'ignore dans listing. 7. Persistance Pour avoir mon LKM chargé au démarrage on remplace l'image de `initramfs` qui contient le filesystem initiale qui est chargé en mémoire et qui `mount` le vrai filesystem et qui contient des LKM avec des drivers. Donc, on crée un `initramfs` fauté avec mon LKM, et on ajoute la ligne de chargement du rootkit dans le script `init`. ## Bibliographie * [Learn linux rootkit](https://xcellerator.github.io/posts/linux\_rootkits\_01/) * [WRITING SIMPLE ROOTKIT](https://theswissbay.ch/pdf/Whitepaper/Writing%20a%20simple%20rootkit%20for%20Linux%20-%20Ormi.pdf) * [Hooking syscalls with ftrace](https://nixhacker.com/hooking-syscalls-in-linux-using-ftrace/) * [Linux hook system call](https://cdmana.com/2021/07/20210731031948859C.html) * [Persistent rootkit](https://yassine.tioual.com/posts/backdoor-initramfs-and-make-your-rootkit-persistent/) * [Hide processes](https://jm33.me/linux-rootkit-for-fun-and-profit-0x02-lkm-hide-filesprocs.html)