Was tun setresuid()
und setresgid()
tun?
Um dieses Beispiel besser zu verstehen, müssen wir uns diese beiden Funktionen und die drei Parameter ansehen, die sie annehmen.
Aus dieser Antwort (und der Manpage "credentials(7)":
Unter Linux hat jeder Prozess die folgenden Benutzer- und Gruppenkennungen:
-
Echte Benutzer-ID und echte Gruppen-ID. Diese IDs bestimmen, wem der Prozess gehört. Zusammenfassend ist dies wer Sie sind .
-
Effektive Benutzer-ID und effektive Gruppen-ID. Diese IDs werden vom Kernel verwendet, um die Berechtigungen zu bestimmen, die der Prozess beim Zugriff auf gemeinsam genutzte Ressourcen wie Nachrichtenwarteschlangen, gemeinsam genutzten Speicher und Semaphore haben wird. Auf den meisten UNIX-Systemen bestimmen diese IDs auch die Berechtigungen beim Zugriff auf Dateien. Linux verwendet jedoch die Dateisystem-IDs für diese Aufgabe. Zusammenfassend ist dies was Sie tun können .
-
Gespeicherte Set-Benutzer-ID und gespeicherte Set-Gruppen-ID. Diese IDs werden in Set-User-ID- und Set-Group-ID-Programmen verwendet, um eine Kopie der entsprechenden effektiven IDs zu speichern, die gesetzt wurden, als das Programm ausgeführt wurde. Ein Set-User-ID-Programm kann Privilegien annehmen und fallen lassen, indem es seine effektive Benutzer-ID zwischen den Werten seiner realen Benutzer-ID und der gespeicherten Set-User-ID hin- und herschaltet. Zusammenfassend ist dies wer Sie vorher waren .
Außerdem ist es wichtig, das SetUID-Bit zu verstehen. Dies führt dazu, dass ein ausführbares Programm mit den Rechten des Eigentümers ausgeführt wird, nicht desjenigen, der es aufruft.
Ein Wertpapier nightmare
Ihre Frage erwähnt ausdrücklich diesen nightmare
gehört root
und hat das SetUID-Bit gesetzt. Das bedeutet, dass jeder Benutzer nightmare
ausführen darf führt es im Wesentlichen als root
aus . Das bedeutet, dass alle untergeordneten Prozesse von nightmare
- wie sie beim Aufruf von system()
gespawnt werden - werden auch als root
ausgeführt .
Aber jetzt wirklich, was bedeutet setresuid()
tun?
In diesem Zusammenhang? Nichts. Da der Benutzer bereits Dinge als root
ausführt , die weitere Verwertung wird dadurch in keiner Weise beeinträchtigt.
Können Sie /dev/tty
verwenden ?
Diese Frage macht in diesem Zusammenhang wenig Sinn. Sie müssen sich das entsprechende Code-Snippet ansehen, um zu sehen, wo sich die Zeichenfolge /dev/tty
befindet kommt aus.
if (open("/dev/tty", O_RDWR) != -1) {
fire();
rax = sub_4008d0();
}
Das bedeutet, dass das Programm versucht, /dev/tty
zu öffnen zum Lesen und Schreiben und wenn das gelingt, ruft fire()
auf .
Durch Benennen einer Bash-Funktion /dev/tty()
, erhalten Sie nicht die gewünschten Ergebnisse, da open()
erfordert als ersten Parameter einen Pfad zu einer Datei. Es ist völlig unabhängig von bash
und hat kein Konzept von Bash-Funktionen.
Was ist mit puts()
?
Genauso macht das wenig Sinn. strings
ist keine Magie und versteht den Kontext nicht. Es sucht lediglich nach einer Reihe von Bytes, die druckbare ASCII-Zeichen sind.
puts()
ist nur eine C-Funktion, die einen String ausgibt.
Was ist mit /usr/bin/aafire
?
Obwohl ich es persönlich nicht versucht habe, scheint es praktisch /usr/bin/aafire
zu sein hätte anstelle von /usr/bin/sl -al
verwendet werden können . Wenn dies nicht korrekt ist, kommentieren Sie es bitte und ich werde diesen Teil bearbeiten.
Würde es immer noch funktionieren, wenn ein relativer Pfad verwendet würde?
Ja, eigentlich sogar noch besser! system()
ruft intern sh -c
auf , die den $PATH
auflösen muss Variable, um sl
zu finden . Wenn die Pfadvariable so geändert wurde, dass sie .
enthält oder jedes andere vom Benutzer beschreibbare Verzeichnis mit höherer Priorität als /usr/bin
, dann könnte ich einfach ./sl
symbolisieren bis /bin/bash
.
Spielt es eine Rolle, welche Art von Binärdatei/ELF die Root-SUID-Datei ist?
Ja, da das SetUID-Bit bei Shell-Skripten ignoriert wird. Es muss eine native ausführbare Datei sein.