Warum funktioniert das Setuid-Bit inkonsistent?

8

Ich habe den Code geschrieben:

// a.c
#include <stdlib.h>
int main () {
  system("/bin/sh");
  return 0;
}

kompiliert mit Befehl:

gcc a.c -o a.out

Setuid-Bit hinzugefügt:

sudo chown root.root a.out
sudo chmod 4755 a.out

Unter Ubuntu 14.04 habe ich als allgemeiner Benutzer Root-Rechte erhalten.

aber unter Ubuntu 16.04 habe ich immer noch die Shell des aktuellen Benutzers.

Warum ist es anders?

user10883182
quelle

Antworten:

9

Was sich geändert hat, ist, dass es /bin/shentweder wurde bashoder blieb, dashwas eine zusätzliche Flagge erhielt -p, die das Verhalten von Bash nachahmt.

Für Bash muss das -pFlag die Setuid-Berechtigung nicht löschen, wie in der Manpage erläutert :

Wenn die Shell mit einer effektiven Benutzer- (Gruppen-) ID gestartet wird, die nicht der tatsächlichen Benutzer- (Gruppen-) ID entspricht, und die Option -p nicht angegeben wird, werden keine Startdateien gelesen, Shell-Funktionen werden nicht von der Umgebung, den SHELLOPTS, geerbt Die Variablen BASHOPTS, CDPATH und GLOBIGNORE werden ignoriert, wenn sie in der Umgebung angezeigt werden, und die effektive Benutzer-ID wird auf die tatsächliche Benutzer-ID festgelegt . Wenn die Option -p beim Aufruf angegeben wird, ist das Startverhalten dasselbe, aber die effektive Benutzer-ID wird nicht zurückgesetzt.

Vorher war dashdas egal und erlaubte die Ausführung von Setuid (indem nichts unternommen wurde, um dies zu verhindern). Auf der dashManpage von Ubuntu 16.04 ist jedoch eine zusätzliche Option beschrieben, ähnlich wie bash:

-p priv
Versuchen Sie nicht, die effektive UID zurückzusetzen, wenn sie nicht mit der UID übereinstimmt. Dies ist nicht standardmäßig festgelegt, um eine falsche Verwendung durch setuid-Root-Programme über System (3) oder Popen (3) zu vermeiden .

Diese Option gab es weder im Upstream (der möglicherweise nicht auf einen vorgeschlagenen Patch * reagiert hat ) noch in Debian 9, sondern in Debian Buster, der den Patch seit 2018 erhalten hat.

HINWEIS: wie von Stéphane Chazelas erklärt, es ist zu spät zum Aufruf "/bin/sh -p"in system()da system()läuft alles gegeben durch /bin/shund so die setuid ist bereits gesunken. Die Antwort von derobert erklärt im vorherigen Code, wie damit umzugehen istsystem() .

* mehr Details zur Geschichte hier und da .

AB
quelle
system("bash -p")läuft sh -c "bash -p"so haben die Privilegien bereits fallen gelassen worden , wenn bashausgeführt wird.
Stéphane Chazelas
na ja ok Ich werde den "Lösungsteil" entfernen, der von Deroberts Antwort sowieso besser behandelt wird.
AB
Siehe auch bugs.debian.org/cgi-bin/bugreport.cgi?bug=734869
Stéphane Chazelas
Sieht aus wie Ubuntu Fixed Dash in Wily (15.10). bugs.launchpad.net/ubuntu/+source/dash/+bug/1215660
Mark Plotnick
1
Beachten Sie, dass Debian früher umgekehrt war. Es wurde verwendet, um Bash zu patchen, um keine Berechtigungen zu verlieren. Ob es sich um eine Verbesserung handelt, ist fraglich. Nun, Leute, die ein system()mit erhöhten Privilegien machen wollen (was setresuid()natürlich nicht der Fall sein sollte), machen am Ende ein Vorher, was viel schlimmer ist, da die Shell dann nicht weiß, dass es suid ist, also nicht Aktivieren Sie den Modus, in dem es seiner Umgebung nicht vertraut.
Stéphane Chazelas
8

Wahrscheinlich ändert die Shell aus irgendeinem Grund ihre effektive Benutzer-ID im Rahmen ihres Startvorgangs wieder in die tatsächliche Benutzer-ID. Sie können dies überprüfen, indem Sie Folgendes hinzufügen:

/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);

vor deinem system(). (Selbst unter Linux müssen Sie wahrscheinlich nur die echten festlegen. Die gespeicherten sollten in Ordnung sein, um sie in Ruhe zu lassen. Dies ist nur brutale Gewalt zum Debuggen. Je nachdem, warum Sie die Set-ID verwenden, müssen Sie diese möglicherweise natürlich verwenden um die echten IDs auch irgendwo zu speichern.)

[Wenn dies nicht nur eine Übung ist, in der Sie lernen, wie Setid funktioniert, gibt es viele Sicherheitsprobleme, über die Sie sich Sorgen machen müssen, insbesondere beim Aufrufen einer Shell. Es gibt beispielsweise viele Umgebungsvariablen, die das Verhalten der Shell beeinflussen. Bevorzugen Sie einen bereits bestehenden Ansatz, sudowenn dies überhaupt möglich ist.]

derobert
quelle
Ich habe mich darauf konzentriert, warum es sich geändert hat, während Sie angegeben haben, wie Sie das Problem vermeiden können. +1
AB
Wenn Sie wirklich irgendwo etwas zum Speichern der echten IDs benötigen, ist die gespeicherte ID natürlich ein äußerst praktischer Ort, um dies zu tun. Besonders wenn die effektiven IDs nicht root sind: root.
Kevin