home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- # ypcrack: AJCD 27/8/91
- #
- # Crack passwords in YP password file incrementally; warns users and system
- # manager about cracked passwords.
- #
- # Usage: ypcrack [-debug] [-crack] [-verbose] [-mail sysmgr]
-
- $prog = $0; $prog =~ s%.*/%%;
- $dir = $0; $dir =~ s%/[^/]*$%%;
-
- chdir ($dir) || die "$0: can't chdir to $dir\n";
-
- $debug = 0; # testing?
- $crack = 0; # if testing, do we still crack properly?
- $verbose = 0; # talk about it?
- $mail = "faults"; # who to mail report to
-
- while ($_ = shift(@ARGV)) {
- if (/^-d(ebug)?$/) { $debug = 1; }
- elsif (/^-c(rack)?$/) { $crack = 1; }
- elsif (/^-v(erbose)?$/) { $verbose = 1; }
- elsif (/^-m(ail)?$/) { $mail = shift(@ARGV); }
- else {
- print STDERR "Usage: $prog [-debug] [-verbose] [-mail sysmgr] [-crack]\n";
- exit 1;
- }
- }
-
- sub onfield {
- local(@one) = split(/:/, $a);
- local(@two) = split(/:/, $b);
- return ($one[0] cmp $two[0]);
- }
-
- sub mail {
- local($to) = shift(@_);
- local($subject) = shift(@_);
- local($temp) = "/tmp/$prog.$$";
- open(TEMP, ">$temp") || die "$prog: can't open temp file $temp\n";
- print TEMP @_, "\n";
- close(TEMP);
- if ($debug) {
- print STDERR "To: $to\n", "Subject: $subject\n";
- system ("cat <$temp");
- } else {
- system ("mail -s $subject $to < $temp");
- }
- unlink($temp) || die "$prog: can't remove temp file $temp\n";
- }
-
- if (! $debug) {
- print STDERR "Getting new password file\n" if ($verbose);
- rename("passwd", "passwd.old"); # ignore failure
- system("ypcat passwd >passwd")/256 && die "$prog: ypcat failed: $!\n";
- }
-
- print STDERR "Sorting passwd\n" if ($verbose);
- open(PASSWD, "passwd") || die "$prog: can't open passwd\n";
- @passwd = <PASSWD>;
- close(PASSWD);
- @passwd = sort onfield @passwd;
-
- if (open(PASSWD, "passwd.old")) {
- print STDERR "Sorting passwd.old\n" if ($verbose);
- @oldpasswd = <PASSWD>;
- close(PASSWD);
- @oldpasswd = sort onfield @oldpasswd;
- } else {
- @oldpasswd = ();
- }
-
- print STDERR "Reading previously cracked accounts\n" if ($verbose);
- if (open(CRACKED, "cracked.last")) {
- @lasttime = <CRACKED>;
- close(CRACKED);
- } else {
- @lasttime = ();
- }
-
- @diffs = ();
- $newp = 1; # new passwd entry required
- print STDERR "Differencing passwd and passwd.old\n" if ($verbose);
- foreach $entry (@passwd) {
- ($name,$pwd) = split(/:/, $entry);
- $done = 0;
- while (! $done) {
- ($oname,$opwd) = split(/:/, shift(@oldpasswd)) if ($newp);
- if ($name eq $oname) {
- push(@diffs, $entry) if ($pwd ne $opwd ||
- grep($name eq substr($_, $[, index($_, " ")),
- @lasttime));
- $newp = 1;
- $done = 1;
- } elsif ($name lt $oname) {
- push(@diffs, $entry);
- $newp = 0;
- $done = 1;
- } else { # $name gt $oname
- $newp = 1;
- }
- }
- }
-
- if ($debug) {
- print STDERR "Passwords changed:\n";
- print STDERR @diffs;
- }
-
- if ($#diffs >= 0) {
- open(CRACKED, ">pwdiff") || die "$prog: can't create pwdiff\n";
- print CRACKED @diffs;
- close(CRACKED);
- print STDERR "Starting Crack on pwdiff\n" if ($verbose);
- if ($debug && ! $crack) {
- @cracked = grep(s/.*Guessed (\w*).*\[(.*)\].*/\1 \2/, `cat debug.out`);
- } else {
- @cracked = grep(s/.*Guessed (\w*).*\[(.*)\].*/\1 \2/, `Crack -f pwdiff`);
- }
- if ($debug) {
- print STDERR "Cracked accounts:\n";
- print STDERR @cracked;
- }
- # check for previously cracked accounts, mail crackee
- foreach $twit (@cracked) {
- ($name, $pwd) = split(" ", $twit);
- if (grep($name eq substr($_, $[, index($_, " ")), @lasttime)) {
- chop $twit; $twit .= " ***\n";
- print STDERR "Disabling $name [$pwd]: cracked already\n" if ($verbose);
- &mail($name, "Your password",
- "Your password ($pwd) has been guessed by the password cracker twice\
- in a row.\
-
- PLEASE CHANGE IT TO SOMETHING MORE SECURE *NOW*.
-
- The system manager will soon check that you have changed your password, and\
- disable your account if you have not.\
- \
- Secure passwords are generally six characters or longer, and include a mixture\
- of upper and lower-case alphabetic characters, punctuation, and digits.");
- } else {
- print STDERR "Mailing $name about password $pwd\n" if ($verbose);
- &mail($name, "Your password",
- "Your password ($pwd) has been guessed by the password cracker.\
-
- PLEASE CHANGE IT TO SOMETHING MORE SECURE.\
- \
- If you do not, your account will be disabled next time the password cracker\
- is run.\
- \
- Secure passwords are generally six characters or longer, and include a mixture\
- of upper and lower-case alphabetic characters, punctuation, and digits.");
- }
- }
- if ($#cracked >= 0) {
- print STDERR "Mailing report to $mail\n" if ($verbose);
- &mail($mail, "Cracked passwords", "User Password\n\n", @cracked, "
- Entries marked *** have been cracked before. The account should be disabled
- if the user does not change the password now.");
- }
- open(CRACKED, ">cracked.last") || die "$prog: can't update cracked.last\n";
- print CRACKED @cracked;
- close(CRACKED);
- chmod 0600, "cracked.last" || die "$prog: can't protect cracked.last\n";
- } else {
- print STDERR "No changed passwords\n" if ($verbose);
- open(CRACKED, ">cracked.last") || die "$prog: can't clean cracked.last\n";
- close(CRACKED);
- }
-