it-swarm.com.de

Die Unix-Ausführungsberechtigung kann leicht umgangen werden. Ist es überflüssig oder was ist die Absicht dahinter?

Die Unix-Leseberechtigung ist tatsächlich dieselbe wie die Ausführungsberechtigung, wenn also z. Ein Prozess hat Schreibzugriff und kann dieselbe Datei auch ausführen.

Dies kann ziemlich einfach gemacht werden: Zuerst muss dieser Prozess den Inhalt der Datei, die ausgeführt werden soll, in einen Puffer laden. Anschließend ruft es eine Funktion aus einer gemeinsam genutzten Bibliothek auf, die die ELF im Puffer analysiert und an die richtigen Adressen lädt (wahrscheinlich durch Überschreiben des alten Prozesses wie gewohnt beim Aufruf von execvp). Der Code springt zum Einstiegspunkt des neuen Programms und es wird ausgeführt.

Ich bin mir ziemlich sicher, dass Dennis Ritchie und Ken Thompson sich dieses Problems bewusst waren. Warum haben sie diese Berechtigung überhaupt erfunden, was ist die Absicht dahinter und was ist der Sinn davon, wenn es nicht verhindern kann, dass ein Prozess, bei dem ein Benutzer Lesezugriff hat, ausgeführt wird? Gibt es überhaupt einen solchen Sinn oder ist er überflüssig?

Könnte dies sogar ein ernstes Sicherheitsproblem sein? Gibt es Systeme, die auf der Stärke von rw- oder r---Berechtigungen beruhen?

59
Martin Erhardt

Es gibt eine noch einfachere Möglichkeit, die Berechtigung "Ausführen" zu umgehen: Kopieren Sie das Programm in ein Verzeichnis, das Sie besitzen, und setzen Sie das Bit "Ausführen".

Die Berechtigung "Ausführen" ist keine Sicherheitsmaßnahme. Die Sicherheit wird auf einer niedrigeren Ebene bereitgestellt, wobei das Betriebssystem bestimmte Aktionen einschränkt. Dies geschieht, weil auf vielen Unix-ähnlichen Systemen (insbesondere in den Tagen von Ritchie und Thompson) davon ausgegangen wird, dass der Benutzer seine eigenen Programme erstellen kann. In einer solchen Situation ist die Verwendung der Berechtigung "Ausführen" als Sicherheitsmaßnahme sinnlos, da der Benutzer einfach eine eigene Kopie eines vertraulichen Programms erstellen kann.

Als konkretes Beispiel können Sie fdisk als nicht privilegierten Benutzer ausführen, um zu versuchen, die Partitionstabelle der Festplatte zu verschlüsseln:

$ /sbin/fdisk /dev/sda 

Welcome to fdisk (util-linux 2.24.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

...

Changed type of partition 'Linux' to 'Hidden NTFS WinRE'.

Command (m for help): w
fdisk: failed to write disklabel: Bad file descriptor

Diese letzte Zeile ist fdisk, der versucht, einen "Schreib" -Dateideskriptor für die Festplatte zu erhalten, und der fehlschlägt, weil der Benutzer, den ich ausführe, keine Berechtigung dazu hat.

Die Berechtigung "Ausführen" dient zwei Zwecken: 1) dem Betriebssystem mitteilen, welche Dateien Programme sind, und 2) dem Benutzer mitteilen, welche Programme ausgeführt werden können. Beides ist eher beratend als obligatorisch: Sie können ohne Erlaubnis ein perfekt funktionierendes Betriebssystem erstellen, aber es verbessert die Benutzererfahrung.

Wie R .. hervorhebt, gibt es einen besonderen Fall, in dem die Berechtigung "Ausführen" aus Sicherheitsgründen verwendet wird: Wenn für ein Programm auch das Bit "setuid" gesetzt ist. In diesem Fall kann die Berechtigung "Ausführen" verwendet werden, um einzuschränken, wer das Programm ausführen darf. Bei jeder Methode zum Umgehen der Berechtigung "Ausführen" wird auch der Status "Setuid" entfernt, sodass hier kein Sicherheitsrisiko besteht.

80
Mark

Sie können das Ausführungsbit, aber nicht das Lesebit für eine ausführbare Datei setzen. Auf diese Weise kann niemand die Datei kopieren, aber die Benutzer können sie trotzdem ausführen.

Dies ist heute ziemlich sinnlos, da a) es nur für kompilierte Programme funktioniert, nicht mit Skripten (auf den meisten Systemen); b) Heutzutage, da 90% aller Unixe Linux sind, können Benutzer ausführbare Dateien von nahezu jedem Ort kopieren, und c) der Speicherplatz, den eine kopierte ausführbare Datei belegt, spielt keine Rolle.

Trotzdem gab es früher Verwendungszwecke dafür.

Das Unix-System, das ich vor 30 Jahren in der Schule verwendet habe, war in Bezug auf RAM und Speicherplatz) sehr begrenzt. Insbesondere das Dateisystem /usr/tmp War sehr klein, was zu Problemen führte, wenn Jemand hat versucht, ein großes Programm zu kompilieren. Natürlich sollten die Schüler sowieso keine "großen Programme" schreiben. Große Programme waren normalerweise Quellcodes, die von "irgendwo" kopiert wurden. Viele von uns haben /usr/bin/cc nach /home/<myname>/cc Und benutzte dd, um die Binärdatei zu patchen, um /tmp Anstelle von /usr/tmp Zu verwenden, was größer war. Natürlich machte dies das Problem nur noch schlimmer - den Speicherplatz Die Belegung dieser Kopien war damals von Bedeutung, und jetzt füllte sich /tmp regelmäßig, sodass andere Benutzer ihre Dateien nicht mehr bearbeiten konnten. Nachdem sie herausgefunden hatten, was passiert war, führten die Systemadministratoren einen chmod go-r /bin/* /usr/bin/* durch, der "behoben" wurde "das Problem und löschte alle unsere Kopien des C-Compilers.

Eine andere Verwendung besteht darin, der Shell mitzuteilen, welche Dateien ausgeführt werden sollen und welche nicht. Sie möchten nicht, dass eine zufällige Textdatei ausgeführt wird, weil Sie ihren Namen eingegeben haben. Das x-Bit bietet eine Möglichkeit, dies zu verhindern. (Heutzutage konnte die Shell nur den Anfang der Datei betrachten und sie nur ausführen, wenn sie mit #! Beginnt, dies wurde jedoch viel später eingeführt.) Die Vervollständigungsfunktion von bash schlägt ebenfalls nur Dateien mit ausführbaren Bits vor, wenn Sie einen Befehl eingeben.

Es gibt eine vorgefertigte Möglichkeit, eine beliebige Datei auszuführen: Übergeben Sie sie als Argument an den dynamischen Linker (der der geeignete Interpreter für eine dynamisch geladene ausführbare Datei ist). Z.B. unter Linux,

cp /bin/ls /tmp/
chmod -x /tmp/ls
/lib/ld-linux.so.2 /tmp/ls

Dies unterliegt jedoch der gleichen Einschränkung wie das Lesen der Datei und das Springen zum Code: Die Bits setuid werden nicht ausgewertet.

Früher hatten wir oft Binärdateien wie /bin/su:

-rwsr-xr-- root wheel  ...  /bin/su

Nur Mitglieder der Gruppe wheel, die von den Systemadministratoren auf Personen gekürzt wurden, die das Kennwort root kennen, können den Befehl su ausführen, selbst wenn ein Pufferüberlauf vorliegt In dieser Binärdatei, die es Anrufern ermöglicht, die Sicherheit zu umgehen, kann der Exploit nur von Personen verwendet werden, die das Kennwort ohnehin kennen.

7
Simon Richter

Ich bin überrascht, dass niemand sonst auf eine andere Verwendung von + x Bit verwiesen hat: Verzeichnisse. Vielleicht sind Sie nach der Ausführung von (Beispiel) etwas in/bin (Shell-Skript oder auf andere Weise), aber es gibt mehr, um Bits als Dateien auszuführen (natürlich ein Verzeichnis IS eine Datei, aber es ist eine andere Art von Datei).

Wenn Sie + x Zugriff auf ein Verzeichnis haben, aber -r auf dasselbe Verzeichnis, haben Sie die folgenden Funktionen:

  • Wenn Sie den Namen einer Datei (oder eines Verzeichnisses) in diesem Verzeichnis kennen, können Sie ihn auflisten (z. B. ls darauf). Sie müssen jedoch den Namen kennen.
  • Sie können nicht darauf zugreifen (über den Befehl cd oder den Systemaufruf chdir).

Wenn Sie jedoch -x und + r haben, können Sie Folgendes tun:

  • Sie können nicht in das Verzeichnis wechseln (wie oben).
  • Sie können die Dateien auflisten. Da Sie jedoch keinen + x-Zugriff auf das Verzeichnis haben, können Sie nicht auf die Dateien selbst zugreifen.
  • Dies bedeutet auch, dass Sie nicht aktualisieren können (nur Zeitstempel oder auf andere Weise) und sie auch nicht in einem Texteditor (oder cat oder ...) öffnen können.

Wenn Sie + rx haben, können Sie all das tun (außer dass Sie + w benötigen, um in das Verzeichnis selbst zu schreiben, dh neue Dateien erstellen; Dateien bearbeiten funktioniert, Entfernen funktioniert nicht, Erstellen nicht).

Und ja, dies bedeutet, dass einige Personen Dateien anzeigen oder bearbeiten können, jedoch nur, wenn sie den genauen Pfad dazu kennen (sofern sie ohnehin die Rechte zum Bearbeiten haben). Und ja: ls ist eine Liste und das gilt für die Suche nach Verzeichnissen. Zusammenfassend lässt sich sagen, dass die Ausführung eines Verzeichnisses in dieses Verzeichnis geändert wird (aus welchem ​​Grund auch immer). Natürlich ist das Ganze wirklich wichtig.

6
user54909

Wenn Sie aus irgendeinem Grund den Binärcode geheim halten möchten, können Sie das Programm ausführbar machen, ohne lesbar zu sein. Dies ist nicht sinnvoll, wenn diese Benutzer physischen Zugriff auf den Computer haben. Es ist auch nicht sinnvoll, wenn der Quell- oder Binärcode allgemein verfügbar ist. Dies ist also ein ziemlich begrenzter Anwendungsfall.

Wenn das Programm ein Setuid- oder Setgid-Bit hat, bewirkt der Ausführungszugriff mehr als das, was durch Lesen der Binärdatei erreicht werden kann. Ein Ansatz besteht darin, eine ausführbare setuid-Datei zu erstellen, die nur für eine bestimmte Gruppe ausführbar ist. Wenn es weltweit lesbar war, konnten Personen außerhalb dieser Gruppe es immer noch nicht kopieren und das setgid-Bit in der ursprünglichen ausführbaren Datei verwenden. (In den meisten Fällen würde ich jedoch lieber setgid als setuid verwenden und dann die Gruppe im Verzeichnis verwenden, um zu steuern, wer auf die ausführbare Datei zugreifen kann.)

Normalerweise wird das ausführbare Bit einfach verwendet, um anzugeben, welche Dateien überhaupt Programme sind. Auf diese Weise kann die Fertigstellung besser funktionieren und Sie führen nicht versehentlich unerwünschte ausführbare Dateien aus.

Wenn Sie verhindern möchten, dass Benutzer eine ausführbare Datei kopieren und ausführen, können Sie Home-Verzeichnisse mit noexec bereitstellen. Damit dies sinnvoll ist, müssen Sie noexec für jedes Dateisystem verwenden, in das der Benutzer alles schreiben kann.

4
kasperd

Die Berechtigung zum Ausführen von Bits wird vom Kernel beim Ausführen des Systemaufrufs exec (2) (und Cousins) überprüft. Sie benötigen es nur, um Programme auf Kernel-Ebene auszuführen.

Nur Programme mit diesem Bit (je nachdem, was Sie als Eigentümer, Gruppe oder andere trifft, werden überprüft) können vom Kernel exec () ed ==.

Eine andere Sache ist, was die Shell tut, wenn sie ein Shell-Skript oder Perl interpretiert, oder welchen Interpreter Sie auch haben mögen. Bei Skripten überprüft der Kernel das #!... am Anfang der Datei als magische Zahl und startet die dort angegebene Shell (Sie benötigen auch die Ausführungsberechtigung für die Shell), und Sie brauchen = Leseberechtigungen für dieses Skript, da die Shell es öffnen und lesen muss, um interpretiert zu werden. Für Shell-Skripte benötigen Sie Leseberechtigung sowie Ausführungsberechtigung. Für Shell-Skripte benötigen Sie jedoch nur Leseberechtigung, da Sie ein Shell-Skript immer ausführen können, indem Sie die Shell ausführen und das Shell-Skript als Parameter übergeben (oder Eingabedatei)

Natürlich kann das Ausführungsbit, wie bereits erwähnt, umgangen werden, indem das Programm kopiert und ausführbar gemacht wird. Sie können es jedoch nicht kopieren, wenn Sie keine Leseberechtigung zum Erstellen dieser Kopie haben (fahren Sie fort) um es ausführen zu können).

Versuchen Sie (natürlich als Root) die Berechtigungen in ls (1) zu ändern und machen Sie es 0111 (---x--x--x) und versuchen Sie, eine ausführbare Kopie davon zu erstellen, und sehen Sie, wie Sie Ihre ausführbare Kopie nicht erhalten können, selbst wenn Sie sie weiterhin ausführen können.

In Verzeichnissen bedeutet Ausführungsbit etwas anderes. Der Kernel verwendet die Berechtigung 'x', wenn er den Pfad durchläuft (in der Kernelfunktion namei ()). Wenn Sie also keine Ausführungsberechtigungen für ein Verzeichnis haben, können Sie diese auch nicht verwenden es, noch die Dateien, auf die zugegriffen werden kann. Selbst Sie können einen Verzeichnisinhalt mit Leseberechtigungen lesen, aber Sie können nicht auf die darin enthaltenen Dateien zugreifen. Im Gegenteil, Sie können Ausführungsberechtigungen für ein Verzeichnis haben, aber keinen Lesezugriff, und Sie können die darin enthaltenen Dateien verwenden, aber den Verzeichnisinhalt nicht sehen.

2
Luis Colorado