So können Benutzer ein Skript ausführen, ohne geschützte Informationen preiszugeben

476
WTK

In Anbetracht der Tatsache, dass der Root-Benutzer über einige Anmeldeinformationen verfügt (z. B. einen API-Schlüssel), die in einer Umgebungsvariablen festgelegt sind, und einem nicht privilegierten Benutzer John. Wie kann ich John ein Skript ausführen lassen, das den API-Schlüssel verwendet, ohne dass der Wert an John verloren geht ?

1
Es fühlt sich für mich an, dass Sie ein Proxy-Programm haben müssen, das unter dem Root-Benutzer ausgeführt wird, der die Arbeit für John übernimmt und die Informationen zurückgibt, die John wünscht. Mokubai vor 6 Jahren 4
Hmm, @Mokubai weitere Hinweise oder Beispiele, auf die ich mich verlassen kann? Und zu einem anderen Hinweis - Ich habe gelesen, dass ich mit einem Hokuspokus das Skript ausführbar machen kann, aber nicht lesbar ist. Würde das in diesem Fall funktionieren? WTK vor 6 Jahren 0
Ich sehe keine Möglichkeit, ein Skript ausführbar zu machen, aber irgendwie nicht lesbar. Sie können das Skript als einen anderen Benutzer ausführen, aber Sie müssen dem Benutzer entweder das Kennwort oder die Berechtigung "sudo" erteilen, um das Skript auszuführen. Ich kann kaum glauben, dass es absolut sicher ist, um ein einfaches Lesen zu verhindern. Wenn Sie Beweise für das Gegenteil haben, wäre das gut zu beweisen. Ich habe keine Beispiele zur Hand, wie es gemacht werden sollte, es gibt zu viele Möglichkeiten und wir haben keine Ahnung, welche Einschränkungen Sie haben, außer diesen Schlüssel nicht zu verlieren. Mokubai vor 6 Jahren 0

1 Antwort auf die Frage

2
G-Man

Die Frage scheint ein wenig unscharf zu sein.

  • Die Frage an sich spricht davon, einen Wert aus einer "Super-User-Umgebungsvariablen" (dh einer "Root-Umgebungsvariablen") zu erhalten. Ich bin mir nicht mal sicher, was das bedeutet. Wollen Sie damit sagen, dass John den Wert aus der Umgebung eines (anderen) Benutzers erhalten soll, der als "root" angemeldet ist oder der als "root" durch suoder ausgeführt wird sudo? Oder sprechen Sie von der Umgebung eines Prozesses (wahrscheinlich eines Hintergrundprozesses), der als "root" ausgeführt wird?

    Was auch immer Sie dabei vor Augen haben, das klingt so, als sei der Schlüssel sehr dynamisch und kurzlebig. Da ich nicht verstehe, was das bedeutet, kann ich nicht sagen, dass es unmöglich ist, aber es hört sich schwierig an.

  • In einem Kommentar sprechen Sie jedoch davon, ein Skript ausführbar, aber nicht lesbar zu machen. Dies legt nahe, dass Sie bereit sind, den Schlüssel fest in das Skript aufzunehmen, solange Benutzer, die keine Root-Benutzer sind, ihn nicht lesen können. Dies legt nahe, dass der Schlüssel sehr statisch ist und sich so selten ändert, dass Sie das Skript jedes Mal ändern möchten, wenn sich der Schlüssel ändert.

    U & L hat zu diesem Thema einen langen Thread: Kann ein Skript zwar ausführbar, aber nicht lesbar sein?   Leider sind die meisten Antworten negativ, oder Ablenkungen, Ablenkungen oder Problemumgehungen, von denen einige besser funktionieren als andere. Santana schlägt beispielsweise vor, einen Eintrag zu erstellen /etc/sudoers, mit dem John das Skript mit erhöhten Berechtigungen ausführen kann, ohne es als sich selbst lesen zu können. Wenn das Skript jedoch keine erhöhten Berechtigungen benötigt (außer zum Abrufen des Schlüssels), möchten Sie es nicht mit erhöhten Berechtigungen ausführen.

    Zu dieser verwandten Frage (zu Super User) präsentiere ich jedoch einen einfachen Weg, um ein Skript ausführbar zu machen, aber nicht lesbar, indem es in ein C-Programm eingebunden wird. Wie ich in dieser Antwort erkläre, ist diese Technik nicht narrensicher. Es gibt Möglichkeiten, wie Informationen auslaufen können.

  • Die sinnvollste / plausibelste Interpretation, IMHO, ist, dass der Schlüssel in einer Datei gespeichert wird, die John nicht lesen kann. Die traditionelle Implementierung solcher Vereinbarungen ist setUID und / oder setGID. ( sudoist auch nützlich.)

Hier ist ein Beispiel, wie das geht. Schreiben Sie ein C-Programm wie folgt:

#include <stdio.h> #include <stdlib.h>  #define KEY_FILE (passender Pfadname) #define SCRIPT (passender Pfadname)  Main() { FILE * key_fp; Zeichenschlüssel [80]; (gegebenenfalls anpassen) gid_t gid; uid_t uid; Zeichen * Args [10]; (gegebenenfalls anpassen)  key_fp = fopen (KEY_FILE, "r"); if (key_fp == NULL) { perror (KEY_FILE); Ausfahrt (1); } (Ihr Code zum Lesen und Bestätigen des Schlüssels ) fclose (key_fp); if (setenv ("KEY", Schlüssel, 1)! = 0) { fprintf (stderr, "Problem mit setenv (). \ n"); Ausfahrt (1); } gid = getgid (); uid = getuid (); // benutzen // if (setresgid (gid, gid, gid)! = 0 || setresuid (uid, uid, uid)! = 0) // wenn sie verfügbar sind; Andernfalls if (setregid (gid, gid)! = 0 || setreuid (uid, uid)! = 0) { fprintf (stderr, "Privilegien für das Löschen von Problemen. \ n"); Ausfahrt (1); } args [0] = "Skriptname"; (gegebenenfalls anpassen) args [1] = NULL; execv (SCRIPT, args); perror (SCRIPT); Ausfahrt (1); }

Definieren Sie KEY_FILEden vollständigen Pfadnamen der Datei, die den Schlüssel enthält, und definieren Sie SCRIPTden vollständigen Pfadnamen der Datei, die das Skript enthält. Stellen Sie sicher, dass John Lesezugriff auf das Skript hat, jedoch nicht auf die Schlüsseldatei, und dass er keinen Schreibzugriff auf eines der Verzeichnisse in beiden Pfaden hat. Sorgen Sie dafür, dass dieses Programm die Schlüsseldatei lesen kann, indem Sie es als setUID und / oder setGID festlegen. Es liest den Schlüssel, fügt ihn in die Umgebung ein, löscht Berechtigungen und führt das Skript aus. (Möglicherweise möchten Sie den obigen Code so ändern, dass die dem Programm angegebenen Befehlszeilenargumente an das Skript übergeben werden.)

Wie oben erwähnt, wird das Skript mit Johns UID und GID ausgeführt, jedoch mit dem Schlüssel in der Umgebung. Auf einigen Systemen kann es für John möglich sein, die Umgebung des Skripts von oder mit zu lesen . In diesem Fall kann es hilfreich sein, das Skript den Schlüssel sofort in eine lokale (nicht exportierte) Variable zu kopieren und die Variable aufzuheben ./proc/(pid_of_script)/environpsKEY

Es ist wahrscheinlich sicher, dass das Skript den Schlüssel an ein Programm weitergibt

  • durch ein Rohr (z. B. ),printf "%s" (key_value) | (program)
  • durch ein hier Dokument oder
  • durch einen Here-String.

Die Risiken der Weitergabe des Wertes durch die Umwelt sind oben erwähnt. Vermeiden Sie es, es als Befehlszeilenparameter zu übergeben, da dies definitiv durch gesehen werden kann ps.

Wenn Sie das Programm lauffähig machen möchten sudo, müssen Sie möglicherweise Johns UID und GID hartcodieren, da sudodie realen und die effektiven IDs festgelegt werden.