Übergeben von Fähigkeiten durch Exec

Übergeben von Fähigkeiten durch Exec

Ich versuche zu verstehen, wie Linux-Fähigkeiten an einen Prozess weitergegeben werden, der exec()von einem anderen ausgeführt wurde. Soweit ich gelesen habe, muss eine Fähigkeit im vererbbaren Set enthalten sein, damit sie nach der Ausführung erhalten bleibt. Ich bin mir jedoch nicht sicher, wie dieses Set gefüllt wird.

Mein Ziel ist es, ein Programm als normaler Benutzer ausführen zu können, für das normalerweise Root-Rechte erforderlich sind. Es muss die Fähigkeit haben, cap_dac_overrideeine private Datei lesen zu können. Weitere Fähigkeiten möchte ich ihm nicht geben.

Hier ist mein Wrapper:

#include <unistd.h>

int main(int argc, char *argv[]) {
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

Dies funktioniert, wenn ich für die resultierende ausführbare Datei die Setuid-Berechtigung festlege:

~ $ sudo chown root: ./registerdns
~ $ sudo chmod u+s ./registerdns
~ $ ./registerdns 
Successfully registered hostname with DNS

Ich würde jedoch lieber Capabilities statt Setuid verwenden. Ich habe versucht, die cap_dac_overrideCapability im Wrapper festzulegen:

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

Ich habe auch versucht, das Vererbungsflag für die cap_dac_overrideFähigkeit der netausführbaren Datei selbst zu setzen:

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ sudo setcap cap_dac_override=i /usr/bin/net
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

Ich muss den Wrapper verwenden, um sicherzustellen, dass die Funktion nur bei Verwendung genau dieses Argumentsatzes verfügbar ist. Das netProgramm führt noch verschiedene andere Dinge aus, bei denen es gefährlich sein könnte, den Benutzern zu weitreichende Berechtigungen dafür zu erteilen.

Ich verstehe offensichtlich nicht, wie die Vererbung funktioniert. Ich kann nicht herausfinden, wie ich den Wrapper so einrichte, dass er seine Fähigkeiten an den Ersetzungsprozess weitergibt, damit dieser sie nutzen kann. Ich habe die Manpage und zahllose andere Dokumente darüber gelesen, wie es funktioniert.sollenArbeit, und ich dachte, ich würde das tun, was es beschreibt.

Antwort1

Es stellt sich heraus, dass die Einstellung +i auf dem Wrappernichtfüge die Fähigkeit dem CAP_INHERITABLESet für den Wrapper-Prozess hinzu, damit sie nicht durchgereicht wird exec. Ich musste daher vor dem Aufruf manuell CAP_DAC_OVERRIDEhinzufügen :CAP_INHERITABLEexecl

#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv[]) {
    cap_t caps = cap_get_proc();
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
    cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
    cap_set_proc(caps);
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_free(caps);
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

Zusätzlich musste ich cap_dac_overridedie erlaubten Dateifunktionen um Folgendes ergänzen /usr/bin/netund das effektive Bit setzen:

~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS

Ich glaube, ich verstehe jetzt völlig, was passiert:

  1. Der Wrapper benötigt es CAP_DAC_OVERRIDEin seinem zulässigen Satz, damit er es zu seinem vererbbaren Satz hinzufügen kann.
  2. Der vererbbare Prozesssatz des Wrappers unterscheidet sich von seinem vererbbaren Dateisatz. Daher ist die Einstellung +i für die Datei sinnlos. Der Wrapper muss using CAP_DAC_OVERRIDE/ explizit hinzufügen .CAP_INHERITABLEcap_set_flagcap_set_proc
  3. Die netDatei muss in ihrem vererbbaren Set haben CAP_DAC_OVERRIDE, damit sie die Fähigkeit vom Wrapper tatsächlich in ihr CAP_PERMITTEDSet erben kann. Außerdem muss das effektive Bit gesetzt sein, damit es automatisch zu hochgestuft wird CAP_EFFECTIVE.

Antwort2

Ich denke, Sie brauchen beides:

setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net

Die peaktivierten Flags registerdnsgeben an, dass die Berechtigung durch Ausführen des Programms erworben wird. Die iaktivierten Flags netgeben an, dass die Berechtigung vom aufrufenden Programm übernommen werden darf.

verwandte Informationen