lkm_rootkit/README.md

70 lines
3.1 KiB
Markdown

# 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$,`
**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)