lkm_rootkit/README.md

3.4 KiB

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).

    $ echo "secretroot" > /dev/null`
    
  4. Cacher LKM

    Pour cacher le LKM, on récupère la liste des modules chargées et on supprime le rootkit.

    $ echo "secrethideme" > /dev/null
    
  5. Révélation de LKM

    Pour révéler le LKM, on ajoute mon module dans la liste des modules chargées.

    $ echo "secretreveal" > /dev/null
    
  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 pids retenus. Si c'est le cas, on l'ignore dans listing.

    $ echo "secrethide\$42\$" > /dev/null
    
  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.

    $ sudo ./persistance.sh
    

Bibliographie