home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / perl / pass.chk < prev    next >
Text File  |  1992-03-10  |  7KB  |  275 lines

  1. #!/bin/sh -- need to mention perl here to avoid recursion
  2. 'true' || eval 'exec perl -S $0 $argv:q';
  3. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
  4. & eval 'exec /usr/local/bin/perl -S $0 $argv:q'
  5.         if 0;
  6.  
  7. #
  8. #  Pass.chk -- a password guesser.  Functionally equivalent to the original
  9. # cops password guesser.  The -P option doesn't work right now (alpha release,
  10. # don't you know :-), since we're doing funky things with password caching,
  11. # but this will change soon.
  12. #
  13. #  Usage: $0 [options] dictionary
  14. #
  15. #    -P pfile    password file (not working)
  16. #    -p        print found passwords (incompatible with -M)
  17. #       -d        check prefix/suffix of digits [0-9]
  18. #       -g        check all words in gcos, plan, project, signature files
  19. #    -r         reverse the word tests
  20. #    -s         check all single chars as passwords
  21. #    -u         output the current user being checked
  22. #    -U         try uppercase word tests
  23. #    -v        verbose, print advisory information
  24. #    -x         check guess+prefix/suffix with strange chars added on
  25. #    -0 (zero)    change all o's ("oh"'s) to 0 (zeros)
  26. #    -1 (one)    change all i's to 1 (ones)
  27. #    -m         misspell words -- chop off first and last chars,
  28. #            if > 3 chars.  E.g. "dinner" ==> "inner" and "dinne"
  29. #
  30. # Originally written by Tim Tessin with lots more features, etc., etc., etc.
  31. # I ripped out all of his extra functionality that duplicated some of the
  32. # other cops stuff, and some things that just didn't fit, and added some
  33. # code to finish the simulation of the old checker. -- dan
  34.  
  35. require "getopts.pl";
  36. # can probably just do "|| &usage;" since &usage is only used once. ;-)
  37. &Getopts("p0dgrsuUv1P:mx") || print STDERR "Usage: $0 -p0xdgrsuUPvm\n";
  38.  
  39. # diff password file?
  40. if (defined($opt_P)) { $'GET_PASSWD = "/bin/cat $opt_P"; }
  41. require "pass.cache.pl";
  42.  
  43. $Passwd = "/etc/passwd";
  44. @strange_things = (" ", ";", ",", ".", "!", "@", "#", "$",
  45.                      "%", "^", "&", "*", "(", ")", "-", "_", 
  46.                      "=", "+", "[", "]", "{", "}", "'", "\"",
  47.                      "|", "`", "~", ">", "<");
  48.  
  49. # unbuffer output
  50. select (STDOUT); $| = 1;
  51.  
  52. $dups = 0;        # duplicate name entries
  53. $new = 0;        # new entries
  54. $changed = 0;        # password (and other data) changed
  55. $deleted = 0;        # deleted entries
  56. $updated = 0;        # data other than password changed
  57. $nlog = 0;        # number of log entries, used for print decisions
  58. $ntest = 0;
  59. $ndone = 0;
  60.  
  61. for $uid (keys %uname2passwd) {
  62.     next if length($pass = $uname2passwd{$uid}) != 13;
  63.     next unless $pass; # shall we report null passwd's, too?  ;-)
  64.     if ($try = &dopwd()) {
  65.         $pwd = ($opt_p) ? $try : "";
  66.         # printf "Username: %-8s  <password guessed>  $pwd\n",$P[0];
  67.         printf "Warning!  $uid password Problem: Guessed: %s\t\t$pwd\n",$P[0];
  68.         }
  69.     $ndone++;
  70.     }
  71.  
  72. 1;
  73. # end of program
  74.  
  75.  
  76. ######################## Support Subroutines ###########################
  77. # dopwd tests each password entry against several simple checks and all
  78. # the words in the dictionaries specified.  The simple checks consists
  79. # of trying the username as the password ('joe' accounts), words derived
  80. # from the gecos fields (usually first and last names).
  81.  
  82. sub dopwd {
  83.     $tries = 0;
  84.  
  85.     print "$uid\n" if ($opt_u);
  86.  
  87.     # try user name
  88.     ($try = &testpwd($uid,$pass)) && return $try;
  89.     # try uiduid
  90.     if (length($uid) < 8) {
  91.     ($try = &testpwd($uid . $uid,$pass)) && return $try;
  92.     }
  93.  
  94.     # do gcos field?
  95.     if ($opt_g) {
  96.     @gcos = split(/[.,& -]/,$uname2gcos{$uid});
  97.     foreach $i (@gcos) {
  98.         next unless $i;        # skip null split values
  99.         ($try = &testpwd($i,$pass)) && return $try;
  100.     }
  101.  
  102.     # Try names from misc files
  103.     #
  104.     undef %words;
  105.     # files to check
  106.     @files2chk = ("/.project", "/.plan", "/.signature");
  107.     $home = $uname2dir{$uid};
  108.     for $i (@files2chk) {
  109.         open (FOOFILE, $home . $i);
  110.         while (<FOOFILE>) {
  111.         chop;
  112.         @line = split(/([.,;\s])/);
  113.         for $j (@line) {
  114.             $words{$j}=$j unless $j=~/[\s]/;
  115.         }
  116.         }
  117.         close FOOFILE;
  118.     }
  119.     for $k (values %words) {
  120.         # print "word $k\n";
  121.         ($try = &testpwd($k,$pass)) && return $try;
  122.     }
  123.     }
  124.  
  125. # do dictionaries
  126. # save state of upper/reverse so individual dicts can temporarily
  127. # override.
  128. foreach $i (@ARGV) {
  129.     if (open (DICT,$i)) {
  130.         while (<DICT>) {
  131.             chop;
  132.             if ($try = &testpwd($_,$pass)) {
  133.                 close DICT;
  134.                 return $try;
  135.                 }
  136.             }
  137.         close DICT;
  138.         }
  139.     }
  140. return 0;
  141. }
  142.  
  143.  
  144. # small subroutines to help the main password cracker.  All are labeled
  145. # p_xxx, where xxx is the identifying name.
  146. #
  147.  
  148. # if leading character is upper-case, also try lower case version
  149. sub p_lc {
  150.     local($try) = @_;
  151.     local($ntry);
  152.     if ( $try =~ /^[A-Z]/ ) {
  153.     ($ntry = $try) =~ y/A-Z/a-z/;
  154.     push(@total_guesses, $ntry);
  155.     }
  156. }
  157.  
  158. # reverse check
  159. sub p_rev {
  160.     local($try) = @_;
  161.     local($ntry);
  162.     $ntry = reverse $try;
  163.     if ($ntry ne $try) {
  164.     push(@total_guesses, $ntry);
  165.     }
  166. }
  167.  
  168. # uppercase check
  169. sub p_up {
  170.     local($try) = @_;
  171.     local($ntry);
  172.     ($ntry = $try) =~ y/a-z/A-Z/;
  173.     if ($ntry ne $try) { push(@total_guesses, $ntry); }
  174. }
  175.  
  176. # testpwd checks a word to see if it matches the encrpted password
  177. # if the word is capitalized, the lowercase version is tried as well
  178.  
  179. sub testpwd {
  180. local ($try,$pass) = @_;
  181. local (@total_guesses);
  182.  
  183. push(@total_guesses, $try);
  184.  
  185. # free (lower case) check if first letter is uppercase
  186. &p_lc($try);
  187. # reverse?
  188. if ($opt_r) { &p_rev($try); }
  189. # uppercase?
  190. if ($opt_U) { &p_up($try); }
  191.  
  192. # single digit tacked on to beginning and end
  193. if ($opt_d) {
  194.     if (length ($try) < 8) {
  195.         foreach $i ('0'..'9') {
  196.             $ntry = $i.$try;
  197.             push(@total_guesses, $ntry);
  198.             if ($opt_r) { &p_rev($ntry); }
  199.             if ($opt_U) { &p_up($ntry); }
  200.             }
  201.         foreach $i ('0'..'9') {
  202.             $ntry = $try.$i;
  203.             push(@total_guesses, $ntry);
  204.             if ($opt_r) { &p_rev($ntry); }
  205.             if ($opt_U) { &p_up($ntry); }
  206.             }
  207.         }
  208.     }
  209.  
  210. # change o's to 0's ("oh"'s to zeros)
  211. if ($opt_0) {
  212.     if (($ntry = $try) =~ s/o/0/g) { push(@total_guesses, $ntry); }
  213.     }
  214. if ($opt_1) {
  215.     if (($ntry = $try) =~ s/i/1/g) { push(@total_guesses, $ntry); }
  216.     }
  217.  
  218. # misspell words -- truncate first and last letter, if > 3 chars
  219. # thanks to  William Vajk, learn@ddsw1.MCS.COM, who posted this idea.
  220. if ($opt_m) {
  221.     $len = length($try);
  222.     if ($len > 3) {
  223.         ($ntry = $try) =~ s/^.//; push(@total_guesses, $ntry);
  224.         if ($len < 9) {
  225.             ($ntry = $try) =~ s/.$//; push(@total_guesses, $ntry);
  226.             }
  227.         }
  228.     }
  229.  
  230. # weird things!  Tacked on to beginning and end
  231. if ($opt_x) {
  232.     if (length ($try) < 8) {
  233.         foreach $i (@strange_things) {
  234.             $ntry = $i.$try;
  235.             push(@total_guesses, $ntry);
  236.             if ($opt_r) { &p_rev($ntry); }
  237.             if ($opt_U) { &p_up($ntry); }
  238.             }
  239.         foreach $i (@strange_things) {
  240.             $ntry = $try.$i;
  241.             push(@total_guesses, $ntry);
  242.             if ($opt_r) { &p_rev($ntry); }
  243.             if ($opt_U) { &p_up($ntry); }
  244.             }
  245.         }
  246.     }
  247.  
  248. # do single letters, #'s, if needed
  249. if ($opt_s && $uid ne $last_user) {
  250.     $last_user = $uid;
  251.     foreach $i (@strange_things) { push(@total_guesses,$i); }
  252.     foreach $i (0..9) { push(@total_guesses, $i); }
  253.     foreach $i (A..Z) { push(@total_guesses, $i); }
  254.     foreach $i (a..z) { push(@total_guesses, $i); }
  255.     }
  256.  
  257. if ($opt_v) {
  258.     foreach $i (@total_guesses) {
  259.         print "Trying \"$i\" on $uid\n";
  260.         $epw = crypt($i,$pass);
  261.         ($epw eq $pass) && return $i;
  262.         }
  263.     }
  264. else {
  265.     foreach $i (@total_guesses) {
  266.         $epw = crypt($i,$pass);
  267.         ($epw eq $pass) && return $i;
  268.         }
  269.     }
  270. undef @total_guesses;
  271.  
  272. return 0;
  273. }
  274.