Re[2]: mailbox parsing problem in imap-4.7c

2000-08-15T00:00:00
ID SECURITYVULNS:DOC:544
Type securityvulns
Reporter Securityvulns
Modified 2000-08-15T00:00:00

Description

Hello Mark,

I have tested MDAs of different vendors under few OSs. All of them assume empty line to be at the end of message. Most of them comment out "From " in any "\n\nFrom " pattern. At least qpoper and BSD mail check for empty line under any supported OS and I never heard of any problem because of this. If you think this problem isn't serious you can try something like:

perl -e 'print "1\nFrom user Wed Dec 2 05:53:22 1992\n\n"x70000' |\ mail -s "Ooooops" victim

On FreeBSD 3.2 box with 128 MB RAM this ~2.5Mb message causes next situation: then trying to receive this message(s) any tested MUA dies because of memory problems, after that ipop3 process freezes in sbwait state with 99% CPU usage locking ~12Mb of memory. You can try larger messages - I have no test environment :)

P.S. I'm not Unix guru, but I believe it should be standard for Unix mailbox and both MDA and imap must follow standard. A copy of this message sent to sendmail team (as a mail.local developers), I think together you can find a truth - where is the bug :). I left both original message and your reply below.

P.P.S I think if software has some special requirements for delivery agent it should be at least pointed in documentation.

P.P.P.S. The patch is trivial. I'm not sure it fixes all cases but at least it protects against this very exploit.

$ diff -c unix.c.old unix.c unix.c.old Wed Feb 23 03:43:30 2000 --- unix.c Thu Aug 10 12:58:19 2000
** 1048,1053 *
--- 1048,1054 ----
unsigned long i,j,k,m;
char c,
s,t,u,tmp[MAILTMPLEN],date[30];
int ti = 0,pseudoseen = NIL,retain = T;
+ int wasempty;
unsigned long nmsgs = stream->nmsgs;
unsigned long prevuid = nmsgs ? mail_elt (stream,nmsgs)->private.uid : 0; unsigned long recent = stream->recent;
***
1389,1404
k = m = 0; /
no previous line size yet
/
/
note current position
/
j = LOCAL->filesize + GETPOS (&bs);
if (i) do { / look for next message /
s = unix_mbxline (stream,&bs,&i);
if (i) { / got new data? /
! VALID (s,t,ti,zn); / yes, parse line /
if (!ti) { / not a header line, add it to message /
elt->rfc822_size +=
k = i + (m = (((i < 2) || s[i - 2] != '\r') ? 1 : 0));
/ update current position /
j = LOCAL->filesize + GETPOS (&bs);
}
}
} while (i && !ti); / until found a header /
elt->private.msg.text.text.size = j -
--- 1390,1408 ----
k = m = 0; / no previous line size yet /
/ note current position /
j = LOCAL->filesize + GETPOS (&bs);
+ wasempty = 1;
if (i) do { / look for next message /
s = unix_mbxline (stream,&bs,&i);
if (i) { / got new data? /
! if (wasempty) VALID (s,t,ti,zn); / yes, parse line /
if (!ti) { / not a header line, add it to message /
elt->rfc822_size +=
k = i + (m = (((i < 2) || s[i - 2] != '\r') ? 1 : 0));
/ update current position /
j = LOCAL->filesize + GETPOS (&bs);
}
+ if ( s == '\n') wasempty = 1;
+ else wasempty = 0;
}
} while (i && !ti); /
until found a header */
elt->private.msg.text.text.size = j -

Thursday, August 10, 2000, 12:59:48 AM, you wrote:

MC> Thank you very much for your message.

MC> Unfortunately, although "blank line before the From header" is a very common MC> convention, it is not universal. There are MDAs which do not guarantee a MC> blank line before the From header.

MC> Consequently, if I were to "fix this bug", I would create a different bug with MC> messages being missed.

MC> The only time this ever becomes a security problem is if the MDA tries to be MC> clever, by not writing a ">" quoting character if there is no blank line in MC> front of a line that appears to be a From header.

MC> There is another alternative, and I recommend this alternative:

MC> The MDA should not be so clever. The MDA should always quote all lines which MC> appear to be a From header, regardless of whether or not there is a blank line MC> in front of it.

MC> Legitimate messages with lines that look like a From header are very rare. It MC> is alright if the MDA omits the quoting if the line begins with "From " but MC> otherwise does not look like a From header; for example, a line starting with MC> text such as "From this example, you can see..."). However, it should always MC> quote lines that match the syntax of a From header.

MC> I hope that this answer is satisfactory for you. I agree that you have MC> brought up a valid issue, and that MDA authors should consider it.

Title: mailbox parsing problem Security risk: low to average Impact: malicious users can spoof e-mail headers, bypass virus checks, etc. Affected software: imap-4.7c and prior versions. Discovered: agk@sandy.ru, 3APA3A@SECURITY.NNOV.RU

Details:

There is a bug in Unix mailbox parsing. Next message in mailbox determined only by format of "From " string. No check is made about previous line to be empty. This allows malicious user to create fake "From " line and RFC 822 headers. This faked message will not be tested by delivery software before passing to MUA. This allows to bypass virus protection, protection against vulnerabilities in MUAs (such as "Date: " in Outlook).

Problem is in unix.c. Then "From " header is checked there is no any checks for previous line to be empty:

s = unix_mbxline &#40;stream,&amp;bs,&amp;i&#41;;
t = NIL,zn = 0;
if &#40;i&#41; VALID &#40;s,t,ti,zn&#41;; /* see if valid From line */
if &#40;!ti&#41; {                /* someone pulled the rug from under us */

Exploitation: message with a structure like: (anytext) (valid From field without newline, f.e. From user Wed Dec 2 05:53:22 1992) (faked RFC Header)

(faked body)

Test follows: From user Wed Dec 2 05:53:22 1992 Received: from evil hacker From: test To: test Date: Tue, 08 Aug 2000 11:45:26 -0700000000000

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