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 >
Wrap
Text File
|
1992-03-10
|
7KB
|
275 lines
#!/bin/sh -- need to mention perl here to avoid recursion
'true' || eval 'exec perl -S $0 $argv:q';
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
& eval 'exec /usr/local/bin/perl -S $0 $argv:q'
if 0;
#
# Pass.chk -- a password guesser. Functionally equivalent to the original
# cops password guesser. The -P option doesn't work right now (alpha release,
# don't you know :-), since we're doing funky things with password caching,
# but this will change soon.
#
# Usage: $0 [options] dictionary
#
# -P pfile password file (not working)
# -p print found passwords (incompatible with -M)
# -d check prefix/suffix of digits [0-9]
# -g check all words in gcos, plan, project, signature files
# -r reverse the word tests
# -s check all single chars as passwords
# -u output the current user being checked
# -U try uppercase word tests
# -v verbose, print advisory information
# -x check guess+prefix/suffix with strange chars added on
# -0 (zero) change all o's ("oh"'s) to 0 (zeros)
# -1 (one) change all i's to 1 (ones)
# -m misspell words -- chop off first and last chars,
# if > 3 chars. E.g. "dinner" ==> "inner" and "dinne"
#
# Originally written by Tim Tessin with lots more features, etc., etc., etc.
# I ripped out all of his extra functionality that duplicated some of the
# other cops stuff, and some things that just didn't fit, and added some
# code to finish the simulation of the old checker. -- dan
#
require "getopts.pl";
# can probably just do "|| &usage;" since &usage is only used once. ;-)
&Getopts("p0dgrsuUv1P:mx") || print STDERR "Usage: $0 -p0xdgrsuUPvm\n";
# diff password file?
if (defined($opt_P)) { $'GET_PASSWD = "/bin/cat $opt_P"; }
require "pass.cache.pl";
$Passwd = "/etc/passwd";
@strange_things = (" ", ";", ",", ".", "!", "@", "#", "$",
"%", "^", "&", "*", "(", ")", "-", "_",
"=", "+", "[", "]", "{", "}", "'", "\"",
"|", "`", "~", ">", "<");
# unbuffer output
select (STDOUT); $| = 1;
$dups = 0; # duplicate name entries
$new = 0; # new entries
$changed = 0; # password (and other data) changed
$deleted = 0; # deleted entries
$updated = 0; # data other than password changed
$nlog = 0; # number of log entries, used for print decisions
$ntest = 0;
$ndone = 0;
for $uid (keys %uname2passwd) {
next if length($pass = $uname2passwd{$uid}) != 13;
next unless $pass; # shall we report null passwd's, too? ;-)
if ($try = &dopwd()) {
$pwd = ($opt_p) ? $try : "";
# printf "Username: %-8s <password guessed> $pwd\n",$P[0];
printf "Warning! $uid password Problem: Guessed: %s\t\t$pwd\n",$P[0];
}
$ndone++;
}
1;
# end of program
######################## Support Subroutines ###########################
# dopwd tests each password entry against several simple checks and all
# the words in the dictionaries specified. The simple checks consists
# of trying the username as the password ('joe' accounts), words derived
# from the gecos fields (usually first and last names).
sub dopwd {
$tries = 0;
print "$uid\n" if ($opt_u);
# try user name
($try = &testpwd($uid,$pass)) && return $try;
# try uiduid
if (length($uid) < 8) {
($try = &testpwd($uid . $uid,$pass)) && return $try;
}
# do gcos field?
if ($opt_g) {
@gcos = split(/[.,& -]/,$uname2gcos{$uid});
foreach $i (@gcos) {
next unless $i; # skip null split values
($try = &testpwd($i,$pass)) && return $try;
}
# Try names from misc files
#
undef %words;
# files to check
@files2chk = ("/.project", "/.plan", "/.signature");
$home = $uname2dir{$uid};
for $i (@files2chk) {
open (FOOFILE, $home . $i);
while (<FOOFILE>) {
chop;
@line = split(/([.,;\s])/);
for $j (@line) {
$words{$j}=$j unless $j=~/[\s]/;
}
}
close FOOFILE;
}
for $k (values %words) {
# print "word $k\n";
($try = &testpwd($k,$pass)) && return $try;
}
}
# do dictionaries
# save state of upper/reverse so individual dicts can temporarily
# override.
foreach $i (@ARGV) {
if (open (DICT,$i)) {
while (<DICT>) {
chop;
if ($try = &testpwd($_,$pass)) {
close DICT;
return $try;
}
}
close DICT;
}
}
return 0;
}
# small subroutines to help the main password cracker. All are labeled
# p_xxx, where xxx is the identifying name.
#
# if leading character is upper-case, also try lower case version
sub p_lc {
local($try) = @_;
local($ntry);
if ( $try =~ /^[A-Z]/ ) {
($ntry = $try) =~ y/A-Z/a-z/;
push(@total_guesses, $ntry);
}
}
# reverse check
sub p_rev {
local($try) = @_;
local($ntry);
$ntry = reverse $try;
if ($ntry ne $try) {
push(@total_guesses, $ntry);
}
}
# uppercase check
sub p_up {
local($try) = @_;
local($ntry);
($ntry = $try) =~ y/a-z/A-Z/;
if ($ntry ne $try) { push(@total_guesses, $ntry); }
}
# testpwd checks a word to see if it matches the encrpted password
# if the word is capitalized, the lowercase version is tried as well
sub testpwd {
local ($try,$pass) = @_;
local (@total_guesses);
push(@total_guesses, $try);
# free (lower case) check if first letter is uppercase
&p_lc($try);
# reverse?
if ($opt_r) { &p_rev($try); }
# uppercase?
if ($opt_U) { &p_up($try); }
# single digit tacked on to beginning and end
if ($opt_d) {
if (length ($try) < 8) {
foreach $i ('0'..'9') {
$ntry = $i.$try;
push(@total_guesses, $ntry);
if ($opt_r) { &p_rev($ntry); }
if ($opt_U) { &p_up($ntry); }
}
foreach $i ('0'..'9') {
$ntry = $try.$i;
push(@total_guesses, $ntry);
if ($opt_r) { &p_rev($ntry); }
if ($opt_U) { &p_up($ntry); }
}
}
}
# change o's to 0's ("oh"'s to zeros)
if ($opt_0) {
if (($ntry = $try) =~ s/o/0/g) { push(@total_guesses, $ntry); }
}
if ($opt_1) {
if (($ntry = $try) =~ s/i/1/g) { push(@total_guesses, $ntry); }
}
# misspell words -- truncate first and last letter, if > 3 chars
# thanks to William Vajk, learn@ddsw1.MCS.COM, who posted this idea.
if ($opt_m) {
$len = length($try);
if ($len > 3) {
($ntry = $try) =~ s/^.//; push(@total_guesses, $ntry);
if ($len < 9) {
($ntry = $try) =~ s/.$//; push(@total_guesses, $ntry);
}
}
}
# weird things! Tacked on to beginning and end
if ($opt_x) {
if (length ($try) < 8) {
foreach $i (@strange_things) {
$ntry = $i.$try;
push(@total_guesses, $ntry);
if ($opt_r) { &p_rev($ntry); }
if ($opt_U) { &p_up($ntry); }
}
foreach $i (@strange_things) {
$ntry = $try.$i;
push(@total_guesses, $ntry);
if ($opt_r) { &p_rev($ntry); }
if ($opt_U) { &p_up($ntry); }
}
}
}
# do single letters, #'s, if needed
if ($opt_s && $uid ne $last_user) {
$last_user = $uid;
foreach $i (@strange_things) { push(@total_guesses,$i); }
foreach $i (0..9) { push(@total_guesses, $i); }
foreach $i (A..Z) { push(@total_guesses, $i); }
foreach $i (a..z) { push(@total_guesses, $i); }
}
if ($opt_v) {
foreach $i (@total_guesses) {
print "Trying \"$i\" on $uid\n";
$epw = crypt($i,$pass);
($epw eq $pass) && return $i;
}
}
else {
foreach $i (@total_guesses) {
$epw = crypt($i,$pass);
($epw eq $pass) && return $i;
}
}
undef @total_guesses;
return 0;
}