--- title: "Sécurité système : passage dans le noyau" date: 2023-11-16 tags: ["Linux", "noyau"] categories: ["Sécurité système", "Cours"] mathjax: true --- Lors du cours sécurité logicielles, nous voulions devenir `root`, maintenant nous voulons aller dans le noyau! Sur notre machine cible, nous devons donc devenir `root` si noue ne le sommes pas déjà et ensuite **devenir invisible**. Les objectifs de cette partie du cours sont : * Avoir une vision globale de l'architecture du noyau; * Comprendre ses mécanismes de protections; * Comprendre les mécanismes de transmissions de données; * Comprendre les mécanismes fournis par le noyau aux utilisateurs pour leurs protection. ## Le noyau Commençons par regarder l'organisation de son code source, voici les dossiers les plus importants: * `include/`: les fichiers d'entêtes (`.h`), par exempel celle pour `printk()`; * `lib/`: les différentes bibliothèques comme par exemple les calculs de CRC ou les algorithmes de chiffement. * `arch/`: les codes spécifiques aux architectures spécifiques (`x86`, `x86_54` `AARCH64`) * `init/`: le code relatif à l'initialisation du noyau (le code lancé dès le démarrage) * `kernel/`: fourre-tout non lié au matériel, [les signaux]({{}}) par exemple; * `mm/`: tout ce qui est relatif à la gestion de la mémoire comme les accès, les permissions, la swap etc. * `block/`: code relatif aux périphérique de type *block* (stockage); * `fs`: code relatif aux systèmes de fichiers; * `net`: code relatif à la gestion du réseau; * `sound`: code relatif à la gestion du son; * `drivers/`: tous les pilotes non présent dans les 4 catégories ci-dessus. C'est ici la partie la plus importante, mais aussi celle avec le plus de bugs[^bugs]; ## Le passage en mode noyau Lors d'un appel système, nous passons de l'autre côté de la barrière : du mode utilisateur nous passons en mode noyau. `malloc()` par exemple fait appel à `sbrk` côté noyau (comme appel système). Les différents composants su mode noyau sont: * L'ordonanceur (*scheduler*); * Le hestionnaire de memoire (*memory managment*); * Les pilotes (*drivers*); * VFS pour Virtual Files System: c'est un composant central du noyau (n'oublions pas la philosophie Unix : *tout est fichiers*). VFS accède ensuite à *BlkDev* ou *NetDev* (mais aussi dans le *MemoryManager*). ## Les points d'entrées Le noyau comporte plusieurs point d'entrées: * Demarrage du noyau: `start_kernel` lorsque le bootloadeur du matériel passe la main au noyau; * Les appels système, comme par exemple `sys_open`, `sys_read` etc. * Les appels au *VFS*, comme `vfs_read` ou `vfs_open`... *VFS* utilise aussi un cache en mémoire; * Les systèmes de fichiers comme `ext2_file_read_iter`. Nous verrons en TD `unlock_ioctl`, véritable couteau suisse non factorisé pour certaines actions sur les systèmes de fichiers. * Les sockets (réseau ou non) avec entre autres `inet_accept`, `inet_sendmsg` ## Objets du noyau Le code source de *Linux* est écrit en C orienté objets (`structs`) : ```c // fichier struct file * f // répertoire struct dentry * d // socket struct socket * s // répertoire ouvert struct dir_context * d // inode struct inode * i // buffer réseau struct sk_buf * n ``` Toutes ces structures peuvent pointer les unes les autres, voir se contenir (il est possible de trouver les conteneurs avec `container_of`). [^bugs]: On parle bien ici en proportion du nombre de lignes de code