Sicherheitslücke durch exec()

Hallo

Folgendes Problem:
Auf einem Linux-Server läuft php als Apache-Modul. Mehrere Benutzer haben dort Webspace. Jeder dieser Benutzer hat FTP-Zugriff auf das Verzeichnis /www/htdocs/Nutzername und für jeden Nutzer gibt es auch ein Linux-Benutzer-Konto, mit dem man nur auf sein eigenes Verzeichnis zugreifen kann. PHP aber läuft als Benutzer php, der auf alle Verzeichnise Zugriff hat. Mit den PHP-eigenen Funktionen für Dateizugriff gibt es kein Problem, ein Zugriff auf fremde Nutzerverzeichnisse ist durch entsprechende Einstellungen gesperrt. Allerdings kann man mit exec() fremde Verzeichnisse auslesen, da der per exec() ausgeführte Befehl ja unter gleichem Nutzer läuft wie der PHP-Prozess.

Als Lösung kämen in Betracht:
-PHP als CGI mit modsu, dabei läuft der PHP-Prozess unter dem Benutzer, zu dem die php-Datei gehört. => zu langsam
-PHP als FastCGI mit modsu, dabei müsste aber für jeden Nutzer dauerhaft ein FastCGI-PHP-Prozess laufen. => braucht viel Rechenleistung
-exec() und ähnliche Befehle deaktivieren. => Scripte, die exec() verwenden, laufen nicht mehr. Das gilt vor allem für Bildergalerien, die ImageMagick per exec() werwenden.

Es wurde auch schon über Safemode nachgedacht, bei dem nur Programme aus dem angegebenen exec-Dir ausgeführt werden können. Allerdings reichen schon cd und echo zusammen mit dem Kürzel * für ‚alle Dateien im Verzeichnis‘ zur Nutzung der Sicherheitslücke. Diese Befehle sind aber keine Programme sondern werden von der Shell ausgewertet. Sie sind also auch ohne zugehörige ausführbare Datei im exec-Dir verfügbar.
Nebenbemerkung: Wieso kann man in exec() oder system() Shellbefehle verwenden? Mit exec und system sollen doch nur echte Programme aufgerufen werden. Für Shellbefehle gibt es ja extra shell_exec().

Die ideale Lösung wäre, wenn PHP die Befehle unter anderen Nutzerrechten ausführen könnte. Technisch wäre das kein Problem, aber ich habe nirgends eine Einstellung dazu gefunden.

Was kann man also tun?

Gruß Johannes

Hallo Johannes,

weitere Variante, wenn es nur um das Auslesen der Daten geht:
statt

/www/htdocs/Nutzername

/www/htdocs//Nutzername

und /www/htdocs chmod 711 (dann ist nichts mehr mit auflisten, cd geht aber).

Wenn man die Nutzernamen nicht erraten kann, geht es auch ohne Zufallszahl dazwischen und nur dem chmod.

Im PHP ist dann idealerweise display_errors aus, weil da steht der komplette Pfad zur Datei mit drin, so das ein Nutzer durch einen Fehler das Verzeichnis eines anderen wieder erraten könnte.

Alex

Hallo

und /www/htdocs chmod 711 (dann ist nichts mehr mit auflisten,
cd geht aber).

Wenn man die Nutzernamen nicht erraten kann, geht es auch ohne
Zufallszahl dazwischen und nur dem chmod.

Das war die bisherige Methode.

Im PHP ist dann idealerweise display_errors aus, weil da steht
der komplette Pfad zur Datei mit drin, so das ein Nutzer durch
einen Fehler das Verzeichnis eines anderen wieder erraten
könnte.

Das war bisher nicht der Fall.

Die Benutzernamen sind 8-stellige Buchstaben-Zahlen-Kombinationen. Man kommt also nur durch Zufall an einen solchen Nutzernamen heran.
Trotzdem wäre eine Lösung schön, bei der die Geheimhaltung von Nutzernamen nicht notwendig ist.

Johannes

Hallo Johannes,

hast Du Dir mpm-itk schon angesehen?

Ciao
Rudy

hast Du Dir mpm-itk schon angesehen?

Das klingt interessant.
Wenn ich das richtig verstehe, dann laufen die wartenden Apache-Prozesse also root, wenn dann eine Anfage kommt wechseln sie zum entsprechenden Benutzerkonto.

Zitat: This means that any security hole before the request is parsed will be a root security hole.

Wie groß ist denn das Risiko, welches man sich damit einhandelt?

Johannes

Hi,

hast Du Dir mpm-itk schon angesehen?

Das klingt interessant.
Wenn ich das richtig verstehe, dann laufen die wartenden
Apache-Prozesse also root, wenn dann eine Anfage kommt
wechseln sie zum entsprechenden Benutzerkonto.

Genau, das wird mit AssignUserId in der jeweiligen Virtualhost Konfiguration festgelegt. Einfacher gehts kaum.

Zitat: This means that any security hole before the request is
parsed will be a root security hole.

Wie groß ist denn das Risiko, welches man sich damit
einhandelt?

Wenn Das System durch einen Bug in einem Modul angreifbar ist, der nutzbar ist, bevor der Apache den Virtualhost gewählt hat (und damit ja auf die Userid umgeschaltet hat), dann hättest Du theoretisch einen Angreifer mit Root-Rechten auf der Maschine. Da steht aber auch, dass der capabilities-Patch für den als Root laufenden Prozess die Rechte zur Ausführung vieler gefährlicher Funktionen nimmt, es ist also immerhin ein begrenzter Root-Zugang. Es ist nicht zu vergessen, dass das alles nur zum Tragen kommt, wenn ein Bug in einem Modul genutzt wird - da musst Du natürlich als Webserver-Betreiber Security-Bulletins lesen und updaten - und, wie Du sicher sowieso machst, von Anfang an alle Module rausnehmen, die Du nicht brauchst, um das Risiko zu minimieren. Die Gefahr, alle Virtualhosts mit demselben User laufen zu lassen, ist empfinde ich als ungleich höher; das wird schlimmer, je mehr User den Server nutzen. Was weiß der Hoster schon, welche ungesicherten Skripts die Kunden auf den Server laden, welche Angreifer die dann finden und was die dann mit allen vorhandenen Hostings anfangen…

Ciao
Rudy