weidner/archives/2013/10/

Analyse von Zugriffsproblemen unter Linux (3) - POSIX Capabilities

In diesem Teil der Serie gehe ich auf die Analyse von Problemen mit POSIX Capabilities ein.

Zur Erinnerung: In Teil 1 befasste ich mich mit Standardzugriffsrechten und in Teil 2 mit Dateiattributen.

In Teil 4 geht es um AppArmor.

Wer sich tiefer in das Thema einarbeiten möchte, dem empfehle ich die Seite von Chris Friedhoff zum Thema POSIX Capabilities & File POSIX Capabilities. In diesem Artikel zeige ich nur, wie man einen Einstieg in das Thema findet, um sich im Rahmen einer Fehlersuche ein Bild machen zu können. Trotzdem komme ich nicht um einige Grundlagen herum.

Worum geht es?

Das Ziel bei der Entwicklung der POSIX Capabilities war, die alles umfassenden Privilegien des root Benutzers aufzuteilen in einzelne Privilegien, die je nach Bedarf einzelnen Prozessen und/oder Programmen zugewiesen werden. Traditionell darf ein Prozess, der unter UID 0 läuft, in einem UNIX-System fast alles: auf alle Speicherbereiche, alle Geräte, alle Dateien zugreifen, Netzwerkschnittstellen direkt nutzen, ...

Wenn ein Programm, wie zum Beispiel ping, welches direkt auf die Netzwerkschnittstelle zugreift, nur eines dieser Privilegien benötigt, dann bekommt der Prozess, der es ausführt mit dem SUID-Bit alle anderen Privilegien ebenfalls. Gelingt es einem Angreifer, einen Programmfehler auszunutzen, kann er dadurch seine Privilegien erhöhen, also die Rechte von root erlangen.

Genau an dieser Stelle setzen die POSIX Capabilities an. Auf einem System, das diese kennt, kann ich dem Programm ping das SUID-Bit entfernen und stattdessen die Capability CAP_NET_RAW vergeben. Damit funktioniert das Programm wie vorher, bei einem ausgenutzten Programmfehler gewinnt der Angreifer maximal genau dieses Privileg.

Wie funktioniert es?

Welche Capabilities es im Einzelnen gibt, erfahre ich aus der Handbuchseite capabilities in Sektion 7 (man 7 capabilities), oder direkt aus der Datei /usr/include/linux/capabilities.h.

Capabilities werden zum einen für ausführbare Dateien festgelegt und zum anderen für Prozesse. Sie können das Kennzeichen permitted (erlaubt), effective (aktiv) oder inheritable (vererbbar) haben. Alle Capabilities mit einem bestimmten Kennzeichen bilden das entsprechende Set.

Das Permitted Set einer Datei verleiht die entsprechenden Capabilities dem Prozess, der sie ausführt. Das Permitted Set eines Prozesses enthält alle Capabilities, die dieser Prozess verwenden könnte.

Das Inheritable Set einer Datei geht nur dann in das Permitted Set eines Prozesses ein, wenn dieser die entsprechenden Kennzeichen ebenfalls in seinem Inherited Set hat. Damit ist es möglich, die an eine Datei vergebenen Capabilities nur ausgewählten Prozessen verfügbar zu machen, die über die entsprechenden inheritable Kennzeichen verfügen.

Das Effective Set einer Datei benötigt zusätzlich noch das effective oder inheritable Kennzeichen der einzelnen Capabilities. Dann setzt es das Effective Set des Prozesses für die Capabilities, die im Permitted Set des Prozesses enthalten sind.

Für Details verweise ich auf den Artikel von Chris Friedhoff.

Was muss ich tun?

Kommen wir zum praktischen Teil, am Beispiel von ping. Nachdem ich das SUID-Bit entfernt habe, funktioniert das Programm nicht mehr:

$  ls -l /bin/ping
-rwxr-xr-x 1 root root 35712 Nov  8  2011 /bin/ping
$ ping -c1 localhost
ping: icmp open socket: Operation not permitted

Die Ursache wird mir hier schon angegeben, strace zeigt es noch einmal deutlich:

 $ strace ping -c1 localhost 2>&1|grep EPERM
 socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = -1 EPERM (Operation not permitted)

Mit dem Programm setcap kann ich ping die benötigte Capability verleihen:

 $ sudo setcap cap_net_raw=ep /bin/ping
 $ getcap /bin/ping
 /bin/ping = cap_net_raw+ep
 $  ping -c1 localhost
 PING localhost (127.0.0.1) 56(84) bytes of data.
 64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.107 ms

 --- localhost ping statistics ---
 1 packets transmitted, 1 received, 0% packet loss, time 0ms
 rtt min/avg/max/mdev = 0.107/0.107/0.107/0.000 ms

Und schon funktioniert es wieder. Damit kann jeder auf dem System ping verwenden, ohne dass dieses Programm mit den Rechten von root laufen muss. Will ich die Anzahl der Prozesse und/oder Benutzer einschränken, die das Programm nutzen können, verwende ich statt dem Kennzeichen permitted das Kennzeichen inheritable:

 $ sudo setcap cap_net_raw=ei /bin/ping
 $ getcap /bin/ping
 /bin/ping = cap_net_raw+ei
 $ /sbin/getpcaps $$
 Capabilities for `4848': =
 $ ping -c1 localhost
 ping: icmp open socket: Operation not permitted

Da die File-Capability mit dem Kennzeichen inheritable nur wirksam wird, wenn auch der Prozess das Kennzeichen inheritable für diese Capability besitzt, fehlen mir nun die nötigen Rechte.

Diese kann ich zum Beispiel beim Login am System, oder (zum Test) mit su bekommen, wenn ich libpam-cap installiert habe. Dazu füge ich die folgende Zeile in /etc/pam.d/su ein

auth        required    pam_cap.so

und "vererbe" mir via /etc/security/capability.conf die nötigen Capabilities:

$ egrep -v '^\s*(|#.*)$' /etc/security/capability.conf 
cap_net_raw mathias
none  *

Nun muss ich mir noch die nötigen Rechte holen:

$ /sbin/getpcaps $$
Capabilities for `4848': =
$ su - mathias
Password: 
$ /sbin/getpcaps $$
Capabilities for `22807': = cap_net_raw+i
$ ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.103 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.103/0.103/0.103/0.000 ms

Und schon geht es wieder.

Damit bin ich schon fertig mit meiner Kurzbesprechung der POSIX Capabilities. Halten wir fest, dass ich für die Analyse von Problemen vier Programme verwende:

Und natürlich die Datei /usr/include/linux/capabilities.h beziehungsweise die Handbuchseite capabilities, welche mir zeigen, welche Capabilities ich verwenden kann.

Dieser Artikel wird Teil des Buches Fehlersuche bei Linux-Servern und IP-Netzwerken, an dem ich momentan arbeite. Weitere Informationen zu diesem Buch finden sich unter http://buecher.mamawe.net/buecher/troubleshoot-linux-network/.

Posted 2013-10-20
Tags: