2013-12-17 14 views
6

Ich schrieb ein kleines C-Dienstprogramm namens killSPR, um die folgenden Prozesse auf meiner RHEL-Box zu töten. Die Idee ist, dass jeder, der sich in diese Linux-Box einloggt, in der Lage ist, dieses Dienstprogramm zu benutzen, um die unten erwähnten Prozesse zu beenden (was nicht funktioniert - unten erklärt).setuid auf einer ausführbaren Datei scheint nicht zu funktionieren

[email protected] /tmp > ps -eaf | grep -v grep | grep " SPR " 
cadmn 5822 5821 99 17:19 ?  00:33:13 SPR 4 cadmn 
cadmn 10466 10465 99 17:25 ?  00:26:34 SPR 4 cadmn 
cadmn 13431 13430 99 17:32 ?  00:19:55 SPR 4 cadmn 
cadmn 17320 17319 99 17:39 ?  00:13:04 SPR 4 cadmn 
cadmn 20589 20588 99 16:50 ?  01:01:30 SPR 4 cadmn 
cadmn 22084 22083 99 17:45 ?  00:06:34 SPR 4 cadmn 
[email protected] /tmp > 

Dieses Dienstprogramm von dem Benutzer besessen wird cadmn (unter denen diese Prozesse ausgeführt werden) und hat die setuid- Flagge auf ihrem festgelegt (siehe unten).

/* 
* Program Name: killSPR.c 
* Description: A simple program that kills all SPR processes that 
* run as user cadmn 
*/ 
#include <stdio.h> 
int main() 
{ 
    char *input; 
    printf("Before you proceed, find out under which ID I'm running. Hit enter when you are done..."); 
    fgets(input, 2, stdin); 

    const char *killCmd = "kill -9 $(ps -eaf | grep -v grep | grep \" SPR \" | awk '{print $2}')"; 
    system(killCmd); 
    return 0; 
} 

ein Benutzer (pmn) verschieden von cadmn versucht, die oben genannten Verfahren mit diesem Programm zu töten und nicht (siehe unten):

[email protected] /tmp > ls -l killSPR 
-rwsr-xr-x 1 cadmn cusers 9925 Dec 17 17:51 killSPR 
[email protected] /tmp > 

Der C-Code ist unten angegeben

[email protected] /tmp > ./killSPR 
Before you proceed, find out under which ID I'm running. Hit enter when you are done... 
sh: line 0: kill: (5822) - Operation not permitted 
sh: line 0: kill: (10466) - Operation not permitted 
sh: line 0: kill: (13431) - Operation not permitted 
sh: line 0: kill: (17320) - Operation not permitted 
sh: line 0: kill: (20589) - Operation not permitted 
sh: line 0: kill: (22084) - Operation not permitted 
[email protected] /tmp > 

Während der Benutzer wartet, um oben zu kommen, wird der Prozess killSPR inspiziert und läuft als der Benutzer cadmn ((siehe unten), obwohl killSPR die Prozesse nicht beenden kann.

[email protected] /tmp > ps -eaf | grep -v grep | grep killSPR 
cadmn 24851 22918 0 17:51 pts/36 00:00:00 ./killSPR 
[email protected] /tmp > 

BTW, keine der Hauptpartitionen hat jede nosuid auf sich

[email protected] /tmp > mount | grep nosuid 
[email protected] /tmp > 

Der setuid-Flag auf der ausführbaren Datei scheint nicht die gewünschte Wirkung zu haben. Was fehlt mir hier? Habe ich missverstanden, wie setuid funktioniert?

+0

gibt es einen Grund, dies nicht nur ein Shell-Skript statt einer kompilierten Binärdatei mit '777' Berechtigungen sein könnte? – txtechhelp

+1

@txtechhelp - Ein Shell-Skript mit Dauerwelle 777 wird nicht funktionieren. Hier ist der Grund - Wenn der Benutzer 'pmn' dieses Skript aufgerufen hat, würde der folgende Prozess als Benutzer' pmn' ausgeführt werden, der keine Privilegien zum Töten der Prozesse hat, die als Benutzer 'cadmn' ausgeführt werden (außer Sie sind der root, Sie können keine Prozesse beenden, die von anderen ausgeführt werden. BTW, setzen Setuid-Flag auf Skripts auch nicht: setuid auf Skripten, die in einer der Shell-Sprachen geschrieben werden, werden vom System als Sicherheitsfunktion ignoriert. Daher muss dies ein kompiliertes Programm sein. Hoffe das beantwortet Ihre Frage. – pmn

+0

Ich verstehe Benutzerrechte und Einschränkungen von Linux/Unix-Systemen, ich frage, warum Sie versuchen, dies über ein C-Programm (das die gleichen Einschränkungen, wenn als separaten Benutzer in einem separaten Login ausgeführt wird) angesichts der Code Sie tun habe gepostet ... du rufst einfach einen Systembefehl von einem C-Programm auf, das den gleichen Effekt hat wie den gleichen Befehl ('kill' in deinem Programm) durch ein Shell-Skript aufzurufen.Stattdessen klingt es so, als ob Sie einem bestimmten Programm "Dienst wie Kontrolle" für Nicht-Root-Benutzer geben möchten. Wenn das korrekt ist, formulieren Sie bitte Ihre Frage um: – txtechhelp

Antwort

1

In erster Linie hilft, ermöglicht setuid bit einfach ein Skript, um die uid einzustellen. Das Skript muss immer noch setuid() oder setreuid() aufrufen, um im real uid oder effective uid laufen zu können. Ohne Aufruf von setuid() oder setreuid() wird das Skript weiterhin als der Benutzer ausgeführt, der das Skript aufgerufen hat.

Vermeiden Sie system und exec, da sie aus Sicherheitsgründen Privilegien fallen lassen. Sie können kill() verwenden, um die Prozesse zu beenden.

Überprüfen Sie diese.

http://linux.die.net/man/2/setuid

http://man7.org/linux/man-pages/man2/setreuid.2.html

http://man7.org/linux/man-pages/man2/kill.2.html

+0

Danke. Setreuid hat den Trick gemacht (obwohl Setuid nicht funktioniert hat). Dennoch ist das Verhalten nicht konsistent und hier ist der Grund: Das genaue Szenario, das mit der RHEL-Box nicht funktioniert hat, funktionierte ohne setuid oder settreuid auf Mint XFCE 15, das als VM auf meinem Heim-PC läuft! – pmn

+0

Der Unterschied zwischen 'setuid()' und 'setreuid()' ist der Besitz der Datei. Für Dateien, die 'setuid()' verwenden, muss es 'root' und' setid bit' gehören. Im Code 'setuid()' kann dann auf eine beliebige 'uid' einschließlich 'root' umgeschaltet werden. In Ihrem Fall möchten Sie 'setuid()' zu 'cadmn'. Wenn Sie möchten, dass die Datei 'cadmn' gehört, wird 'setuid()' nicht funktionieren, aber 'setreuid()' wird es tun. Das hast du wahrscheinlich gemacht. Die Manpage für 'setuid()' und 'setreuid()' diskutierte diesen Unterschied. – alvits

1

Sie sollten Ihre system Anruf mit exec Anruf ersetzen. Manual für system sagen wir es fallen Privilegien, wenn Sie von suid Programm ausgeführt.

Der Grund ist in man system erklärt:

Verwenden System nicht() von einem Programm mit Set-User-ID oder Set-Gruppe-ID Privilegien, weil seltsame Werte für einige Umgebungsvariablen könnten verwendet werden, um die Systemintegrität zu untergraben. Verwenden Sie stattdessen die Funktion exec (3), aber nicht execlp (3) oder execvp (3). system() funktioniert nicht in fact, funktioniert ordnungsgemäß von Programmen mit set-user-ID oder set-group-ID Privilegien auf Systemen, auf denen/bin/sh bash Version 2 ist, da Bash 2 Privilegien beim Start ablegt. (Debian eine modifizierte bash verwendet, die nicht dies nicht tun, wenn sie als sh aufgerufen.)

Wenn Sie system mit exec ersetzen Sie müssen in der Lage sein, Shell-Syntax zu verwenden, es sei denn, Sie /bin/sh -c <shell command> nennen, ist es das, was system ist tatsächlich tun.

+0

Oh, ich verstehe. Lass mich das versuchen und zu dir zurückkommen. – pmn

+0

'exec' hat die gleichen Benutzereinschränkungen wie' system' .. mit anderen Worten, wenn 'userX' keine Berechtigung zum Lesen/Schreiben/Ausführen von irgendetwas im Ordner '/ blahsy/blah' hat, dann ein C-Aufruf zu' system/exec ('ls -l/blahsy/blah') 'würde eine Operation nicht erlauben Fehler geben, weil' userX' keine Berechtigung für diesen Ordner hat .. wenn Sie dies stattdessen tun, obwohl 'system ('sudo ls -l/blahsy/blah ') ', könnte es eine andere Geschichte sein – txtechhelp

+0

Hmm, dann sieht es so aus, als hätte ich die Kräfte von setuid missverstanden. Kannst du mir ein Szenario geben, in dem ich setuid benutzen kann? – pmn

2

Schauen Sie sich diesen Link auf machen ein Shell-Skript einen Daemon:

Best way to make a shell script daemon?

Sie möchten vielleicht auch einige 'linux script to service' googeln, ich founda coupleof links zu diesem Thema.

Die Idee ist, dass Sie ein Shell-Skript umschließen, das einige grundlegende Dinge enthält, die es einem Benutzer ermöglichen, ein Programm zu steuern, das als ein anderer Benutzer ausgeführt wird, indem stattdessen ein Script vom Typ 'Service' aufgerufen wird. Zum Beispiel könnten Sie /usr/var/myservice/SPRkiller als "Service" -Skript einpacken, das dann einfach als solches von einem beliebigen Benutzer aufgerufen werden könnte: service SPRkiller start, dann SPRkiller würde ausgeführt, kill die entsprechenden Dienste (vorausgesetzt, das SPR 'Programm' wird als nicht ausgeführt Root-Benutzer).

Dies ist, was es klingt wie Sie versuchen zu erreichen. Das Ausführen eines Programms (Shell-Skript/C-Programm/was auch immer) beinhaltet die gleichen Benutzereinschränkungen, egal was passiert (außer für Eskalationsfehler/Hacks).

Nebenbei bemerkt, scheinen Sie ein kleines Missverständnis über Benutzerrechte auf Linux/Unix zu haben, sowie was bestimmte Befehle und Funktionen tun. Wenn ein Benutzer keine Berechtigung hat, eine bestimmte Aktion auszuführen (wie kill der Prozess eines anderen Benutzers), hat das Aufrufen von setuid für das gewünschte Programm kill (oder kill selbst) keinen Effekt, da der Benutzer keine Berechtigung dazu hat ein anderer Benutzer 'Raum' ohne Super-Benutzerrechte. Selbst wenn Sie sich in einem Shell-Skript oder einem C-Programm befinden und denselben system-Befehl aufrufen, erhalten Sie denselben Effekt.

http://www.linux.com/learn/ eine große Ressource ist, und hier ist ein Link für file permissions

Hoffnung, die