Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Double loop?

by RayQ (Initiate)
on Apr 30, 2005 at 12:23 UTC ( #452843=perlquestion: print w/ replies, xml ) Need Help??
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.

Comment on Double loop?
Download Code
Re: Double loop?
by Animator (Hermit) on Apr 30, 2005 at 13:10 UTC

    A reply to your second problem: do you need to add -T? or does -w works aswell? if -w works aswell, then I guess you have problems with the line-endings... (as in, using DOS-line endings in a UNIX-shell)... which is most likely caused because you uploaded (or copied) the file in binary mode instead of ASCII mode...

    I can't reply to your first question/problem since your code is not indeted, and therfor I need to do a way to big effort to read it... (I could ofcourse tidy it using Perl::Tidy and read it then, but I don't think I should go to the trouble of doing that, since you are the one seeking help)

    It might be a good idea to read `perldoc perlstyle`...

      I *did* indent it >_> It shows up indented to me at least. I used PHP style, as I'm used to that, is perl style /that/ much different from PHP style? Anyway, I edited it, better now? ^_^;;
        Strange, it shows differently in the result in the question than what I type in the box to edit it, and what it shows in said box.
        EDIT: It's now uploaded to my server, http://as.switch2hosting.com/perl.txt, to show the correct indenting.
        Did you include it inside <code> - </code> tags? See Writeup Formatting Tips for more.

        Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

        Don't fool yourself.
Re: Double loop?
by Animator (Hermit) on Apr 30, 2005 at 16:53 UTC

    Ok, much better (the formatting of the code)

    Some notes:

    • while (<PASS>) it would be better to write: while (my $curpass = <PASS>) (and remove the my $curpass = $_;-line)
    • (The same note goes for while(<DICT>))
    • it would be better if you put the close (DICT) after the while (<DICT>)-block, and use last; where you currently use close
    • Instead of open PASS, $passfile you should/could use: open PASS, "<:crlf", $passfile. This is a) safer, and b) it allows you to remove the chop-line (chomp will do just fine).

      Many thanks =D

      What exactly did I have wrong?
Re: Double loop?
by Dietz (Curate) on Apr 30, 2005 at 17:36 UTC
    Well, I gave it a try and refactored your script just a bit ;-).
    I also included 'use strict' and 'use warnings'.

    Note: passwords.txt should contain the plain password and Wordlist should contain the hash
    I confused the files and changed 'crack($_, $curpass_);' to 'crack($curpass, $_);'

    #!/usr/bin/perl use strict; use warnings; 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 %opts); my $dictionary = $opts{d} || '/usr/share/dict/words'; my $hash = $opts{h}; my $passfile = $opts{f}; my $mode = $opts{m} || 'md5'; my $help = $opts{a}; my %algo = ( md5 => [ 32, \&md5_hex ], sha1 => [ 40, \&sha1_hex ], sha224 => [ 56, \&sha224_hex ], sha256 => [ 64, \&sha256_hex ], sha384 => [ 96, \&sha384_hex ], sha512 => [128, \&sha512_hex ], ); die help() if $hash and $passfile or $help; die help() unless $passfile or $hash; if ($hash) { len_err() unless length($hash) == $algo{$mode}[0]; open DICT, $dictionary or file_err('dictionary', $dictionary); print "Cracking hash ...\n"; while(<DICT>) { crack($hash, $_); } } if ($passfile) { open PASS, $passfile or file_err('password', $passfile); print "Cracking file ...\n"; while(<PASS>) { chomp(my $curpass = $_); open DICT, $dictionary or file_err('dictionary', $dictionary); while(<DICT>) { #crack($_, $curpass); wrong order crack($curpass, $_); } } close PASS; } sub crack { chomp(my $hash = shift); chomp(my $pass = shift); my $crack = $algo{$mode}[1]($pass); if($hash eq $crack) { print "\nMatch found!\nPlainText : $pass\n\n"; exit 0; } } sub len_err { die " Invalid hash length!\n Length for an $mode hash should be $algo{$mode}[0]!\n See $0 -a for details\n"; } sub file_err { my ($type, $file) = @_; die " Could not open $type file : $file. Please make sure the file exists and you have read access to it. Error occured\n"; } 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"; exit; }
Re: Double loop?
by Dietz (Curate) on Apr 30, 2005 at 22:01 UTC
    Please don't delete code from your original question or change it otherwise without stating so.
    When you have problems formatting content for PM please see Writeup Formatting Tips as frodo72 already stated.

    Referring to offsite code (on your own server) isn't a good idea either, you would probably not keep it there forever, and other monks will get a different picture of this thread when you're changing the OP afterwards.

    In fact, you changed even your code on your server, taking snippets from my last reply and now it looks like I just took out a few spaces and posted a neater version of yours.

    I thought in posting a refactored, tidier and more compact version you could compare your efforts with someone elses try.

    In your current version of your offsite code (http://as.switch2hosting.com/perl.txt) you took snippets and ideas from our replies and included following statement now:

    You are free to customize this script as you wish, but do not
    redistribute without written permission from TipoNaSoft.

    Huh?
    Is it really so special that one needs a written permission from you?

    I'm adding your original code now below just that I don't stand here as a fool.

    Original posting (OP) from RayQ:
    #!/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]); } }
      Right, forgot I had changed it, lemme change it back xD
      That is just a fake disclaimer.
      Also, I did include it in code tags, and I had read that page. It just changed my tabbing everywhere, {'s were appearing where they shouldn't.
        ++ for inserting your original code in the OP again and for being so honest to say so.

        Keep at it!

        Cheers!

        That is just a fake disclaimer.

        IANAL, but AFAIK there is no such thing as a "fake" legal statement. While you are free to license your code under whichever license you choose, keep in mind that non-OSI compatible licenses will largely preclude others from citing your source in reply to any inquiries you might have.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://452843]
Approved by moot
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2014-07-29 09:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (213 votes), past polls