NOTE: this the security alert as sent to CERT on 2000-08-08.  Though
it is formatted as and strongly based on the previous suidperl advisory
(http://www.cert.org/advisories/CA-97.17.sperl.html) this is not an
official CERT advisory.  It has not been issued or checked by CERT.

Jarkko Hietaniemi <jhi@iki.fi>
Perl 5.7 development lead

UPDATE 2001-04-07:

       Perl 5.6.1 (released any day now) will contain the proposed fix.
       Perl 5.7.0 and Perl 5.7.1 (developer releases that will evolve
       into 5.8.0) contain the proposed fix.

	CERT never gave an advisory on this, despite my several attempts
	at getting any response from them.

	No other platforms than Linux have been reported vulnerable.

UPDATE 2000-10-06:

       For some unknown reason CERT still has not given an advisory on this.
       I will try to remind them.

       So far the only platform known to have been vulnerable is Linux,
       all distributions.  No other platforms have been found to be
       vulnerable.  Here are some security advisories given by various
       Linux distributors.

       http://www.linuxsecurity.com/advisories/caldera_advisory-607.html
       http://www.linuxsecurity.com/advisories/debian_advisory-608.html
       http://www.linuxsecurity.com/advisories/mandrake_advisory-610.html
       http://www.linuxsecurity.com/advisories/redhat_advisory-647.html
       http://www.linuxsecurity.com/advisories/slackware_advisory-685.html
       http://www.linuxsecurity.com/advisories/suse_advisory-630.html
       http://www.linuxsecurity.com/advisories/turbolinux_advisory-627.html
       http://www.linuxsecurity.com/advisories/other_advisory-624.html
       http://www.linuxsecurity.com/advisories/other_advisory-631.html

       (the two last ones are for the 'Conectiva' and 'Trustix' distributions)

---------------------------------------------------------------------------

TOPIC

        Vulnerability in suidperl (sperl)

I.      Description

        On some systems, setuid and setgid scripts (scripts written
        in the C shell, Bourne shell, or Perl, for example, with the
        set user or group ID permissions enabled) are insecure due to
        a race condition in the kernel. For those systems, Perl versions
        5 and 4 attempt to work around this vulnerability with an optional
        component, a special program named suidperl, also known as sperl.
        This program attempts to emulate the set-user-ID and set-group-ID
        features of the kernel.

        There is a vulnerability in suidperl built from any Perl 5.n and
        Perl 4.n distributions.  An exploit kit is available which allows
        any local user to execute arbitrary commands as root.

        NOTE: the 'suidperl' component is neither built nor installed
        by default.

II.     Impact

        Local users of a system which has suidperl installed are able
        to execute arbitrary commands as root.

III.    Solution

        Use the instructions in Section III.A to find out whether your system
        is vulnerable and, if it is, to (optionally) disable the suidperl
        and sperl programs.  If you find that your system is vulnerable,
        replace the suidperl and sperl programs with new versions,

        Section III.B describes how to do that if your site uses versions of
        suidperl and sperl that are provided as part of a vendor-supplied
        distribution. Sites that installed suidperl and sperl programs
        themselves from the Perl source distribution should patch the
        distribution and reinstall perl as described in Section III.C.
        Note that Perl4 is no longer supported.

Section III.A.
        Determine if your system is vulnerable and disable vulnerable programs

        A system is vulnerable if both the following conditions are true:

        (1) you have a program called /bin/mail

        Try
                        
                ls -l /bin/mail

        If this returns something like "not found" or
        "No such file or directory" you are safe from this particular
        vulnerability because the exploit depends on using /bin/mail.

        (2) you have suidperl installed with setuid or setgid rights

        To determine if a system is vulnerable to this problem and to disable
        the programs that are believed to be vulnerable, use the following
        find command or a variant. Consult your local system documentation to
        determine how to tailor the find program on your system.

        After you have run this command on all the local filesystems of all
        all your systems, they will no longer be vulnerable. Note that after
        disabling the suidperl and sperl programs, they will no longer
        be able to emulate the set-user-ID and et-group-ID features of
        the kernel.  If some application depended on that functionality,
        it will no more work.

        You will need to run the find command on each system you maintain
        because the command examines files on the local disk only. Substitute
        the names of your local file systems for FILE_SYSTEM_NAMES in the
        example. Example local file system names are /, /usr, and /var.
        You must do this as root.

        Note that this is one long command, though we have separated
        it onto four lines using back-slashes.

		find FILE_SYSTEM_NAMES -xdev -type f \
		\( -name 'sperl*' -o -name 'suidperl' \) \
		\( -perm -04000 -o -perm -02000 \) \
		-print -ok chmod ug-s '{}' \;

        This command will find all files on a system that are 
        - only in the file system you name (FILE_SYSTEM_NAMES -xdev) 
        - regular files (-type f) 
        - named appropriately (-name 'sperl*' -o -name 'suidperl') 
        - setuid or setgid (-perm -04000 -o -perm -02000) 

        Once found, those files will

        - have their names printed (-print) 
        - have their modes changed, but only if you type `y' in response
          to the prompt (-ok chmod ug-s '{}' \;)

        You can also double check the situation using Perl's own knowledge
        of where the suidperl would be installed.

        The usual installation directory for perl executables like suidperl
        is /usr/bin but you should check the output of

                perl -V:installbin

        If that is something else than

                installbin='/usr/bin';

        you should run

                perl -MConfig -e '$ib = $Config{installbin}; for ("sperl*", "suidperl") {system("ls -l $ib/$_")}'

        If this shows something like

-rwsr-xr-x   2 root     bin   12345678 Mar 27 21:54 /opt/bin/sperl5.00503
-rwsr-xr-x   2 root     bin   12345678 Mar 27 21:54 /opt/bin/suidperl

        or

-rw-r-sr-x   2 root     bin   12345678 Mar 27 21:54 /opt/bin/sperl5.00503
-rw-r-sr-x   2 root     bin   12345678 Mar 27 21:54 /opt/bin/suidperl

        you still have setuid or setgid perls (the 's' in the 4th
        or 7th columns) and you should use chmod to disable the
        setuid and setgid rights:

                chmod ug-s /opt/bin/sperl* /opt/bin/suidperl

Section III.B.

        If your vendor ships suidperl or sperl, you may be vulnerable and need
        a patch. Appendix A contains information provided by the following
        vendors. If your vendor is not on this list, please contact the vendor
        directly.

        [TBD]

        Until you can install a patch, we recommend disabling suidperl
        as described in Section III.A. The find command above will help
        you do that. If you need suidperl or sperl, see the alternatives
        in Section III.C below.

Section III.C.
        Install suidperl or sperl from 5.6.0 source code and apply a patch.

        If you would like to keep using setuid Perl scripts, fix Perl
        yourself by following these steps:

        1. Go to your Perl 5.6.0 source directory, or else obtain a
           a fresh Perl 5.6.0 distribution from

                http://www.cpan.org/CPAN/src/5.0/perl-5.6.0.tar.gz

        or another CPAN archive accessible to you:

                http://www.cpan.org/CPAN/SITES.html

        This file is approximately 5.4 megabytes in size. 

        2. Using the "patch" program, apply the patch that is enclosed
           below in Appendix B.1.

        3. Build and install the patched Perl 5.6.0.
           If you have never built Perl before, be sure to read
           the "INSTALL" file first.

        The steps in more detail, this should work for most sites.

        1.0  Assuming the source code kit and the patch have already been
             downloaded to the current directory...

        1.1. Unpack the source code kit

                gunzip perl-5.6.0.tar.gz
                tar xf perl-5.6.0.tar

        2.1. Change to the source code directory

                cd perl-5.6.0

        2.2. Apply the patch

                patch -p1 < ../sperl-5.6.0-2000-08-05.patch

        3.1. Configure

                sh ./Configure -ders

        3.2. Rebuild and test

                make all test

             If everything went fine, the "test" target will in the end
             output "All tests successful."

        3.3. Install

                make install

        Perl 5.6.0 binaries that have had this patch applied,
        and therefore are safe from all known attacks, can be
        identified by the output of the "perl -V" command:
        the "Locally applied patches" list will include
        "SUIDMAIL - fixes for suidperl security". 

        Some sites may for stability reasons prefer to patch and reinstall
        some earlier version of Perl.  The Appendix B contains the patches
        for 5.6.0 and for releases that are still known to be in widespread
        use: 5.005_03, 5.004_05, and 5.004_04.  Any earlier release is very
        much unsupported.  Upgrade to (patched) Perl 5.6.0 is encouraged.

---------------------------------------------------------------------------

Appendix A - Vendor Information

        [unofficial, seen in bugtraq: Redhat 6.* and 7.0 are vulnerable,
         as is Mandrake 6.0]

        [TBD]

---------------------------------------------------------------------------

Appendix B - Source Code Patch Information

        In addition to being shown here the source code patches will be
        available also at http://www.cpan.org/src/5.0/sperl-2000-08-05/
	For details about the patch, see Appendix C.

B.1.    Patch for perl 5.6.0:

diff -rc perl-5.6.0.dist/patchlevel.h perl-5.6.0/patchlevel.h
*** perl-5.6.0.dist/patchlevel.h	Wed Mar 22 22:23:11 2000
--- perl-5.6.0/patchlevel.h	Tue Aug  8 03:06:46 2000
***************
*** 69,75 ****
   */
  #if !defined(PERL_PATCHLEVEL_H_IMPLICIT) && !defined(LOCAL_PATCH_COUNT)
  static	char	*local_patches[] = {
! 	NULL
  	,NULL
  };
  
--- 69,76 ----
   */
  #if !defined(PERL_PATCHLEVEL_H_IMPLICIT) && !defined(LOCAL_PATCH_COUNT)
  static	char	*local_patches[] = {
!         NULL
! 	,"SUIDMAIL - fixes for suidperl security"
  	,NULL
  };
  
diff -rc perl-5.6.0.dist/perl.c perl-5.6.0/perl.c
*** perl-5.6.0.dist/perl.c	Sat Mar 18 00:35:15 2000
--- perl-5.6.0/perl.c	Mon Aug  7 20:56:56 2000
***************
*** 2758,2773 ****
  	    if (tmpstatbuf.st_dev != PL_statbuf.st_dev ||
  		tmpstatbuf.st_ino != PL_statbuf.st_ino) {
  		(void)PerlIO_close(PL_rsfp);
- 		if (PL_rsfp = PerlProc_popen("/bin/mail root","w")) {	/* heh, heh */
- 		    PerlIO_printf(PL_rsfp,
- "User %"Uid_t_f" tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
- (Filename of set-id script was %s, uid %"Uid_t_f" gid %"Gid_t_f".)\n\nSincerely,\nperl\n",
- 			PL_uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
- 			(long)PL_statbuf.st_dev, (long)PL_statbuf.st_ino,
- 			CopFILE(PL_curcop),
- 			PL_statbuf.st_uid, PL_statbuf.st_gid);
- 		    (void)PerlProc_pclose(PL_rsfp);
- 		}
  		Perl_croak(aTHX_ "Permission denied\n");
  	    }
  	    if (
--- 2758,2763 ----
(end of patch for perl 5.6.0)

B.2.    Patch for perl 5.005_03:

diff -rc perl5.005_03.dist/patchlevel.h perl5.005_03/patchlevel.h
*** perl5.005_03.dist/patchlevel.h	Sun Mar 28 19:11:58 1999
--- perl5.005_03/patchlevel.h	Tue Aug  8 03:06:39 2000
***************
*** 40,45 ****
--- 40,46 ----
   */
  static	char	*local_patches[] = {
  	NULL
+ 	,"SUIDMAIL - fixes for suidperl security"
  	,NULL
  };
  
diff -rc perl5.005_03.dist/perl.c perl5.005_03/perl.c
*** perl5.005_03.dist/perl.c	Sat Mar 27 19:49:17 1999
--- perl5.005_03/perl.c	Mon Aug  7 20:57:45 2000
***************
*** 2220,2235 ****
  	    if (tmpstatbuf.st_dev != PL_statbuf.st_dev ||
  		tmpstatbuf.st_ino != PL_statbuf.st_ino) {
  		(void)PerlIO_close(PL_rsfp);
- 		if (PL_rsfp = PerlProc_popen("/bin/mail root","w")) {	/* heh, heh */
- 		    PerlIO_printf(PL_rsfp,
- "User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
- (Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
- 			(long)PL_uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
- 			(long)PL_statbuf.st_dev, (long)PL_statbuf.st_ino,
- 			SvPVX(GvSV(PL_curcop->cop_filegv)),
- 			(long)PL_statbuf.st_uid, (long)PL_statbuf.st_gid);
- 		    (void)PerlProc_pclose(PL_rsfp);
- 		}
  		croak("Permission denied\n");
  	    }
  	    if (
--- 2220,2225 ----
(end of patch for perl 5.005_03)

B.3.    Patch for perl 5.004_05:

diff -rc perl5.004_05.dist/patchlevel.h perl5.004_05/patchlevel.h
*** perl5.004_05.dist/patchlevel.h	Thu Apr 29 17:54:58 1999
--- perl5.004_05/patchlevel.h	Tue Aug  8 03:08:02 2000
***************
*** 39,44 ****
--- 39,45 ----
  /* The following line and terminating '};' are read by perlbug.PL. Don't alter. */ 
  static	char	*local_patches[] = {
  	NULL
+ 	,"SUIDMAIL - fixes for suidperl security"
  	,NULL
  };
  
diff -rc perl5.004_05.dist/perl.c perl5.004_05/perl.c
*** perl5.004_05.dist/perl.c	Tue Apr  6 22:38:11 1999
--- perl5.004_05/perl.c	Mon Aug  7 21:03:57 2000
***************
*** 1926,1941 ****
  	    if (tmpstatbuf.st_dev != statbuf.st_dev ||
  		tmpstatbuf.st_ino != statbuf.st_ino) {
  		(void)PerlIO_close(rsfp);
- 		if (rsfp = my_popen("/bin/mail root","w")) {	/* heh, heh */
- 		    PerlIO_printf(rsfp,
- "User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
- (Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
- 			(long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
- 			(long)statbuf.st_dev, (long)statbuf.st_ino,
- 			SvPVX(GvSV(curcop->cop_filegv)),
- 			(long)statbuf.st_uid, (long)statbuf.st_gid);
- 		    (void)my_pclose(rsfp);
- 		}
  		croak("Permission denied\n");
  	    }
  	    if (
--- 1926,1931 ----
(end of patch for perl 5.004_05)

B.4.    Patch for perl 5.004_04:

diff -rc perl5.004_04.dist/patchlevel.h perl5.004_04/patchlevel.h
*** perl5.004_04.dist/patchlevel.h	Wed Oct 15 12:55:19 1997
--- perl5.004_04/patchlevel.h	Tue Aug  8 03:10:03 2000
***************
*** 39,44 ****
--- 39,45 ----
  /* The following line and terminating '};' are read by perlbug.PL. Don't alter. */ 
  static	char	*local_patches[] = {
  	NULL
+ 	,"SUIDMAIL - fixes for suidperl security"
  	,NULL
  };
  
diff -rc perl5.004_04.dist/perl.c perl5.004_04/perl.c
*** perl5.004_04.dist/perl.c	Tue Oct 14 21:09:18 1997
--- perl5.004_04/perl.c	Mon Aug  7 21:37:51 2000
***************
*** 2039,2054 ****
  	    if (tmpstatbuf.st_dev != statbuf.st_dev ||
  		tmpstatbuf.st_ino != statbuf.st_ino) {
  		(void)PerlIO_close(rsfp);
- 		if (rsfp = my_popen("/bin/mail root","w")) {	/* heh, heh */
- 		    PerlIO_printf(rsfp,
- "User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
- (Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
- 			(long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
- 			(long)statbuf.st_dev, (long)statbuf.st_ino,
- 			SvPVX(GvSV(curcop->cop_filegv)),
- 			(long)statbuf.st_uid, (long)statbuf.st_gid);
- 		    (void)my_pclose(rsfp);
- 		}
  		croak("Permission denied\n");
  	    }
  	    if (
--- 2039,2044 ----
(end of patch for perl 5.004_04)

------------------------------------------------------------------------

Appendix C - The Exploit and Patch Details

        The bug was reported by Michal Zalewski <lcamtuf@tip.pl> on Saturday,
        2000-Aug-05, in a bugtraq security mailing list message [2]
        titled "sperl 5.00503 (and newer ;) exploit".  Included in
	the message as also an exploit kit.

        The cause of the vulnerability is, ironically enough,
        Perl trying to report a suspected security incident,
        by sending email to the root account using the external
        /bin/mail program.  Unfortunately /bin/mail is too featureful
        and can be tricked into giving an interactive shell
        instead of sending email.  The shell inherits the
        superuser rights.

        The supplied patches are rather blunt: they simply remove
        the sending of the email message.  At later point a more
        elegant fix may be supplied that retains the feature,
        if the feature is considered worth it.

[1] Message-id <Pine.LNX.4.21.0008051825300.26685-101000@dione.ids.pl>
    Here is a link to the message in the bugtraq mailing list archives:

http://www.securityfocus.com/frames/?content=/templates/archive.pike%3Flist%3D1%26date%3D2000-08-01%26msg%3DPine.LNX.4.21.0008051825300.26685-101000%40dione.ids.pl

------------------------------------------------------------------------