[comp.bugs.sys5] A security hole

terry@wsccs.UUCP (terry) (02/23/88)

	Do NOT write a setuid program that uses getcwd().  The getcwd() call
does a popen() of the "pwd" shell command and does not check it's path.  This
means that someone could write their own pwd and execute the command from
their directory, thus gaining root access via a sh -c.


| Terry Lambert           UUCP: ...!decvax!utah-cs!century!terry              |
| @ Century Software       or : ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'There are monkey boys in the facility.  Do not be alarmed; you are secure' |

berger@imag.UUCP (Gilles BERGER SABBATEL) (02/29/88)

In article <181@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:
>
>	Do NOT write a setuid program that uses getcwd().  The getcwd() call
>does a popen() of the "pwd" shell command and does not check it's path.  This
>means that someone could write their own pwd and execute the command from
>their directory, thus gaining root access via a sh -c.

I am not sure this is a real problem.  As far as I know, pwd is built in
the standard sys V shell.  Whenever you try to execute pwd, the builtin
command is executed, even if there is another pwd in your path.

The only way to execute another pwd is to give explicitely its full
pathname (ex: ./pwd), so I think that getcwd() is quite secure.
Obviously, the problem could exist if /bin/sh were not the standard sys V
shell.
-- 
Gilles BERGER SABBATEL
IMAG-TIM3/INPG, 46 Avenue Felix Viallet, F-38031 GRENOBLE CEDEX - FRANCE
Tel: 76 47 98 55 Ext: 606
UUCP: ...!seismo!mcvax!inria!archi!berger or: berger@archi

rcodi@koel.rmit.oz (Ian Donaldson) (03/04/88)

in article <181@wsccs.UUCP>, terry@wsccs.UUCP (terry) says:
> 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
> does a popen() of the "pwd" shell command and does not check it's path.  This
> means that someone could write their own pwd and execute the command from
> their directory, thus gaining root access via a sh -c.

This would be a hole if your system had the BSD /bin/sh, but in the SVR2
/bin/sh, the "pwd" command is a built-in and always executes the same way 
regardless of any PATH setting or the contents of the current directory.  

Since SVR2 getcwd() just takes the output of popen("pwd") it is safe in
-that- regard.  There might of course be other security holes lurking 
though.. since you -are- invoking a shell.

[So much for the concept of "keeping the shell simple and small"...]

In the BSD /bin/sh, pwd is not a built-in, and you would receive the
described behaviour.  But in BSD the equivalent to SVR2 getcwd(3) is 
getwd(3), and this doesn't use popen(3) or /bin/sh, so doesn't have 
this problem.  Its also much much faster.  Try issuing the SVR2 getcwd()
function from a program that has a 4Mb data segment and you will see
what I mean (on systems that don't have copy-on-write fork()'s).

Ian D

sow@cad.luth.se (Sven-Ove Westberg) (03/05/88)

In article <2613@imag.UUCP> berger@imag.UUCP (Gilles BERGER SABBATEL) writes:
|In article <181@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:
|>
|>	Do NOT write a setuid program that uses getcwd().  The getcwd() call
|>does a popen() of the "pwd" shell command and does not check it's path.  This
|>means that someone could write their own pwd and execute the command from
|>their directory, thus gaining root access via a sh -c.
|
|I am not sure this is a real problem.  As far as I know, pwd is built in
|the standard sys V shell.  Whenever you try to execute pwd, the builtin
|command is executed, even if there is another pwd in your path.
|
|The only way to execute another pwd is to give explicitely its full
|pathname (ex: ./pwd), so I think that getcwd() is quite secure.
|Obviously, the problem could exist if /bin/sh were not the standard sys V
|shell.
|-- 
|Gilles BERGER SABBATEL
|IMAG-TIM3/INPG, 46 Avenue Felix Viallet, F-38031 GRENOBLE CEDEX - FRANCE
|Tel: 76 47 98 55 Ext: 606
|UUCP: ...!seismo!mcvax!inria!archi!berger or: berger@archi


This IS a security hole and it has nothing to do with if pwd is
built in or not. I will NOT explain in detail how you do. Terry
didn't see the real security hole.


Sven-Ove Westberg, CAD, University of Lulea, S-951 87 Lulea, Sweden.
Tel:     +46-920-91677  (work)                 +46-920-48390  (home)
UUCP:    {uunet,mcvax}!enea!cad.luth.se!sow
Internet: sow@cad.luth.se

jh@pcsbst.UUCP (Johannes Heuft) (03/08/88)

In general: using system(3) or popen(3) inside a set-uid-on-exec
program is a severe security violation. Please believe guys
how know about it. If I would tell why, everybody could crack a
SVR2 within a four-line shell script! AT&T did a lot for
fixing this security hole in SVR3.*

For the same reason set-uid shell scripts should be outlawed (in BSD4.*).
Note, that getcwd(3) still calls popen("/bin/pwd" ...). Use getpwd()
if this routine is available.

ccement@rivm.UUCP (Martien F v Steenbergen) (03/08/88)

In article <181@wsccs.UUCP>, terry@wsccs.UUCP (terry) writes:
> 
> 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
> does a popen() of the "pwd" shell command and does not check it's path.  This
> means that someone could write their own pwd and execute the command from
> their directory, thus gaining root access via a sh -c.

First of all, by writing a setuid program you automatically open
the security hole and you are likely to fall in. You must always
be suspicious of any setuid program.

Second, when you really need a setuid program you'll have to check a lot
of permissions etc. yourself. One system call was created to help you with
access permissions: access(2). access(2) uses the real user IDs instead
of the effective user IDs when checking access permissions. (Remember that
a setuid program only changes the effective user ID of the calling process.)

________________________________________________________________
Martien F. van Steenbergen
National Institute of Public Health and Environmental Protection
dept. RIVM/CCE
PO Box 1
3720 BA Bilthoven
The Netherlands

tel: (31) 30 742819
email: ...!mcvax!rivm!martien
___________________________MSDOSN'T_____________________________

chip@pedsga.UUCP (03/09/88)

In article <388@koel.rmit.oz> rcodi@koel.UUCP writes:
>in article <181@wsccs.UUCP>, terry@wsccs.UUCP (terry) says:
>> 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
>> does a popen() of the "pwd" shell command and does not check it's path.  This
>> means that someone could write their own pwd and execute the command from
>> their directory, thus gaining root access via a sh -c.
>
>This would be a hole if your system had the BSD /bin/sh, but in the SVR2
>/bin/sh, the "pwd" command is a built-in and always executes the same way 
>regardless of any PATH setting or the contents of the current directory.  

Mild flames accepted for the following statement:

"Nothing which is 'builtin' to the shell is guarenteed to stay builtin."

Since many (okay some) UNIX sites also have a source license, if you 
recompile the shell after altering msg.c (change the "pwd" builtin to 
"_pwd" or whatever), then it seems that a call to getcwd would execute 
the pwd in your carefully, although mischiefously (is that a word?) 
setup path to get the desired root privileges.

EAT
THIS
INEWS
!!!!!
!!!!!
-- 
         Chip ("My grandmother called me Charles once. ONCE!!") Maurer
     Concurrent Computer Corporation, Tinton Falls, NJ 07724 (201)758-7361
        uucp: {mtune|purdue|rutgers|princeton|encore}!petsd!pedsga!chip
                       arpa: pedsga!chip@UXC.CSO.UIUC.EDU

jc@minya.UUCP (John Chambers) (03/10/88)

In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
> In article <181@wsccs.UUCP>, terry@wsccs.UUCP (terry) writes:
> > 
> > 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
> > does a popen() of the "pwd" shell command and does not check it's path.  This
> > means that someone could write their own pwd and execute the command from
> > their directory, thus gaining root access via a sh -c.
> 
> First of all, by writing a setuid program you automatically open
> the security hole and you are likely to fall in. You must always
> be suspicious of any setuid program.

Uh, I'm not sure I believe all this.  I mean, I understand why root should
never include "." or any world-writable directories in its search path.
Does your unspecified hole amount to anything more than this?  If so, you
aren't saying anything at all about getcwd() or popen(), just about search 
paths.

> Second, when you really need a setuid program you'll have to check a lot
> of permissions etc. yourself. 

This adds to my conviction that someone doesn't know what they're talking
about.  Do you perhaps mean "setuid-root"?  If so, you are of course correct.
If you don't understand my point, you don't know enough about Unix security
to pontificate on the subject.

Also, I'm sure that I'm far from the only one who is getting tired of seeing
dire warnings like:
	The 'cc' command contains a MAJOR security hole; you should delete it
	from your system as fast as possible.  I can't tell you what the hole
	is, because it would allow any hacker to break into any Unix system in
	the world.  Believe me; I know what I'm talking about.
It's easy enough to make up warnings like these, but many of them turn out
on investigation to be full of bull; some are in fact fraudulent attempts
to discredit someone else's useful software.

Anyhow, what can one do with getcwd() or popen() within a setuid program
(root or otherwise) that isn't a consequence of the search path?  If there
is a real security hole here, I'd be very interested in reading about it.

-- 
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

friedl@vsi.UUCP (Stephen J. Friedl) (03/10/88)

In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
> Second, when you really need a setuid program you'll have to check a lot
> of permissions etc. yourself. One system call was created to help you with
> access permissions: access(2). access(2) uses the real user IDs instead
> of the effective user IDs when checking access permissions. (Remember that
> a setuid program only changes the effective user ID of the calling process.)

comp.unix.wizards has had several recent postings on access(2).
Many people use access(2) incorrectly and it causes no end of
difficulty for those writing restricted setuid or setgid systems.
Send me a note if you want a copy of my near-flame on this with
info on how *not* to use it.

     Steve
-- 
Life : Stephen J. Friedl @ V-Systems, Inc./Santa Ana, CA   *Hi Mom*
CSNet: friedl%vsi.uucp@kent.edu  ARPA: friedl%vsi.uucp@uunet.uu.net
uucp : {kentvax, uunet, attmail, ihnp4!amdcad!uport}!vsi!friedl

friedl@vsi.UUCP (Stephen J. Friedl) (03/10/88)

In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
 > > [somebody else's stuff (sorry, deleted it)]
 > > First of all, by writing a setuid program you automatically open
 > > the security hole and you are likely to fall in. You must always
 > > be suspicious of any setuid program.
 >
 > Uh, I'm not sure I believe all this.  I mean, I understand why root should
 > never include "." or any world-writable directories in its search path.
 > Does your unspecified hole amount to anything more than this?  If so, you
 > aren't saying anything at all about getcwd() or popen(), just about search
 > paths.

You can never remind people enough about search paths because it
is so easy to mess up.  Also, it is not "obvious" that asking the
system for your current directory will fork another process while
doing so.  Set[ug]uid programs should do something like:

        putenv("PATH=/bin:/usr/bin:/etc");

early so the user's path is totally ignored no matter what the
rest of the program does.  Sometimes perhaps you can't do this
but in most cases it will help a lot.

 > This adds to my conviction that someone doesn't know what they're talking
 > about.  Do you perhaps mean "setuid-root"?  If so, you are of course correct.
 > If you don't understand my point, you don't know enough about Unix security
 > to pontificate on the subject.

Hold it.  If I find a breakable setuid program on a machine I
will get root eventually.  Example: if I break the "bin" group on
a machine where /bin is drwxrwxr-x (like my SVR3.1 3B2/400)  I can
replace /bin/ls with my own program.  My version will exec the
"real" ls but if root is the uid then it will do something
special for me.  Setuid/setgid *anything* is dangerous.

 > Also, I'm sure that I'm far from the only one who is getting tired of seeing
 > dire warnings like:
 >      The 'cc' command contains a MAJOR security hole; you should delete it
 >      from your system as fast as possible.  I can't tell you what the hole
 >      is, because it would allow any hacker to break into any Unix system in
 >      the world.  Believe me; I know what I'm talking about.
 > It's easy enough to make up warnings like these, but many of them turn out
 > on investigation to be full of bull; some are in fact fraudulent attempts
 > to discredit someone else's useful software.

We all hate them, partly because we would *love* to know what the
bug is (of course *we* would never misused this information).
Too bad there aren't good ways to fix the bugs without giving a
class in smashing systems.  The best you can do is consult your
friendly neighborhood security wizard and ask him/her about it.
They are perhaps more capable of evaluating the nature of the
threat.

 > Anyhow, what can one do with getcwd() or popen() within a setuid program
 > (root or otherwise) that isn't a consequence of the search path?  If there
 > is a real security hole here, I'd be very interested in reading about it.

Even if a program does

        system("/bin/pwd");

it can still be smashed, partially related to the search path.
See the last item on the list for the fix.

These rules have probably been posted a hundred times but I
don't mind doing it one more.

*    don't write setuid programs

*    if you must, don't make them setuid root.  Make them some
     new uid/gid that is not part of the system (avoid bin, sys,
     adm, etc.)

*    write setgid instead of setuid if you can

*    if the special access is in a limited area, write a separate
     program that does just that job and make the rest of the
     program non-set-anything.  Then have the main program call
     the setuid guy for the secure stuff.  Example: /bin/mv is
     normal but calls (setuid root) /usr/lib/mv_dir to move
     directories around.

*    open all your secure files early in the program, then do

         setuid(getuid());
         setgid(getgid());

     This turns off the setuid/setgid permissions and makes the
     program a normal peon user process again.  Remember, once a
     file is open permissions don't count any more.

*    if you must run set[ug]id all the time, write your own
     system() that does the previous item after the fork but
     before the exec.  This makes the child not have any special
     permissions. It doesn't always help if you need to exec
     a protected process in a protected areA, but it works in
     a lot of cases.

*    If your programs call popen or system, put the line

          putenv("IFS= \n\t");

     in it early.  This closes up a fairly obscure hole; read your
     /bin/sh manual if you are really interested in this.  Ask
     your local security wizard about this for more info.


     One thing about security is that there is always somebody
out there who knows more than you do, and all they need is one
bug that you didn't think of.  The above list is certainly not
all-inclusive, and the security wizards out there are welcome to
flame me (privately unless it is of general interest) if I blew
it on something.

     Steve
-- 
Life : Stephen J. Friedl @ V-Systems, Inc./Santa Ana, CA   *Hi Mom*
CSNet: friedl%vsi.uucp@kent.edu  ARPA: friedl%vsi.uucp@uunet.uu.net
uucp : {kentvax, uunet, attmail, ihnp4!amdcad!uport}!vsi!friedl

brad@bradley.UUCP (03/11/88)

Also watch out for "IFS=" in the shell with popen and setuid.  On
system V (not BSD), you can set IFS=/; export IFS and if it does a
popen("/xxx/yuyy", "w"); or "r", then all you need is a a program
called xxx in the current working directory.

jum@cosmo.UUCP (Uwe Mager) (03/11/88)

In article <478@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
...
>
>Anyhow, what can one do with getcwd() or popen() within a setuid program
>(root or otherwise) that isn't a consequence of the search path?  If there
>is a real security hole here, I'd be very interested in reading about it.

There is a nice hack to make the sh misunderstood the path variable.
For example the following will work on most SYSV machines:
in file named ``bin'' in your cwd:

IFS=" \t\n" # escapes for readability
/bin/sh </dev/tty >/dev/tty 2>&1
pwd

and now from a command line:
IFS="/"; export IFS
at now + 1 minute # or any setuid root containing getcwd

This will not work with the Korn shell, there is a special check for IFS.
-- 
Jens-Uwe Mager
jum@focus.UUCP || jum@cosmo.UUCP

levy@ttrdc.UUCP (Daniel R. Levy) (03/11/88)

In article <357@pedsga.UUCP>, chip@pedsga.UUCP writes:
> Mild flames accepted for the following statement:

OK, here's a flick of my Bic.

# "Nothing which is 'builtin' to the shell is guarenteed to stay builtin."
# Since many (okay some) UNIX sites also have a source license, if you 
# recompile the shell after altering msg.c (change the "pwd" builtin to 
# "_pwd" or whatever), then it seems that a call to getcwd would execute 
# the pwd in your carefully, although mischiefously (is that a word?) 
# setup path to get the desired root privileges.

If you can replace /bin/sh you already have privileges (and /bin/sh is
surely not the only or even the easiest place a system cracker could plant
a Trojan horse under those circumstances), or a system admin was verrrry
careless with permissions on /bin or /bin/sh.  If you have your own doctored
copy of "sh" it does you no good if it isn't in /bin/sh.  (popen explicitly
uses "/bin/sh").
-- 
|------------Dan Levy------------|  Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
|         an Engihacker @        |  	<most AT&T machines>}!ttrdc!ttrda!levy
| AT&T Computer Systems Division |  Disclaimer?  Huh?  What disclaimer???
|--------Skokie, Illinois--------|

ccement@rivm.UUCP (Martien F v Steenbergen) (03/11/88)

In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
> In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
> > First of all, by writing a setuid program you automatically open
> > the security hole and you are likely to fall in. You must always
> > be suspicious of any setuid program.
> 
> Uh, I'm not sure I believe all this.  I mean, I understand why root should
> never include "." or any world-writable directories in its search path.
> Does your unspecified hole amount to anything more than this?  If so, you
> aren't saying anything at all about getcwd() or popen(), just about search 
> paths.

What I am trying to say is that you must be careful writing setuid-root
(C etc.)) programs.
So many already fell into the security hole. You cannot warn them
enough. Perhaps there exists a book which describes a lot of Unix security
related topics. I'd love to have one.

> > Second, when you really need a setuid program you'll have to check a lot
> > of permissions etc. yourself. 
> 
> This adds to my conviction that someone doesn't know what they're talking
> about.  Do you perhaps mean "setuid-root"?  If so, you are of course correct.

Of course I mean setuid-root (sorry).

> If you don't understand my point, you don't know enough about Unix security
> to pontificate on the subject.

I do understand your point.
You're right, I should be more careful stating my opinions.

> Also, I'm sure that I'm far from the only one who is getting tired of seeing
> dire warnings like:
> 	The 'cc' command contains a MAJOR security hole; you should delete it
> 	from your system as fast as possible.  I can't tell you what the hole
> 	is, because it would allow any hacker to break into any Unix system in
> 	the world.  Believe me; I know what I'm talking about.
> It's easy enough to make up warnings like these, but many of them turn out
> on investigation to be full of bull; some are in fact fraudulent attempts
> to discredit someone else's useful software.

That's true, but since the Unix market and its user is growing rapidly,
there are a lot of unexperienced `system managers', who will fall into the
security hole. I think any help is welcome for those persons.
If you're tired of reading those warning, then don't read them!
(You read mine |->)

________________________________________________________________
Martien F. van Steenbergen
National Institute of Public Health and Environmental Protection
dept. RIVM/CCE
PO Box 1
3720 BA Bilthoven
The Netherlands

tel: (31) 30 742819
email: ...!mcvax!rivm!martien
________________________________________________________________

mb@ttidca.TTI.COM (Michael Bloom) (03/12/88)

In article <379@vsi.UUCP> friedl@vsi.UUCP (Stephen J. Friedl) writes:
|In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:

| > dire warnings like:
| >      The 'cc' command contains a MAJOR security hole; you should delete it
| >      from your system as fast as possible.  I can't tell you what the hole
| >      is, because it would allow any hacker to break into any Unix system in
| >      the world.  Believe me; I know what I'm talking about.
| > It's easy enough to make up warnings like these, but many of them turn out
| > on investigation to be full of bull; some are in fact fraudulent attempts

Umm, if I remember my history lessons correctly, this *intentionally
coded* bug was only in an early version of the ritchie compiler, and
not in pcc.  Please don't delete cc. (at least not yet; gnu cc is
still in beta test :-)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/13/88)

In article <892@cosmo.UUCP> jum@cosmo.UUCP (Jens-Uwe Mager(sysop)) writes:
>This will not work with the Korn shell, there is a special check for IFS.

I couldn't find any valid reason for importing IFS, so the BRL Bourne
shell resets it to the default value at the beginning of a shell script.

dpw@unisec.usi.com (Darryl P. Wagoner) (03/13/88)

>So many already fell into the security hole. You cannot warn them
>enough. Perhaps there exists a book which describes a lot of Unix security
>related topics. I'd love to have one.
>

Yes there is: 

Unix System Security
by Patrick H. Wood and Stephen G. Kochan

(From the back)

Here is a practical guide to computer security on the Unix system for the
user, administrator, or potenial Unix buyer.  It will teach you 
everything you need to know to make your system secure and keep it
that way.  Topics covered include:

* file and directory permissions

* password security

* how the setuid/gid permissions work and how to use them

* How the various security-related Unix commands and functions work

* how to write secure programs

* different methods of data encryption - including the government
  standard DES algorithm -- and how secure they are

* data encryption over communication networks

* how to discover and plug potenial security holes in your system

* how to periodically monitor your system to maintain security

Also included is the complete surce for several security auditing and 
administration programs.

<end of back cover>

If you are a novice this will give you a cookbook guide to security and
if you are a wizard it will be a good spring board for better programs
to improve your security.  In my security seminar I aways recommend that
they get a copy.  It the best investment in security that you can make.
-- 
Darryl Wagoner		dpw@unisec.usi.com
UniSecure Systems, Inc.; 			OS/2, Just say No!
Round Rock,  Tx; (512)-255-8751 (home) (512)-823-3774
UUCP:  {ut-sally!uiucuxc!kitty}!unisec!dpw

hermit@chessene.UUCP (Mark Buda) (03/14/88)

In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
> 
> Uh, I'm not sure I believe all this.  I mean, I understand why root should
> never include "." or any world-writable directories in its search path.
> [stuff]  If so, you
> aren't saying anything at all about getcwd() or popen(), just about search 
> paths.
> 
> Anyhow, what can one do with getcwd() or popen() within a setuid program
> (root or otherwise) that isn't a consequence of the search path?  If there
> is a real security hole here, I'd be very interested in reading about it.
> 
> John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

Root's search path has nothing to do with setuid-root programs - they
get their path from the process that invokes them, so you don't have any
control over the search path (unless you explicitly change it in your
setuid program - but how many people think of doing that?)

--
Mark Buda, The Embattled Hermit          Domain: hermit@chessene.uucp
Dumb: ...{rutger,ihnp4,cbosgd}!bpa!vu-vlsi!devon!chessene!hermit
"Dr. Johnson, can you come over right away? My father has a hibachi on his
head."

terry@wsccs.UUCP (terry) (03/15/88)

In article <722@rivm05.UUCP>, Martien F v Steenbergen writes:
> First of all, by writing a setuid program you automatically open
> the security hole and you are likely to fall in. You must always
> be suspicious of any setuid program.

	Not if you program it correctly.  The point was that the security was
not checked by specification of the execution path, and it should have been,
as getcwd() is a library routine.

> Second, when you really need a setuid program you'll have to check a lot
> of permissions etc. yourself. One system call was created to help you with
> access permissions: access(2). access(2) uses the real user IDs instead
> of the effective user IDs when checking access permissions. (Remember that
> a setuid program only changes the effective user ID of the calling process.)

	The access() call is a kludge.  I could do that anyway with the
following:

	system( "/bin/sh -c <command>");

	Where <command> is the command I want run with the _real_ UID and GID.
Remember that the child inherits the parents effective as it's real, if it's
done this way.  This is helpful for running things which make sure you're
root before they will run.

> ___________________________MSDOSN'T_____________________________

I can't argue with you here... :-)

				Terry Lambert
				terry@wsccs

terry@wsccs.UUCP (terry) (03/15/88)

In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
} In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
} In article <181@wsccs.UUCP>, I write:
} > 
} > 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
} > does a popen() of the "pwd" shell command and does not check it's path.
} 
} Also, I'm sure that I'm far from the only one who is getting tired of seeing
} dire warnings like:
} 	The 'cc' command contains a MAJOR security hole; you should delete it
} 	from your system as fast as possible.  I can't tell you what the hole
} 	is, because it would allow any hacker to break into any Unix system in
} 	the world.  Believe me; I know what I'm talking about.
} It's easy enough to make up warnings like these, but many of them turn out
} on investigation to be full of bull; some are in fact fraudulent attempts
} to discredit someone else's useful software.

	Read the source code.  I was simply pointing out something you should
be aware of.  The fix, if you haven't figured it out for yourself yet, is to
simply force the path for pwd.  I was simply suggesting that AT&T fix it.

} Anyhow, what can one do with getcwd() or popen() within a setuid program
} (root or otherwise) that isn't a consequence of the search path?

	Nothing.  That's not the point.  How do you specify the PATH env
variable from within your C program?  Inquiring minds want to know...
the who point, I thought, of this bugs forum, was to bring bugs to the
attention of the people in charge of removing them.

}                                                                   If there
} is a real security hole here, I'd be very interested in reading about it.

	Well... how do _you_ do a mknod under sys5?  Is it a suid root program
on _your_ system, like everone elses, or do you always log in as root?  Do you
determine path via osmosis, or some method unbeknownst to us?  If not, it's
a problem.

	When all else fails, consult the source code.

| Terry Lambert           UUCP: ...!{ decvax, ihnp4 }...                      |
| @ Century Software       or : ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'There are monkey boys in the facility.  Do not be alarmed; you are secure' |

chris@mimsy.UUCP (Chris Torek) (03/15/88)

Incidentally, note that the 4.3BSD /bin/sh does not import IFS from
the environment (like Doug Gwyn's BRL sh), except that it does this
*only* if you are root or if geteuid()!=getuid().  (Making it an exception
for root/setuid is, I think, bogus.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

allbery@ncoast.UUCP (Brandon Allbery) (03/19/88)

As quoted from <478@minya.UUCP> by jc@minya.UUCP (John Chambers):
+---------------
| In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
| > Second, when you really need a setuid program you'll have to check a lot
| > of permissions etc. yourself. 
| 
| This adds to my conviction that someone doesn't know what they're talking
| about.  Do you perhaps mean "setuid-root"?  If so, you are of course correct.
| If you don't understand my point, you don't know enough about Unix security
| to pontificate on the subject.
+---------------

If I wasn't *real* careful with the (setuid) program which grabs incoming
sources.misc submissions, someone could gain write access to any of my files.
Such as my .login.  This isn't a potential security hole?  (The alternative
is to make a certain directory world-writeable; not a sound idea in this case.)
-- 
	      Brandon S. Allbery, moderator of comp.sources.misc
       {well!hoptoad,uunet!hnsurg3,cbosgd,sun!mandrill}!ncoast!allbery

dpw@unisec.usi.com (Darryl P. Wagoner) (03/19/88)

>	Nothing.  That's not the point.  How do you specify the PATH env
>variable from within your C program?  Inquiring minds want to know...
>the who point, I thought, of this bugs forum, was to bring bugs to the
>attention of the people in charge of removing them.

On Sys V or at least the one's I work on have a function called putenv(3)
and there is a public domain set of routines that will work on both
BSD and Sys V, called setenv(3l), delenv(3l), etc.

Cheers,



-- 
Darryl Wagoner		dpw@unisec.usi.com
UniSecure Systems, Inc.; 			OS/2, Just say No!
Round Rock,  Tx; (512)-255-8751 (home) (512)-823-3774
UUCP:  {ut-sally!uiucuxc!kitty}!unisec!dpw

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/20/88)

In article <319@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:
>In article <478@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
>} In article <722@rivm05.UUCP>, ccement@rivm.UUCP (Martien F v Steenbergen) writes:
>} In article <181@wsccs.UUCP>, I write:
>} > 	Do NOT write a setuid program that uses getcwd().  The getcwd() call
>} > does a popen() of the "pwd" shell command and does not check it's path.
>	Read the source code.  I was simply pointing out something you should
>be aware of.  The fix, if you haven't figured it out for yourself yet, is to
>simply force the path for pwd.  I was simply suggesting that AT&T fix it.

Enough, already.  Here's an alternative solution:

/*
	getcwd -- get current working directory name (POSIX and SVID compatible)

	last edit:	21-Sep-1987	D A Gwyn

	This public-domain getcwd() routine can be used to replace the UNIX
	System V library routine (which uses popen() to capture the output of
	the "pwd" command).  Once that is done, "pwd" can be reimplemented as
	just puts(getcwd()).

	This implementation depends on every directory having entries for
	"." and "..".  It also depends on the internals of the <dirent.h>
	data structures to some degree.

	I considered using chdir() to ascend the hierarchy, followed by a
	final chdir() to the path being returned by getcwd() to restore the
	location, but decided that error recovery was too difficult that way.
	The algorithm I settled on was inspired by my rewrite of the "pwd"
	utility, combined with the dotdots[] array trick from the SVR2 shell.
*/

#include	<sys/types.h>
#include	<sys/stat.h>
#include	<dirent.h>
#include	<errno.h>
#include	<string.h>

typedef char	*pointer;		/* (void *) if you have it */

extern void	free();
extern pointer	malloc();
extern int	fstat(), stat();

extern int	errno;			/* normally done by <errno.h> */

#ifndef NULL
#define	NULL	0			/* amorphous null pointer constant */
#endif

#ifndef NAME_MAX
#define	NAME_MAX	255		/* maximum directory entry size */
#endif

char	*
getcwd( buf, size )			/* returns pointer to CWD pathname */
	char		*buf;		/* where to put name (NULL to malloc) */
	int		size;		/* size of buf[] or malloc()ed memory */
	{
	static char	dotdots[] =
"../../../../../../../../../../../../../../../../../../../../../../../../../..";
	char 		*dotdot;	/* -> dotdots[.], right to left */
	DIR		*dirp;		/* -> parent directory stream */
	struct dirent	*dir;		/* -> directory entry */
	struct stat	stat1, stat2;	/* info from stat() */
	struct stat	*d = &stat1;	/* -> info about "." */
	struct stat	*dd = &stat2;	/* -> info about ".." */
	register char	*buffer;	/* local copy of buf, or malloc()ed */
	char		*bufend;	/* -> buffer[size] */
	register char	*endp;		/* -> end of reversed string */
	register char	*dname;		/* entry name ("" for root) */
	int		serrno = errno;	/* save entry errno */

	if ( size == 0 )
		{
		errno = EINVAL;		/* invalid argument */
		return NULL;
		}

	if ( (buffer = buf) == NULL	/* wants us to malloc() the string */
	  && (buffer = (char *)malloc( (unsigned)size )) == NULL
	   )	{
		errno = ENOMEM;		/* cannot malloc() specified size */
		return NULL;
		}

	if ( stat( ".", dd ) != 0 )	/* prime the pump */
		goto error;		/* errno already set */

	endp = buffer;			/* initially, empty string */
	bufend = &buffer[size];

	for ( dotdot = &dotdots[sizeof(dotdots)]; dotdot != dotdots; )
		{
		dotdot -= 3;		/* include one more "/.." section */
					/* (first time is actually "..") */

		/* swap stat() info buffers */
		{
		register struct stat	*temp = d;

		d = dd;			/* new current dir is old parent dir */
		dd = temp;
		}

		if ( (dirp = opendir( dotdot )) == NULL )	/* new parent */
			goto error;	/* errno already set */

		if ( fstat( dirp->dd_fd, dd ) != 0 )
			{
			serrno = errno;	/* set by fstat() */
			(void)closedir( dirp );
			errno = serrno;	/* in case closedir() clobbered it */
			goto error;
			}

		if ( d->st_dev == dd->st_dev )
			{		/* not crossing a mount point */
			if ( d->st_ino == dd->st_ino )
				{	/* root directory */
				dname = "";
				goto append;
				}

			do
				if ( (dir = readdir( dirp )) == NULL )
					{
					(void)closedir( dirp );
					errno = ENOENT;	/* missing entry */
					goto error;
					}
			while ( dir->d_ino != d->st_ino );
			}
		else	{		/* crossing a mount point */
			struct stat	t;	/* info re. test entry */
			char		name[sizeof(dotdots) + 1 + NAME_MAX];

			(void)strcpy( name, dotdot );
			dname = &name[strlen( name )];
			*dname++ = '/';

			do	{
				if ( (dir = readdir( dirp )) == NULL )
					{
					(void)closedir( dirp );
					errno = ENOENT;	/* missing entry */
					goto error;
					}

				(void)strcpy( dname, dir->d_name );
				/* must fit if NAME_MAX is not a lie */
				}
			while ( stat( name, &t ) != 0
			     || t.st_ino != d->st_ino
			     || t.st_dev != d->st_dev
			      );
			}

		dname = dir->d_name;

		/* append "/" and reversed dname string onto buffer */
    append:
		if ( endp != buffer	/* avoid trailing / in final name */
		  || dname[0] == '\0'	/* but allow "/" when CWD is root */
		   )
			*endp++ = '/';

		{
		register char	*app;	/* traverses dname string */

		for ( app = dname; *app != '\0'; ++app )
			;

		if ( app - dname >= bufend - endp )
			{
			(void)closedir( dirp );
			errno = ERANGE;	/* won't fit allotted space */
			goto error;
			}

		while ( app != dname )
			*endp++ = *--app;
		}

		(void)closedir( dirp );

		if ( dname[0] == '\0' )	/* reached root; wrap it up */
			{
			register char	*startp;	/* -> buffer[.] */

			*endp = '\0';	/* plant null terminator */

			/* straighten out reversed pathname string */
			for ( startp = buffer; --endp > startp; ++startp )
				{
				char	temp = *endp;

				*endp = *startp;
				*startp = temp;
				}

			errno = serrno;	/* restore entry errno */
			return buffer;
			}
		}

	errno = ENOMEM;			/* actually, algorithm failure */

    error:
	if ( buf == NULL )
		free( (pointer)buffer );

	return NULL;
	}

jh@pcsbst.UUCP (Johannes Heuft) (03/23/88)

In article <892@cosmo.UUCP> jum@cosmo.UUCP (Jens-Uwe Mager(sysop))
reveals the IFS trick.

Jens-Uwe, lots of system administrators with SVR2 (or less) will hate you
now, because their task of maintaining a decent computer operation will
be turned sour by some would-like-to-be hackers, who are worse than
the real ones.

There is no real work-around in SVR2 except removing the set-userid
bits or even the programs. Even if you cannot spare a seperate
machine for networking you will be surprised how many set-userid bits
or set-userid bit programs may be removed without hindering the
system operation. Think about it and try it. Somebody should make
a list of such programs and comment on what happens if the bits
are removed. Here a small start of this list:

	at      program may be removed in most installations
	crontab remove suid-bit and let system administrator do
		crontab installation
	cu      should remove suid-bit and wait for complaints
	login   remove suid-bit -> logout via login does not work (no problem)
	rmail
	mail
	mailx   depending on several settings, e.g. umask, following
		procedure may work (as in SVR3)

		introduce new group "mail"

		chgrp mail /bin/mail /usr/bin/mailx
		chmod 2555 /bin/mail /usr/bin/mailx
		chgrp mail /usr/mail
		chmod 775  /usr/mail
		chgrp mail /usr/mail/*
		chmod 775  /usr/mail/*

	su      try the IFS-tick. If it does work REMOVE su. Write
		your own su if necessary.
	/usr/lib/ex*
		remove suid-bit (see other security articles!)
	umount
	mount   remove suid bits and wait for complaints
	...
	...

Does somebody care to comment or add to the list??

The IFS problem is fixed in SVR3.

rsalz@bbn.com (Rich Salz) (03/24/88)

Every single program that is subject to the "IFS" trick can be
protected by written a wrapper that sets the environment properly,
then calls the real program.  If you put all these programs in
one common directory, then you can have one front-end which has
hardlinks all over the place, and a simple exec based on argv[0].
	/r$
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

friedl@vsi.UUCP (Stephen J. Friedl) (03/24/88)

In article <175@pcsbst.UUCP>, jh@pcsbst.UUCP (Johannes Heuft) writes:
> In article <892@cosmo.UUCP> jum@cosmo.UUCP (Jens-Uwe Mager(sysop))
> reveals the IFS trick.
> 
> Jens-Uwe, lots of system administrators with SVR2 (or less) will hate you
> now, because their task of maintaining a decent computer operation will
> be turned sour by some would-like-to-be hackers, who are worse than
> the real ones.
> 
> There is no real work-around in SVR2 except removing the set-userid
> bits or even the programs.

Yes, there is a workaround; it is tedious but it works.  Write
a small front-end (say. lp.c) that does:

	/*--------------------- lp.c -----------------------*/
	#define	REAL_LP	/usr/bin/.lp

	main(argc, argv)
	int	argc;
	char	*argv[];
	{
		putenv("IFS= \t\n");
		putenv("SHELL=/bin/sh");
		putenv("PATH=/bin:/usr/bin");

		execv(REAL_LP, argv);
	}
	/*--------------------- lp.c -----------------------*/

(*) rename /usr/bin/lp to /usr/bin/.lp
(*) install the above lp fix to /usr/bin/lp
(*) remove setuid/setgid permissions from /usr/bin/.lp
(*) add the setuid/setgid permission + owner + group to /usr/bin/lp
(*) remove all read access from the now-setuid file

The old program is still susceptible to the IFS bug but it is
entirely harmless: the setuid front-end will fix it.  Disclaimer:
no warranty that this fixes all bugs, prevents all scam, or stops
all hunger in the world.  It works for me but there are always
smarter people out there.

Not all of the programs Johannes mentions are at risk, but in
any case, it has been my experience that making all setuid or
setgid programs unreadable by anybody will help quite a bit.
There is much to be learned by poking around object files, and
closing this door makes it much more difficult to see where
the holes are or might be.

---
Steve Friedl      V-Systems, Inc.        *Hi Mom*
friedl@vsi.com   {uunet,attmail,ihnp4}!vsi!friedl

-- 
Steve Friedl      V-Systems, Inc.        *Hi Mom*
friedl@vsi.com   {uunet,attmail,ihnp4}!vsi!friedl

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/24/88)

In article <175@pcsbst.UUCP> jh@pcsbst.UUCP (Johannes Heuft) writes:
>In article <892@cosmo.UUCP> jum@cosmo.UUCP (Jens-Uwe Mager(sysop))
>reveals the IFS trick.
>Jens-Uwe, lots of system administrators with SVR2 (or less) will hate you

Oh, come on.  The IFS trick is quite well-known, ESPECIALLY among
the "hackers" who like to mess up system operation.  It is better
for everyone to be aware of the problem than to pretend that by
not talking about it there will be no problem.

>There is no real work-around in SVR2 except ...
>The IFS problem is fixed in SVR3.

It is easy to fix this in the SVR2 shell, too:
/*	@(#)main.c	1.7	*/
...
	/*
	 * default internal field separators - $IFS
	 */
	assign(&ifsnod, sptbnl);	/* DAG -- was dfault(); now forced */

And don't say "but what if you don't have source"?  The originator
of your binary distribution DOES have source; get them to fix it.

jv@mhres.mh.nl (Johan Vromans) (03/24/88)

In article <544@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes:
>Every single program that is subject to the "IFS" trick can be
>protected by written a wrapper that sets the environment properly,
>then calls the real program.

I tried to replace "/bin/sh" this way, and although everything seemed to
work great, eventually I found out that all my outbound news was being
rejected with a "inews: inbound news is garbled" on the remote machines.

Didn't have the time to track down the problem, so my system is insequre
again. Any suggestions?

#---------------- sh.c ----------------
main (argc, argv)
int argc;
char *argv[];
{
	putenv ("IFS=\" \t\n\"");
	execv ("/bin/SH", argv);
	return -1;
}
#---------------- ----------------


-- 
Johan Vromans                              | jv@mh.nl via European backbone
Multihouse N.V., Gouda, the Netherlands    | uucp: ..{uunet!}mcvax!mh.nl!jv
"It is better to light a candle than to curse the darkness"

jc@heart-of-gold (John M Chambers x7780 1E342) (03/25/88)

In article <7521@ncoast.UUCP>, allbery@ncoast.UUCP (Brandon Allbery) writes:
> If I wasn't *real* careful with the (setuid) program which grabs incoming
> sources.misc submissions, someone could gain write access to any of my files.
> Such as my .login.  This isn't a potential security hole?  (The alternative
> is to make a certain directory world-writeable; not a sound idea in this case.)

OK, I'll bite.  Here are the permissions on my home directory and .login: 

drwxrwxr-x 21 jc       wheel        2560 Mar 24 08:30 .
-rw-r--r--  2 jc       wheel         250 Jan 29 14:53 .login

And here's the rnews command:

22531 -rwsr-sr-x 2 news news 114688 Mar 17 13:33 /news/bin/rnews   

Explain to me how someone could use this setuid-news, setgid-news program
to write into my .login file.  Now need to explain further; I do appreciate
why I wouldn't want you to do that.  But I don't quite see how this setup
makes it possible.

I do understand why I wouldn't want to turn off these setuid and setgid bits.
In my experience, rnews is very often triggered by things (like cron) that
are run by root, and I've seen a lot of problems caused by news files ending
up owned by root rather than news.  I wouldn't trust news run by root, and I
don't trust cron to correctly run things under other ids;  I've had too many
surprises there to believe that I can reliably control cron.  So the setuid
and setgid bits are needed to guarantee that cron can't start rnews up with
root permissions.  This seems to me to restrict incoming news to only those
directories with news write permissions.  If I'm wrong, I'd like to know, so
I can start looking for other ways to do the job.


-- 
[Send flames; they keep it cool in this lab :-]

Am I the same John Chambers as jc@minya?  You decide....
Hint:  That guy over at ut-sally is an imposter.  (;-)

mike@ists (Mike Clarkson) (03/25/88)

In article <130@heart-of-gold>, jc@heart-of-gold (John M Chambers x7780 1E342) writes:
> I do understand why I wouldn't want to turn off these setuid and setgid bits.
> In my experience, rnews is very often triggered by things (like cron) that
> are run by root, and I've seen a lot of problems caused by news files ending
> up owned by root rather than news.  I wouldn't trust news run by root, and I
> don't trust cron to correctly run things under other ids;  I've had too many
> surprises there to believe that I can reliably control cron.  So the setuid
> and setgid bits are needed to guarantee that cron can't start rnews up with
> root permissions.  This seems to me to restrict incoming news to only those
> directories with news write permissions.  If I'm wrong, I'd like to know, so
> I can start looking for other ways to do the job.

Use su in your crontab:

	0 * * * * su news -c "rnews -U"

Then rnews (or whatever command you like) will run as news, not root.
Also wise to do this with anything else you really don't need root to
be running: like uucico.


-- 
Mike Clarkson						mike@ists.UUCP
Institute for Space and Terrestrial Science
York University, North York, Ontario,
CANADA M3J 1P3						(416) 736-5611

guy@gorodish.Sun.COM (Guy Harris) (03/27/88)

> Use su in your crontab:
> 
> 	0 * * * * su news -c "rnews -U"
> 
> Then rnews (or whatever command you like) will run as news, not root.

Or, if you're running an S5R2 or later "cron", just put this entry in "news"'s
"crontab" file rather than "root"'s.  (Make sure you allow "news" to run
"cron" by setting up "cron.allow" and "cron.deny" properly.)

friedl@vsi.UUCP (Stephen J. Friedl) (03/27/88)

In article <168@ists>, mike@ists (Mike Clarkson) writes:
> In article <130@heart-of-gold>, jc@heart-of-gold (John M Chambers x7780 1E342) writes:
> > ...  I wouldn't trust news run by root, and I
> > don't trust cron to correctly run things under other ids;  I've had too many
> > surprises there to believe that I can reliably control cron.
> 
> Use su in your crontab:
> 
> 	0 * * * * su news -c "rnews -U"

A reminder that 3B2/3B5 System V Release 2 and 3 have separate
crontabs for each user and they take care of doing the "su"
business for you.

-- 
Steve Friedl     V-Systems, Inc.     *Hi Mom*
friedl@vsi.com   {uunet,ihnp4}!vsi.com!friedl

nevin1@ihlpf.ATT.COM (00704a-Liber) (03/31/88)

In article <130@heart-of-gold> jc@heart-of-gold (John M Chambers x7780 1E342) writes:
.OK, I'll bite.  Here are the permissions on my home directory and .login: 
.
.drwxrwxr-x 21 jc       wheel        2560 Mar 24 08:30 .
.-rw-r--r--  2 jc       wheel         250 Jan 29 14:53 .login
.
.And here's the rnews command:
.
.22531 -rwsr-sr-x 2 news news 114688 Mar 17 13:33 /news/bin/rnews   
.
.Explain to me how someone could use this setuid-news, setgid-news program
.to write into my .login file.  Now need to explain further; I do appreciate
.why I wouldn't want you to do that.  But I don't quite see how this setup
.makes it possible.

It is not possible for someone to *directly* abuse this to write to your
(uid=jc, gid=wheel) .login file.  However, someone may be able to abuse
rnews and become uid=news, gid=news.  They would then have access to all of
news's files.  This is where the security break is.


BTW, some time ago I saw a file with the following permissions:

-rwsrwsrwx	foo	bar		somefile

From a security standpoint, what's wrong with this picture?? (Please DON'T
post answers to this question; it is merely rhetorical.)
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

nevin1@ihlpf.ATT.COM (00704a-Liber) (03/31/88)

In article <544@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes:
.Every single program that is subject to the "IFS" trick can be
.protected by written a wrapper that sets the environment properly,
.then calls the real program.

But what stops the user from bypassing the wrapper and calling the real
program directly?
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

friedl@vsi.UUCP (Stephen J. Friedl) (03/31/88)

In article <4212@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes:
} In article <544@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes:
} .Every single program that is subject to the "IFS" trick can be
} .protected by written a wrapper that sets the environment properly,
} .then calls the real program.
} 
} But what stops the user from bypassing the wrapper and calling the real
} program directly?

The wrapper is setuid and the "real" program has its special
permissions removed.  If you bypass the wrapper the best you
can do is break your own usercode :-).

-- 
Steve Friedl           V-Systems, Inc.            *Hi Mom*
friedl@vsi.com {uunet,ihnp4}!vsi.com!friedl attmail!friedl

dpw@unisec.usi.com (Darryl P. Wagoner) (03/31/88)

In article <4212@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes:
.In article <544@fig.bbn.com> rsalz@bbn.com (Rich Salz) writes:
..Every single program that is subject to the "IFS" trick can be
..protected by written a wrapper that sets the environment properly,
..then calls the real program.
.
.But what stops the user from bypassing the wrapper and calling the real
.program directly?

Simply, the problem is setuid bit programs that has a popen in them.

This does a exec of "sh -c program argvs".  This means that /bin/sh
is the problems with IFS.  So how can they bypass?

-- 
Darryl Wagoner		dpw@unisec.usi.com
UniSecure Systems, Inc.; 			OS/2, Just say No!
Round Rock,  Tx; (512)-255-8751 (home) (512)-823-3774
UUCP:  {ut-sally!uiucuxc!kitty}!unisec!dpw

allbery@ncoast.UUCP (Brandon Allbery) (04/04/88)

As quoted from <130@heart-of-gold> by jc@heart-of-gold (John M Chambers x7780 1E342):
+---------------
| In article <7521@ncoast.UUCP>, allbery@ncoast.UUCP (Brandon Allbery) writes:
| > If I wasn't *real* careful with the (setuid) program which grabs incoming
| > sources.misc submissions, someone could gain write access to any of my files.
| > Such as my .login.  This isn't a potential security hole?  (The alternative
| > is to make a certain directory world-writeable; not a sound idea in this case.)
| 
| OK, I'll bite.  Here are the permissions on my home directory and .login: 
| 
| drwxrwxr-x 21 jc       wheel        2560 Mar 24 08:30 .
| -rw-r--r--  2 jc       wheel         250 Jan 29 14:53 .login
| 
| And here's the rnews command:
| 
| 22531 -rwsr-sr-x 2 news news 114688 Mar 17 13:33 /news/bin/rnews   
| 
| Explain to me how someone could use this setuid-news, setgid-news program
| to write into my .login file.  Now need to explain further; I do appreciate
+---------------

-rwsr-xr-x   1 allbery  System     56462 Mar 20 16:33 /u/allbery/bin/stash

Recall that moderated submissions are *mailed* to the moderator, not posted.
And, of course, I should hope that I own my home directory and .login.
-- 
	      Brandon S. Allbery, moderator of comp.sources.misc
       {well!hoptoad,uunet!hnsurg3,cbosgd,sun!mandrill}!ncoast!allbery

avenger@runx.ips.oz (Troy Rollo ) (04/05/88)

>.
>.drwxrwxr-x 21 jc       wheel        2560 Mar 24 08:30 .
>.-rw-r--r--  2 jc       wheel         250 Jan 29 14:53 .login
>.
>.And here's the rnews command:
>.
>.22531 -rwsr-sr-x 2 news news 114688 Mar 17 13:33 /news/bin/rnews   
>.
>.Explain to me how someone could use this setuid-news, setgid-news program
>.to write into my .login file.  Now need to explain further; I do appreciate
>.why I wouldn't want you to do that.  But I don't quite see how this setup
>.makes it possible.
>
>It is not possible for someone to *directly* abuse this to write to your
>(uid=jc, gid=wheel) .login file.  However, someone may be able to abuse
>rnews and become uid=news, gid=news.  They would then have access to all of
>news's files.  This is where the security break is.

	Once a user has broken through the news uid and gid they can
	modify rnews. The hacker copies the genuine version to another
	place, then creates his own program which sets its effective
	user and group IDs back to the real user and group IDs. The
	program then creates a new file on another directory under your
	uid and gid with the mode 6777 (setuid, setgid, rwx for all).
	Later another program can be copied over it. Alternatively that
	program can be placed in the file by the bogus rnews.
	
	The new rnews then goes on to execute the real rnews, so the
	person who runs rnews will be completely unaware of what
	has happened.

	Voila... the hacker has your user and group IDs 
	and can modify your .login or anything else.

	BTW. I have broken through news programs with setuid
	and setgid on two occasions, which illustrates the
	fact that it is difficult to be certain about any
	setuid, setgid program.

	----------------------------------------------------------------
Internet: avenger@runx.ips.oz.au	Founder of the League of
UUCP: uunet!runx.ips.oz.au!avenger	Computer Criminals

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/12/88)

In article <1458@runx.ips.oz> avenger@runx.ips.oz (Troy Rollo ) writes:
>The program then creates a new file on another directory under your
>uid and gid with the mode 6777 (setuid, setgid, rwx for all).
>Later another program can be copied over it. Alternatively that
>program can be placed in the file by the bogus rnews.

The "alternative" has to be used, since writing a file normally
clears the set-?ID bits, at least on reasonable implementations
of UNIX.  (The exception is when UID 0 does this, but "news"
should not be UID 0.)

friedl@vsi.UUCP (Stephen J. Friedl) (04/13/88)

In article <7659@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> The "alternative" has to be used, since writing a file normally
> clears the set-?ID bits, at least on reasonable implementations
> of UNIX.  (The exception is when UID 0 does this, but "news"
> should not be UID 0.)

SVR2 and SVR3 on the 3B2 don't clear set-?ID bits on write, and
I've not heard of any straight Sys V ports that do this.  No comment
on the "reasonable" tag, but I think that clear-set?id-on-write
is not as widespread as the above paragraph might indicate.  Too bad.
-- 
Steve Friedl   V-Systems, Inc.   "Yes, I'm jeff@unh's brother"
friedl@vsi.com  {backbones}!vsi.com!friedl  attmail!vsi!friedl