32.17 Kernel-Erweiterungen und ProPolice
Im Folgenden sollen einige interessante Erweiterungen für Linux- und BSD-Kernel besprochen werden. Die einzelnen Erweiterungen werden dabei nur sehr grundlegend behandelt.
32.17.1 ProPolice
Bevor wir zu den eigentlichen Kernel-Patches kommen, soll an dieser Stelle noch der sogenannte ProPolice-Patch für den GNU C Compiler (gcc) besprochen werden. Dieses Feature aus dem Hause IBM ist auch als GCC Stack Smashing Protection bekannt.
ProPolice baut verschiedene Schutzmechanismen für den Stack ein, um Angriffe wie Buffer-Overflows zu erschweren.
Zu diesen Features gehört der Schutz der Pointer innerhalb eines Stackframes. Zudem werden lokale Funktionsvariablen (bei einer IA32-Architektur) vor den Puffern platziert. Überschreibt ein Angreifer also einen Puffer, so überschreibt er keine Variablen. Die gesicherte Rücksprungadresse und der Extended Instruction Pointer (EIP) werden ebenfalls vor den Puffern platziert und können somit auch nicht überschrieben werden. Um einen überschriebenen Puffer zu erkennen, wird hinter den Puffern zusätzlich ein Canary-Wert eingefügt (der durch /dev/random mit Zufallswerten arbeitet). Wird dieser Wert verändert, so wird ein Puffer überschrieben, und es steht fest, dass der Stack beschädigt wurde.
Anwendungen mit SSP kompilieren
Um ein Programm nun so zu kompilieren, dass es durch die SSP geschützt wird, übergibt man beim Kompilieren den Parameter -fstack-protector.
Achtung: Im Normalfall werden nur Puffer ab einer Größe von 8 Bytes durch den Patch geschützt. Modifiziert man allerdings den Patch bzw. den Quellcode des GCC, so lässt sich diese Grenze anpassen.
Das folgende Programm soll nun einmal mit und einmal ohne SSP übersetzt werden. Falls mehr Byte übergeben werden, als in dem Puffer »buf« gespeichert werden können, so werden andere Werte auf dem Stack überschrieben. [Fn. Es muss nicht unbedingt eine andere Variable überschrieben werden, da der gcc manchmal mehr Speicher als nötig reserviert.] Wir werden uns den Unterschied einmal ansehen.
Listing 32.18 test.c
#include <string.h>
int main(int argc, char *argv[])
{
char buf[10];
if (argc > 1)
strcpy(buf, argv[1]);
return 0;
}
Listing 32.19 SSP-Test
hikoki:/tmp/ssp> gcc -o test test.c
hikoki:/tmp/ssp> ./test abcdefffffffffffffffffffffffff
Segmentation fault
hikoki:/tmp/ssp> gcc -o test -fstack-protector test.c
hikoki:/tmp/ssp> ./test abcdefffffffffffffffffffffffff
*** stack smashing detected ***: ./test terminated
Abort
hikoki:/tmp/ssp>
32.17.2 SELinux/SEBSD und AppArmor
Beim SELinux-Projekt (Security enchanged Linux) handelt es sich um eine Erweiterung des Linux-Kernels (inklusive einiger Programme) zur Verbesserung der Sicherheit. Das Projekt wird von der NSA und von Red Hat entwickelt. SELinux bietet Mandatory Access Control (MAC) für Linux; dabei handelt es sich um die Möglichkeit, Regeln für den Zugriff auf Systemressourcen zu erstellen, die unabhängig vom Benutzer und vom Prozess sind. SELinux ist in fast allen populären Distributionen integriert, wird jedoch wegen seiner Komplexität auch kritisiert. In der BSD-Welt steht mit SEBSD eine SeLinux-Portierung auf FreeBSD bereit, die mit dem MAC- Framework TrustedBSD lauffähig ist.
AppArmor wurde von der Firma Immunix entwickelt, die mittlerweile von Novell übernommen wurden. Im Gegensatz zu SELinux lassen sich mit AppArmor (das sich ebenfalls in diversen populären Distributionen findet) Regeln gezielt für einzelne Prozesse definieren.
32.17.3 Openwall (OWL)
Das Openwall-Projekt ist Bestandteil vieler gehärteter Linux-Distributionen. Die Funktionalität von Openwall werden teilweise auch von anderen Kernel-Patches unterstützt (besonders von grsecurity/PaX).
Zu den Features gehört eine Stack-Härtung: Der Stack eines Programms kann oft durch Buffer-Overflow-Exploits angegriffen werden, wozu er ausführbar sein muss. Openwall unterbindet diese Möglichkeit.
Die Links und FIFOs im Verzeichnis /tmp und der Zugriff auf /proc werden ebenfalls durch OWL gehärtet.
Weitere Features sind die RLIMIT_NPROC-Überprüfung für den Syscall execve() und das Löschen von nicht verwendeten Shared Memory Pages im Speicher. [Fn. RLIMIT_NPROC gibt die Anzahl der Prozesse an, die ein Benutzer maximal gleichzeitig laufen lassen kann. Shared Memory ist eine Art der Interprozesskommunikation (IPC).]
32.17.4 grsecurity
Bei grsecurity handelt es sich um einen sehr umfangreichen Kernel-Patch plus Administrationstools. grsecurity implementiert diverse Features, die auch Openwall kennt (FIFO-Restrictions etc.), Rule Set Based Access Control (RSBAC), zufällige Prozess-IDs, chdir()-Hardening, Unterstützung für zufällige TCP-Quell-Ports, Logging von Signalen, Zugriffsbeschränkungen auf /dev/kmem und /dev/mem sowie das komplette PaX-Projekt, das wir im folgenden Abschnitt besprechen werden.
Eine ausführliche Auflistung der aktuellen Features erhalten Sie auf der Seite http://www.grsecurity.net/features.php.
32.17.5 PaX
PaX (Page exec) ist ein Kernel-Patch zur Absicherung von Speicherseiten. Das Primärziel ist die Verhinderung erfolgreicher Stack-Smashing-Angriffe (die so genannte Stack Smashing Protection), die nicht mit dem ProPolice-Patch des GCC zu verwechseln ist. Zu diesem Zweck wurde eine Executable Space Protection implementiert, die – vereinfacht gesagt – verhindern soll, dass es zur Ausführung von Shellcode und zu erfolgreichen Return-to-Libc-Angriffen kommt. [Fn. Dieses Thema ist sehr umfassend und es wird leider wesentlich mehr Security- und Kernel-Know-how zum Verständnis von PaX benötigt, als wir Ihnen hier bieten können.]
PaX erreicht das Ziel durch zwei Techniken:
- Nicht ausführbare Speicherseiten
Eingeschleuster Code, der zur Ausführung gebracht werden soll, muss sich innerhalb von Speicherseiten (Pages) befinden, denen das Ausführen von Programmcode erlaubt ist. Sind diese Seiten nicht ausführbar, so wird auch der Code nicht ausgeführt. - Zufällige Speicheradressen
Wenn ein Angreifer versucht, eine bestimmte Funktion im Speicher aufzurufen, obwohl dies nicht geplant ist, so wird dazu die Speicheradresse dieser Funktion benötigt. Durch die sogenannte Address Space Layout Randomzation wählt PaX diese Adressen bei jedem Programmstart neu und erschwert so das Erraten der Adresse einer Funktion.
Wir möchten nicht verschweigen, dass es noch weitere ähnliche Projekte gibt (z. B. W{}X unter OpenBSD oder Exec Shield bei Fedora Linux).
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.