Simple /etc/shadow Cracker
Question: I'm trying to get this shadow file cracker working but I keep getting a
TypeError: integer required.

I'm sure its the way I'm using the bytearray function. I've tried creating a
new object with bytearray for the "word" and the "salt" however to no avail.
So then I tried passing the bytearray constructor to the pbkdf2 function and
still nothing. I will post the code:

    
    
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    import hashlib, binascii 
    import os,sys
    import crypt
    import codecs
    from datetime import datetime,timedelta
    import argparse
    today = datetime.today()
    
    # Takes in user and the encrypted passwords and does a simple   
    # Brute Force Attack useing the '==' operator. SHA* is defined by
    # a number b/w $, the char's b/w the next $ marker would be the
    # rounds, then the salt, and after that the hashed password. 
    # object.split("some symbol or char")[#], where # is the 
    # location/index within the list
    def testPass(cryptPass,user):
    
    digest = hashlib.sha512
    dicFile = open ('Dictionary.txt','r')
    ctype = cryptPass.split("$")[1]
    if ctype == '6':
     print "[+] Hash type SHA-512 detected ..."
     print "[+] Be patien ..."
     rounds = cryptPass.split("$")[2].strip('rounds=')
     salt = cryptPass.split("$")[3]
     print "[DEBUG]: " + rounds
     print "[DEBUG]: " + salt
     #   insalt = "$" + ctype + "$" + salt + "$"  << COMMENTED THIS OUT
    for word in dicFile.readlines():
     word = word.strip('\n')
     print "[DEBUG]: " + word
     cryptWord = hashlib.pbkdf2_hmac(digest().name,bytearray(word, 'utf-8'),bytearray(salt, 'utf-8'), rounds)
     if (cryptWord == cryptPass):
        time = time = str(datetime.today() - today)
        print "[+] Found password for the user: " + user + " ====> " + word + " Time: "+time+"\n"
        return
     else:
        print "Nothing found, bye!!"
        exit
    
    # argparse is used in main to parse arguments pass by the user.
    # Path to shadow file is required as a argument. 
    def main():
    
     parse = argparse.ArgumentParser(description='A simple brute force /etc/shadow .')
     parse.add_argument('-f', action='store', dest='path', help='Path to shadow file, example: \'/etc/shadow\'')
     argus=parse.parse_args()
     if argus.path == None:
         parse.print_help()
         exit
     else:
         passFile = open (argus.path,'r', 1) # ADDING A 1 INDICATES A BUFFER OF A
    for line in passFile.readlines():   # SINGLE LINE '1<=INDICATES 
     line = line.replace("\n","").split(":") # EXACT BUFFER SIZE
     if  not line[1] in [ 'x', '*','!' ]:
        user = line[0]
        cryptPass = line[1]
        testPass(cryptPass,user)
    
    if __name__=="__main__":
     main()
    

OUTPUT:

    
    
    [+] Hash type SHA-512 detected ...
    [+] Be patien ...
    [DEBUG]: 65536
    [DEBUG]: A9UiC2ng
    [DEBUG]: hellocat
    Traceback (most recent call last):
     File "ShadowFileCracker.py", line 63, in <module>
        main()
      File "ShadowFileCracker.py", line 60, in main
      testPass(cryptPass,user)
      File "ShadowFileCracker.py", line 34, in testPass
        cryptWord = hashlib.pbkdf2_hmac(digest().name,bytearray(word, 'utf-8'),bytearray(salt, 'utf-8'), rounds)
     TypeError: an integer is required
    


Answer: The `rounds` variable needs to be an integer, not a string. The correct line
should be:

    
    
    rounds = int(cryptPass.split("$")[2].strip('rounds='))
    

Also, `strip()` might not be the best method for removing the leading
"rounds=". It will work, but it strips a set of characters and not a string. A
slightly better method would be:

    
    
    rounds = int(cryptPass.split("$")[2].split("=")[1])
    

