Prüfe, ob ein Befehl in Bash existiert (einschließlich Superusern)

8

Ich möchte überprüfen, ob ein Programm auf einem UNIX-System installiert ist.

Ich könnte Befehle wie:

verwenden
  • command -v ,
  • hash ,
  • type ,
  • which ...

... und alle von ihnen sind bereits erwähnt in diese Antwort .

Allerdings funktioniert keiner von ihnen, wenn ich testen möchte, als normaler Benutzer , ob ich oder ein Superuser einen bestimmten Befehl ausführen kann.

Hier ist ein Beispiel, was ich meine:

%Vor%

Wie Sie sehen, hat der normale Benutzer nichts über das Vorhandensein des Befehls poweroff erfahren. Beachten Sie, dass die Dummy-Benutzer auf jeden Fall sehen können, was sich in /sbin befindet.

    
rr- 28.06.2013, 17:12
quelle

2 Antworten

13

Quelle des Problems

Der Grund, warum die Befehle, die Sie versucht haben, nicht funktionieren, ist, dass sie nur nach ausführbaren Dateien in $PATH variable suchen. Lasst uns zuerst unsere Hypothese testen.

%Vor%

Das bestätigt meine obige Aussage.
Sehen wir uns an, wie $PATH für verschiedene Benutzer aussieht:

%Vor%

Um zu überprüfen, ob ein gegebener Befehl für einen bestimmten Benutzer verfügbar ist (in Ihrer Frage, nämlich: root), müssen Sie seine Umgebungsvariable $PATH kennen.

Die Lösung

Die Werte solcher Umgebungsvariablen auf Debian können normalerweise in /etc/profile und in /etc/environment/ Dateien gefunden werden. Es gibt keine einfache Möglichkeit, diese Werte zu erhalten, indem man sie aus Dateien herausfischt.

Die einfachste Lösung besteht darin, bekannte Verzeichnisse vorübergehend der Variablen $PATH hinzuzufügen und dann command -v :

zu verwenden %Vor%

Es gibt ein Problem mit dieser Lösung: Wenn Sie portierbar sein wollen, wissen Sie nicht wirklich, welche Ordner Sie verketten sollten. In den meisten Fällen sollte dieser Ansatz jedoch ausreichend sein.

Alternative Lösung

Was Sie stattdessen tun können, ist ein script -Programm zu schreiben, das setuid bit . Das Setuid-Bit ist eine etwas versteckte Eigenschaft von Linux-Betriebssystemen, die es Programmen ermöglicht, mit ihren Besitzerrechten ausgeführt zu werden. Sie schreiben also ein Programm, das einige Befehle wie Superuser ausführt, außer dass es von normalen Benutzern ausgeführt werden kann. Auf diese Weise können Sie die Ausgabe von command -v poweroff sehen, wie es ein root tun würde.

Leider können Dinge, die Shebang verwenden, nicht das Setuid-Bit , so dass Sie kein Shell-Skript dafür erstellen können und Sie brauchen ein Programm in C. Hier ist ein Beispielprogramm, das den Job erledigen würde:

%Vor%

Sicherheitshinweis : Die obige Version hat eine sehr einfache Argumentvalidierung (sie lässt nur Strings durch, die mit ^[a-z]*$ übereinstimmen). Echtes Programm sollte wahrscheinlich eine bessere Validierung beinhalten.

Testen

Angenommen, wir haben die Datei in test.c gespeichert. Wir kompilieren es und fügen setuid bit hinzu:

%Vor%

Beachten Sie, dass chown vor chmod geht. Das 4 vor dem üblichen 755 Muster ist das setuid Bit.
Jetzt können wir das Programm als normaler Benutzer testen.

%Vor%

Und das Beste von allem - es ist portabel genug, um mit Cygwin ohne Probleme zu arbeiten. :)

    
rr- 28.06.2013, 17:12
quelle
3

Die wirkliche Antwort ist, dass Sie den "any superuser" Aspekt nicht erfüllen können, wenn Sie meinen: "Erscheint dieser Befehl im Suchpfad eines Benutzers mit sudo Zugriff?". Der Grund ist, dass Sie die Startskripte jedes Benutzers ausführen müssen, um herauszufinden, wie sein Suchpfad letztendlich aussieht - viele Benutzer fügen ihre eigenen ~ / bin oder ~ / pod / abi / x86_64-ubu-1204 / bin oder was auch immer hinzu und Gott weiß was noch (/ afs / bin, irgendjemand?) - und viele Startskripte haben Nebenwirkungen, die das Ganze in ein echtes Chaos verwandeln könnten, einschließlich der Erzeugung von Protokollen, dem Starten von Dämonen verschiedener Art und so weiter. Sie werden wirklich in Schwierigkeiten geraten, wenn eines der Startskripte dieser Benutzer versucht, den neuen Befehl selbst auszuführen, da sie dann eine Rekursion durchführen und auf Ihrem eigenen System einen Denial-of-Service-Angriff auslösen.

Was Sie noch sicherer testen können:

  • kann jemand einen Befehl ausführen, der durch den vollständigen Pfadnamen gegeben ist? (überspringt das Startskriptwahnsinn)
  • kann der aktuelle Benutzer den einfachen (nicht vollständig pathed) Befehl ausführen?
  • kann der aktuelle Benutzer den einfachen Befehl mit sudo ausführen? (Dies macht einige Annahmen über Startskripte von root)
  • kann jeder Benutzer, der eine Standardumgebung ausführt, den Befehl ausführen? (Verwenden Sie einen Dummy-Benutzer mit einer bekannten Konfiguration).

Auf einem größeren System mit Tausenden von Benutzern ist die Option "Jeder" nicht praktikabel. Ältere Sites werden KEINE root-fähigen Befehle wünschen, die die Skripte beliebiger Benutzer ausführen, auch nicht die von sudo-fähigen, allgemein vertrauenswürdigen Admins.

    
Alex North-Keys 28.06.2013 22:33
quelle

Tags und Links