tchrist@convex.COM (Tom Christiansen) (11/17/90)
In article <1990Nov16.121518.5644@lth.se> magnus%thep.lu.se@Urd.lth.se (Magnus Olsson) writes: >In article <6644@ethz.UUCP> prl@iis.UUCP (Peter Lamb) writes: >> SETUID SHELL SCRIPTS ARE INHERENTLY A SECURITY HOLE! >> >> You *CAN'T* make them hackerproof. > >Why? I answered this already, but apparently I didn't cross post; these threads are diverging into different newsgroups. Summary: You NEVER WANT setuid shell scripts. Ever. If you already know why, skip the rest of this message. --tom ------- Forwarded Message Date: 15 Nov 90 17:30:39 GMT From: tchrist@convex.COM (Tom Christiansen) Subject: Re: how to setuid for shell scripts? Organization: CONVEX Software Development, Richardson, TX Newsgroups: comp.unix.internals In article <25009@adm.brl.mil> K390590%AEARN@pucc.princeton.edu ( Steinparz Fra nz) writes: >Could someone give me advice how to make a shell script which inherits >its access rights from its owner as this is done by set uid for regular >programs. Just setting the set uid bit via CHMOD 06xxx does not work >on vax under ultrix. You don't want to do that. Here follows a longish treatise on why not. Setuid (and setgid) scripts should be disabled in the kernel. There's a lot of confusion about why this is necessary, so this will try to explain it. There are the obvious caveats like being careful of IFS and PATH in both the script and anything it calls, and so on and so forth, but even if these bases are carefully covered, a subtler problem remains for which no work-around exists. When you execute a shell script, what really happens is that the kernel (at least, modern ones) opens the file you asked it to run, sees the magic number of "#!", and then calls the interpreter following that to run the script for you. The problem is that it passes the name of the script to the shell, and the shell must then reopen the script. That means we opened the script twice. Consider the following scenario: /usr/local/bin/zot is a suid shell script. ~/snark is a symlink pointing to zot. ~/gotcha is some program that if run as root would compromise security, such as by giving me a root shell. I type something like "nice +64 snark &" and let the kernel ever so slowly decide to call the shell with an argument of snark. It's already set the euid to root because it's pointing to zot, which is suid root. Now the shell ever so slowly starts up. In the meantime, I make snark point not to zot but to gotcha. Bingo! By the time the suid shell opens snark, it gets gotcha instead of zot, and the whole system is down the tubes. As you see, the presence of ANY suid root script on a system allows anyone to run anything as root. This is obviously a Very Bad Thing. Even a suid user foo script is bad, due to the transitive nature of insecurity. Now, if the suid script is in perl or ksh, they could keep working even with suid scripts disabled in the kernel because these programs have alternate versions of themselves (suidperl and suid_exec) installed suid for just this reason. (Theoretically -- last I checked suid_exec didn't quite work for this.) Csh and sh scripts, however, simply will not work. You should really disable suid scripts in your kernel, or get your vendor to do so if you can't. This is a strong statement, but from a security standpoint, it's your only option. Barring that, seek them out and rendor them impotent on your system with a find, a file, and a chmod. You could actually fix the kernel not to run through namei/lookuppn/foobar twice in the kernel, but this is harder (less so if you support /dev/fd*). Furthermore, other inherent perils remain (see below). One work around is to create a C wrapper that's suid that does the exec of the interpreter itself. You could use the public domain sudo program for this. - --tom ps: Here is an additional posting on the subject: - ------- Forwarded Message Date: 10 Aug 90 19:41:32 GMT From: vlb@magic.apple.com (Vicki Brown) Subject: Re: Suid script security Organization: Apple Computer Newsgroups: comp.unix.questions In article <14920003@hpdmd48.boi.hp.com> markw@hpdmd48.boi.hp.com (Mark Wolfe) writes: > > I know that suid scripts are a bad idea from reading comp.questions and >comp.wizards over the last year or so. It seems that just about every guru >in the world has posted a warning NOT to do it, so I decided I would follow >the advice (it's a rare subject that all guru's agree on). However, it appears >that I'm now about to have one of these ugly animals forced on me from above, >so I'd like some advice: > > 1) Just what are the security risks involved? (i.e. how would someone attack > a system via one of these). > > 2) What can I do to make this as secure as possible? Warning - very long response ahead. Proceed at your own risk. There was a very interesting paper in the USENIX Association's publication, ;login: ( "How To Write a Setuid Program", Matt Bishop, ;login: Vol 12, Number 1, January/February 1987). An excerpt: Some versions of UNIX allow command scripts, such as shell scripts, to be made setuid ... Unfortunately, given the power and complexity of many command interpreters, it is often possible to force them to perform actions which were not intended, and which allow the user to violate system security. This leaves the owner of the setuid script open to a devastating attack. In general, such scripts should be avoided. ... suppose a site has a setuid script of sh commands. An attacker simply executes the script in such a way that the shell ... appears to have been invoked by a person logging in. UNIX applies the setuid bit on the script to the shell, and ... it becomes interactive... One way to avoid having a setuid script is to turn off the setuid bit on the script, and ... use a setuid [binary] program to invoke it. This program should take care to call the command interpreter by its full path name, and reset environment information such as file descriptors and environment variables to a known state. However, this method should be used only as a last resort and as a temporary measure, since with many command interpreters it is possible even under these conditions to force them to take undesirable action. The biggest problem with shell scripts is that you (the programmer / administrator) have very little control over the programs which run within the script. As a very real example, I ran across a script which allowed users to enter bug reports, using the "vi" editor. The script was setuid root, because it wanted to save files in funny places. The programmer had guarded against shell escapes (a known feature of vi), by making this script the login shell. However, he couldn't guard against another feature :e /etc/passwd You can attempt to make your script as safe as possible by 1) being very restrictive in your choice of UID. That is, make the script setuid for a non-privileged user, rather than root (for example, if it must write a log file, could the log file live in some locked area, accessed only by a new and otherwise non-privileged account?) 2) making the script setgid rather than setuid, with a very restricted GID (see #1) 3) ensuring that the script is short, very simple, and does not make use of commands such as `vi', `mail' or anything interactive. setuid programs should do ONE thing only, and in a non-complex manner. 4) setting the PATH, IFS, and other environment variables explicitly within the script 5) locking down the permissions on the script. If possible allow it to be run only by group members. Never allow write permission. 6) If your version of UNIX permits, take away read permission for anyone other than the owner. It's a bit harder to break something if you can't see how it works. 7) Rewrite it in C (carefully) 8) Convince your management that they don't really need this. If you plan to keep the script, or re-write it, try and get a copy of the paper. If you can't find it, send me mail. Vicki Brown A/UX Development Group Apple Computer, Inc. Internet: vlb@apple.com MS 58A, 10440 Bubb Rd. UUCP: {sun,amdahl,decwrl}!apple!vlb Cupertino, CA 95014 USA Ooit'n Normaal Mens Ontmoet? En..., Beviel't? (Did you ever meet a normal person? Did you enjoy it?) - ------- End of Forwarded Message ------- End of Forwarded Message