Vous allez rapidement comprendre pourquoi mon dernier billet expliquait comment compiler et installer un Kernel Linux. J’avais déjà dans l’idée de vous expliquer comment il est possible de sécuriser un Kernel avec grsecurity, je voulais simplement faire correctement les choses.
Sécuriser un Kernel avec grsecurity : grsecurity Késséssé ?
grsecurity est un patch permettant d’augmenter la sécurité d’un noyau Linux en renforcant le controle d’accès local et le confinement des applications. De plus il inclut PAX, un ensemble de correctifs rendant votre système plus résistant à l’exploitation de vulnérabilités.
Sécuriser un Kernel avec grsecurity : Pré-requis
Je radote, tu radotes, il radote, etc.
Comme dans mon précédent mémo, je vous conseille fortement d’effectuer une sauvegarde de votre système avant d’installer un nouveau Kernel. Puisque j’adore me répéter, je vous rappelle que compiler un noyau prend du temps et beaucoup d’espace disque.
Installation des dépendances
La compilation d’un noyau avec le module grsecurity requiert plus de dépendances. Il vous faudra commencer par récupérer la version de gcc installée sur votre système.
gcc -v
Qui dans ici nous donne
root@noobunbox:~$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Maintenant installons les dépendances requises, n’oubliez pas de remplacer 4.9 par votre version de gcc
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc kernel-package gcc-4.9-plugin-dev
Sécuriser un Kernel avec grsecurity : C’est parti
Ici aussi nous allons créer un nouveau répertoire, parce que l’on est un peu psycho-rigide et que l’on aime travailler proprement
mkdir ~/kernel-grsecurity && cd ~/kernel-grsecurity
grsecurity n’est pas compatible avec les derniers Kernels, à l’heure ou j’écris ce mémo, la dernière version du noyau Linux avec laquelle est compatible grsecurity est la version 4.4.7. Téléchargeons là
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.7.tar.xz wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.7.tar.sign
Vérifions la signature de l’archive
unxz linux-4.4.7.tar.xz gpg --verify linux-4.4.7.tar.sign
Si tout va bien, voici ce que vous devriez obtenir
root@noobunbox:~/kernel-grsecurity$ gpg --verify linux-4.4.7.tar.sign gpg: les données signées sont supposées être dans « linux-4.4.7.tar » gpg: Signature faite le mar. 12 avril 2016 19:09:46 MSK avec la clef RSA d'identifiant 6092693E gpg: Bonne signature de « Greg Kroah-Hartman (Linux kernel stable release signing key) <greg[at]kroah.com> » gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance. gpg: Rien n'indique que la signature appartient à son propriétaire. Empreinte de clef principale : 647F 2865 4894 E3BD 4571 99BE 38DB BDC8 6092 693E
Nous pouvons donc extraire l’archive
tar xvf linux-4.4.7.tar
Sécuriser un Kernel avec grsecurity : Patch du Kernel
Commençons donc par nous déplacer dans le répertoire contenant les sources du noyau 4.4.7
~/kernel-grsecurity/linux-4.4.7
Téléchargeons le dernier patch grsecurity disponible (201604152208) ainsi que sa signature
wget https://grsecurity.net/test/grsecurity-3.1-4.4.7-201604152208.patch wget https://grsecurity.net/test/grsecurity-3.1-4.4.7-201604152208.patch.sig
Vérifions que le patch soit correctement signé
root@noobunbox:~/kernel-grsecurity/linux-4.4.7$ gpg --verify grsecurity-3.1-4.4.7-201604152208.patch.sig gpg: les données signées sont supposées être dans « grsecurity-3.1-4.4.7-201604152208.patch » gpg: Signature faite le sam. 16 avril 2016 05:09:53 MSK avec la clef RSA d'identifiant 2525FE49 gpg: Bonne signature de « Bradley Spengler (spender) <spender[at]grsecurity.net> » gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance. gpg: Rien n'indique que la signature appartient à son propriétaire. Empreinte de clef principale : DE94 52CE 46F4 2094 907F 108B 44D1 C0F8 2525 FE49
Tout semble normal, nous pouvons donc appliquer le patch aux sources du Kernel, pour cela rien de plus simple, lançons la commande suivante
patch -p1 < grsecurity-3.1-4.4.7-201604152208.patch
La liste des fichiers patchés apparaît dans votre terminal
[...] patching file tools/gcc/gen-random-seed.sh patching file tools/gcc/initify_plugin.c patching file tools/gcc/kallocstat_plugin.c patching file tools/gcc/kernexec_plugin.c patching file tools/gcc/latent_entropy_plugin.c patching file tools/gcc/randomize_layout_plugin.c patching file tools/gcc/size_overflow_plugin/.gitignore patching file tools/gcc/size_overflow_plugin/Makefile [...]
Sécuriser un Kernel avec grsecurity : Configuration du Kernel
Copiez le fichier de configuration de votre Kernel, histoire de ne pas risquer de tout casser en touchant a tout ?
cp /boot/config-$(uname -r) .config
Maintenant ouvrons le menu de configuration du Kernel (étape obligatoire)
make menuconfig
Dans ce menu naviguez vers « Security Options »
Puis vers Grsecurity
Utilisez la barre espace de votre clavier pour modifier la configuration du module Grsecurity
Naviguez vers Configuration Method
Sélectionnez Automatic
Networking Support -> Networking options -> Network packet filtering framework (Netfilter) -> IP:Netfilter Configuration -> Enable: IPv4 masquerade support + iptables support Networking Support -> Networking options -> Network packet filtering framework (Netfilter) -> IPV6:Netfilter Configuration -> ip6tables NAT support -> Enable: masquerade support
Vous pouvez maintenant sauvegarder votre configuration et quitter.
Sécuriser un Kernel avec grsecurity : Compilation du Kernel
Ici aussi on met un peu d’ordre dans nos fichiers
make-kpkg clean
Maintenant récupérez le nombre de coeur CPU disponibles sur votre machines
nproc
Dans mon cas, cette commande me retourne le chiffre 12. Je peux donc affecter jusqu’à 12 cores à la compilation du Kernel
Nous pouvons maintenant lancer la compilation du Kernel (modifiez l’option -j 12 en fonction du nombre de cores que vous souhaitez affecter à cette opération)
fakeroot make-kpkg --initrd --revision=1.0.noobunbox kernel_image kernel_headers -j 12
Sécuriser un Kernel avec grsecurity : Installation du Kernel
La compilation est terminée, deux fichiers devraient avoir été générés, vérifions
root@noobunbox:~/kernel-grsecurity/linux-4.4.7$ ls ../*.deb ../linux-headers-4.4.7-grsec_1.0.noobunbox_amd64.deb ../linux-image-4.4.7-grsec_1.0.noobunbox_amd64.deb
Je vais me répéter mais ce n’est pas grave 🙂 je vous conseille de transférer ces deux paquets sur une machine virtuelle afin de les tester. Connectez vous donc sur votre MACHINE VIRTUELLE via SSH.
Avant de pouvoir installer notre Kernel grsecurity, nous allons devoir installer deux paquets
apt-get install paxctl paxtest
Maintenant installez les deux paquets précédemment transférés
sudo dpkg -i linux-headers-4.4.7-grsec_1.0.noobunbox_amd64.deb sudo dpkg -i linux-image-4.4.7-grsec_1.0.noobunbox_amd64.deb
L’installation terminée, redémarrez votre machine virtuelle. Une fois le redémarrage terminé, vérifiez la version du Kernel installé via la commande
root@noobunbox:~$ uname -a Linux debian 4.4.7-grsec #1 SMP Sun Apr 17 23:04:15 MSK 2016 x86_64 GNU/Linux
Sécuriser un Kernel avec grsecurity : Test du module grsecurity
Afin de vérifier que grsecurity fonctionne correctement nous allons utiliser la commande suivante
root@noobunbox:~$ paxtest blackhat
Cette commande permet de simuler l’exploit de vulnérabilités. Si tout va bien voici ce que vous devriez obtenir
root@noobunbox:~# paxtest blackhat PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter[at]adamantix.org> Released under the GNU Public Licence version 2 or later Writing output to /root/paxtest.log It may take a while for the tests to complete Test results: PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter[at]adamantix.org> Released under the GNU Public Licence version 2 or later Mode: Blackhat Linux noobunbox 4.4.7-grsec #1 SMP Sun Apr 17 23:04:15 MSK 2016 x86_64 GNU/Linux Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable shared library bss : Killed Executable shared library data : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 28 bits (guessed) Heap randomisation test (ET_EXEC) : 23 bits (guessed) Heap randomisation test (PIE) : 35 bits (guessed) Main executable randomisation (ET_EXEC) : 28 bits (guessed) Main executable randomisation (PIE) : 28 bits (guessed) Shared library randomisation test : 28 bits (guessed) Stack randomisation test (SEGMEXEC) : 35 bits (guessed) Stack randomisation test (PAGEEXEC) : 35 bits (guessed) Arg/env randomisation test (SEGMEXEC) : 39 bits (guessed) Arg/env randomisation test (PAGEEXEC) : 39 bits (guessed) Randomization under memory exhaustion @~0: 28 bits (guessed) Randomization under memory exhaustion @0 : 28 bits (guessed) Return to function (strcpy) : paxtest: return address contains a NU LL byte. Return to function (memcpy) : Killed Return to function (strcpy, PIE) : paxtest: return address contains a NU LL byte. Return to function (memcpy, PIE) : Killed
Pour comparaison voici ce que l’on obtient avec un Kernel ne comprenant pas le module grsecurity
root@noobunbox:~$ paxtest blackhat PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Writing output to /root/paxtest.log It may take a while for the tests to complete Test results: PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Mode: Blackhat Linux noobunbox 4.5.1 #1 SMP Sun Apr 17 16:04:50 MSK 2016 x86_64 GNU/Linux Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable shared library bss : Killed Executable shared library data : Killed Executable anonymous mapping (mprotect) : Vulnerable Executable bss (mprotect) : Vulnerable Executable data (mprotect) : Vulnerable Executable heap (mprotect) : Vulnerable Executable stack (mprotect) : Vulnerable Executable shared library bss (mprotect) : Vulnerable Executable shared library data (mprotect): Vulnerable Writable text segments : Vulnerable Anonymous mapping randomisation test : 29 bits (guessed) Heap randomisation test (ET_EXEC) : 14 bits (guessed) Heap randomisation test (PIE) : 30 bits (guessed) Main executable randomisation (ET_EXEC) : 29 bits (guessed) Main executable randomisation (PIE) : 28 bits (guessed) Shared library randomisation test : 29 bits (guessed) Stack randomisation test (SEGMEXEC) : 30 bits (guessed) Stack randomisation test (PAGEEXEC) : 30 bits (guessed) Arg/env randomisation test (SEGMEXEC) : 22 bits (guessed) Arg/env randomisation test (PAGEEXEC) : 22 bits (guessed) Randomization under memory exhaustion @~0: 28 bits (guessed) Randomization under memory exhaustion @0 : 28 bits (guessed) Return to function (strcpy) : paxtest: return address contains a NULL byte. Return to function (memcpy) : Killed Return to function (strcpy, PIE) : paxtest: return address contains a NULL byte. Return to function (memcpy, PIE) : Killed
Source
- Grsecurity, Documentation