Läsa nästa text.
5034514 2000-04-24  23:20  /101 rader/ Postmaster
Mottagare: Bugtraq (import) <10602>
Ärende: unsafe fgets() in sendmail's mail.local
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: bugtraq@securityfocus.com
X-Priority: 3 (Normal)
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID:  <2694.000424@SECURITY.NNOV.RU>
Date:         Mon, 24 Apr 2000 16:40:32 +0400
Reply-To: 3APA3A <3APA3A@SECURITY.NNOV.RU>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: 3APA3A <3APA3A@SECURITY.NNOV.RU>
Organization: http://www.security.nnov.ru
X-To:         bugtraq@security.nnov.ru, bugtraq@securityfocus.com
X-cc:         security-officer@freebsd.org
To: BUGTRAQ@SECURITYFOCUS.COM

Topic:
      unsafe fgets() in sendmail's mail.local

Description:
      There are 4 problems:
      1. Possibility to insert LMTP commands into e-mail message
      2. Possibility of deadlock between sendmail and mail.local
      3. Possibility to corrupt user's mailbox
      4. Possibility to change e-mail headers of the message in user's
      mailbox

Vulnerable software:
     Problems  1  and  2:  sendmail  before 8.10.0 (8.9.3 tested), all
     platforms
     Problems  3  and  4:  sendmail  8.10.0 and 8.10.1 (8.10.1 tested)
     under Solaris only

Status: vendor contacted, problems 1 and 2 are patched in sendmail 8.10.0

Long description:

 Problem 1:

 While  in  LMTP mode mail.local checks input for ".\n" string to find
 the  end  of the message. Sendmail will not allow this string to pass
 through,  but using of fgets() with buffersize 2048 allows to emulate
 end of the message with a string

 "(2047 chars).\n"

 The rest of the message will be treated as LMTP commands. This allows
 to  send messages to multiple mailboxes (including private and closed
 ones) with any spoofed information bypassing sendmail and without any
 filtering, checking, logging etc.

 Problem 2:

 In  the  conditions  of  the  problem  1, mail.local will return LMTP
 answers to sendmail. Because sendmail doesn't expects any output from
 mail.local  at this point, replies will not be taken from I/O buffer.
 If  extreamaly  large number of LMTP commands is used in the text, or
 the rest of the message is just a collection of text strings (in this
 case  mail.local  will  reply with a error for every string) sendmail
 and  mail.local  will  be  deadlocked then the buffer will be filled.
 This  deadlock  problem  regardless  to  LMTP  command  execution was
 reported  to  sendmail  team  by  Peter  Jeremy and patched in 8.10.0
 release.

 Problem 3:

 sendmail  8.10.0 introduces support for "Content-Length: " header for
 Solaris in mail.local. This header stores the size of the message and
 is  used  by  mail  retrieving  software  (f.e. qpopper) to calculate
 message  boundary  in  the  mailbox. If this header already exists in
 message  it will be stripped, but because fgets() is used for parsing
 message  it's  possible  to add "Content-Length: 99999999" header and
 comment  out real "Content-Length: " causing mailbox corruption using
 strings

 "(2047 chars)\n"
 "Content-Length: 99999999\n"

 in the end of message header.

 Problem 4:

 If message body is empty and last string of the message header is

 "(2047 chars)Content-Length: \n"

 the  headers  of  this  message  will be glued to the next message in
 mailbox,   because  '\n'  character  will  be  lost  while  stripping
 Content-Length.



http://www.security.nnov.ru
         /\_/\
        { . . }     |\
+--oQQo->{ ^ }<-----+ \
|  3APA3A  U  3APA3A   }
+-------------o66o--+ /
                    |/
You know my name - look up my number (The Beatles)
(5034514) ------------------------------------------

5038233 2000-04-26  05:27  /149 rader/ Postmaster
Mottagare: Bugtraq (import) <10620>
Ärende: Re: unsafe fgets() in sendmail's mail.local
------------------------------------------------------------
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="vkogqOf2sHV7VnPd"
Message-ID:  <20000425091054.A30214@zardoc.endmail.org>
Date:         Tue, 25 Apr 2000 09:10:54 -0700
Reply-To: Claus Assmann <ca+bugtraq@ZARDOC.ENDMAIL.ORG>
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Claus Assmann <ca+bugtraq@ZARDOC.ENDMAIL.ORG>
X-To:         BUGTRAQ@SECURITYFOCUS.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <2694.000424@SECURITY.NNOV.RU>; from 3APA3A@SECURITY.NNOV.RU o 
             Mon, Apr 24, 2000 at 04:40:32PM +0400

--vkogqOf2sHV7VnPd
Content-Type: text/plain; charset=us-ascii

On Mon, Apr 24, 2000, 3APA3A wrote:
> Topic:
>       unsafe fgets() in sendmail's mail.local

>       1. Possibility to insert LMTP commands into e-mail message
>       2. Possibility of deadlock between sendmail and mail.local
>       3. Possibility to corrupt user's mailbox
>       4. Possibility to change e-mail headers of the message in user's
>       mailbox

> Vulnerable software:
>      Problems  1  and  2:  sendmail  before 8.10.0 (8.9.3 tested), all
>      platforms
>      Problems  3  and  4:  sendmail  8.10.0 and 8.10.1 (8.10.1 tested)
>      under Solaris only

Thanks for the notification and your help to create a patch.
The attached patch will be in the next release of sendmail.

PS: Content-Length: shouldn't be used anyway :-)

--vkogqOf2sHV7VnPd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="p.m.c"

Index: mail.local.c
===================================================================
RCS file: /cvs/mail.local/mail.local.c,v
retrieving revision 8.145
retrieving revision 8.146
diff -u -r8.145 -r8.146
--- mail.local.c	2000/04/25 15:27:08	8.145
+++ mail.local.c	2000/04/25 15:48:32	8.146
@@ -746,7 +746,8 @@
 	FILE *fp = NULL;
 	time_t tval;
 	bool eline;
-	bool fullline = TRUE;
+	bool fullline = TRUE;	/* current line is terminated */
+	bool prevfl;		/* previous line was terminated */
 	char line[2048];
 	int fd;
 	char tmpbuf[sizeof _PATH_LOCTMP + 1];
@@ -783,16 +784,19 @@
 #endif /* CONTENTLENGTH */

 	line[0] = '\0';
-	for (eline = TRUE; fgets(line, sizeof(line), stdin); )
+	eline = TRUE;
+	while (fgets(line, sizeof(line), stdin) != (char *)NULL)
 	{
 		size_t line_len = 0;
 		int peek;
+
+		prevfl = fullline;	/* preserve state of previous line */
 		while (line[line_len] != '\n' && line_len < sizeof(line) - 2)
 			line_len++;
 		line_len++;

 		/* Check for dot-stuffing */
-		if (fullline && lmtprcpts && line[0] == '.')
+		if (prevfl && lmtprcpts && line[0] == '.')
 		{
 			if (line[1] == '\n' ||
 			    (line[1] == '\r' && line[2] == '\n'))
@@ -801,7 +805,7 @@
 			line_len--;
 		}

-		/* Check to see if we have the full line from the fgets() */
+		/* Check to see if we have the full line from fgets() */
 		fullline = FALSE;
 		if (line_len > 0)
 		{
@@ -809,12 +813,11 @@
 			{
 				if (line_len >= 2 &&
 				    line[line_len - 2] == '\r')
-				    {
-					(void) strlcpy(line + line_len - 2,
-						       "\n", sizeof line -
-							     line_len + 2);
+				{
+					line[line_len - 2] = '\n';
+					line[line_len - 1] = '\0';
 					line_len--;
-				    }
+				}
 				fullline = TRUE;
 			}
 			else if (line[line_len - 1] == '\r')
@@ -834,7 +837,7 @@
 			fullline = TRUE;

 #ifdef CONTENTLENGTH
-		if (line[0] == '\n' && HeaderLength == 0)
+		if (prevfl && line[0] == '\n' && HeaderLength == 0)
 		{
 			eline = FALSE;
 			HeaderLength = ftell(fp);
@@ -849,7 +852,7 @@
 			}
 		}
 #else /* CONTENTLENGTH */
-		if (line[0] == '\n')
+		if (prevfl && line[0] == '\n')
 			eline = TRUE;
 #endif /* CONTENTLENGTH */
 		else
@@ -860,10 +863,17 @@
 			eline = FALSE;
 #ifdef CONTENTLENGTH
 			/* discard existing "Content-Length:" headers */
-			if (HeaderLength == 0 &&
+			if (prevfl && HeaderLength == 0 &&
 			    (line[0] == 'C' || line[0] == 'c') &&
 			    strncasecmp(line, ContentHdr, 15) == 0)
-					continue;
+			{
+				/*
+				**  be paranoid: clear the line
+				**  so no "wrong matches" may occur later
+				*/
+				line[0] = '\0';
+				continue;
+			}
 #endif /* CONTENTLENGTH */

 		}

--vkogqOf2sHV7VnPd--
(5038233) ------------------------------------------