show me

Guy Harris guy at gorodish.Sun.COM
Thu Aug 4 13:01:40 AEST 1988


> The poster asked what the danger of a setuid shell was.

No, the poster asked what the danger of a setuid shell *script* is:

> From: kai at uicsrd.csrd.uiuc.edu
> Newsgroups: comp.unix.wizards
> Subject: show me
> Date: 28 Jul 88 01:53:00 GMT
>
> I've seen talk about how unsafe setuid shell scripts are, but haven't ever
> seen any examples that prove this.  Would someone please explain to me know
> why, as a system administrator, I shouldn't ever use setuid/setgid shell
> scripts?

I think we all know why a shell that is running setuid, and that is under the
control of a potentially-hostile user, is dangerous; this hardly needs
explanation - especially not in "comp.unix.wizards".

However, what may not be obvious is that, with a system that permits setuid
shell *scripts* (not setuid *shells*!) by using the mechanism described below,
a hostile user can put the setuid shell that runs the script under their
control.

Some UNIX systems implement an idea that I believe Dennis Ritchie originally
proposed: if an "exec"-family system call is made on a file beginning with the
characters "#!", it treats the file as a script to be interpreted.  It reads
the first line of the file, and checks that it is in the form

	#! <pathname>

or

	#! <pathname> <additional characters>

It then tries to run the file named <pathname>, which must be an executable
file (i.e., it cannot in turn begin with "#!).  The argument list passed to
that program is the argument list from the "exec", with the pathname of the
script inserted as the first argument, and with the <additional characters>
inserted as the second argument if present.

Thus, you can begin a Bourne shell script with

	#! /bin/sh

and give it execute permission; an "exec"-family system call, when given the
pathname of that script, will succeed, even though the file isn't a binary
program.  The program that will actually be executed is "/bin/sh"; the first
argument to "/bin/sh" will be the pathname of the script, so if the script is
called "foo", and you do

	execl("foo", "foo", "argument", (char *)NULL);

the Bourne shell will be executed with the first argument being "foo" and the
second argument being "argument".  It will then execute the script "foo"
(if it's readable), with the first argument to the script being "argument".

The kernel will honor the setuid and setgid bits on such a script.  The shell
in question will be run setuid or setgid if the script has the setuid or
setgid bits set - *regardless of whether the shell itself is setuid or
setgid*.  "/bin/sh" can have mode "r-xr-xr-x"; it is not setuid, so you have
not granted setuid privileges to everybody whose login shell is "/bin/sh", but
if the script is setuid, the shell will run setuid when the script is
"exec"ed.

The problem is that such a script must be "airtight" in order for this to be
safe.  You must not be able to make the shell running the script do anything
other than what the script intends it to do.  Unfortunately, there are a
variety of ways you *can* fool the shell into doing something other than what
the script nominally tells it to do.

Again, it's obvious that if you make "/bin/sh" owned by root, with mode
"r-sr-xr-x", you render your system totally insecure.  That wasn't what was
being discussed; if you have setuid shell scripts, you have a security problem
even if "/bin/sh" is *NOT* setuid.

The naive user may think that setuid shell *scripts* are safe, since
"obviously" the only thing the shell will do when using the aforementioned
mechanism is whatever the author of the script intended, assuming that the
author of the script is sufficiently careful.  This is not true; it is
tricky to plug some of the security holes caused by using this mechanism, and
given that non-obvious holes have appeared before, it's not clear how secure
you can be that you've plugged the last such hole.



More information about the Comp.unix.wizards mailing list