Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

chroot: not super-user

3 views
Skip to first unread message

Mike Hoehn

unread,
Feb 9, 1993, 12:45:20 PM2/9/93
to
Ich habe hier folgendes Problem:

Ich moechte einen Account als chroot-Account einrichten.
Das Problem ist nur, dass chroot folgende Meldung ausgibt, wenn
es nicht von root aus gestartet wird:

chroot: not super-user

Probeweise habe ich mal den owner von chroot auf root gesetzt und ihm
das setuid-Bit verpasst. Dann funktioniert die Sache so, wie ich sie
mir vorstelle, allerdings mit dem ganz grossen Haken, dass die durch
chroot aufgerufene Shell auch root-Privilegien besitzt.

Das ist nicht Sinn der Sache. Ich moechte einfach vom .profile aus
chroot aufrufen koennen, ohne setuid-root etc., so dass die ur-
spruengliche uid beibehalten wird.

In den Manuals habe ich leider nichts gefunden, deswegen frage ich hier.
Ich hoffe, dass es da ueberhaupt eine Moeglichkeit gibt.

Mike

--
Mike Hoehn email: b...@birnehh.mali.sub.org
Ernst-Mittelbach-Ring 27 Tel.: +49 40 5525486
DW-2000 Hamburg 61 SAVE THE VINYL

Martin P. Ibert

unread,
Feb 10, 1993, 3:40:16 AM2/10/93
to
b...@birnehh.mali.sub.org (Mike Hoehn) writes:
> Das ist nicht Sinn der Sache. Ich moechte einfach vom .profile aus
> chroot aufrufen koennen, ohne setuid-root etc., so dass die ur-
> spruengliche uid beibehalten wird.

Das geht aber nicht. Ich habe dieses Problem auch gehabt. Bei SVR4 soll man
ja durch Anhaengen eine *chens an das passwd-Eintrag (bzw. an den Namen der
Shell) ein automatisches chroot(2) mit anschliessender neuer Login-Prozedur
vorschreiben koennen. Leider hat das bei mir nicht geklappt, weil ich nicht
herausgefunden habe, was ich alles in den Unterbaum kopieren muss. Also
hab ich das eben selbst hingehackt. Aber Vorsicht: Du musst immer noch
einiges kopieren!

/etc/passwd-Eintrag:

pub:x:206:204:Free Software!:/home/pub:/opt/sbin/chrootlogin

ls -l von /opt/sbin/chrootlogin:

-r-s--x--x 2 root opt 25864 Oct 9 02:29 /opt/sbin/chrootlogin

Source von /opt/sbin/chrootlogin:

static char rcs_id[]="$Id: chrootlogin.c,v 1.1 1992/10/09 01:25:34 martini Exp martini $";
/*
* $Log: chrootlogin.c,v $
* Revision 1.1 1992/10/09 01:25:34 martini
* Initial revision
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <pwd.h>
#include <utmp.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
struct passwd *pwd;
struct utmp utmp, *up;
char
*home,
*logname,
*shell,
*tty,
envsh[BUFSIZ],
envhome[BUFSIZ],
argv0[BUFSIZ];
int newfd;

if( (home=getenv("HOME")) == NULL)
{
fputs("No $HOME\n", stderr);
exit(1);
}

if( (logname=getenv("LOGNAME")) == NULL)
{
fputs("No $LOGNAME\n", stderr);
exit(1);
}

if( (tty=ttyname(fileno(stdin))) == NULL)
{
fputs("ttyname: Cannot find device\n", stderr);
exit(1);
}
printf("Logged in at %s\n", tty);
strncpy(utmp.ut_line, tty+5, sizeof(utmp.ut_line));
if( (up=getutline(&utmp)) == NULL)
{
fputs("getutline: Cannot find utmp entry\n", stderr);
exit(1);
}
memcpy(&utmp, up, sizeof(utmp));
endutent();

if(chroot(home) != 0)
{
perror("chroot");
exit(1);
}
printf("chroot() to %s\n", home);

if( (newfd=open(tty, O_RDWR)) < 0
|| chown(tty, getuid(), getgid())
|| dup2(newfd, 0) < 0
|| dup2(newfd, 1) < 0
|| dup2(newfd, 2) < 0
|| close(newfd) != 0)
{
perror(tty);
exit(1);
}

if( (pwd=getpwnam(logname)) == NULL)
{
fputs("No /etc/passwd entry\n", stderr);
exit(1);
}

shell=pwd->pw_shell;
home=pwd->pw_dir;

sprintf(envsh, "SHELL=%s", shell);
sprintf(envhome, "HOME=%s", home);

if(putenv(envsh) != 0 || putenv(envhome) != 0)
{
perror("putenv");
exit(1);
}

utmpname("/etc/utmp");
(void)getutline(&utmp);
if(pututline(&utmp) == NULL)
{
fputs("pututline: Cannot create utmp entry\n", stderr);
exit(1);
}
endutent();

if(setuid(getuid()) != 0 || setgid(getgid()) != NULL)
{
perror("set[ug]id");
exit(1);
}

if(chdir(home) != 0)
{
perror(home);
exit(1);
}

sprintf(argv0, "-%s", basename(shell));
argv[0]=argv0;

execvp(shell, argv);

perror(shell);

return(1);
}
--
__ | Martin P. Ibert, Westendallee 100 d, D-1000 Berlin 19, Germany,
( )__ | +4930-3056541, mar...@heaven7.in-berlin.de ...@cs.tu-berlin.de
( )_ |----------------------------------------------------------------
(_________) | All that we see or seem/is but a dream within a dream. --E.A.P.

Mike Hoehn

unread,
Feb 11, 1993, 3:58:49 PM2/11/93
to
mar...@heaven7.in-berlin.de (Martin P. Ibert) writes:

>[chroot-Login]

>/etc/passwd-Eintrag:

>pub:x:206:204:Free Software!:/home/pub:/opt/sbin/chrootlogin

Ergaenzend ist zu sagen, dass in diesem Fall in /home/pub/etc eine
Kopie von /etc/passwd anzulegen ist. Dort muss jetzt fuer User "pub"
das HOME-Directory relativ zu /home/pub angegeben werden.

Ansonsten funktioniert das Programm wirklich prima! <lob> :-)

Kristian Koehntopp

unread,
Feb 11, 1993, 5:58:18 AM2/11/93
to
In <C26zz...@birnehh.mali.sub.org> b...@birnehh.mali.sub.org (Mike Hoehn) writes:
>Ich moechte einen Account als chroot-Account einrichten.
>Das Problem ist nur, dass chroot folgende Meldung ausgibt, wenn
>es nicht von root aus gestartet wird:

>chroot: not super-user

chroot(2), der Systemaufruf, kann nur durch den Superuser
aufgerufen werden. Wuerde man den chroot(2)-Systemaufruf fuer
normaler User freigeben, waere folgendes Szenario denkbar:

1. User richtet sich einen Dateibaum ~wurzel ein, in dem alle
wichtigen Binaries (ggf. als Hardlinks) vorhanden sind.
2. Er legt in ~wurzel/etc eine falsche passwd-Datei an, die
diesen Eintrag enthaelt:

root::0:0:Hacker:/:/bin/sh

3. Er legt mit chroot(2) die Wurzel seines Dateisystems auf
~wurzel.
4. Er su(1)t sich nach root (kein Passwort) und legt mit
mknod(1) ein /dev/hd0a an.
5. Dann macht er die Platte platt.

Ich habe bei mir ein Login sauger eingerichtet, das eine
spezielle Shell hat:

sauger::994:101:Datensauger:/Benutzer/sauger:/usr/local/bin/saugerlogin

Die Shell /usr/local/bin/saugerlogin ist ein SUID
root-Programm, das ich mir geschrieben habe.

$ ls -l /usr/local/bin/saugerlogin
---s--x--x 1 root 16384 Feb 10 22:02 /usr/local/bin/saugerlogin

Es laeuft so unter BSD-Unix. Das Programm macht folgendes:

0. Beginn als root, unge-chroot(2)et.
1. Im syslog(3) den Sauger vermerken.
2. chroot(2) aufrufen
3. setuid(3) aufrufen, damit der folgende Sermon als sauger
laeuft.
4. Jetzt wird der Sauger-Account noch weiter eingeschraenkt:
nice und setrlimit setzen dem Sauger einige Grenzen.
5. Zum Schluss wird die wirkliche Shell des Saugers aufgerufen.

Im Dateibaum von Sauger muessen eine /etc/passwd, /etc/shells
(BSD!) und die benoetigten Shared Libraries vorhanden sein,
sonst funktioniert nichts. Einige Programme, die man dem Sauger
zur Verfuegung stellt (etwa less(1)) benoetigen noch weitere
Hilfsdateien in /usr/lib (etwa less.help).

Die Anpassung nach System V sollte durch Streichung aller
syslog- und setrlimit-Aufrufe kein Problem sein.

Noch sicher waere es, den Sauger-Dateibaum auf ein
NFS-gemountetes Dateisystem zu legen, auf dem SUID-Programme
und Device-Dateien einfach ignoriert werden.

Wer wirklich paranoid ist, laesst das saugerlogin auf einer
pty-Session laufen und kontrolliert das Benehmen des Saugers am
Bildschirm mit (ich arbeite gerade daran).

------------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

main()
{
time_t now;
char *tstr;
struct rlimit limit;

/* Login loggen */
now = time(0);
tstr = ctime(&now);
openlog("saugerlogin", LOG_PID | LOG_NDELAY, LOG_AUTH);
syslog(LOG_ERR, "Login eines Saugers");

/* chroot() und setze Userid */
chroot("/u/home/ftp");
setuid(994); /* sauger */

/* nice setzen */
nice(10);

/* Limits setzen */
limit.rlim_cur = 900;
limit.rlim_max = 900;
setrlimit(RLIMIT_CPU, &limit);

limit.rlim_cur = 16*1024*1024;
limit.rlim_max = 16*1024*1024;
setrlimit(RLIMIT_FSIZE, &limit);

limit.rlim_cur = 8*1024*1024;
limit.rlim_max = 8*1024*1024;
setrlimit(RLIMIT_DATA, &limit);

limit.rlim_cur = 8*1024*1024;
limit.rlim_max = 8*1024*1024;
setrlimit(RLIMIT_STACK, &limit);

limit.rlim_cur = 0;
limit.rlim_max = 0;
setrlimit(RLIMIT_CORE, &limit);

limit.rlim_cur = 1024*1024;
limit.rlim_max = 1024*1024;
setrlimit(RLIMIT_RSS, &limit);

/* Meldung drucken */
printf("Willkommen zum Sauger-Download auf black.toppoint.de.\n");

/* Shell starten mit integrierter Katastrophenbehandlung */
printf("execl error = %d\n", execl("/bin/csh", "-csh", NULL));
printf("errno = %d\n", errno);
printf("Sorry, aber das Sauger-Login ist derzeit nicht verfuegbar.\n");
printf("Bitte informieren Sie den Operator.\n");
printf("Kristian Koehntopp, +49 431 676689 Q\n");
sleep(5);
exit(0);
}
------------------------------------------------------------------------------


>Das ist nicht Sinn der Sache. Ich moechte einfach vom .profile aus
>chroot aufrufen koennen, ohne setuid-root etc., so dass die ur-
>spruengliche uid beibehalten wird.

Das hingegen kann aus den o.a. Gruenden nicht gehen.

Kristian
--
"Was macht das Fraktal im Buchenwald?"
-- Georg Hoermann

Rodney Volz

unread,
Feb 12, 1993, 1:08:17 AM2/12/93
to
/*

In article <C26zz...@birnehh.mali.sub.org> b...@birnehh.mali.sub.org (Mike Hoehn) writes:
>Ich moechte einen Account als chroot-Account einrichten.
>Das Problem ist nur, dass chroot folgende Meldung ausgibt, wenn
>es nicht von root aus gestartet wird:
>
>chroot: not super-user
>
>Probeweise habe ich mal den owner von chroot auf root gesetzt und ihm
>das setuid-Bit verpasst. Dann funktioniert die Sache so, wie ich sie
>mir vorstelle, allerdings mit dem ganz grossen Haken, dass die durch
>chroot aufgerufene Shell auch root-Privilegien besitzt.

*/

main()
{
chroot("/your/new/root/containing/all/neccessary/shlibs/etc/pp")
setuid(getuid());
setgid(getgid());
execl("/bin/sh","Boring Bourneshell",NULL,NULL);
}

/* -Rodney Volz */
--
Rodney Volz - 7000 Stuttgart 1 - FRG
===================> ...uunet!uka!smurf!tyrell!rodney <====================
Tyrell: +49 711 651429 V32bis Public access - rod...@tyrell.tynet.sub.org
\_____________ May your children and mine live in peace. _______________/

Patrick Schaaf

unread,
Feb 12, 1993, 3:57:30 AM2/12/93
to
kr...@black.toppoint.de (Kristian Koehntopp) writes:
>chroot(2), der Systemaufruf, kann nur durch den Superuser
>aufgerufen werden. Wuerde man den chroot(2)-Systemaufruf fuer
>normaler User freigeben, waere folgendes Szenario denkbar:

>2. Er legt in ~wurzel/etc eine falsche passwd-Datei an, die


> diesen Eintrag enthaelt:
> root::0:0:Hacker:/:/bin/sh
>3. Er legt mit chroot(2) die Wurzel seines Dateisystems auf
> ~wurzel.
>4. Er su(1)t sich nach root (kein Passwort)

Das kann er allerdings nur (oder korrigier' mich), wenn er seine Wurzel auf
dem gleichen Filesystem anlegt, auf dem auch das su-binary steht, und er
vor dem chroot einen Hardlink in seine Wurzel reingelegt hat. Wenn ich
alle suid-Programme in einem Filesystem sammle, auf das kein User Schreib-
berechtigung hat, sollte Dein Szenario nicht mehr greifen. Aber wer macht
sich schon die Muehe...

#undef NITPICK
Patrick

--
progress and die. this is just the way the world goes round.
a comment by patrick schaaf, saarbruecken, germany.

Martin P. Ibert

unread,
Feb 12, 1993, 2:30:53 AM2/12/93
to
b...@birnehh.mali.sub.org (Mike Hoehn) writes:
> Ergaenzend ist zu sagen, dass in diesem Fall in /home/pub/etc eine
> Kopie von /etc/passwd anzulegen ist. Dort muss jetzt fuer User "pub"
> das HOME-Directory relativ zu /home/pub angegeben werden.

Das ist wohl war, so sieht /home/pub/etc/passwd aus:

root:x:0:0:The System Manager Himself:/:
pub:x:206:204:Free Software!:/:/usr/bin/ksh
pubadm:x:207:204:Free Software Administration:/:/usr/bin/ksh
--
__| |__ Martin P. Ibert, Fürstenweg 11, D-13589 Berlin, -30/6/93 D-1000 B 20
__ __ +------------------------------------------------------------------+
| | | Jede Glorifizierung eines Menschen, der im Kriege getötet worden |
| | | ist, bedeutet drei Tote im nächsten Krieg. (Kurt Tucholsky 1932) |

Martin P. Ibert

unread,
Feb 12, 1993, 6:26:29 AM2/12/93
to
mar...@heaven7.in-berlin.de (Martin P. Ibert) writes:
> b...@birnehh.mali.sub.org (Mike Hoehn) writes:
> > Ergaenzend ist zu sagen, dass in diesem Fall in /home/pub/etc eine
> > Kopie von /etc/passwd anzulegen ist. Dort muss jetzt fuer User "pub"
> > das HOME-Directory relativ zu /home/pub angegeben werden.
>
> Das ist wohl war, so sieht /home/pub/etc/passwd aus:
wahr *aua*

Überhaupt wird man vermutlich durch Versuch und Irrtum herausfinden müssen,
was nun alles kopiert werden muß. Hierbei erweist sich das SVR4-Tool truss(1)
als ausgesprochen hilfreich.
--
Nur nicht an die eigene Nase, \ PE \ Martin Ibert, Fürstenweg 11, \
nur nicht vor der eigenen Tür, \ WERNER \ D-13589 Berlin, alt: 1000/20 \
nur nicht aus der eigenen Tasche,\_________\ mar...@heaven7.in-berlin.de \
alles, was ihr wollt -- nur nicht von mir! \ oder mar...@cs.tu-berlin.de \

Alexander Rawass

unread,
Feb 17, 1993, 8:25:41 AM2/17/93
to
In article <C26zz...@birnehh.mali.sub.org>, Mike Hoehn writes:

> Ich habe hier folgendes Problem:
>
> Ich moechte einen Account als chroot-Account einrichten.
> Das Problem ist nur, dass chroot folgende Meldung ausgibt, wenn
> es nicht von root aus gestartet wird:
>
> chroot: not super-user
>
> Probeweise habe ich mal den owner von chroot auf root gesetzt und ihm
> das setuid-Bit verpasst. Dann funktioniert die Sache so, wie ich sie
> mir vorstelle, allerdings mit dem ganz grossen Haken, dass die durch
> chroot aufgerufene Shell auch root-Privilegien besitzt.
>

Da solltest du dir ein kleines C-Programm schreiben, welches nichts
weiter tut als ein
{
setuid(usernummer);
setgid(gruppennummer);
system("/bin/irgendeineshell");
}

Dieses C-Programm nimmstt du dann als Login-Shell und schenkst es root.root
und setzt es auf setuid....

Die Shell sollte dann unter <usernummer> laufen!

--
Rawalex (a_ra...@informatik.uni-kl.de)
Rawalex (a_ra...@informatik.uni-kl.de)

Kristian Koehntopp

unread,
Feb 18, 1993, 9:38:21 AM2/18/93
to
In <1993Feb17.1...@rhrk.uni-kl.de> a_ra...@informatik.uni-kl.de (Alexander Rawass) writes:
> {
> setuid(usernummer);
> setgid(gruppennummer);
> system("/bin/irgendeineshell");
> } ^^^^^^


>Dieses C-Programm nimmstt du dann als Login-Shell und schenkst es root.root
>und setzt es auf setuid.... ^^^^^^^^^
^^^^^^

Argh. system(), SUID und root in einem Posting!

Kristian
--
Kristian Koehntopp, Harmsstrasse 98, DW-2300 Kiel, +49 431 676689
"Hier ist Ihre private Telefongesellschaft. Wir unterbrechen jetzt Ihr
Gespraech und senden Werbung."

Stefan Rupp

unread,
Feb 21, 1993, 5:25:00 PM2/21/93
to
Moin Kristian,

kr...@black.toppoint.de schrieb am Do, 18.02.93 15:38 in DCO.UNIX:


> Argh. system(), SUID und root in einem Posting!

Kannst Du diese Deine Aeusserung etwas genauer (und vielleicht hoeflicher)
formulieren?

Ciao,
struppi

Josef Wolf

unread,
Feb 22, 1993, 3:14:43 PM2/22/93
to
kr...@black.toppoint.de (Kristian Koehntopp) writes:
>Argh. system(), SUID und root in einem Posting!

Ist eigentlich jemandem aufgefallen, dass in der letzten iX ein aehnlicher
Patzer unterlaufen ist? Im Text die Empfehlung SUID zu setzen (natuerlich auf
root :-) und im Programm ein system() ohne irgendwelche Sicherheitspruefungen.
Und das Beste an der ganzen Geschichte: ein auszufuehrendes Kommando wird
direkt von argv[] zu system() durchgereicht. Und natuerlich kein Hinweis, dass
es damit ein Sicherheitsproblem geben koennte. Noch einfacher kann man es
diversen zwielichtigen Gestalten wohl kaum noch machen...

Beim Lesen dieses Beitrages kam mir schon der Gedanke, das iX-Abonnement
zu kuendigen ;-)

Gruss
Sepp

PS: Ob dieser Patzer irgendwie mit der Vereinigung mit dem UNIX-Magazin
zusammenhaengt? ;-)
--
se...@ppcger.ppc.sub.org
Josef Wolf, Germersheim, Germany
..!ira.uka.de!smurf.sub.org!ppcger.ppc.sub.org

Kristian Koehntopp

unread,
Feb 24, 1993, 3:36:01 AM2/24/93
to
In <A35...@AC2.maus.de> Stefa...@ac2.maus.de (Stefan Rupp) writes:
>kr...@black.toppoint.de schrieb am Do, 18.02.93 15:38 in DCO.UNIX:
> > Argh. system(), SUID und root in einem Posting!

>Kannst Du diese Deine Aeusserung etwas genauer (und vielleicht hoeflicher)
>formulieren?

Ich fand es eigentlich nicht unhoeflich, jedenfalls war es
nicht so gemeint.

Die Verwendung von system()-Aufrufen in SUID-root Programmen
kann in vielen Faellen eine Sicherheitsluecke darstellen, da
system() eine Shell startet und diese Shell bzw. ihr Verhalten
von verschiedenen Umgebungsvariablen anhaengt (SHELL=, IFS=,
PATH= und andere).

> Da solltest du dir ein kleines C-Programm schreiben, welches nichts
> weiter tut als ein
> {

> setuid(usernummer);
> setgid(gruppennummer);
> system("/bin/irgendeineshell");
> }
>

> Dieses C-Programm nimmstt du dann als Login-Shell und schenkst es root.root
> und setzt es auf setuid....

- Setze "SHELL" auf einen Wrapper, der einen exec auf /bin/sh
mit der Option -i (interactive) aufruft oder setze SHELL auf
einen Wrapper, der /etc/passwd loescht.

Einige system()-Versionen fangen das ab bzw. beachten den
Wert von SHELL nicht.

*ODER*

- Setze IFS auf "/" und setze ein Programm "bin" in den
Suchpfad. Es wird das Programm "bin" mit dem Parameter
"irgendeineshell" gestartet.

Jetzt mache einen "exec loginprogrammvonoben". Da die ganze
Chose SUID root laeuft -> *BOOM*.

Es gibt noch ein paar mehr Ansatzpunkte. Daher merke:
Grundsaetzlich ist die Verwendung von system() in SUID-root
Programmen eine Scheissidee.

Christoph Badura

unread,
Feb 25, 1993, 5:21:05 AM2/25/93
to
In <1993Feb24.0...@black.toppoint.de> kr...@black.toppoint.de (Kristian Koehntopp) writes:
>Die Verwendung von system()-Aufrufen in SUID-root Programmen
>kann in vielen Faellen eine Sicherheitsluecke darstellen, da
>system() eine Shell startet und diese Shell bzw. ihr Verhalten
>von verschiedenen Umgebungsvariablen anhaengt (SHELL=, IFS=,
>PATH= und andere).

Ein system(3) der SHELL oder PATH beachtet ist kaputt.

>- Setze "SHELL" auf einen Wrapper, der einen exec auf /bin/sh
> mit der Option -i (interactive) aufruft oder setze SHELL auf
> einen Wrapper, der /etc/passwd loescht.
> Einige system()-Versionen fangen das ab bzw. beachten den
> Wert von SHELL nicht.

>- Setze IFS auf "/" und setze ein Programm "bin" in den
> Suchpfad. Es wird das Programm "bin" mit dem Parameter
> "irgendeineshell" gestartet.

Unter welchen sytem(3) Versionen soll das funktionieren?

Ausserdem solltest Du mal die man-Page von system(3) lesen.
--
Christoph Badura --- b...@flatlin.ka.sub.org

Personally, I don't care whether someone is cool enough to quote Doug
Gwyn--I only care whether Doug Gwyn is cool enough to quote. -- Larry Wall

Olaf Titz

unread,
Feb 25, 1993, 6:46:22 AM2/25/93
to
In article <C2yyw...@ppcger.ppc.sub.org> se...@ppcger.ppc.sub.org (Josef Wolf) writes:

> Und das Beste an der ganzen Geschichte: ein auszufuehrendes Kommando wird
> direkt von argv[] zu system() durchgereicht. Und natuerlich kein Hinweis, dass
> es damit ein Sicherheitsproblem geben koennte. Noch einfacher kann man es

>...

> PS: Ob dieser Patzer irgendwie mit der Vereinigung mit dem UNIX-Magazin
> zusammenhaengt? ;-)

Ich habe mir (bisher sporadischer iX-Leser, fand sie aber immer sehr
gut) neulich eine iX gekauft und bin "uber den offensichtlich
unvermeidlichen Niveauverlust ziemlich erschrocken...

Olaf
--
| Olaf Titz - comp.sc.student | o | uk...@dkauni2.bitnet | old address |
| univ. of karlsruhe - germany | _>\ _ | s_t...@ira.uka.de | is still |
| +49-721-60439 | (_)<(_) | praetorius@irc | valid |
"My heart is human - my blood is boiling - my brain IBM" - Mr. Roboto

Stefan Rupp

unread,
Feb 26, 1993, 7:41:00 AM2/26/93
to
Moin Kristian,

kr...@black.toppoint.de schrieb am Mi, 24.02.93 09:36:


> Daher merke: Grundsaetzlich ist die Verwendung von system() in SUID-root
> Programmen eine Scheissidee.

Danke.

Ciao,
struppi

Rodney Volz

unread,
Feb 27, 1993, 1:52:43 AM2/27/93
to
In article <C3023...@flatlin.ka.sub.org>

b...@flatlin.ka.sub.org (Christoph Badura) writes:
>
>Ein system(3) der SHELL oder PATH beachtet ist kaputt.

system(3) ist es sicher egal, wie das Environment aussieht. Allerdings
wird /bin/sh ihr Verhalten nach diesem Environment richten.

>Unter welchen sytem(3) Versionen soll das funktionieren?

Das hat nichts mit system() zu tun, sondern ist Problem (oder Feature)
der Shell. Es sollte auf jedem **ix so wie beschrieben funktionieren.

>Ausserdem solltest Du mal die man-Page von system(3) lesen.

Aha.

Das folgende Programm sollte die Sache deutlicher machen.

main()
{
system("env");
}

Gruss,
-Rodney

Kristian Koehntopp

unread,
Feb 27, 1993, 8:41:00 AM2/27/93
to
In <C3023...@flatlin.ka.sub.org> b...@flatlin.ka.sub.org (Christoph Badura) writes:
>>- Setze IFS auf "/" und setze ein Programm "bin" in den
>> Suchpfad. Es wird das Programm "bin" mit dem Parameter
>> "irgendeineshell" gestartet.

>Unter welchen sytem(3) Versionen soll das funktionieren?

Z.B. NeXTstep 3.0:

$ IFS="/"; export IFS
$ probe
/bin/csh
sh: Benutzer: not found
$

wenn ich probe, d.h.

void main()
{
printf("%s\n", getenv("SHELL"));
system("/Benutzer/kris/Source/probe/huhu");
}

starte, wobei huhu ein einfaches Shellscript "echo huhu" ist.

>Ausserdem solltest Du mal die man-Page von system(3) lesen.

$ man 3 system | col -b | uniq

SYSTEM(3) UNIX Programmer's Manual SYSTEM(3)

NAME
system - issue a shell command

SYNOPSIS
system(string)
char *string;

DESCRIPTION
System causes the string to be given to sh(1) as input as if
the string had been typed as a command at a terminal. The
current process waits until the shell has completed, then
returns the exit status of the shell.

SEE ALSO
popen(3S), execve(2), wait(2)

DIAGNOSTICS
Exit status 127 indicates the shell couldn't be executed.

Sehr aufschlussreich.

"as if the string had been typed as a command at the terminal"
wuerde aber implizieren, dass SHELL und PATH beachtet werden,
sofern man dieser Man-Page ueberhaupt was entnehmen kann.

Tatsaechlich wird SHELL nicht beachtet, PATH spielt bei der
Suche nach der Shell auch keine Rolle, aber bei der Suche nach
dem angegebenen Kommando (Argument von system(3)), wenn ein
relativer Pfadname angegeben wurde. IFS wird (von NeXTstep)
beachtet, insbesondere dann, wenn das Argument von system(3)
ein Kommando mit absolutem Pfadnamen war.

Unter LINUX klappt der Trick mit dem IFS nicht:

/home/kris/Source/probe $ IFS="/"; export IFS
/home/kris/Source/probe $ probe
/bin/sh
huhu
/home/kris/Source/probe $

Die /bin/sh unter LINUX ist ein Link zur bash(1). Die setzt
vermutlich beim Startup IFS auf vernuenftige Werte. Auch LINUX
beachtet SHELL nicht. LINUX hat keine system(3) Manualpage.

Dagegen produziert ISC 2.2.1

$ IFS="/"; export IFS
$ probe
/bin/tcsh
sh: home: not found
$

verhaelt sich also in jeder Hinsicht wie NeXTstep. Die
Manual-Page zu system(3) unter ISC ist im uebrigen mit der vom
NeXT fast woertlich identisch, bis hin zum "as if typed" und so
weiter.

Stevens schreibt dazu in "Advanced Programming in the UNIX
environment" auf p. 224 unten:

What happens if we call system from a set-user-ID
program? This is a security hole and should never be
done.

Er zeigt dann kurz die Auswirkungen von SUID-Programmen (RUID,
EUID) und schliesst auf p. 226 im Kleingedruckten mit

One reason for the admonition is that system invokes
the shell to parse the command string and the shell
uses its IFS variable as the input field separator.
Older versions of the shell didn't reset this variable
to a normal set of characters when invoked. This
allowed a malicious user to set IFS before system was
called, causing a system to execute a different program.

Die Implementation von system(3), die Stevens auf p. 223
vorstellt, benutzt ein execl(3) auf /bin/sh, um eine Shell zu
starten. Wenn die tatsaechliche Implementation aehnlich ist,
werden SHELL und PATH also fuer die Ausfuehrung der Shell
selbst niemals beachtet.

Andererseits wird PATH von der aufgerufenen Shell benutzt, um
das angegebene Kommando zu starten. Es kann also sein, dass
eine Version des Kommandos gestartet wird, die der Autor des
Programms *nicht* im Sinn hatte, als er das (moeglicherweise
SUID laufende) Programm schrieb:

main()
{
system("ls");
}

unter SUID root gehoert zum Beispiel mit einem

$ PATH=/tmp:$PATH
$ export PATH
$ cat /tmp/ls
#! /bin/sh --
nice --10 rm -rf / &
exec /bin/ls $*
$ ls

bestraft.

Zusammenfassend kann man also sagen, dass die Verwendung von
system, SUID und root in einem Programm ein "Argh!" wert ist.

Was ich mit meinem ersten Artikel zum Ausdruck bringen wollte.

Wenn Du mir jetzt Deine system(3) Manual-Page schicken
wuerdest..

Kristian
--
Kristian Koehntopp, Harmsstrasse 98, DW-2300 Kiel, +49 431 676689

"Today, 'open system' really means 'open your wallet to buy my system'."
-- Mike Stefanik, comp.unix.misc

Christian Riede

unread,
Mar 1, 1993, 6:07:38 AM3/1/93
to
In article <A36...@AC2.maus.de>, Stefan Rupp writes:

kr...@black.toppoint.de schrieb am Mi, 24.02.93 09:36:
> Daher merke: Grundsaetzlich ist die Verwendung von system() in SUID-root
> Programmen eine Scheissidee.

Aha. Kann das mal jemand ein bischen ausfuehren?

Gruss, Christian

--
Christian Riede, Lange Strasse 88, W7500 Karlsruhe 51, Germany ===\\ || //
Tel. (+49) 721 {886091 | 608-4487 | 608-2749} ___ ====\\ ||//
EMail: c...@senga.ka.sub.org, ri...@ira.uka.de ________|________=====\\ ||\\
PGP 2.1 public key: finger ri...@iras1.ira.uka.de 0 \\_|| \\

Juergen Nickelsen

unread,
Feb 28, 1993, 9:26:28 AM2/28/93
to
In article <1993Feb27.1...@black.toppoint.de>
kr...@black.toppoint.de (Kristian Koehntopp) writes:

> Die Implementation von system(3), die Stevens auf p. 223
> vorstellt, benutzt ein execl(3) auf /bin/sh, um eine Shell zu
> starten. Wenn die tatsaechliche Implementation aehnlich ist,
> werden SHELL und PATH also fuer die Ausfuehrung der Shell
> selbst niemals beachtet.

Bei 4.3 BSD ist es definitiv so (eben (nochmal) nachgesehen), und
sowohl bei SunOS 4 als auch bei System V R3 ist es so, dass das Modul
system.o in der libc den String "/bin/sh" enthaelt und keinen Aufruf
von getenv(3).

--
Juergen Nickelsen

Christoph Badura

unread,
Mar 3, 1993, 7:29:29 PM3/3/93
to

>In <C3023...@flatlin.ka.sub.org> b...@flatlin.ka.sub.org (Christoph Badura) writes:
>>>- Setze IFS auf "/" und setze ein Programm "bin" in den
>>> Suchpfad. Es wird das Programm "bin" mit dem Parameter
>>> "irgendeineshell" gestartet.

>>Unter welchen sytem(3) Versionen soll das funktionieren?

>$ IFS="/"; export IFS


>$ probe
>/bin/csh
>sh: Benutzer: not found

Ein Punkt fuer Dich.

>Sehr aufschlussreich.

In der Tat.

>"as if the string had been typed as a command at the terminal"
>wuerde aber implizieren, dass SHELL und PATH beachtet werden,

Natuerlich nicht, denn da stand:


> System causes the string to be given to sh(1) as input as if

>Tatsaechlich wird SHELL nicht beachtet, PATH spielt bei der


>Suche nach der Shell auch keine Rolle,

Genau.

>aber bei der Suche nach
>dem angegebenen Kommando (Argument von system(3)), wenn ein
>relativer Pfadname angegeben wurde.

War es aber nicht, weil ein Absoluter Pfadname angegeben wurde.

Christoph Badura

unread,
Mar 3, 1993, 7:36:52 PM3/3/93
to
In <1993Feb27....@tyrell.tynet.sub.org> rod...@tyrell.tynet.sub.org (Rodney Volz) writes:
>system(3) ist es sicher egal, wie das Environment aussieht. Allerdings
>wird /bin/sh ihr Verhalten nach diesem Environment richten.

Thema verfehlt, setzen.

>Das folgende Programm sollte die Sache deutlicher machen.
> main()
> {
> system("env");
> }

Das Programm war aber (sinngemaes):

main()
{
system("/bla/fasel/shell");

0 new messages