#!/usr/bin/perl
#
# PerlCrack v0.3
# by offspring (allen@vasoline.org)
#    NAiVE (harton@vasoline.org)
####
# Now Including Death Crack!
####

### Configuration

# Please change this to your pcrack directory.
$crackdir = "$ENV{'HOME'}/pcrack";

### End Of Configuration

# Grab this machines hostname
chop($hostname = `/bin/hostname -s`);

# This process id
$pid = $$;

# Results
$outfile = $hostname.".".$pid;

@charlist = (
  '', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
  's','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K',
  'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3',
  '4','5','6','7','8','9','~','`','!','@','#','$','%','^','&','*','(',')',
  '-','_','+','=','{','}','[',']',':',';',',','.','<','>','?','\\','|','/'
);
$totchars = $#charlist;


print "PerlCrack v0.3\n";
print "by offspring (allen\@vasoline.org)\n";
print "   NAiVE (harton\@vasoline.org)\n\n";
print "Simply press Control-C to abort at any time.\n";
print "Password File: ";
chop($passwdfile = <STDIN>);
if (!-e $passwdfile) {die("\nFile not found: $passwdfile\n");}
print "Dictionary File: ";
chop($dictfile = <STDIN>);
if (!-e $dictfile) {die("\nFile not found: $dictfile\n");}
print "Do you wish to Death Crack (y/n)? ";
chop($deathtxt = <STDIN>);
$_ = $deathtxt;
$death = 0;
if (/^y/ || /^Y/) {
  $death = 1;
}
$resfile = $passwdfile.".res";
print "\nLoading saved info, Please wait .. ";
@storedc = ();
@storedw = ();
@found = ();
if (-e "$crackdir/pcrack.dat") {
  open(IN, "$crackdir/pcrack.dat");
  while (<IN>) {
    chop;
    ($c, $w) = split(/:/);
    @storedc[$#storedc + 1] = $c;
    @storedw[$#storedw + 1] = $w;
  }
  close(IN);
}
print "Done\n";
$resume = 0;
if (-e $resfile && $death == 1) {
  open(RES, "$resfile");
  @list = <RES>;
  ($_a, $_b, $_c, $_d, $_e, $_f, $_g, $_h) = split(/::/, $list[1]);
  $resume = 1;
  $first = 1;
  print "Resuming crack of $passwdfile. New Findings will be stored in $outfile\n\n";
} else {
  print "Attempting to ";
  print "Crack then Death " if ($death == 1);
  print "Crack $passwdfile. Findings will be stored in $outfile\n\n";
}
&deathcrack if ($resume == 1);
exit if ($resume == 1);
$date = `date`;
open(OUT, ">$outfile") || die("\nUnable to open $outfile for writing.\n");
print OUT "#\n";
print OUT "# File Generated by PerlCrack v0.3\n";
print OUT "# Written by offspring (allen\@vasoline.org)\n";
print OUT "#            NAiVE (daniel\@vasoline.org)\n";
print OUT "#\n";
print OUT "# Password File: $passwdfile\n";
print OUT "# Dictionary File: $dictfile\n";
print OUT "# Started: $date\n";
close(OUT);
open(F, $passwdfile) || die("\nUnable to open $passwdfile for reading.\n");
line: while (<F>) {
  chop;
  ($login, $passwd, $rest) = split(/:/);
  $quit = 0;
  if (!$passwd) {
    open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
    @found[$#found + 1] = $login;
    printf(OUT "Login: %-10s  NULL PASSWORD\n", $login);
    close(OUT);
  } else {
    $_ = $passwd;
    if (/^\*:/) {
      $quit = 1;
      @found[$#found + 1] = $login;
    }
  }
  $salt = substr($passwd, 0, 2);
  $logc = crypt($login, $salt);
  next line if ($quit == 1);
  if ($logc eq $passwd) {
    open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
    printf(OUT "Login: %-10s  Password: %-10s\n", $login, $login);
    close(OUT);
    open(SAVE, ">>$crackdir/pcrack.dat");
    print SAVE $passwd.":".$login."\n";
    close(SAVE);
    @storedc[$#storedc + 1] = $wordc;
    @storedw[$#storedw + 1] = $word;
    @found[$#found + 1] = $login;
    $quit = 1;
  }
  next line if ($quit == 1);
  $i = 0;
  while (($i <= $#storedc) && ($quit == 0)) {
    if ($storedc[$i] eq $passwd) {
      open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
      printf(OUT "Login: %-10s  Password: %-10s\n", $login, $storedw[$i]);
      close(OUT);
      @found[$#found + 1] = $login;
      $quit = 1;
    }
    $i = $i + 1;
  }
  next line if ($quit == 1);
  if (!$quit) {
    open(D, $dictfile) || die("\nUnable to open $dictfile for reading.\n");
    while (<D>) {
      chop($word = $_);
      $wordc = crypt($word, $salt);
      if ($wordc eq $passwd) {
        open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
        printf(OUT "Login: %-10s  Password: %-10s\n", $login, $word);
        close(OUT);
        open(SAVE, ">>$crackdir/pcrack.dat");
        print SAVE $passwd.":".$word."\n";
        close(SAVE);
        @storedc[$#storedc + 1] = $wordc;
        @storedw[$#storedw + 1] = $word;
        @found[$#found + 1] = $login;
        $quit = 1;
      }
      next line if ($quit == 1);
    }
    close(D);
  }
}
close(F);
if ($death == 1) {
  &deathcrack;
}
exit;
sub deathcrack {
  $quit = 0;
  $date = `date`;
  open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
  print OUT "# Finished Normal Cracking, now attempting DeathCrack $date\n";
  close(OUT);
  open(F, $passwdfile) || die("\nUnable to open $passwdfile for reading.\n");
  f: while (<F>) {
    chop;
    ($login, $passwd, $rest) = split(/:/);
    $quit = 0;
    foreach $_login (@found) {
      if ($_login eq $login) {
        $quit = 1;
      }
    }
    $salt = substr($passwd, 0, 2);
    next f if ($quit == 1);
    if ($quit == 0) {
    for ($i=0;$i<=$totchars;$i++) {
        for ($j=0;$j<=$totchars;$j++) {
          for ($k=0;$k<=$totchars;$k++) {
            for ($l=0;$l<=$totchars;$l++) {
              for ($m=0;$m<=$totchars;$m++) {
                for ($n=0;$n<=$totchars;$n++) {
                  for ($o=0;$o<=$totchars;$o++) {
                    for ($p=0;$p<=$totchars;$p++) {
                      if ($firstr == 1) {
                        $firstr = 0;
                        $p = $_a; $o = $_b; $n = $_c;
                        $m = $_d; $l = $_e; $k = $_f;
                        $j = $_g; $i = $_h;          
                      }
		      system("echo $o > werd.txt");
                      $word = $charlist[$p].$charlist[$o].$charlist[$n].$charlist[$m].$charlist[$l].$charlist[$k].$charlist[$j].$charlist[$i];
                      $wordc = crypt($word, $salt);
                      if ($wordc eq $passwd) {
                        open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
                        printf(OUT "Login: %-10s  Password: %-10s\n", $login, $word);
                        close(OUT);
                        open(SAVE, ">>$crackdir/pcrack.dat");
                        print SAVE $passwd.":".$word."\n";
                        close(SAVE);
                        @storedc[$#storedc + 1] = $wordc;
                        @storedw[$#storedw + 1] = $word;
                        $quit = 1;
                      }
                      open(RES, ">$resfile");
                      print RES $p."::".$o."::".$n."::".$m."::".$l."::".$k."::".$j."::".$i."\n";
                      close(RES);
                      next f if ($quit == 1);
                    }
                    next f if ($quit == 1);
                  }
                  next f if ($quit == 1);
                }
                next f if ($quit == 1);
              }
              next f if ($quit == 1);
            }
            next f if ($quit == 1);
          }
          next f if ($quit == 1);
        }
        next f if ($quit == 1);
      }
      next f if ($quit == 1);
    }
    open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
    print OUT "# Unable to crack $login\n";
    close(OUT);
  }
  if (-e $resfile) {
    system("rm $resfile");
  }
  close(F);
  $date = `date`;
  open(OUT, ">>$outfile") || die("\nUnable to open $outfile for writing.\n");
  print OUT "\n# Crack Finished at $date\n";
  close(OUT);
}
