v05i063: Solving the setuid script problem
David Goodenough
dg at lakart.UUCP
Sat Dec 3 10:27:57 AEST 1988
Posting-number: Volume 5, Issue 63
Submitted-by: "David Goodenough" <dg at lakart.UUCP>
Archive-name: secure
[Any setuid gurus want to say whether this is actually secure or not? ++bsa]
After all the discussion about the lack of security of setuid shell scripts,
I put the following together. It runs shell scripts, but is a little more
careful as to what it will run. There's no makefile - just compile this,
copy it to /bin/secure, chown it to root, and chmod it 4755. secure.8
describes the layout of /etc/secure - it's just a line for each safe shell
script, containing the full pathname first, and the numeric uid the run the
script.
--
dg at lakart.UUCP - David Goodenough +---+
| +-+-+
....... !harvard!xait!lakart!dg +-+-+ |
AKA: dg%lakart.uucp at harvard.harvard.edu +---+
--- cut here --- cut here --- cut here --- cut here --- cut here ---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the '#! /bin/sh' line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (NOT csh) to create the files:
# A: secure.c
# B: secure.8
#
# Unwrapping with no options prevents overwriting files that already exist;
# giving a '-c' switch causes files to be overwritten regardless.
#
# wrapped by dg at lakart(David Goodenough) on Wed Nov 23 10:13:18 EST 1988
#
if test -f secure.c -a x$1 != x-c
then
echo shar: file secure.c already exists
else
echo shar: extracting secure.c
sed "s/^X//" <<\##__EOF..secure.c__## >secure.c
X#include <stdio.h>
X
X#define SECURE "/etc/secure"
X
Xmain(n, a)
Xchar **a;
X {
X int uid;
X FILE *fp;
X char program[100];
X
X if (strcmp(a[0], "SEC-URE"))/* I'm damned if I know why this is */
X { /* necessary, but it is */
X (void) strcpy(program, a[0]);
X a[0] = "SEC-URE";
X execv(program, a); /* re exec ourselves so setuid bits work */
X exit(1); /* this should never happen */
X }
X if ((fp = fopen(a[1], "r")) == (FILE *) NULL)
X exit(1); /* file not found */
X (void) fclose(fp);
X if (a[1][0] != '/')
X exit(1); /* only pass an absolute pathname to /bin/sh */
X if ((fp = fopen(SECURE, "r")) == (FILE *) NULL)
X exit(1); /* can't find the file of secure programs */
X while (fscanf(fp, "%s %d", program, &uid) == 2)
X {
X if (strcmp(program, a[1]) == 0)
X { /* aha ..... we found our program */
X (void) fclose(fp);
X (void) unsetenv("IFS");
X /* tweak the environment for added safety */
X (void) setenv("PATH", "/bin:/usr/bin", 1);
X (void) setuid(uid); /* set the uid */
X a[0] = "-sh";
X execv("/bin/sh", a);
X exit(1); /* this should never happen */
X }
X }
X exit(1); /* come here if we didn't find the program */
X }
##__EOF..secure.c__##
fi
if test -f secure.8 -a x$1 != x-c
then
echo shar: file secure.8 already exists
else
echo shar: extracting secure.8
sed "s/^X//" <<\##__EOF..secure.8__## >secure.8
X.\" dg at lakart - David Goodenough Wed Nov 23 09:47:12 EST 1988
X.\"
X.TH SECURE 8 "Nov 23, 1988"
X.UC 4
X.SH NAME
X.B secure
X\- run setuid shell scripts safely
X.SH SYNOPSIS
X.B #! /bin/secure
X.br
X.SH DESCRIPTION
X.B Secure
Xis never normally executed from a shell. Instead it can be used
Xas the interpreter for shell scripts that need to be run setuid someone
Xelse: this is done by making the first line of the script
X.PP
X.ti+5n
X#! /bin/secure
X.PP
Xrather than the usual
X.PP
X.ti+5n
X#! /bin/sh
X.PP
X.B Secure
Xdetermines if a script can be safely run by looking in
X/etc/secure. This is a list of secure shell scripts, and the numeric
Xuser id that the script is to be run with. A typical line from
X/etc/secure might be
X.PP
X.ti+5n
X/usr/script 0
X.PP
Xwhich would mean that /usr/script should be run as root.
X.PP
XBecause
X.B secure
Xwill only
Xexec a pathname beginning with '/', that comes from /etc/secure, it
Xcannot be used to illegally gain root access.
X.PP
XIn addition, for the sake of security,
X.B secure
Xsets the PATH environment variable back to a simple default, and deletes
Xthe IFS environment variable.
X.SH "SEE ALSO"
X.BR sh (1),
##__EOF..secure.8__##
fi
# end of shell archive
exit 0
More information about the Comp.sources.misc
mailing list