http://www.perlmonks.org?node_id=452843

RayQ has asked for the wisdom of the Perl Monks concerning the following question:

I'm just starting on perl, and I thought of something stupid to do, a password cracker of sorts.
I had had managed to make it crack single passwords (Easy enough, loop for the pass in the dictionary, exit if found and echo what was found). Now I tried to make it be able to read the password hashes from a list file, like:
hasha
hashb
hashc
And that's what I am not able to do. Currently, I have it set up as a loop in the password file, and inside that, a loop in the dictionary. The code is:
#!/usr/bin/perl -T use Getopt::Std; use Digest::SHA qw(sha1_hex sha224_hex sha256_hex sha384_hex sha512_he +x); use Digest::MD5 qw(md5_hex); getopts('d:h:f:m:a'); my $dictionary = $opt_d; my $hash = $opt_h; my $mode = $opt_m; my $help = $opt_a; my $passfile = $opt_f; if($mode == ""){$mode = "md5";} my $algo = $mode; my %length; $length{'md5'} = 32; $length{'sha1'} = 40; $length{'sha224'} = 56; $length{'sha256'} = 64; $length{'sha384'} = 96; $length{'sha512'} = 128; if($help && (!$hash && !$passfile) || (!$hash && !$passfile)){help();e +xit(1);} &main; sub main { if($dictionary eq "") { $dictionary = "/usr/share/dict/words"; } if($hash) { if(length($hash) != $length{$algo}) { print STDERR "Invalid hash length!\nLength for an $algo ha +sh should be $length{$algo}!\nSee $0 -a for details.\n"; exit(1); } print "Cracking....\n"; } if($passfile eq "") { open DICT, $dictionary or die(" Could not open dictionary file : $dictionary. Please make sure the file exists and you have read access +to it. Error occured"); while(<DICT>) { chomp($_); if(hash($algo, $_) eq $hash) { print "\nMatch found!\nPlainText : " . $_ . "\n\n"; exit(0); } } } else { open PASS, $passfile or die(" Could not open password file : $passfile. Please make sure the file exists and you have read access +to it. Error occured"); print "Cracking....\n"; while(<PASS>) { open DICT, $dictionary or die(" Could not open dictionary file : $dictionary. Please make sure the file exists and you have read acc +ess to it. Error occured"); my $curpass = $_; chomp($curpass); chop($curpass); while(<DICT>) { my $word = $_; chomp($word); chop($word); #print $number."\n"; if(hash($algo, $word) eq $curpass) { print "$curpass :: $word\n"; close(DICT); } } } close(PASS); } exit(1); } sub help { print " Usage: $0 [-d dictionary] [-h hash|-f file] [-m mode]\n Crack [hash] or [file] using [mode] hashing, and [dictionary] +file.\n Currently, supported hashing methods are: MD5 SHA1 SHA224 SHA256 SHA384 SHA512 If no dictionary file is specified, /usr/share/dict/words will + be used.\n If no mode is specified, MD5 will be used. Example: $0 -h a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 -m sha1 $0 -d /usr/local/Wordlist -h 098f6bcd4621d373cade4e832627b4f6 $0 -f /usr/bin/passwords.txt -d /usr/local/Wordlist \n"; } sub hash # hash($algo, $_) { if($_[0] eq "md5") { return md5_hex($_[1]); } elsif($_[0] eq "sha1") { return sha1_hex($_[1]); } elsif($_[0] eq "sha224") { return sha224_hex($_[1]); } elsif($_[0] eq "sha256") { return sha256_hex($_[1]); } elsif($_[0] eq "sha384") { return sha384_hex($_[1]); } elsif($_[0] eq "sha512") { return sha512_hex($_[1]); } }
I have several problems. One, if the hashes's plaintexts are "a","b","c","a", it'll find until c, but never a. And second, if I dont leave an empty line after the passwords in the password file, it misses the last hash D=
What am I doing wrong here?

And another, separate problem, which I dont know what is the cause.
I can't use #!/usr/bin/perl as the shebang line, it says wrong interpreter, I have to add something (In this case -T) for it to work.
Anyone know what might be causing this? Thanks.