Vulnerability Development mailing list archives
Re: exim remote heap overflow, probably not exploitable
From: Nick Cleaton <nick () cleaton net>
Date: Wed, 3 Sep 2003 20:11:27 +0100
On Mon, Sep 01, 2003 at 07:00:34AM +0100, Nick Cleaton wrote:
Exim (www.exim.org) is a message transfer agent (MTA) developed at the University of Cambridge for use on Unix systems connected to the Internet. There's a heap overflow in all versions of exim3 and exim4 prior to version 4.21. It can be exercised by anyone who can make an SMTP connection to the exim daemon. The overflow is very limited, and in my opinion it's probably not exploitable. However, it's possible that this will prove to be exploitable for arbitrary command execution on some platforms in some circumstances. Patches: http://www.exim.org/pipermail/exim-announce/2003q3/000094.html Full details coming soon to vuln-dev.
At line 1972 of exim-4.20/src/smtp_in.c : if (*smtp_data == 0) Ustrcpy(smtp_data, "(no argument given)"); 'smtp_data' is a pointer into the 513 byte heap buffer 'cmd_buffer'. A carefully formatted HELO or EHLO command can arrange for '*smtp_data' to be 0 and for 'smtp_data' to be within 2 bytes of the end of 'cmd_buffer', so that the string "o argument given)" followed by a NULL is written off the end of cmd_buffer. Consider an input line consisting of "HELO" followed by 506 spaces followed by a NULL then a newline. This is the longest input line that this loop at line 441 will accept: while ((c = (receive_getc)()) != '\n' && c != EOF) { if (ptr >= cmd_buffer_size) { os_non_restarting_signal(SIGALRM, sigalrm_handler); return OTHER_CMD; } cmd_buffer[ptr++] = c; } Now the code at line 462 removes any trailing whitespace from the buffer and NULL terminates it: while (ptr > 0 && isspace(cmd_buffer[ptr-1])) ptr--; cmd_buffer[ptr] = 0; but it doesn't trim all our spaces because the NULL we put at the end of the line protects them. At this point the buffer is mostly full of spaces, but the last two chars in the buffer are NULLs. Now smtp_data is pointed to the character after the HELO command, and then advanced over any whitespace by this code at line 508: while (isspace(*smtp_data)) smtp_data++; after which smtp_data points to the NULL at byte 511 of cmd_buffer. We can, of course, choose to use less space characters so as to write less far off the end of the buffer. So, we can write a single NULL up to 18 bytes off the end of the buffer, with the side effect of writing ASCII over everything up to the NULL. Papers such as http://www.phrack.org/show.php?p=57&a=8 and http://bespin.org/~qitest1/txt/heap_off_by_one.txt.asc suggest that it might well be exploitable under linux. My main reason for rating this as "probably not exploitable" even under Doug Lea's malloc is that the 513 byte buffer is never free()ed, and neither is the 8192 byte buffer that gets malloc()ed immediately after the 513 byte buffer. A quick scan of the exim sources didn't find much in the way of free() calls on buffers over 512 bytes in any code that runs in normal circumstances before these two buffers get allocated, so I'm imagining that it's likely that they'll both come off the wilderness chuck. The relevant part of the heap will then look something like: 513ByteBuffer CorruptBoundaryTag 8192ByteBuffer and the corrupt boundary tag will never be accessed since the chunks before and after it are never free()ed. Does that seem reasonable, or am I in dreamland ? Can anyone get as far as a segfault on some platform ? -- Nick Cleaton nick () cleaton net
Current thread:
- Re: exim remote heap overflow, probably not exploitable Nick Cleaton (Sep 03)