Sicherheits-Aspekte des UNIX-Path

Ernst Bötsch

Man sollte Hackern das Leben nicht unnötigerweise leicht machen. In diesem Beitrag wird eine einfache Methode vorgestellt, wie man sich auf UNIX-Rechnern vor (möglicherweise gefährlichen) Kommandos aus unbekannter Quelle schützen kann

Funktion der $PATH-Variablen

Beim Betriebssystem `UNIX' startet man Kommandos (Programme, Shell-Skripts etc.) normalerweise ohne die Angabe eines absoluten oder relativen Pfads, d.h. man gibt nur den Namen des Kommandos selbst an. In diesem Fall muß das System selbst herausfinden, in welchem Verzeichnis des großen File-Systems das gewünschte Kommando steht.

Für diesen Zweck gibt es die Shell- bzw. Environment-Variable `$PATH', die i.a. in einem System- oder privaten Profile (z.B. in `$HOME/.profile' bzw. `$HOME/.login' oder `$HOME/.cshrc') gesetzt wird. Bei der C-Shell (und ihren Varianten, z.B. TC-Shell) gibt es zusätzlich noch die Shell-Variable `$path', die mit `$PATH' automatisch verknüpft ist.

Die $PATH-Variable besteht aus einer Liste von Verzeichnissen, die der Reihe nach von links nach rechts nach dem gewünschten Kommando durchsucht werden. Die einzelnen Verzeichnisse der Liste werden jeweils durch einen Doppelpunkt (`:') getrennt. Das erste gefundene Kommando wird dann ausgeführt. Gibt es in allen Verzeichnissen kein Kommando mit dem gesuchten Namen, so gibt UNIX eine Fehlermeldung aus (`...: Command not found.').

Schutz vor Kommandos aus unbekannter Quelle

Die Ausführung von Kommandos aus unbekannter Quelle ist immer mit einem Sicherheits-Risiko verbunden. Es könnte sich nämlich bei einem derartigen Kommando um ein `trojanisches Pferd' handeln, d.h. das Kommando macht nicht (nur) das, was es eigentlich soll, sondern es führt noch Aktionen aus, die sicher nicht im Sinne der Benutzer sind (z.B. wird das Home-Verzeichnis gelöscht oder das Kommando protokolliert Paßwörter mit und schickt sie dann einem Hacker).

Vor unbekannten Programmen schützt man sich am besten durch eine wohlüberlegte Belegung der $PATH-Variablen. Dabei sollte man mehrere Aspekte berücksichtigen:

  • Die Variable sollte nur Verzeichnisse enthalten, die von der Systemverwaltung oder von einem selbst gepflegt werden. Bei anderen Verzeichnissen kann man nicht sicher sein, ob dort nicht ein trojanischen Pferd abgelegt wurde.
    Dies setzt natürlich voraus, daß die/der Systemverwalter(in) bzw. die/der Benutzer(in) die Kommando-Verzeichnisse sorgfältig pflegt, d.h. man legt in diesen Verzeichnissen nur Kommandos aus vertrauenswürdiger Quelle ab und überprüft regelmäßig, ob die Verzeichnisse nicht heimlich von einem Hacker korrumpiert wurden.
  • In der Verzeichnis-Liste in `$PATH' sollte nie das aktuelle Arbeits-Verzeichnis `.' enthalten sein (die Begründung für die sonst möglichen Sicherheits-Probleme siehe unten).
    Kann man in seltenen Ausnahmefällen auf `.' in `$PATH' nicht verzichten, so sollte `.' wenigsten nur an letzter Stelle stehen.
  • Besitzt man eigene Verzeichnisse mit Kommandos (z.B. `$HOME/bin'), so sollten diese Verzeichnisse
    • nur für einen selbst schreibbar sein,
    • und in `$PATH' möglichst weit hinten stehen.

Gefahren bei einer falsch belegten $PATH-Variablen

Die Gefahren einer falsch gesetzten $PATH-Variablen werden anhand von 2 Beispielen verdeutlicht:

  • Das 1. Beispiel geht von folgenden Voraussetzungen aus:
    • `$PATH' hat den Wert `.:/bin:/usr/bin:/usr/local/bin'.
    • Ein Hacker hat im öffentlichen Verzeichnis `/tmp', in dem ja jeder schreiben darf, ein trojanisches Pferd mit dem Namen `ls' abgelegt.
    • Der Benutzer befindet sich gerade in `/tmp', d.h. `/tmp' ist das aktuelle Arbeits-Verzeichnis.
    • Der Benutzer führt das Kommando `ls' aus.

    In diesem Fall wird beim Start von `ls' zuerst in `/tmp' nach `ls' gesucht (`.' steht nämlich an 1. Stelle in `$PATH' und der Benutzer befindet sich gerade in `/tmp'!). UNIX wird dann natürlich sofort fündig und führt das trojanische Pferd des Hackers aus! Das eigentlich beabsichtigte System-Kommando `/usr/bin/ls' wird gar nicht erst erreicht.

  • Das 2. Beispiel unterscheidet sich vom 1. nur im Wert von `$PATH': `/bin:/usr/bin:/usr/local/bin:.'.

    Diesmal wird zwar das richtige System-Kommando `/usr/bin/ls' zuerst gefunden und auch korrekt ausgeführt.

    Allerdings passiert es gerade bei kurzen Kommandos relativ häufig, daß man sich bei der Eingabe vertippt (z.B. `la' statt dem richtigen `ls') und das Kommando ausführt, bevor man den Irrtum bemerkt und ihn korrigieren kann.

    Hacker wissen dies natürlich auch und legen deshalb z.B. in `/tmp' trojanische Pferde unter dem Namen von häufigen Tippfehler-Varianten ab.

    Befindet sich also z.B. ein trojanisches Pferd mit dem Namen `la' in `/tmp', so wird auch wieder das Hacker-Kommando beim entsprechenden Tippfehler gestartet (in `/bin', `/usr/bin' und `/usr/local/bin' befindet sich nämlich keine Datei `la').

Wie man also sieht, sollte `.' am besten überhaupt nicht in `$PATH' enthalten sein.

Achtung! In der $PATH-Variablen kann das aktuelle Arbeits-Verzeichnis nicht nur mit einem `.' sondern auch mit einer leeren Komponente angegeben werden!
Die Such-Pfade `.:/bin:/usr/bin' und `:/bin:/usr/bin' bzw. `/bin:/usr/bin:.' und `/bin:/usr/bin:' sind also z.B. jeweils gleichwertig und damit auch gleich gefährlich.

Probleme bei einer $PATH-Variablen ohne `.'

Entfernt man nun `.' aus der $PATH-Variablen, so gibt es möglicherweise kleine Probleme; dies ist aber i.a. kein Grund, `.' in `$PATH' zu lassen:

  • Schlampig programmierte Skripts und Programme funktionieren dann möglicherweise nicht mehr.

    Dies ist das einzige ernstzunehmende Gegenargument. Aber auch in diesem Fall sollte man zuerst nach einer anderen Abhilfe suchen, bevor man `.' wieder in `$PATH' aufnimmt. Ist letzteres (in seltenen Ausnahmefällen!) doch nicht zu vermeiden, so sollte `.' wie schon erwähnt in `$PATH' ganz am Schluß stehen.

  • Benutzer sind hilfslos, wenn plötzlich ein Kommando nicht mehr gefunden wird.

    Dies tritt vor allem dann auf, wenn man eigene Programme entwickelt, und dann z.B. `a.out' nicht mehr gefunden wird.

    Eine einfache Abhilfe für den Start von Kommandos im aktuellen Arbeits-Verzeichnis ist jedoch der Präfix `./'. Man tippt dann z.B. einfach `./a.out'.

  • Manche Benutzer bringen auch vor, daß das Arbeiten ohne `.' in `$PATH' viel unbequemer ist.

    Bei näherer Betrachtung ist dies jedoch nur ein Schein-Argument:

    • Deutlich mehr als 95% der verwendeten interaktiven Kommandos befinden sich in einem der Standard-Verzeichnisse und werden deshalb auch ohne den `.' in `$PATH' gefunden.
    • Beim kleinen Rest sind die 2 zusätzlichen Tastedrücke des Präfix `./' auf jeden Fall akzeptabel, wenn man den Sicherheits-Gewinn bedenkt.

Fazit

Neben dem reinen Sicherheits-Gewinn (und dies sollte alleine schon ausreichen) hat es auch noch einen weiteren Vorteil, wenn `.' nicht am Anfang der $PATH-Liste steht: Es gibt dann nämlich keine misteriösen Effekte, wenn ein Benutzer selbst Kommandos schreibt, die den Namen eines System-Kommandos haben. Beim Beispiel `ls' leuchtet dies unmittelbar ein und man kommt im Fehlerfall dem Problem relativ schnell auf die Spur.

Um einen viel unangenehmeren Fall handelt es sich beim Beispiel `test'. Oft nennen Benutzer während der Programmentwicklung das eigene Programm `test' und übersehen dabei, daß es ein System- bzw. Shell-internes Kommando `test' gibt, das sehr häufig innerhalb von Shell-Skripts verwendet wird. Als Folge davon funktionieren plötzlich einige Shell-Skripts nicht mehr und man erhält i.a. nur sehr irreführende Hinweise auf die Ursache.

Als Konsequenz der Sicherheits-Probleme hat das LRZ am 31.3.1998 in den Muster-Prologen in `/sw/share/prologdateien/' (bzw. anderer Zugriffspfad `/client/examples/prologdateien/') den `.' aus der $PATH-Variablen entfernt.

Alle Benutzer sollten in Ihrem eigenen Interesse bei den eigenen Prologen im Home-Verzeichnis analog verfahren (z.B. indem Sie sich die aktuellen Muster-Prologe des LRZ holen).

Als 2. Maßnahme wird am Juli-Wartungstag 6.7.1998 in den System-Prologen ebenfalls der `.' aus der $PATH-Variablen entfernt.
Bitte berücksichtigen Sie, daß dann Ihre Batch-Jobs evtl. mit Fehler abstürzen werden, falls Sie Ihre Batch-Skripten nicht entsprechend anpassen!
Bitte beheben Sie das Problem aus Sicherheitsgründen nicht einfach dadurch, daß Sie zum Ausgleich in Ihren eigenen Prologen im Home-Verzeichnis den `.' in der $PATH-Variablen hinzufügen! Verwenden Sie stattdessen besser bei eigenen Kommandos einen absoluten Pfad oder ergänzen Sie Ihre $PATH-Variable um Verzeichnisse mit eigenen Kommandos.