Frage Kann ein Programm sagen, dass es unter sudo läuft?


Ich habe ein Programm, das sich anders verhalten sollte, wenn es unter "sudo" ausgeführt wird. Kann man herausfinden, ob es unter sudo läuft?

Aktualisieren: Jemand fragte, warum ich das machen wolle. In diesem Fall gibt es auf einem Mac, der MacPorts verwendet, eine Ausgabe, die Sie anweist, einen bestimmten Befehl auszuschneiden und einzufügen. Wenn der Befehl "MacPorts" mit "sudo" ausgeführt wurde, sollte sudo im Beispielbefehl enthalten sein:

$ sudo port selfupdate 
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.2.1 installed,
MacPorts base version 2.2.1 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

^^^^^^^^^ it would be really sweet if it output "sudo port upgrade outdated" instead.  It would be even better if it just did it for you :-)

26
2018-01-20 22:12


Ursprung


Ich bin neugierig: Kannst du erklären, wie es sich anders verhalten soll? - sciurus
@Sciurus ist normalerweise der allgemeine Anwendungsfall in einem Installationsskript, das root-Rechte erfordert; wenn du sie nicht hast, stirb sofort. - Nick T
Das klingt wie meta.stackexchange.com/questions/66377/was-ist-the-xy-problem/... . Was bist du? Ja wirklich willst du machen? - Jenny D
Ich erinnere mich vage an einen Befehl, der sich bewusst ist, dass er als root ausgeführt wird oder nicht ... Ich denke, die Antwort lautet "ja". - Rolf


Antworten:


Ja, es sind 4 Umgebungsvariablen gesetzt, wenn ein Programm unter sudo läuft:

$ sudo env |grep SUDO
SUDO_COMMAND=/usr/bin/env
SUDO_USER=tal
SUDO_UID=501
SUDO_GID=20

Beachten Sie, dass diese durch einfaches Setzen gefälscht werden können. Vertraue ihnen nicht auf etwas Kritisches.

Zum Beispiel: In diesem Programm müssen wir dem Benutzer mitteilen, dass er ein anderes Programm ausführen soll. Wenn der aktuelle mit sudo ausgeführt wurde, wird der andere auch sein.

#!/bin/bash

echo 'Thank you for running me.'

if [[ $(id -u) == 0 ]]; then
  if [[ -z "$SUDO_COMMAND" ]]; then
    echo 'Please now run: next_command'
  else
    echo 'Please now run: sudo next_command'
  fi
else  echo 'Error: Sadly you need to run me as root.'
  exit 1
fi

Beachten Sie, dass es nur für eine SUDO_ * -Variable testet, wenn es zuerst beweisen kann, dass es als root ausgeführt wird. Selbst dann wird es nur verwendet, um einen hilfreichen Text zu ändern.


44
2018-01-20 22:12



Was würde ich für "irgendetwas Kritisches" verwenden? - Kevin
@Kevin, wenn jemand mit seiner Umgebung schraubt, um vorgeblich erhöhte Privilegien zu haben, dann wissen sie hoffentlich was sie tun und werden die Konsequenzen akzeptieren. - Nick T
Downvoted weil jede Antwort, die durch "traue ihnen nicht für etwas Kritisches" qualifiziert werden muss, überhaupt keine Antwort ist, sondern ein hässlicher Hack. - Stephen C


Dies beantwortet die Frage nicht direkt, aber ich glaube nicht, dass hier die richtige Frage gestellt wird. Es scheint mir, dass der Fragesteller ein Programm will, das sich vermutlich anders verhält, wenn es bestimmte Berechtigungen hat oder nicht, aber ich würde argumentieren, dass das Überprüfen von Sudo nicht der richtige Weg ist. Erstens können viele Systeme kein "sudo" implementieren, es ist unter Linux oder vielen Unixen keineswegs erforderlich.

Zum Beispiel kann ein Benutzer bereits als root angemeldet sein, was das sudo sinnwidrig macht oder vielleicht hat das System nicht root-Benutzer, die noch Fähigkeiten haben, um die administrative Aufgabe auszuführen, die das Programm möglicherweise ausführen möchte. Schließlich hat das System vielleicht überhaupt kein root oder sudo und verwendet statt dessen ein obligatorisches Zugriffskontrollsystem mit verschiedenen Fähigkeiten, ohne dass alle Superuser, in die sudo versetzt werden kann. Oder der Benutzer könnte sudoed werden, aber in ein Konto, das aus Sicherheitsgründen keine Berechtigungen als sein eigenes Konto hat (Ich führe oft nicht vertrauenswürdigen Code mit einem temporären nicht privilegierten Benutzer aus, der nur auf Ramdisks schreiben kann, um meine Berechtigungen nicht zu erhöhen ). Es ist insgesamt eine schlechte Idee, ein bestimmtes Berechtigungsmodell wie sudo oder das Vorhandensein von root anzunehmen oder davon auszugehen, dass ein sudoed-Benutzer bestimmte Berechtigungen besitzt.

Wenn Sie herausfinden wollen, ob Sie Berechtigungen zum Ausführen einer Operation haben, ist der beste Weg in der Regel einfach zu versuchen, es zu tun, dann errno auf Berechtigungsprobleme überprüfen, wenn es fehlschlägt oder wenn es eine mehrstufige Operation ist, die entweder alle fehlschlagen oder alle erfolgreich sein müssen Sie können überprüfen, ob eine Operation mit Funktionen wie POSIX funktioniert Zugriff Funktion (Vorsicht vor möglichen Rennbedingungen hier, wenn Berechtigungen aktiv geändert werden)

Wenn Sie zusätzlich den echten Benutzer hinter dem sudo kennen müssen, können Sie das verwenden getlogin Funktion, die für jede interaktive Sitzung mit einem zugrunde liegenden Terminal funktionieren sollte und es Ihnen beispielsweise ermöglichen würde, zu finden, wer den Befehl zum Auditing "wirklich" ausführt oder das Home-Verzeichnis des realen Benutzers zum Speichern von Protokollen findet.

Schließlich, was Sie wirklich wollen, ist herauszufinden, ob ein Benutzer Root-Zugriff (immer noch eine schlechte Idee, aber weniger Implementierung spezifisch), die Sie verwenden können Getuid um nach einer UID von 0 und somit nach root zu suchen.


11
2018-01-21 10:57





Es gibt zwei Mechanismen, die verwendet werden können.

  • Das Überprüfen der Umgebungsvariablen kann in beide Richtungen gefälscht werden, ist aber am einfachsten zu machen. growisofs möchte nicht unter SUDO laufen, also lösche ich die SUDO-Variablen in Skripten, in denen ich sie verwende. Es kann in die andere Richtung gefälscht werden. (Die SUDO-Variable wird auch für Skripts, die unter den Befehlen at und batch ausgeführt werden, in die Umgebung übertragen.)
  • Eine andere Möglichkeit zu sehen, ob Sie unter sudo ausgeführt werden, besteht darin, die Prozessliste von Ihrem übergeordneten Prozess auf die Suche nach sudo zu führen. Es wäre schwer zu verbergen, dass du auf diese Weise unter Sudo gelaufen bist, aber es ist komplexer. Es ist immer noch möglich zu fälschen, dass Sie unter sudo laufen.

Es ist üblicher, zu überprüfen, ob Sie als der geeignete Benutzer ausgeführt werden. Das id Befehl kann dazu verwendet werden. TomOnTime verwendet das Skript id Befehl, um zu bestimmen, ob sudo ist möglicherweise erforderlich, um den nächsten Befehl auszuführen.


7
2018-01-21 01:54



> Es wäre schwer zu verbergen, dass du auf diese Weise unter Sudo gelaufen bist Könntest du das nicht einfach umbenennen? sudo binär zu etwas anderem? Oder nennen Sie eine andere ausführbare Datei sudo das Gegenteil vortäuschen? Nicht, dass ich wirklich erwarten würde, dass irgendjemand das vernünftig macht ... - Bob
@Bob würdest du brauchen root Zugriff zum Umbenennen der sudoausführbar. Ein normaler Benutzer wäre dazu nicht in der Lage. Ich habe bemerkt, dass du vortäuschen kannst, dass du unterläufst sudo. Das Umbenennen eines vorhandenen Programms würde funktionieren. Der Code, der für eine dedizierte Fälschung benötigt wird sudo Programm ist trivial. - BillThor
Sie können einfach die Sudo-Binärdatei von irgendwo herunterladen und ihr die richtigen Berechtigungen geben ... - Jens Timmerman
@JensTimmerman Sie benötigen einen root-Zugang, um die richtigen Berechtigungen zu erhalten. Wenn Sie es nur umbenennen oder hart verknüpfen können. Keine Notwendigkeit, es herunterzuladen. Wenn Sie SUID in einer Zielbenutzer-ID installieren (falls dies möglich ist), müssen Sie die Ziel-Benutzer-ID bereits kompromittiert haben. - BillThor
Ah, richtig, es weigert sich, ohne setuid zu arbeiten, mein Schlechter ... - Jens Timmerman


Sie können die effektive und die echte Benutzer-ID vergleichen.

Dies bedeutet nicht unbedingt, dass es Sudo Sudo ausführt (könnte auch gesetzt werden), zeigt aber an, dass das Programm mehr Rechte hat, als der Benutzer erwarten kann. (zum Beispiel in einem Programm, das normalerweise ohne solche Rechte ausgeführt wird, aber während der Installation oder zur Installation von Updates mit ihnen ausgeführt werden muss. Dann können Sie dies verwenden, um eine Warnung darüber zu geben).


2
2018-01-21 11:47



Nee, sudo legt sowohl die effektive als auch die echte ID fest. Im Gegensatz zu suid, was nicht der Fall ist. Hier ist ein triviales C-Programm, das Sie zum Testen verwenden können (Entschuldigung, der Kommentar entfernt neue Zeilen, Sie müssen sie wieder hinzufügen): #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { printf("real = %i, effective = %i\n", getuid(), geteuid()); return 0; } - derobert
... oder alternativ, perl -E 'say $<, "\n", $>' - derobert


Sie können die effektive UID-Variable (EUID) wie folgt überprüfen:

if [[ $EUID -eq 0 ]]; then
    echo "running as root"
else
    echo "not running as root"
fi

2
2018-05-20 09:28



Dies beantwortet die Frage nicht. Der Code gibt die gleiche Ausgabe aus, wenn er als root ausgeführt wird, wie wenn er als sudo ausgeführt wird. - Stephen C
@ StephenC - Ich denke, dass es für die Zwecke des OP keinen Unterschied gibt. IMHO ist es ihr Ziel, Sudo-Ausführung oder -Ausführung von einer authentischen Root-Shell ohne Unterschied zu identifizieren. - Eliran Malka
Ich denke, du könntest recht haben. Ich kam hierher, weil ich nicht verstand warum sudo echo $USER Gibt den nicht privilegierten Benutzernamen aus (die Variable wird vor dem sudo ersetzt). Ich habe Ihren Code tatsächlich in meinem Skript verwendet. Vielen Dank! - Stephen C
herzlich willkommen :) - Eliran Malka


Sie können eine Datei in berühren /root und dann if -e es. Und wenn -e wahr ist, rm (Überprüfen Sie den Fehlercode), damit Ihr Test das nächste Mal funktioniert.

Überprüfen des Fehlercodes (oder Rückkehrcodes) nach dem rm hindert jemanden daran, sudo-Befugnisse zu verwenden, um die Datei zu erstellen, um einen Streich auf dich zu spielen.


-1
2018-01-21 06:36



Diese Antwort prüft, ob der Prozess Schreibberechtigung hat /root (was nicht unbedingt dasselbe ist wie UID 0), prüft aber nicht, ob diese Berechtigungen mit verwendet wurden sudo. - Ladadadada
Ja, die "tausend Wege, eine Katze zu häuten"; Als ich die Antwort schrieb, dachte ich an weitere 4 oder 5 Dinge, also wickelte ich sie ein. - Chris K


Ich habe festgestellt, dass dies gut funktioniert

[ $(cat /proc/$PPID/loginuid) -ne 0 ] && [ "$USER" == "root" ]

-2
2017-10-01 15:47



Das funktioniert nicht, wenn ich es auf FreeBSD, Centos7 oder MacOS X versuche. Ich denke du meinst "/ proc" anstelle von "/ etc". Aber selbst mit dieser Änderung funktioniert es bei keinem dieser drei. "$ USER" wird von sudo zurückgesetzt. Meintest du $ SUDO_USER? Meinst du auch "[[" statt "["? - TomOnTime
Ich habe das Beispiel behoben. Im Grunde ist die Suche nach loginuid nicht gleich 0, aber der Benutzer ist root. - ruckc