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;
				}
}