SUID programs

SUID programs

Post by Bill Heis » Sat, 22 May 1993 04:25:09



I am trying to write a simple little program to do mount(2)
and unmount(2) for use as a non-root user-accessible mount/umount
of Sparc floppies.  

The mount() seems to work fine.

However when I try to unmount(), the system call returns a "not owner"
status.  Apparently it's checking the REAL uid, not the effective uid,
so it's not allowing the user to do this.  The funny thing is that if
I use a Csh script, it Works!  But I'd like to use a program instead
of a script if I can.

The C program looks like this:

if (unmount("/pcfs")) {
  perror("pcfs_umount");
  }
else
  printf ("Floppy unmounted.\n");

and the CSH script that does work looks like this:

#! /bin/csh -b
/usr/etc/umount -v /pcfs
if ($status != 0) then
 echo "Unable to unmount floppy.  Be sure to 'cd' out of /pcfs\!"
 exit 1
endif
/bin/eject /dev/rfd0
if ($status != 0) then
 echo "Unable to eject floppy.  Consult a System Manager."
 exit 1
else
 echo "Floppy Ejected."
endif

Any tips/suggestions would be appreciated.  
BTW, I set the pgm and script to mode 4755.

Thanks in advance.
Bill Heiser

--


 
 
 

SUID programs

Post by Bill Ubelack » Fri, 28 May 1993 06:00:10


I use the following scripts to mount and unmount floppies on sparcstations.
They seem to work pretty well.  

These are the three files that I have in /usr/local/bin

"pcfs" mounts the floppy on /pcfs
"pcfs -u" unmounts and ejects the floppy

*****pcfs***************
***** -rwxr-xr-x  1 root     staff        3405 Aug 11  1992 pcfs

#!/bin/sh
# this script provides a user-friendly interface to /pcfs

Prog=`basename $0`
USAGE="
Usage:  ${Prog}
        ${Prog} -{i|o} [ -b ] [ -q ] [ files ... ]
        ${Prog} -u
-OR- for more help, type:
        ${Prog} -h
"
HELP="
This command provides a user-friendly interface to PC-FS, the MS-DOS interface.
It will copy files between the current directory and the floppy disk.
This command will mount the floppy drive on the directory /pcfs if needed.
${USAGE}
Where:
        -i      input mode - copy files from the floppy to the current directory
        -o      output mode - copy files from the current directory to the floppy
        -u      unmount the floppy drive
        -b      binary copy - don't convert between MS-DOS and Unix
        -l      List file namess on floppy
        -L      Long list files on floppy (ls -l)
        -q      Quiet mode - don't display informative messages

This command will automatically convert files between DOS and Unix formats
        unless the -b option is used
"

if [ ! -d /pcfs ]
then
        echo "${Prog}: No /pcfs directory for mounting!${USAGE}" >&2
        exit 1
fi

Loop="y"
Bin=
MODE=
QUIET=
LIST=

while [ "${Loop}" = "y" ]
do
        case $1 in
                -b)     # binary files
                        BIN="y"
                        ;;
                -h)     # help message
                        echo "${HELP}" >&2
                        exit 0
                        ;;
                -i)     # input files
                        MODE="i"
                        INDIR=/pcfs
                        OUTDIR=`pwd`
                        CONV=dos2unix
                        ;;
                -l)     # list files
                        LIST="l"
                        ;;
                -L)     # list files
                        LIST="L"
                        ;;
                -o)     # output files
                        MODE="o"
                        INDIR=`pwd`
                        OUTDIR=/pcfs
                        CONV=unix2dos
                        ;;
                -q)     QUIET="Y";;   # quiet mode
                -u)     MODE="u";;    # unmount floppy
                -*)     echo "${Prog}: Invalid option ($1)${USAGE}" >&2; exit 1;;
                *)      Loop="n";;    # file names - done looping
        esac
        test "${Loop}" = "y" && shift       # shift if still looping
done

MOUNTED=`/etc/mount | grep "on /pcfs "`

if [ "${MODE}" = "u" ]
then    # just unmount
        if [ -n "${MOUNTED}" ]
        then
                case `pwd` in
                /pcfs*)         # in /pcfs hierarchy
                        echo "${Prog}: You must first cd out of the /pcfs file system." >&2
                        exit 1
                        ;;
                esac

                test -n "${QUIET}" && echo "${Prog}: Unmounting floppy from /pcfs ..." >&2
                floppy_umount >&2

                MOUNTED=`/etc/mount | grep "on /pcfs "`
                if [ -n "${MOUNTED}" ]
                then
                        echo "${Prog}: Floppy unmount failed!" >&2
                        echo "     Make sure no one has cd'ed into the /pcfs directory." >&2
                        exit 1
                fi
        else
                echo "${Prog}: Floppy not mounted" >&2
        fi
        exit
elif [ -z "${MOUNTED}" ]
then    # floppy not mounted
        test -n "${QUIET}" && echo "Mounting floppy disk on /pcfs ..." >&2
        floppy_mount
        MOUNTED=`/etc/mount | grep "on /pcfs "`
        if [ -z "${MOUNTED}" ]
        then
                echo "${Prog}: Floppy mount failed!" >&2
                exit 2
        fi
fi

[ -n "${MOUNTED}" ] && df /pcfs

if [ -n "${LIST}" ]
then
        echo "Files on floppy:"
        [ "${LIST}" = "l" ] && ls /pcfs
        [ "${LIST}" = "L" ] && ls -lg /pcfs
fi

if [ -z "${MODE}" ]
then
        test $# -eq 0 && exit 0 # just mount
        # files specified without any mode
        echo "No input/output mode specified!${USAGE}" >&2
        exit 1
fi

# copying either from or to the floppy

if [ $# -eq 0 ]
then
        Files="*"
else
        Files="$*"
fi

cd ${INDIR}     # go to input directory

# if binary files, then just do a straight copy

if [ -n "${BIN}" ]
then    # yes - binary files
        cp $* ${OUTDIR}
        exit
fi

# copying text files - do it one at a time

for file in ${Files}
do              # process each file
        if [ -r ${INDIR}/$file ]
        then
                test -z "${QUIET}" && echo "processing file ${file} ..."
                ${CONV} ${INDIR}/$file ${OUTDIR}/$file
        else
                echo "${Prog}: File ${INDIR}/$file not found!" >&2
        fi
done

*******floppy_mount***************
******* -rwsr-sr-x  1 root     staff         128 Jun  4  1992 floppy_mount
#! /bin/csh -b
set path = (/usr/etc $path)
/usr/etc/mount -t pcfs -o rw /dev/fd0 /pcfs
echo "Floppy mounted on directory /pcfs"

*******floppy_umount*************
******* -rwsr-sr-x  1 root     staff         128 Jun  4  1992 floppy_umount
#! /bin/csh -b
set path = (/usr/etc $path)
/usr/etc/umount /pcfs
eject
echo "Floppy unmounted from directory /pcfs and ejected"

--
---------------------------------------------------------------------------
Bill Ubelacker        |  
b...@ivy.paramax.com  |
Network Administrator |

 
 
 

SUID programs

Post by Stig Vena » Fri, 28 May 1993 23:43:47


It's quite dangerous to have SUID scripts. I haven't tested
it with csh, but if you're using sh, then any user on your
machine can easily get root access.

Stig

 
 
 

SUID programs

Post by Andre Hoekst » Sat, 29 May 1993 00:24:31


nice scripts, except for the last two (pcfs_mount pcfs_umount):

   IT IS ALWAYS A BAD BAD BAD BAD IDEA TO HAVE ROOT-OWNED SUID/SGID SCRIPTS!!

Why not use mtools (check archie for a site near you)

Andre++
--
-------------------------------------------------------------------------------
 Mechatronics Research Centre Twente     --     Mobile Autonomous Robot Twente

 Twente University  WB/WA  P.O. box 217  NL-7500 AE  ENSCHEDE  THE NETHERLANDS

 
 
 

SUID programs

Post by Bill Gr » Sat, 29 May 1993 08:21:09



>  nice scripts, except for the last two (pcfs_mount pcfs_umount):

>     IT IS ALWAYS A BAD BAD BAD BAD IDEA TO HAVE ROOT-OWNED SUID/SGID SCRIPTS!!
>  ...

Quite.  From _Practical Unix Security_, (Garfinkle & Spafford), p170:

        Because of design flaws in the Unix kernel,  it's possible
        for regular users to gain superuser priveleges if there is
        a SUID shell script on your computer.  ,,,  NEVER USE SUID
        SHELL SCRIPTS.
---
The views and opinions expressed herein are personal and are not necessarily
those of the United States Government or any of its agencies or contractors.

 
 
 

SUID programs

Post by Wietse Vene » Sat, 29 May 1993 05:36:14



>It's quite dangerous to have SUID scripts. I haven't tested
>it with csh, but if you're using sh, then any user on your
>machine can easily get root access.

On most UNIX systems, interpreters such as the csh get the script name
on their command line.  There is a finite time window between the time
that the the kernel examines the script and the time that the shell
opens its argument for reading the commands. On these systems, set-xxx
csh scripts can be spoofed, too.

        Wietse

 
 
 

SUID programs

Post by Gregory Ow » Sat, 29 May 1993 23:59:57




>>   IT IS ALWAYS A BAD BAD BAD IDEA TO HAVE ROOT-OWNED SUID/SGID SCRIPTS!!
>>  ...
>Quite.  From _Practical Unix Security_, (Garfinkle & Spafford), p170:

>        Because of design flaws in the Unix kernel,  it's possible
>        for regular users to gain superuser priveleges if there is
>        a SUID shell script on your computer.  ,,,  NEVER USE SUID
>        SHELL SCRIPTS.

        I was under the impression that on certain new unices they
hacked a way to make SUID shell scripts safe.  Anyone care to comment
or correct me if I am wrong (would _not_ be a suprise).
        Another option may be to use perl which does SUID emulation if
SUID shell scripts are disallowed by the kernel.
        That being said, in general I agree.  Never use SUID scripts.


Systems Programmer and TA, Tufts University Computer Science Dept.

 
 
 

SUID programs

Post by Lars Joergen A » Sun, 30 May 1993 02:22:30



: >  
: > IT IS ALWAYS A BAD BAD BAD BAD IDEA TO HAVE ROOT-OWNED SUID/SGID SCRIPTS!!
: >  ...
: Quite.  From _Practical Unix Security_, (Garfinkle & Spafford), p170:

:       Because of design flaws in the Unix kernel,  it's possible
:       for regular users to gain superuser priveleges if there is
:       a SUID shell script on your computer.  ,,,  NEVER USE SUID
:       SHELL SCRIPTS.

  I think root suid-scripts can be fine for maintenance-groups, if only
the maintenance-group can execute it...  In that way you don't have to
su to root to start scripts that checks all the users disk-usage etc...
But then the maintenance-group should be careful with their passwords,
and their .rhosts-file...

*larsa*

 
 
 

SUID programs

Post by Malcolm Mladenovi » Mon, 31 May 1993 04:05:05



Quote:>  I think root suid-scripts can be fine for maintenance-groups, if only
>the maintenance-group can execute it...  In that way you don't have to
>su to root to start scripts that checks all the users disk-usage etc...
>But then the maintenance-group should be careful with their passwords,
>and their .rhosts-file...

I don't really agree, this reduces the probem for the cracker from:

        break into the root account (assuming no suid-root scripts)
to
        break the account of any user in the maintenance group

It is stll a lot better than having world-accessible suid-root scripts
available, though :-)

Systems that have the /dev/fd/<n> type facility can remove the race by
having the kernel keep the script open and passing the /dev/fd/<script-fd>
name as the script name to the interpreter (this is done on SVR4 for
example).   This has the disadvantage that the script does not know
the name it was invoked by.   However, all the other problems with IFS,
PATH, rogue user data etc. still apply to such scripts.

-Malcolm

[usual disclaimers apply]

 
 
 

SUID programs

Post by Bill Heis » Sun, 30 May 1993 09:28:49



>   IT IS ALWAYS A BAD BAD BAD BAD IDEA TO HAVE ROOT-OWNED SUID/SGID SCRIPTS!!

Doesn't Sun claim they've fixed this hole?

--


 
 
 

SUID programs

Post by Larry Wa » Thu, 03 Jun 1993 05:06:23


: [discussion of nifty /dev/fd/<n> hack deleted]
: However, all the other problems with IFS, PATH, rogue user data etc.
: still apply to such scripts.

Only for certain values of "script".  :-)

Larry Wall

 
 
 

SUID programs

Post by Joerg Czerans » Fri, 04 Jun 1993 06:50:07


: [...]
:       Another option may be to use perl which does SUID emulation if
: SUID shell scripts are disallowed by the kernel.
:       That being said, in general I agree.  Never use SUID scripts.
:

: Systems Programmer and TA, Tufts University Computer Science Dept.

Even perl isn't the solution.  We have SunOS 4.1.3 and perl 4.0.
I was able to trick perl into executing the wrong script by executing
a softlink to a SUID perl script and immediately replacing the softlink
by another perl script before perl opened the script.

So one should at least use a SUID C wrapper for the script.

joerg

--


W-3392 Clausthal-Zellerfeld    Voice (at work)  +49-5323-72-3896
Germany                        Voice (at home)  +49-5323-78858


 
 
 

SUID programs

Post by Larry Wa » Sat, 05 Jun 1993 05:51:49




: : [...]
: :     Another option may be to use perl which does SUID emulation if
: : SUID shell scripts are disallowed by the kernel.
: :     That being said, in general I agree.  Never use SUID scripts.
: :

: : Systems Programmer and TA, Tufts University Computer Science Dept.
:
: Even perl isn't the solution.  We have SunOS 4.1.3 and perl 4.0.
: I was able to trick perl into executing the wrong script by executing
: a softlink to a SUID perl script and immediately replacing the softlink
: by another perl script before perl opened the script.

You sort of ignored the line that says "if SUID shell scripts are
disallowed by the kernel".  Perl doesn't claim to be able to workaround
the bug otherwise.  The SUID emulation is only there to add some secure
SUID back in when it's missing.  It seemed pretty wonderful at the
time, but it's really pretty useless because we never managed to
persuade Sun to disable setuid scripts.

: So one should at least use a SUID C wrapper for the script.

Agreed.  Below is a program that makes this easier.  By the way, you
still get all the Perl taint checks this way, which is a net win.

Larry Wall

#!/usr/bin/perl
'di';
'ig00';
#
# $Header: suidscript,v 1.1 90/08/11 13:51:29 lwall Locked $
#
# $Log: suidscript,v $
# Revision 1.1  90/08/11  13:51:29  lwall
# Initial revision
#

$xdev = '-xdev' unless -d '/dev/iop';

if ($#ARGV >= 0) {


        die "You must use absolute pathnames.\n" unless $name =~ m|^/|;
    }

Quote:}

else {
    open(DF,"/etc/mount|") || die "Can't run /etc/mount";

    while (<DF>) {
        chop;
        $_ .= <DF> if length($_) < 50;


    }

Quote:}


die "Can't find local filesystems" unless $fslist;

open(FIND,
  "find $fslist $xdev -type f \\( -perm -04000 -o -perm -02000 \\) -print|");

while (<FIND>) {
    chop;
    next unless -T;
    print "Fixing ", $_, "\n";
    ($dir,$file) = m|(.*)/(.*)|;
    chdir $dir || die "Can't chdir to $dir";
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
       $blksize,$blocks) = stat($file);
       die "Can't stat $_" unless $ino;
    chmod $mode & 01777, $file;             # wipe out set[ug]id bits
    rename($file,".$file");
    open(C,">.tmp$$.c") || die "Can't write C program for $_";
    $real = "$dir/.$file";
    print C '
main(argc,argv)
int argc;
char **argv;
{
    execv("' . $real . '",argv);

Quote:}

';
    close C;
    system '/bin/cc', ".tmp$$.c", '-o', $file;
    die "Can't compile new $_" if $?;
    chmod $mode, $file;
    chown $uid, $gid, $file;
    unlink ".tmp$$.c";
    chdir '/';
Quote:}

##############################################################################

        # These next few lines are legal in both Perl and nroff.

.00;                    # finish .ig

'di                     \" finish diversion--previous line must be blank
.nr nl 0-1              \" fake up transition to first page again
.nr % 0                 \" start at page 1
'; __END__ ############# From here on it's a standard manual page ############
.TH SUIDSCRIPT 1 "July 30, 1990"
.AT 3
.SH NAME
suidscript \- puts a compiled C wrapper around a setuid or setgid script
.SH SYNOPSIS
.B suidscript [dirlist]
.SH DESCRIPTION
.I Suidscript
creates a small C program to execute a script with setuid or setgid privileges
without having to set the setuid or setgid bit on the script, which is
a security problem on many machines.
Specify the list of directories or files that you wish to process.
The names must be absolute pathnames.
With no arguments it will attempt to process all the local directories
for this machine.
The scripts to be processed must have the setuid or setgid bit set.
The suidscript program will delete the bits and set them on the wrapper.
.PP
Non-superusers may only process their own files.
.SH ENVIRONMENT
No environment variables are used.
.SH FILES
None.
.SH AUTHOR
Larry Wall
.SH "SEE ALSO"
.SH DIAGNOSTICS
.SH BUGS
.ex