.pt zine - Utilitário de cracking para DOS - word

Utilitário de cracking para DOS - word:
-----------------------------------------------
by Elektro

ATENÇÃO: O CÓDIGO DESTE PROGRAMA NÃO É PORTÁVEL PARA SISTEMAS LINUX!!!!
FOI 100% DESENVOLVIDO EM SISTEMA MS-DOS (TURBO C), E OCORRERÃO ERROS DE EXECUÇÃO, QUANDO EXECUTADO NOUTROS SISTEMAS (LINUX)!

Como já disse num artigo anterior, no número anterior da .pt zine no que trata a cracking, é na minha opinião, uma perda de tempo orientar esforços, em termos de programação, para a construção de um cracker! A não ser que se trabalhe directamente em assembly, dificilmente se obterá, com as ferramentas mais usuais, uma melhoria significativa, em termos de velocidade.

Como toda a gente sabe um cracker, apenas encripta possiveis passwords, e compara o resultado final com a entrada da password encriptada,...se coincidirem...Bingo!

Podem então ver que realmente é uma perda de tempo estar a tentar desenvolver ferramentas, neste sentido, e será mais práctico investir tempo e esforço, em aplicações que produzam as tais possiveis e provaveis passwords!
Logo daqui se pode criar uma máxima: No que toca a password cracking em linux, o que interessa é ter uma boa wordlist!!

Existem já muitas aplicações, incluindo crackers, que criam as próprias wordlists, baseados, por exemplo, nas entradas gecos.

A dificuldade porem e arranjar uma aplicação, que reuna uma quantidade razoavel de critérios de origem e alteração, de possiveis passwords!!!

Foi então que num flash, que me surgiu a ideia de criar uma aplicação que a partir de um ficheiro passwd, criasse uma wordlist, cujas strings fossem "retiradas", da entrada username, e gecos e dessas entradas gerar um número razoável de variações dessas entradas!!!(Pois são a partir destas entradas, que os utilizadores criam as suas passwords!! Apesar dos muitos apelos, dos SysAdm, a teoria de usar por exemplo o username invertido, ou o nome proprio, como passwords continua a ser o pão nosso de cada dia, nos sistemas informaticos multi-user!). Mas o grande objectivo desta aplicação, é tentar reunir o máximo de critérios possiveis e imaginários, e ir adicionando ao código uns novos,...para que seja possivel testar o máximo número possivel de variantes de uma string.

O que esta aplição faz é o seguinte:

  - Divide a string correspondente à entrada gecos em varias strings. Ex:
  o resultado será uma matriz:
  Maior
  Lame
  Imaginario

  A estas novas strings adiciona a entrada username.

  - Depois estas strings serão sujeitas a um "tratamento", em que serão criadas novas strings...,tais como a inversao,a concatenação, e alguns mais conhecidos,...e outros menos usados mas que tambem produzem resultados positivos, tais como o acrescento do ano corrente etc...

  Por exemplo, a entrada dum ficheiro passwd: Username:e4\3dkr.4aqCO:502:100:Maior Lame Imaginario:/home/lame:shell

  Criará as seguintes passwords:

          Username
          USERNAME
          username
          emanresU
          UsernameUsername
          Username97
          Maior
          MAIOR
          maior
          Mai0r
          roiaM
          Maior97
          Lame
          LAME
          lame
          emaL
          Lame97
          Imaginario
          IMAGINARIO
          imaginario
          Imaginari0
          oiranigamI
          Imaginario97

  19 passwords geradas a partir de 1 entradas.

  Ou seja, os critérios que para já estão definidos no programa são:

  - a própria string em si
  - todos os caracteres em maiusculas
  - todos os caracteres em minusculas
  - substituição (caso existam) dos 'o' ou 'O' por 0 (zeros)
  - inversão da string
  - adição do ano corrente a string
  - a concatenação do username (UsernameUsername)
  - caso o 1º caracter seja maius. passará a minus. e vice-versa

  Como se pode ver a partir das strings "Username", "Maior", "Lame", "Imaginario", foram criadas 19 novas strings, possiveis passwords!

  Strings com menos de três letras serão ignoradas, porem isto pode ser alterado,....basta alterar o valor de PASS_MIN_LEN.

  No final, o programa dará informações, no que toca ao número de entradas, passwords geradas, contas desactivadas e sem password.

  AVISO: O CÓDIGO DESTE PROGRAMA PODERÁ (AFINAL ESSE É O OBJECTIVO) SER ALTERADO, DESDE QUE A ALTERAÇÃO SEJA PARA ACRESCENTAR MAIS CRITÉRIOS, E NUNCA PARA O TORNAR MENOS COMPLETO...AGRADECIA QUE SEMPRE QUE ALTERASSEM O CÓDIGO, OU TIVESSEM SUGESTÕES ME ENVIASSEM UM MAIL PARA: elektro@kaotik.complex-x.net

  Junto vai o binário deste utilitario para quem nao possui um compilador de C para ms-dos.

  word.exe

  ----------------------------- CORTE POR AQUI --------------------------------

      #include <stdio.h>
      #include <string.h>
      #include <signal.h>
      #include <time.h>

      #define SIM 1
      #define NAO 0
      #define PASS_MIN_LEN 3

      char matriz[15][20];

      struct passwd{
      	      char pw_name[10];
      	      char pw_passwd[14];
      	      int  pw_uid;
      	      int  pw_gid;
      	      char pw_gecos[40];
      	      char pw_dir[40];
      	      char pw_shell[20];
      	      };

      struct passwd *getpwent(char *fn);
      char *minus_maiusc(char *passwd);
      char *maiusc_minus(char *passwd);
      char *o_0(char *passwd);
      int testa_o_0(char *passwd);
      int testa_minus_maius(char *passwd);
      char *maius_minus_todo(char *passwd);
      char *inverte(char *passwd);
      char *concatena(char *passwd);
      void sinal(void);

      		         /*  COMECO DA FUNCAO MAIN   */

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

      int entradas=0,
          contas_desactivadas=0;

      unsigned int passwds=0;

      short int i,
      	  numero,
      	  login_sem_passwd=0;

      struct passwd *p;
      struct tm *tempo;

      time_t *apontador;

           if( argc!=2 ){
      		   printf("Uso: %s \n", argv[0]);
      		   exit(0);
      		  }

           signal(SIGINT, sinal);

           time(apontador);
           tempo=gmtime(apontador);

           while((p=(struct passwd*) getpwent(argv[1]))!=NULL)
           {

      	  if( p->pw_passwd[0]=='*'){
      	       if(strcmp(p->pw_passwd, "*")==0)
      			  continue;
      				   else{
      					contas_desactivadas++;
      				        continue;
      					}
      				    }
      	  if( strlen(p->pw_passwd)!=13)
      		   if(strcmp(p->pw_passwd, "x")==0) ;
      		     else{
      		          login_sem_passwd++;
      		          continue;
      		         }

      	  entradas++;

      		 printf("%s\n", p->pw_name);
      	  if(testa_minus_maius(p->pw_name)==NAO){
      		 printf("%s\n", minus_maiusc(p->pw_name));
      		 passwds++;
      		}
      		 printf("%s\n", maiusc_minus(p->pw_name));
      	  if( (testa_o_0(p->pw_name))==SIM ){
      		 printf("%s\n", o_0(p->pw_name));
      		 passwds++;
      	        }
      	  if( testa_minus_maius(p->pw_name)==SIM){
      		 printf("%s\n", maius_minus_todo(p->pw_name));
      		 passwds++;
      	        }
      		 printf("%s\n", inverte(p->pw_name));
      		 printf("%s\n", concatena(p->pw_name));
      		 printf("%s%d\n", p->pw_name, tempo->tm_year);
      		 passwds+=4;

      	  if( strcmp(p->pw_name, p->pw_gecos)==0)
      					    continue;

           numero=strdiv(p->pw_gecos);
           for(i=0; i<=numero; i++){
      		    printf("%s\n", matriz[i]);
      	  if(testa_minus_maius(matriz[i])==NAO){
      		    printf("%s\n", minus_maiusc(matriz[i]));
      		    passwds++;
      		   }
      		    printf("%s\n", maiusc_minus(matriz[i]));
      	  if( (testa_o_0(matriz[i]))==SIM){
      		    printf("%s\n", o_0(matriz[i]));
      		    passwds++;
      		   }
      	  if( testa_minus_maius(matriz[i])==SIM){
      		    printf("%s\n", maius_minus_todo(matriz[i]));
      		    passwds++;
      		   }
      		    printf("%s\n", inverte(matriz[i]));
      		    printf("%s%d\n", matriz[i], tempo->tm_year);
      		    passwds+=3;
      			      }
      		 }

      printf("\n%d passwords geradas a partir de %d entradas.\n", passwds,entradas);
      printf("%d logins sem password atribuida.\n", login_sem_passwd);
      printf("%d conta(s) desactivadas.\n", contas_desactivadas);

       }

      		       /* FIM DA FUNCAO MAIN */

      	    /* funcao que carrega as entradas do ficheiro */

      struct passwd *getpwent(char *fn)
      {
      static FILE *f = NULL;
      static struct passwd p;
      char s[200];
      int l;

      	if(f == NULL)
      		if((f = fopen(fn,"r")) == NULL){
      			perror("Erro no ficheiro");
      			return NULL;
      		}

      	for(;;){
      		if(fgets(s,200,f)==NULL){
      			fclose(f);
      			f = NULL;
      			return NULL;
      		}

      		l = strlen(s)-1;

      		s[l] = '\0';

      		if(l == 0)
      			continue;

      		p.pw_name[0]	= '\0';
      		p.pw_passwd[0]	= '\0';
      		p.pw_gecos[0]	= '\0';
      		p.pw_dir[0]		= '\0';
      		p.pw_shell[0]	= '\0';

      		strncat(p.pw_name,strtok(s,":"),9);
      		strncat(p.pw_passwd,strtok(NULL,":"),13);
      		sscanf(strtok(NULL,":"),"%d",&p.pw_uid);
      		sscanf(strtok(NULL,":"),"%d",&p.pw_gid);
      		strncat(p.pw_gecos,strtok(NULL,":"),39);
      		strncat(p.pw_dir,strtok(NULL,":"),39);
      		strncat(p.pw_shell,strtok(NULL,":"),20);
      		return &p;
      	}
      }
                 /* Funcao que coloca as palavras de uma string na matriz */

      int strdiv(char *vector){
      int LINHAS,COLUNAS,COLUNAS2=0;

         for(LINHAS=0;;LINHAS++){
             for(COLUNAS=0;;COLUNAS++){
                if(vector[COLUNAS2]=='\0'){
                               matriz[LINHAS][COLUNAS]='\0';
      			 return(LINHAS);
                                     }
                if(vector[COLUNAS2]==32 && vector[COLUNAS2+1]!=32)
                  {
                   COLUNAS2++;
                   break;
                   }

                matriz[LINHAS][COLUNAS]=vector[COLUNAS2];
                COLUNAS2++;
                  }
      		 matriz[LINHAS][COLUNAS]='\0';
      		 if( strlen(matriz[LINHAS])=97 && temp[i] <=122 )
      				     temp[i]=temp[i]-32;
      		}
      	}

      char *maiusc_minus(char *passwd){
      static char temp2[20];
      int i;

      strcpy( temp2, passwd);

            if( temp2[0]>=65 && temp2[0]<=90)
      	  temp2[0]=temp2[0]+32;
      			 else
      			   if( temp2[0]>=97 && temp2[0] <=122)
      			     temp2[0]=temp2[0]-32;
                             return temp2;
      	       		}

      char *o_0(char *passwd){
      static char temp3[20];
      int i;

      strcpy( temp3, passwd);

      	for(i=0;;i++){
      		if( temp3[i]=='\0' )
      			   return temp3;
      		if(temp3[i]=='o' || temp3[i]=='O')
      			   temp3[i]='0';
      				  }
      		}

      int testa_o_0(char *passwd){
      int i;

            for(i=0;;i++){
      	      if(passwd[i]=='\0')
      			      break;
      	      if(passwd[i]=='o' || passwd[i]=='O')
      			      return(SIM);
      		    }
      			      return(NAO);
      	       }

      int testa_minus_maius(char *passwd){
      int i;

        for(i=0;;i++){
      	    if( passwd[i]=='\0')
      			    break;
      	    if( passwd[i]>90 )
      			    return(NAO);
      		}
      		            return(SIM);
      	     }

      char *maius_minus_todo(char *passwd){
      static char temp4[20];
      int i;

      strcpy( temp4, passwd);

           for(i=0;;i++){
      	   if(temp4[i]=='\0')
      			 return temp4;
      	   if(temp4[i]>=65 && temp4[i]<=90)
      			 temp4[i]=temp4[i]+32;
      		 }
      	 }

                     /*  Funcao que inverte uma string  */

      char *inverte(char *passwd){
      static char temp5[20];
      int i,tamanho;
      char temp;

      strcpy( temp5, passwd);
      tamanho=strlen(temp5);

      	  for(i=0; i<(tamanho/2); i++){
      											 temp=temp5[i];
      											 temp5[i]=temp5[(tamanho-1)-i];
      											 temp5[(tamanho-1)-i]=temp;
      											 }
      	  return temp5;
      	  }

                      /*  Funcao que concatena duas strings  */

      char *concatena(char *passwd){
      static char temp6[20];
      int tamanho;

      strcpy( temp6, passwd);
      strcat( temp6, passwd);
      return temp6;
      }

                      /*  Funcao que lida com o sinal Ctrl-C  */

      void sinal(void){
      char opcao;

        printf("\n(s)air? ENTER para continuar: ");
        opcao=getchar();

        switch(opcao){
      		  case 's': exit(0);
      		  default : return;
      				}
      }