suID auf user: 'www-data' mappen...

x0r

x0r

Bitschubser
mahlzeit ich hab' folgendes Problem,

der Eine oder Andere kennt sicher grafische Adminoberflächen wie webmin oder Plesk. Diese Anwendungen bieten ja die Möglichkeit auch einzelne, gerae konfigurierte Server neu zu starten. Da in diesem Fall üblicherweise die entsprechenden Skripte in /etc/init.d angestoßen werden, ist es nötig dem Prozess der sie aufruft erweiterte Privilegien zu gestatten.

In meinem Fall soll dies surch eine CGI-Anwendung geschehen. Dies funktioniert soweit auch für ausführbare Dateien, die nicht mit SUID gemappet sind (cat, ls usw.).
Will ich jedoch eines der Initskripte anstoßen, klappt dass netürlich nicht, da der User 'www-data' die entsprechenden Rechte zum ausführen nicht besitzt.

Bei vergleichbaren Anwendungen (siehe oben) gelingt dies (wenn auch über Javaapplets) ja auch. Über einen Lösungsansatz der mittels popen()-Fkt. in C funktioniert (oder etwas vergleichbares) würde ich mich sehr freuen...

MfG
 
Hilft es vielleicht weiter, wenn Du die gewuenschten Skripte in /etc/sudoers fuer www-data freischaltest und dann innerhalb von popen diese mit 'sudo ...' aufrufst? In sudoers kann man angeben, dass Befehle ohne Passworteingabe ausgefuehrt werden duerfen.
 
Du kannst doch einfach via setuid() dem Programm erstmal andere Rechte geben, das init-Skript starten und danach die Rechte wieder zuruecksetzen, also einfach ein normales setuid-Programm bauen.
 
rikola schrieb:
Hilft es vielleicht weiter, wenn Du die gewuenschten Skripte in /etc/sudoers fuer www-data freischaltest und dann innerhalb von popen diese mit 'sudo ...' aufrufst? In sudoers kann man angeben, dass Befehle ohne Passworteingabe ausgefuehrt werden duerfen.
...hab' ich auch schon überlegt, grundsätzlich könnte dass aber dazu führen dass ein jeder x-beliebige Hampelmann, Bspw.: via Crossite-scripting (vorraus gesetzt er kennt dann auch den Modus der POST_DATEN, aus denen ein ShellCMD zusammengesetzt wird) im Zweifelsfall auch jede beliebige Datei a la: rm -rf / ausführen kann.
:devil: Und bei dem Gedanken stellen sich mir alle Nackenhaare gleichzeitig auf...:devil:

theton schrieb:
Du kannst doch einfach via setuid() dem Programm erstmal andere Rechte geben, das init-Skript starten und danach die Rechte wieder zuruecksetzen, also einfach ein normales setuid-Programm bauen.
...das klingt schon eher wo nach ich suche.
Jedoch, kurz manpages aufgeschlagen und siehe da:
man 2 setuid schrieb:
Thus, a setuid-root program wishing to temporarily drop root
privileges, assume the identity of a non-root user, and then regain root
privileges afterwards cannot use setuid.
You can accomplish this with the (non-POSIX, BSD) call seteuid.

Heist das nun, dass ich das Script nach dem es mit setuid, ausführbar für www-data mache, danach (für den laufenden Prozess) nicht mehr aufzurufen ist (es sei denn ich starte den Prozess als ganzes Neu ?!), oder dass ich das ganze lieber gleich mit seteuid() machen muss ?!


MfG
 
Beispiel:
Code:
int main() {
  int origuid = getuid();
  setuid(0);
  // hier das init-Skript ausfuehren
  ...
  setuid(origuid);
  // weiterer code
  ...
  return(0);
}
Das ganze als Programm mit suid-Flag und schon kann dein Programm das Skript als root ausfuehren und laeuft danach wieder mit der urspruenglichen UID weiter. Zum Sicherheitsaspekt solcher Routinen lies einfach mal http://www.hackerwiki.org/index.php/Angriffe_auf_unsicher_programmierte_Signal-Handler da gehe ich auf dieses Thema (wenn auch im Zusammenhang mit Signal-Handlern) ein. suid-Programme sind immer sicherheitskritisch und sollten mit entsprechender "Vorsicht" programmiert werden.
 
@thethon: Danke für die Hinweise, hab' Dein Beispiel dankbar aufgegriffen (etwas in der Art hatte ich mir schon gedacht), bin jedoch nach etwas herumprobieren immer noch nicht zum Ziel gekommen. Ausgehend von Deinem Codebeispiel hab ich das Problem mal mit einem Minihack illustriert.

Das Ganze sieht etwa so aus:

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{

	if(argc<2)
	{
		printf("\nArgument fehlt !!!\n");
		exit(1);
	}
	else
	{
		printf("\nUID momentan: %d\n\n", getuid());
		if(setuid(atoi(argv[1]))==-1)	
			printf("SUID kann nicht neu gesetzt werden (nicht root?)...\n\n");
		else
			printf("SUID ist jetzt: %d (!) ...\n\n", getuid());
	}
		
	return 0;
	
}


Hier mal die Ausgaben die ich damit erzeuge:

Code:
x0r@304-pc01:~$ ./tsuid 33

UID momentan: 1000
SUID kann nicht neu gesetzt werden (nicht root?)...

dx0r@304-pc01:~$ sudo ./tsuid 33

UID momentan: 0
SUID ist jetzt: 33 (root!) ...

dx0r@304-pc01:~$ sudo su -c "./tsuid 1000" www-data

UID momentan: 33
SUID kann nicht neu gesetzt werden (nicht root?)...

dx0r@304-pc01:~$

Wie Ihr seht, kann nur ein als 'root' gestarteter Process auch SUIDs flaggen, oder hab ich mich vertan ???

EDIT: Entwarnung, hatte folgendes vergessen:

Das Ganze via:
Code:
$chmod -v 4555 ./tsuid
...mit SUID geflagged.

:) ...schon geit dat :)

danke an alle, MfG
 
Zurück
Oben