Bugtraq mailing list archives

REVISED: Majordomo SECURITY patch and fix (offical version)


From: rouilj () cs umb edu (John P. Rouillard)
Date: Wed, 8 Jun 1994 11:36:03 -0400 (EDT)


Sorry, in the hurry to get the patch out because people were starting
to bitch moan and complain, the patch in the last message was mangled
so that the first patch for majordomo.pl wasn't applied. This fixes
that typo.

A potentially serious security problem in Majordomo has just been
brought to my attention.  This problem applies to ALL versions of
Majordomo, including the latest release (1.90). It is quite likely
that this hole is being exploited.

Basicly, through clever hackery of "From:" lines on incoming messages,
someone could convince 'majordomo' or 'request-answer' to run a
command for them as user Majordomo is running as (whatever the
"wrapper" program is setuid to if you are bsd, or the user compiled
into the wrapper if you are a posix box).  This command could, for
instance, send them your password file, or even compile and run a
supplied program to start a shell for them on a specified port, so all
they'd have to do is TELNET to that port from the outside.

The supported fix is included below. It calls sendmail directly using
exec so that the "$to" argument to Sendmail isn't passed through the
shell.  This patch is meant for majordomo 1.90, after applying this
patch, your majordomo will be at version 1.91. This patch can also be
applied to majordomo 1.62 but has not been extensively tested. It
should apply successfully except for the patch to
majordomo_version.pl. Earlier versions of majordomo still have the
security problem, and MUST be patched.

A quick fix for 1.62 and earlier is relatively simple: don't pass the
"$to" argument to Sendmail on the command line.  This argument isn't
necessary to anyway, since Majordomo passes the same info in a "To:"
header to Sendmail; you just have to use the "-t" argument to Sendmail
to tell it to look at the headers instead of the command line for
recipients. If you are using something other than sendmail this quick
fix may not work as is and you will need to figure out the
corresponding fix for your mailer.

Every place in the Majordomo code (generally, this will be in the
"request-answer" file, the "majordomo.pl" file, and your local
majordomo.cf file) where there is a string of the form

        "|/usr/lib/sendmail -f<whatever> $to"           # majordomo.pl
or      "|/usr/lib/sendmail -f<whatever> $reply_to"     # request-answer
or      "|/usr/lib/sendmail -f<whatever> \$to"          # majordomo.cf

change it to 
        "|/usr/lib/sendmail -f<whatever> -t"

This was released yesterday night to the majordomo-workers list to
allow people on the cutting edge to test the patch. Since I have not
heard of any problemns with the patch, it is now being released
generally.

To apply the patch, use the patch(1) program and feed this file as
input. I claim it should be able to be applied to a working majordomo
installation, although it would of course be best to apply it to the
1.90 source distribution and install from there. Alternatively pick up
majordomo version 1.91 (that has the patch applied) from:

        ftp.greatcircle.com:/pub/majordomo/majordomo-1.91.tar.Z

===================================================================
RCS file: /sources/cvsrepos/majordomo/majordomo.pl,v
retrieving revision 1.12
diff -c -r1.12 majordomo.pl
*** 1.12 1994/02/07 20:37:32
--- majordomo.pl 1994/06/07 04:53:24
***************
*** 282,291 ****
      $to = join(", ", @to);
  
      # open the process
!     local($mailer);
      eval "\$mailer = \"$mail_prog\"";
!     open($MAIL, "|$mailer") ||
!       &main'abort("Can't invoke \"$mailer\": $!");
  
      # generate the header.  Note the line beginning with "-"; this keeps
      # this message from being reprocessed by Majordomo if some misbegotten
--- 282,295 ----
      $to = join(", ", @to);
  
      # open the process
!     local(@mailer, $mailer);
      eval "\$mailer = \"$mail_prog\"";
!     @mailer = split(' ', $mailer);
! sub do_exec_sendmail {
!     exec(@_, "");
!       die("Failed to exec mailer \"@_\": $!");
! }
!     open($MAIL, "|-") || &do_exec_sendmail(@mailer);
  
      # generate the header.  Note the line beginning with "-"; this keeps
      # this message from being reprocessed by Majordomo if some misbegotten
===================================================================
RCS file: /sources/cvsrepos/majordomo/majordomo_version.pl,v
retrieving revision 1.7
diff -c -r1.7 majordomo_version.pl
*** 1.7 1994/05/09 17:41:26
--- majordomo_version.pl        1994/06/07 12:52:43
***************
*** 1,5 ****
  # $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.7 1994/05/09 17:41:26 rouilj Exp $
  
! $majordomo_version = "1.90";
  1;
  
--- 1,5 ----
  # $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.7 1994/05/09 17:41:26 rouilj Exp $
  
! $majordomo_version = "1.91";
  1;
  
===================================================================
RCS file: /sources/cvsrepos/majordomo/request-answer,v
retrieving revision 1.2
diff -c -r1.2 request-answer
*** 1.2 1993/09/01 20:37:17
--- request-answer      1994/06/07 04:26:29
***************
*** 37,44 ****
  $in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"};
  $list = $ARGV[0];
  
! open(MAIL, "|/usr/lib/sendmail -f$list-request $reply_to") ||
!     die("Can't connect to sendmail: $!");
  
  print MAIL <<"EOM";
  To: $reply_to
--- 37,48 ----
  $in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"};
  $list = $ARGV[0];
  
! sub do_exec_sendmail {
!     exec("/usr/lib/sendmail", "-f$list-request", "$reply_to") ||
!       die("Failed to exec sendmail");
! }
! 
! open(MAIL, "|-") || &do_exec_sendmail();
  
  print MAIL <<"EOM";
  To: $reply_to
===================================================================
RCS file: /sources/cvsrepos/majordomo/resend,v
retrieving revision 1.28
diff -c -r1.28 resend
*** 1.28        1994/05/08 20:25:49
--- resend      1994/06/07 15:18:48
***************
*** 335,342 ****
      unlink(</tmp/resend.$$.*>);
      exit($status);
  } else {
!     system("$sendmail_cmd </tmp/resend.$$.out &");
!     unlink(</tmp/resend.$$.*>);
      exit(0);
  }
  
--- 335,350 ----
      unlink(</tmp/resend.$$.*>);
      exit($status);
  } else {
!     local(*MAILOUT, *MAILIN, @mailer);
!     @mailer = split(' ', "$sendmail_cmd");
!     open(MAILOUT, "|-") || &do_exec_sendmail(@mailer);
!     open(MAILIN, "/tmp/resend.$$.out");
!     while (<MAILIN>) {
!       print MAILOUT $_;
!     }
!     close(MAILOUT);
!     close(MAILIN);
!     unlink("/tmp/resend.$$.*");
      exit(0);
  }
  
***************
*** 435,442 ****
        open(MAIL, ">-");
        print MAIL ">>> /usr/lib/sendmail -f$sendmail_sender $to\n";
      } else {
!       open(MAIL, "|/usr/lib/sendmail -f$sendmail_sender $to") ||
!           &abort("Can't connect to sendmail: $!");
      }
  
      # generate the header
--- 443,450 ----
        open(MAIL, ">-");
        print MAIL ">>> /usr/lib/sendmail -f$sendmail_sender $to\n";
      } else {
!     local(@mailer) = split(' ',"/usr/lib/sendmail -f$sendmail_sender $to");
!        open(MAIL, "|-") || &do_exec_sendmail(@mailer);
      }
  
      # generate the header
***************
*** 448,451 ****
--- 456,464 ----
  EOM
  
      return;
+ }
+ 
+ sub do_exec_sendmail {
+     exec(@_, "");
+     die("Failed to exec mailer \"@_\": $!");
  }



Current thread: