COMMAND
Sendmail
SYSTEMS AFFECTED
Any systems running sendmail (tested on sendmail 8.11.0, 8.12.0-Beta5)
PROBLEM
Following is based on a RAZOR advisory by Michal Zalewski.
Sendmail signal handlers used for dealing with specific signals
are vulnerable to numerous race conditions.
Sendmail signal handlers used for dealing with specific signals
(SIGINT, SIGTERM, etc) are vulnerable to numerous race conditions,
including handler re-entry, interrupting non-reentrant libc
functions and entering them again from the handler. This set of
vulnerabilities exist because of unsafe library function calls
from signal handlers (malloc, free, syslog, operations on global
buffers, etc).
As sendmail is setuid root and can be invoked by user, and -
moreover - keeps running with root privileges almost all the time,
there is no problem with delivering signals at a specific moment.
It is worth mentioning that not only sendmail is suspectible to
have this kind of problems. Moreover, in some situations, unsafe
signal handlers can be even exploited remotely, by delivering
SIGURG over TCP stream (OOB message). Whenever SIGURG is handled
in remote daemons in verbose way using unsafe functions, this is
an exploitable condition. Note, sendmail is not vulnerable to
this.
One of the attack paths we can see is delivering SIGTERM while
sendmail is working in 'verbose debugging' mode (-d switch).
SIGTERM handler works less or more this way:
- ...
- syslog(...) call with user-dependent information
- ...
- fclose(...)
- free(...)
- free(...)
- ...
- exit(...)
This is important that syslog() function effectively calls
malloc() code to allocate a temporary buffer. As exactly the same
handler is used for SIGINT, and there is no re-entry protection in
this handler, we can reach appropriate (usually the second) free()
call, and deliver SIGTERM. Then, already free()d memory will be
overwritten with user-dependent data from syslog() buffer, as new
memory chunk would fit in the place of free()d buffers. Then,
duplicate free() attempt on the memory region containing
user-dependent data will be performed, which would lead to program
execution path compromise. This is a difficult race, but can
be attempted numerous times.
Note that avoiding re-entry into signal handler is not the only
thing that has to be done. Other possibilities include e.g.
re-entering functions like malloc() - in this case, signal has to
be delivered only once, in the middle of malloc() call. That
would lead to heap corruption. Any functions that are not
reentrant should be protected in a special way or not used at all
in signal handlers.
SOLUTION
Sendmail team agrees with Michal Zalewski's comments regarding
the possibility of heap corruption due to signal delivery. They
do not believe the heap corruption to be easily exploitable due
to the complexity involved with timing and the little control the
user has over the contents of memory in the signal handler. This
is different than buffer overflows attacks which occur on the
stack and allow users to insert specific instructions at a known
location. At the present time, there is no proof that this is
exploitable as there are no known exploits.
However, the corruption could crash the process and they have
taken measures to reduce this possibility in 8.11.4. They have
eliminated the ability to reenter a signal handler making the
attack discussed above impossible. Additionally, sendmail 8.12
will no longer require a set-user-id root binary:
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.11.4.tar.gz
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.11.4.tar.Z
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.12.0.Beta10.tar.gz
ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.12.0.Beta10.tar.Z
For more information on signal delivery race conditions, please
refer to RAZOR whitepaper at:
http://oliver.efri.hr/~crv/security/bugs/mUNIXes/krnl202.html
http://razor.bindview.com/publish/papers/signals.txt