Unsafe Signal Handling unix_chkpwd?

From: Charles Stevenson (coreat_private)
Date: Thu May 31 2001 - 18:57:16 PDT

  • Next message: John: "Re: PIX revealing Statics when hit with NMAP..."

    Michal Zalewski wrote:
    
    Hi, great paper.  I just started hammering at all the standard suid binaries
    and at the moment I'm trying to determine if unix_chkpwd is exploitable:
    
    static void _log_err(int err, const char *format,...)
    {
     va_list args;
    
     va_start(args, format);
     openlog("unix_chkpwd", LOG_CONS | LOG_PID, LOG_AUTH);
     vsyslog(err, format, args);
     va_end(args);
     closelog();
    }
    
    There aren't any calls to free() although exit() was not in your list of
    async-signal safe functions so I will make a grand assumption that possibly
    one of the routines in exit()s cleanup could be exploited. Or possibly
    closelog() or va_end().
    
    static void su_sighandler(int sig)
    {
     if (sig > 0) {
      _log_err(LOG_NOTICE, "caught signal %d.", sig);
      exit(sig);
     }
    }
    
    As you can see the signal handler performs syslog calls.  The first thing
    unix_chkpwd does in main() is setup the signal handlers for various signals:
    
    setup_signals();
    
    If the program is run from a TTY device the program happily logs and then
    sleep()s for 10 seconds. I was thinking at first that a signals could be
    sent to cause the signal handler to be re-entered but there's not really any
    way of getting this to overflow as far as I can know.
    
    I actually was able to get around this by sending a SIGABRT which
    immediately terminates the program.  So it may still be possible to brute
    force unix_chkpwd by sending in a password and then a SIGABRT until you get
    it :-).  It's possible to get input to the program by piping the output of
    another program to it:
    
     echo "core is bored" | unix_chkpwd & sleep 1; killall -ILL unix_chkpwd;
    sleep 1; killall -TRAP unix_chkpwd
    
    This doesn't quite work... produces a log entry like this:
    
    May 31 19:04:31 localhost unix_chkpwd[1073]: no password supplied
    
    In any case... back to the nice sleep(10) line...
    
    unix_chkpwd & sleep 1; killall -ILL unix_chkpwd; sleep 1; killall -TRAP
    unix_chkpwd
    [1] 1254
    This binary is not designed for running in this way
    -- the system administrator has been informed
    [1]  + exit 4     unix_chkpwd
    unix_chkpwd: no process killed
    
    It exits too quickly with the sleep.
    
    May 31 19:25:03 localhost unix_chkpwd[1254]: inappropriate use of Unix
    helper binary [UID=1000]
    May 31 19:25:04 localhost unix_chkpwd[1254]: caught signal 4.
    
    So I tried without the sleep:
    
    [-(core@euclid:~)> unix_chkpwd & sleep 1; killall -TRAP unix_chkpwd; killall
    -SEGV unix_chkpwd
    [1] 1266
    This binary is not designed for running in this way
    -- the system administrator has been informed
    [-(core@euclid:~)>
    [-(01-05-31-19:28:22)-]<pts/4>
    [1]  + exit 11    unix_chkpwd
    
    May 31 19:29:53 localhost unix_chkpwd[1288]: inappropriate use of Unix
    helper binary [UID=1000]
    May 31 19:29:54 localhost unix_chkpwd[1288]: caught signal 11.
    
    It does exit with SIGSEGV so I assume the signal handler is getting
    re-entered. Am I wrong?
    
    Running Debian GNU/Linux unstable arch/ppc:
    ii  libpam-modules 0.72-24        Pluggable Authentication Modules for PAM
    
    Any suggestions? Is this impossible to exploit? If you get something going
    I'd appreciate a copy ;-)
    
    Best Regards,
    Charles Stevenson
    
    P.S. This was written in tired haste... forgive the jumps in my train of
    thought :-)
    
    > RAZOR advisory: Unsafe Signal Handling in Sendmail
    >
    >    Issue Date: May 28, 2001
    >    Contact: Michal Zalewski <lcamtufat_private>
    >
    > Topic:
    >
    >    Sendmail signal handlers used for dealing with specific signals are
    >    vulnerable to numerous race conditions.
    >
    > Affected Systems:
    >
    >    Any systems running sendmail (tested on sendmail 8.11.0, 8.12.0-Beta5)
    >
    > Details:
    >
    >    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 (see "References" for more
    >    details on this family of vulnerabilities). 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.
    >
    > Impact:
    >
    >    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.
    >
    > Vendor response / fix info:
    >
    >    From sendmail-securityat_private:
    >
    >    We agree with Michal Zalewski's comments regarding the possibility of
    >    heap corruption due to signal delivery. We 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 we have taken
    >    measures to reduce this possibility in 8.11.4. We 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.
    >
    >    Note that this attack can only be used by a process started by the
    >    user and therefore can not be used as a denial of service attack and
    >    also is not remotely exploitable. The information regarding remote
    >    attacks and SIGURG does not apply to sendmail as SMTP does not use out
    >    of band messages.
    >
    > References:
    >
    >    For more information on signal delivery race conditions, please
    >    refer to RAZOR whitepaper at:
    >
    >      http://razor.bindview.com/publish/papers/signals.txt
    



    This archive was generated by hypermail 2b30 : Thu May 31 2001 - 22:42:43 PDT