Path: utzoo!utgpu!water!watmath!clyde!att!rutgers!ucsd!ames!oliveb!sun!gorodish!guy From: guy@gorodish.Sun.COM (Guy Harris) Newsgroups: comp.unix.wizards Subject: Re: show me Message-ID: <62734@sun.uucp> Date: 4 Aug 88 03:01:40 GMT References: <62472@sun.uucp> <1126@nusdhub.UUCP> Sender: news@sun.uucp Lines: 82 > 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@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 #! or #! It then tries to run the file named , 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 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.