home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3920 / ypcrack < prev   
Encoding:
Text File  |  1991-08-28  |  5.1 KB  |  170 lines

  1. #!/usr/local/bin/perl
  2. # ypcrack: AJCD 27/8/91
  3. #
  4. # Crack passwords in YP password file incrementally; warns users and system
  5. # manager about cracked passwords.
  6. # Usage: ypcrack [-debug] [-crack] [-verbose] [-mail sysmgr]
  7.  
  8. $prog = $0; $prog =~ s%.*/%%;
  9. $dir = $0; $dir =~ s%/[^/]*$%%;
  10.  
  11. chdir ($dir) || die "$0: can't chdir to $dir\n";
  12.  
  13. $debug = 0;            # testing?
  14. $crack = 0;            # if testing, do we still crack properly?
  15. $verbose = 0;            # talk about it?
  16. $mail = "faults";        # who to mail report to
  17.  
  18. while ($_ = shift(@ARGV)) {
  19.    if (/^-d(ebug)?$/)       { $debug = 1; }
  20.    elsif (/^-c(rack)?$/)    { $crack = 1; }
  21.    elsif (/^-v(erbose)?$/)  { $verbose = 1; }
  22.    elsif (/^-m(ail)?$/)     { $mail = shift(@ARGV); }
  23.    else {
  24.       print STDERR "Usage: $prog [-debug] [-verbose] [-mail sysmgr] [-crack]\n";
  25.       exit 1;
  26.    }
  27. }
  28.  
  29. sub onfield {
  30.    local(@one) = split(/:/, $a);
  31.    local(@two) = split(/:/, $b);
  32.    return ($one[0] cmp $two[0]);
  33. }
  34.  
  35. sub mail {
  36.    local($to) = shift(@_);
  37.    local($subject) = shift(@_);
  38.    local($temp) = "/tmp/$prog.$$";
  39.    open(TEMP, ">$temp") || die "$prog: can't open temp file $temp\n";
  40.    print TEMP @_, "\n";
  41.    close(TEMP);
  42.    if ($debug) {
  43.       print STDERR "To: $to\n", "Subject: $subject\n";
  44.       system ("cat <$temp");
  45.    } else {
  46.       system ("mail -s $subject $to < $temp");
  47.    }
  48.    unlink($temp) || die "$prog: can't remove temp file $temp\n";
  49. }
  50.  
  51. if (! $debug) {
  52.    print STDERR "Getting new password file\n" if ($verbose);
  53.    rename("passwd", "passwd.old"); # ignore failure
  54.    system("ypcat passwd >passwd")/256 && die "$prog: ypcat failed: $!\n";
  55. }
  56.  
  57. print STDERR "Sorting passwd\n" if ($verbose);
  58. open(PASSWD, "passwd") || die "$prog: can't open passwd\n";
  59. @passwd = <PASSWD>;
  60. close(PASSWD);
  61. @passwd = sort onfield @passwd;
  62.  
  63. if (open(PASSWD, "passwd.old")) {
  64.    print STDERR "Sorting passwd.old\n" if ($verbose);
  65.    @oldpasswd = <PASSWD>;
  66.    close(PASSWD);
  67.    @oldpasswd = sort onfield @oldpasswd;
  68. } else {
  69.    @oldpasswd = ();
  70. }
  71.  
  72. print STDERR "Reading previously cracked accounts\n" if ($verbose);
  73. if (open(CRACKED, "cracked.last")) {
  74.    @lasttime = <CRACKED>;
  75.    close(CRACKED);
  76. } else {
  77.    @lasttime = ();
  78. }
  79.  
  80. @diffs = ();
  81. $newp = 1;            # new passwd entry required
  82. print STDERR "Differencing passwd and passwd.old\n" if ($verbose);
  83. foreach $entry (@passwd) {
  84.    ($name,$pwd) = split(/:/, $entry);
  85.    $done = 0;
  86.    while (! $done) {
  87.       ($oname,$opwd) = split(/:/, shift(@oldpasswd)) if ($newp);
  88.       if ($name eq $oname) {
  89.      push(@diffs, $entry) if ($pwd ne $opwd ||
  90.                   grep($name eq substr($_, $[, index($_, " ")),
  91.                        @lasttime));
  92.      $newp = 1;
  93.      $done = 1;
  94.       } elsif ($name lt $oname) {
  95.      push(@diffs, $entry);
  96.      $newp = 0;
  97.      $done = 1;
  98.       } else { # $name gt $oname
  99.      $newp = 1;
  100.       }
  101.    }
  102. }
  103.  
  104. if ($debug) {
  105.    print STDERR "Passwords changed:\n";
  106.    print STDERR @diffs;
  107. }
  108.  
  109. if ($#diffs >= 0) {
  110.    open(CRACKED, ">pwdiff") || die "$prog: can't create pwdiff\n";
  111.    print CRACKED @diffs;
  112.    close(CRACKED);
  113.    print STDERR "Starting Crack on pwdiff\n" if ($verbose);
  114.    if ($debug && ! $crack) {
  115.       @cracked = grep(s/.*Guessed (\w*).*\[(.*)\].*/\1 \2/, `cat debug.out`);
  116.    } else {
  117.       @cracked = grep(s/.*Guessed (\w*).*\[(.*)\].*/\1 \2/, `Crack -f pwdiff`);
  118.    }
  119.    if ($debug) {
  120.       print STDERR "Cracked accounts:\n";
  121.       print STDERR @cracked;
  122.    }
  123.    # check for previously cracked accounts, mail crackee
  124.    foreach $twit (@cracked) {
  125.       ($name, $pwd) = split(" ", $twit);
  126.       if (grep($name eq substr($_, $[, index($_, " ")), @lasttime)) {
  127.      chop $twit; $twit .= " ***\n";
  128.      print STDERR "Disabling $name [$pwd]: cracked already\n" if ($verbose);
  129.      &mail($name, "Your password",
  130. "Your password ($pwd) has been guessed by the password cracker twice\
  131. in a row.\
  132.  
  133. PLEASE CHANGE IT TO SOMETHING MORE SECURE *NOW*.
  134.  
  135. The system manager will soon check that you have changed your password, and\
  136. disable your account if you have not.\
  137. \
  138. Secure passwords are generally six characters or longer, and include a mixture\
  139. of upper and lower-case alphabetic characters, punctuation, and digits.");
  140.       } else {
  141.      print STDERR "Mailing $name about password $pwd\n" if ($verbose);
  142.      &mail($name, "Your password",
  143. "Your password ($pwd) has been guessed by the password cracker.\
  144.  
  145. PLEASE CHANGE IT TO SOMETHING MORE SECURE.\
  146. \
  147. If you do not, your account will be disabled next time the password cracker\
  148. is run.\
  149. \
  150. Secure passwords are generally six characters or longer, and include a mixture\
  151. of upper and lower-case alphabetic characters, punctuation, and digits.");
  152.       }
  153.    }
  154.    if ($#cracked >= 0) {
  155.       print STDERR "Mailing report to $mail\n" if ($verbose);
  156.       &mail($mail, "Cracked passwords", "User Password\n\n", @cracked, "
  157. Entries marked *** have been cracked before. The account should be disabled
  158. if the user does not change the password now.");
  159.    }
  160.    open(CRACKED, ">cracked.last") || die "$prog: can't update cracked.last\n";
  161.    print CRACKED @cracked;
  162.    close(CRACKED);
  163.    chmod 0600, "cracked.last" || die "$prog: can't protect cracked.last\n";
  164. } else {
  165.    print STDERR "No changed passwords\n" if ($verbose);
  166.    open(CRACKED, ">cracked.last") || die "$prog: can't clean cracked.last\n";
  167.    close(CRACKED);
  168. }
  169.