[comp.unix.wizards] Secure setuid shell scripts

sahayman@iuvax.cs.indiana.edu (Steve Hayman) (10/20/88)

What if we had a C program, let's call it "securesh", that you
would use instead of "#!/bin/sh" when you wanted to create
a secure setuid shell script.  "securesh" would try to set
up a reasonable environment, PATH, IFS, etc etc, and then
exec sh to handle shell script.  Sort of the solution that
people have been proposing ("write a C wrapper around your script")
but bundled up nicely.

For instance, suppose we have a setuid root shell script,
/usr/local/bin/myscript.  Instead of starting it with
"#!/bin/sh", we start it with "#!/bin/securesh". 

So securesh starts up with an argument list like this

	/bin/securesh
	/usr/local/bin/myscript
	other options

And securesh (a C program) does ...
	- check the permissions on "myscript" to make
		sure it's setuid (and then setuid() to whatever is appropriate)

	- set PATH to a reasonable value  (of course it may be
		reset later by the script)

	- unset IFS, maybe unset every other environment variable.

	- stat() the script file - if it's a symlink, exit with
		a warning message.  If it's a relative pathname,
		exit with a warning message.  Maybe we open()
		the file as the first thing we do and fstat() it
		in case someone tries to swap it on us.
	
	- perhaps some other checks would be appropriate here

	- once we are convinced that we have a secure environment,
		(ok, a "secure enough" environment), we
		exec /bin/sh /usr/local/bin/myscript


The key here is that we set up a reasonable environment, and then
refuse to execute the script if anything looks fishy (the
file name is a symlink, etc).  Perhaps this would be a reasonable
compromise between wanting the occasional setuid shell script - they
are convenient sometimes - and wanting to be secure.

I think this would provide a "safe enough" way to execute setuid
shell scripts.  I'm familiar with the problems with setuid scripts
now, and think that if you enforced the convention that setuid scripts
*MUST* begin with /bin/securesh instead of /bin/sh, you'd have
enough security.  (I could see maybe running a program from the crontab to 
track down setuid-/bin/sh scripts and turn off their setuid bit.)

If anyone can foresee problems with this approach, I'd like to hear about
them before I try to implement this.


..Steve

--
Steve Hayman    Workstation Manager    Computer Science Department   Indiana U.
sahayman@iuvax.cs.indiana.edu

dhesi@bsu-cs.UUCP (Rahul Dhesi) (10/20/88)

If a 4.3BSD system has not been patched to disallow set-user-id shell
scripts, but root uses no set-user-id scripts, does a security hole
still exist that will allow an unprivileged user to obtain root
privileges?
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi

chris@mimsy.UUCP (Chris Torek) (10/20/88)

In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) asks:
>If a 4.3BSD system has not been patched to disallow set-user-id shell
>scripts, but root uses no set-user-id scripts, does a security hole
>still exist that will allow an unprivileged user to obtain root
>privileges?

If I can modify that to `... but there are no set-user-id scripts that
set the user ID to root', the answer is no (discounting other avenues,
e.g., the `::0:0:::' entries sometimes found in /etc/passwd).  If the
system has not been patched, and there is a set-ID script somewhere,
that script can be used as the basis for gaining the privileges granted
by that ID (user or group) in a way that the author of the script most
likely did not intend.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

sbc@sp7040.UUCP (Stephen Carroll) (10/21/88)

In article <14069@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
] In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) asks:
] >If a 4.3BSD system has not been patched to disallow set-user-id shell
] >scripts, but root uses no set-user-id scripts, does a security hole
] >still exist that will allow an unprivileged user to obtain root
] >privileges?
] 
] If I can modify that to `... but there are no set-user-id scripts that
] set the user ID to root', the answer is no (discounting other avenues,
] e.g., the `::0:0:::' entries sometimes found in /etc/passwd).  If the
] system has not been patched, and there is a set-ID script somewhere,
] that script can be used as the basis for gaining the privileges granted
] by that ID (user or group) in a way that the author of the script most
] likely did not intend.
] -- 

just one question.  Is this problem a security hole for only BSD systems,
or does it exist on other SVID type systems or others?

Stephen B. Carroll
UUCP:   ...!{ hpda | sun }!sp7040!sbc

terryl@tekcrl.CRL.TEK.COM (10/22/88)

In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>If a 4.3BSD system has not been patched to disallow set-user-id shell
>scripts, but root uses no set-user-id scripts, does a security hole
>still exist that will allow an unprivileged user to obtain root
>privileges?

     Yes. The problem is not that root uses a set-user-id shell script,
but that there exists anywhere in the file system a set-user-id shell
script THAT I CAN EXECUTE AS A MERE MORTAL(i.e. normal user). If such
a set-user-id shell script does exist, then in a manner of minutes
(depending on how fast I can type!!! (-:) I can become the id of that
shell script!!!! No matter the id, if I can execute it, I can be that id,
without knowing the password or any other such trickery. If it's a
set-user-id shell script to root, you know the old saying "Well, bend
over backwards and kiss your ..... goodbye!!!

     As has been alluded to MANY times in the past, the problem is NOT
in the semantics of the shell language (i.e. sh, csh, ksh), but in the
semantics of the file system itself. Think about it for a while. I know
when this first hit I said, "Boy, sure sounds like a lot of paranoia to
me". But, after thinking about it for a week or so, the little light
(literally!!) when on inside my head, and then I said, "Yuck!!! That's
not mere paranoia, that's a genuine security hole that's not easily
fixed" (short of disallowing set-user-id shell scripts).

     Just as a little more information, I do need a directory that I can
write to, but it doesn't have to be anywhere special. Since /tmp (and
usually /usr/tmp) is writable by everyone in the world, this will suit
my needs just fine.

bzs@encore.com (Barry Shein) (10/24/88)

From: terryl@tekcrl.CRL.TEK.COM
>In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>>If a 4.3BSD system has not been patched to disallow set-user-id shell
>>scripts, but root uses no set-user-id scripts, does a security hole
>>still exist that will allow an unprivileged user to obtain root
>>privileges?
>
>     Yes. The problem is not that root uses a set-user-id shell script,
>but that there exists anywhere in the file system a set-user-id shell
>script THAT I CAN EXECUTE AS A MERE MORTAL(i.e. normal user). If such
>a set-user-id shell script does exist, then in a manner of minutes
>(depending on how fast I can type!!! (-:) I can become the id of that
>shell script!!!!

I think Rahul is asking the same question I asked and we're both being
misunderstood (I've also gotten some private mail indicating a
misunderstanding.)

Rephrase: If there are NO setuid scripts on the entire system does
there exist a bug which can be exploited?

For example, is there a bug such that a (non-priv'd) user could make a
new script, perhaps setuid'd, and by some machination get it to be
setuid root (eg. link punning to a file owned by, but not setuid, root
or some such thing.)

The reason for the question is, and I think Rahul was also getting at
this, that this would seem to be minimal sufficient cause to shut off
the feature in the system. Anything less (ie. being able to hack at
setuid shell scripts) seems a questionable cause and might be better
handled by merely advising those interested in security not to create
setuid scripts. Put it in the distribution motd or some such thing.

As a counter-example, I've created setuid scripts which setuid to a
psuedo-user who owned some files which, although a nuisance, I
wouldn't lose a lot of sleep over having trashed.

Specifically, I had a psuedo-user "recipes" who owned the recipes
directory and entries for our local alt.gourmand collection and that
was all.

There was a setuid (user=recipes, non-priv'd) script in there which
allowed someone to put a new recipe into the directory and another to
rebuild an index file to incorporate new recipes. It was nice for
random users on a reasonably trustable system to be able to take care
of these things if they noticed them out of synch and I couldn't
imagine any damage they could do I couldn't repair in 15 minutes
(especially cuz I kept a mirror image of everything on another system
for another group, and besides, tape backups were good on that
system.)

I could think of other useful examples, none of them critical (I'm
hardly saying the above is critical, but it fits a pattern I've used
over and again, some non-priv'd setuid scripts to allow users to
manage non-critical files w/o having to go bother a systems person.)
Another was that the games files were owned by a non-priv psuedo-user
"scores" and a script to let a user with a wayward lock file (which
some games created and then refused to let you play again if it
existed, typically a problem after a crash) remove it. So they could
trash all the scores files and lock files in the games area, so what?
Nuisance, but hardly worth the alternative, having people bug
operations to unscrew their rogue games (I know, all can be handled by
C programs, but is it worth it? hardly.)

>But, after thinking about it for a week or so, the little light
>(literally!!) when on inside my head,

I doubt that, perhaps a light went on figuratively, but literally?
Do you really have little electronic filaments in your head? :-)

	-Barry Shein*, ||Encore||

* Chairman, Committee for Eradication of the Use of the Word
"Literally" as an Intensifier.
-- 

dg@lakart.UUCP (David Goodenough) (10/24/88)

From article <14069@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek):
> In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) asks:
>>If a 4.3BSD system has not been patched to disallow set-user-id shell
>>scripts, but root uses no set-user-id scripts, does a security hole
>>still exist that will allow an unprivileged user to obtain root
>>privileges?
> 
> If I can modify that to `... but there are no set-user-id scripts that
> set the user ID to root', the answer is no (discounting other avenues,
> e.g., the `::0:0:::' entries sometimes found in /etc/passwd).  If the
> system has not been patched, and there is a set-ID script somewhere,
> that script can be used as the basis for gaining the privileges granted
> by that ID (user or group) in a way that the author of the script most
> likely did not intend.

One question. What does an

execl("/bin/sh", "/bin/sh", "-", "-i", 0);

do. I.e. what happens when the first line is:

#! /bin/sh -

rather than plain old:

#! /bin/sh

This closes up the security hole very nicely here (unless there's some
sneaky way of getting in that I didn't know about). Incidentally, lakart
is BSD4.3, so we DO have symbolic links: it was suggested that if no
symbolic links existed, then by denying write permission to general users
on all filesystems where suid 0 reside the problem could be reduced. (I'm
not going to say solved, nothing in this world is certain except death
and taxes :-) :-) )

As an aside on the IFS problem: the following is taken from man 1 sh:

          IFS  Internal field separators, normally space, tab,
               and newline.  IFS is ignored if sh is running as
               root or if the effective user id differs from the
               real user id.

i.e. with our shell setting IFS to "/" (or anything) won't help a whole
lot
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@harvard.harvard.edu	  	  +---+

chris@mimsy.UUCP (Chris Torek) (10/25/88)

>>In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) asked:
>>>If a 4.3BSD system has not been patched ....

>In article <14069@mimsy.UUCP> I answered:
>>If the system has not been patched, and there is a set-ID script somewhere,
>>that script can be used as the basis for gaining the privileges granted
>>by that ID (user or group) in a way that the author of the script most
>>likely did not intend.

In article <546@sp7040.UUCP> sbc@sp7040.UUCP (Stephen Carroll) asks:
>just one question.  Is this problem a security hole for only BSD systems,
>or does it exist on other SVID type systems or others?

Since System Vs% do not have directly-executable scripts, System Vs do
not have the problem, because System Vs cannot possibly have any set-ID
scripts.  (Actually, there is a way to have set-ID scripts without having
the kernel do it: you make the interpreter itself set-ID, and have it
check the ID on the script.  I believe ksh can do this.  sh cannot,
certainly not without modification.)

-----
% Not System V, System Vs: there are many different System Vs, all
  incompatible to some extent.  *Which one* shall we consider standard?
-----

 - If the kernel does not have directly-executable scripts, the system
   does not have the bug.

 - If the kernel has the #! mechanism copied directly from 4BSD, the system
   does have the bug.

 - If the kernel has a modified #! mechanism, it might not have the bug.
 
 - If you have on your machine no scripts that are themselves set-ID (user
   or group), you need not worry about the bug, whether it exists or not
   on your system.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

bsy@PLAY.MACH.CS.CMU.EDU (Bennet Yee) (10/25/88)

In article <3969@encore.UUCP> bzs@encore.com (Barry Shein) writes:
]From: terryl@tekcrl.CRL.TEK.COM
]>In article <4409@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
]>>If a 4.3BSD system has not been patched to disallow set-user-id shell
]>>scripts, but root uses no set-user-id scripts, does a security hole
]>>still exist that will allow an unprivileged user to obtain root
]>>privileges?
]>
]>     Yes. The problem is not that root uses a set-user-id shell script,
]>but that there exists anywhere in the file system a set-user-id shell
]>script THAT I CAN EXECUTE AS A MERE MORTAL(i.e. normal user). If such
]>a set-user-id shell script does exist, then in a manner of minutes
]>(depending on how fast I can type!!! (-:) I can become the id of that
]>shell script!!!!
]
]I think Rahul is asking the same question I asked and we're both being
]misunderstood (I've also gotten some private mail indicating a
]misunderstanding.)
]
]Rephrase: If there are NO setuid scripts on the entire system does
]there exist a bug which can be exploited?
]

If there are no setuid scripts on the entire system, there is no way that
somebody could break into the system using the setuid script bug.  If you
create your own script setuid to yourself, you'd only allow other people to
gain access to your account.

-bsy
-- 
Internet:	bsy@cs.cmu.edu		Bitnet:	bsy%cs.cmu.edu%smtp@interbit
CSnet:	bsy%cs.cmu.edu@relay.cs.net	Uucp:	...!seismo!cs.cmu.edu!bsy
USPS:	Bennet Yee, CS Dept, CMU, Pittsburgh, PA 15213-3890
Voice:	(412) 268-7571

dhesi@bsu-cs.UUCP (Rahul Dhesi) (10/25/88)

The set-user-id shell script bug, they say, lies in the semantics of
the file system itself.  Very well:

In article <14139@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) adds:
>...there is a way to have set-ID scripts without having
>the kernel do it: you make the interpreter itself set-ID, and have it
>check the ID on the script.

Which naturally leads me to wonder:  The semantics of the filesystem
are presumably not dependent on whether the kernel handles set-uid
scripts or the set-uid interpreter does (or are they?).  Does the same
security hole exist when a shell, which has been made made set-uid to
root, executes a set-uid scrpt without the kernel's help?
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi

chris@mimsy.UUCP (Chris Torek) (10/25/88)

In article <4483@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>The set-user-id shell script bug, they say, lies in the semantics of
>the file system itself.  Very well: ... Does the same security hole
>exist when a shell, which has been made made set-uid to root, executes
>a set-uid script without the kernel's help?

No.  (Gak, this practically gives it away.  Oh well, everyone has had
plenty of warning to get rid of setuid or setgid scripts that set to
important IDs.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

guy@auspex.UUCP (Guy Harris) (10/26/88)

>just one question.  Is this problem a security hole for only BSD systems,
>or does it exist on other SVID type systems or others?

The one I know of would be a problem on non-BSD systems if they have the
following features:

	1) "#!" - the ability for the kernel to recognize that an
	   executable file is really a shell (or other) script, and to run
	   the appropriate shell on it

	2) symbolic links (not necessary in all cases, but necessary to
	   make it work under arbitrary circumstances)

and that handles certain aspects of process creation in a certain way.

If it's missing 1), the system doesn't *have* set-UID shell scripts in
the sense being discussed here; the trick is that if the *script* has
its set-UID or set-GID bit set, when it runs the shell in question it
will run it with set-UID or set-GID privileges.  Most non-BSD systems
don't have it, but some non-BSD systems do (although many of them
started from BSD, even though they may be S5-compatible...).

maart@cs.vu.nl (Maarten Litmaath) (10/26/88)

In article <303@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
\>just one question.  Is this problem a security hole for only BSD systems,
\>or does it exist on other SVID type systems or others?
\
\The one I know of would be a problem on non-BSD systems if they have the
\following features:
\
\	1) "#!" - the ability for the kernel to recognize that an
\	   executable file is really a shell (or other) script, and to run
\	   the appropriate shell on it
\
\	2) symbolic links (not necessary in all cases, but necessary to
\	   make it work under arbitrary circumstances)

I don't need 2 at all! Just a bit patience will do...
-- 
Hippic sport:                         |Maarten Litmaath @ VU Amsterdam:
             a contradiction in terms.|maart@cs.vu.nl, mcvax!botter!maart

guy@auspex.UUCP (Guy Harris) (10/27/88)

 >The set-user-id shell script bug, they say, lies in the semantics of
 >the file system itself.  Very well:
 >
 >In article <14139@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) adds:
 >>...there is a way to have set-ID scripts without having
 >>the kernel do it: you make the interpreter itself set-ID, and have it
 >>check the ID on the script.
 >
 >Which naturally leads me to wonder:  The semantics of the filesystem
 >are presumably not dependent on whether the kernel handles set-uid
 >scripts or the set-uid interpreter does (or are they?).  Does the same
 >security hole exist when a shell, which has been made made set-uid to
 >root, executes a set-uid scrpt without the kernel's help?

I don't know that I'd say it "lies within the semantics of the file
system" in the sense you may be thinking of.  It lies, in part, with the
way "#!" is implemented, and in part with the way some other system
calls work.  The same security hole (at least the one I'm familiar with,
which I think is the one being discussed here) doesn't exist if the
shell is made set-UID and executes it without the kernel's help.

chris@mimsy.UUCP (Chris Torek) (10/27/88)

In article <307@lakart.UUCP> dg@lakart.UUCP (David Goodenough) suggests:
-#! /bin/sh -
-rather than plain old:
-#! /bin/sh
-This closes up the security hole very nicely here (unless there's some
-sneaky way of getting in that I didn't know about).

Yes, there is a sneaky way that you did not know about.

-it was suggested that if no symbolic links existed, then by denying
-write permission to general users on all filesystems where suid 0 reside
-the problem could be reduced.

That would work around this particular bug.

-As an aside on the IFS problem: the following is taken from man 1 sh:
-          IFS  Internal field separators, normally space, tab,
-               and newline.  IFS is ignored if sh is running as
-               root or if the effective user id differs from the
-               real user id.

IFS should *never* be imported; with any luck I may get this fixed in
4.4BSD.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

ed@mtxinu.UUCP (Ed Gould) (10/27/88)

>just one question.  Is this problem a security hole for only BSD systems,
>or does it exist on other SVID type systems or others?

Set-uid scripts are a security hole on any system, if they exist at all
which is not typical on SysV.

-- 
Ed Gould                    mt Xinu, 2560 Ninth St., Berkeley, CA  94710  USA
{ucbvax,uunet}!mtxinu!ed    +1 415 644 0146

"I'll fight them as a woman, not a lady.  I'll fight them as an engineer."

maart@cs.vu.nl (Maarten Litmaath) (10/27/88)

In article <307@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes:
\...
\#! /bin/sh -
\...
\This closes up the security hole very nicely here (unless there's some
\sneaky way of getting in that I didn't know about).

There's still another way (keyword: race condition).
BTW, our 4.3BSD /bin/sh doesn't stop searching for flags after the `-'.

\Incidentally, lakart
\is BSD4.3, so we DO have symbolic links: it was suggested that if no
\symbolic links existed, then by denying write permission to general users
\on all filesystems where suid 0 reside the problem could be reduced.

That's correct, but a bit inconvenient: no setuid scripts on /usr (/usr/tmp).
-- 
George Bush:                          |Maarten Litmaath @ VU Amsterdam:
             Capt. Slip of the Tongue |maart@cs.vu.nl, mcvax!botter!maart

greim@sbsvax.UUCP (Michael Greim) (10/27/88)

In article <1575@star.cs.vu.nl>, maart@cs.vu.nl (Maarten Litmaath) writes:
> 
> I don't need 2 at all! Just a bit patience will do...

But with symbolic links it works usually at first try on our SUN.
Lucky that normally we don't have any setuid scripts. :-)

	-mg
-- 
email : greim@sbsvax.informatik.uni-saarland.dbp.de
  (some mailers might not like this. Then use greim@sbsvax.uucp)
  or  : ...!uunet!unido!sbsvax!greim
# include <disclaimers/std.h>

guy@auspex.UUCP (Guy Harris) (10/28/88)

>One question. What does an
>
>execl("/bin/sh", "/bin/sh", "-", "-i", 0);
>
>do.

It probably fails on machines where the bit pattern for the "int" value
0 is not the same (either in size or in bit content) as the bit pattern
for a null "char *", but that's neither here nor there.... 

>I.e. what happens when the first line is:
>
>#! /bin/sh -
>
>rather than plain old:
>
>#! /bin/sh

It makes the shell not get confused if you run the script with a name
beginning with "-".  Thus, this is a Good Thing To Do.  However....

>This closes up the security hole very nicely here (unless there's some
>sneaky way of getting in that I didn't know about).

You're thinking of a different security hole.  Adding the "-" flag
doesn't do a damn thing for the one I suspect most of us are thinking
of.  That one is caused by a more subtle problem (one which most of us
discussing it didn't know about until it was pointed out to us, I
suspect - I sure didn't).

guy@auspex.UUCP (Guy Harris) (10/28/88)

>BTW, our 4.3BSD /bin/sh doesn't stop searching for flags after the `-'.

Hmm.  As I remember, it did when I tried it a while ago on a VAX running
4.3BSD off the tape....

martin@mqcomp.oz (Martin Foord) (11/10/88)

I have only started to read this section in the last few days but have read
much on the subject of set[ug]id shell scripts. Probably due to my
ignorance I haven't been able to pick up the main threads of the
problems that occur with them. Could somone elighten me as to the
security hole with set[ug]id scripts and `#!' and the problem with
symbolic links.
				Many Thanks in Advance,
						Martin Foord.


Martin Foord              ACSnet,Ean,CSnet: martin@mqcomp.mq.oz
Computing Discipline      Arpa:  martin%mqcomp.mq.oz@UUNET.UU.NET
Macquarie University 2109 Janet: martin%mqcomp.mq.oz@UK.AC.UKC
Australia                 UUCP:  {uunet,mcvax}!munnari!mqcomp.mq.oz!martin