First let us take a look at a sample entry for from the /etc/shadow
root@securitnik:~# cat /etc/shadow | grep root root:$6$uPdhX/Zf$Kp.rcb4AWwtx0EJq235tzthWXdIEoJnhZjOHbil3od1AyMf3t8Yi6dAPlhbHVG9SLx5VSIPrXTZB8ywpoOJgi.:17564:0:99999:7:::
Each entry above, separated by the ":" represents a different field. For us we will focus on the first two, with the values "root" and "$6$uPdhX/Zf$Kp.rcb4AWwtx0EJq235tzthWXdIEoJnhZjOHbil3od1AyMf3t8Yi6dAPlhbHVG9SLx5VSIPrXTZB8ywpoOJgi." The first entry represents the username which in this case is "root" and the second the password representation.
From the second field - the password representation - the "6" between the first two "$" represents the encryption algorithm being used. This is further confirmed by looking at our "/etc/login.defs" file with a focus on the "ENCRYPT_METHOD". In our file below, we see "ENCRYPT_METHOD SHA512". This tells us that the system is using SHA512.
root@securitynik:~# cat /etc/login.defs | grep "ENCRYPT_METHOD" # This variable is deprecated. You should use ENCRYPT_METHOD. ENCRYPT_METHOD SHA512 # Only used if ENCRYPT_METHOD is set to SHA256 or SHA512.
The second value we need to focus on is the salt, which is in this example "uPdhX/Zf" found between the second and third "$". In this case we are using an 8 byte salt. Consider the salt a random value that is used to make the password stronger. The bigger the salt, the stronger the password should be. For example, an 8 byte salt should make the password harder to crack than a 2 byte crack.
From above, we know the hashing algorithm is SHA512 and we have the salt. The only thing missing now is a string which when we put them all together, we can recompute the password representation. Specifically, this is what we need:
HASH ALGORITHM + SALT + STRING PASSWORD = PASSWORD REPRESENTATION
Here is what we have:
SHA512 (6) + uPdhX/Zf + ???? = PASSWORD REPRESENTATION
Let's load up python3.7 and leverage it's "crypt" module to help us out here.
root@securitynik:~# python3.7 Python 3.7.2 (default, Jan 3 2019, 02:55:40) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import crypt >>> crypt.crypt("Passw0rd", salt="$6$uPdhX/Zf$") '$6$uPdhX/Zf$FtB3X5oeGRWXXg92TjXp/9yuy21iBYTa/YMKrCIUtV4rDBd9zK5tZ0mr0sefszzdz0NUbM670CYJw.g1DFkJu.' >>> crypt.crypt("GuessMe", salt="$6$uPdhX/Zf$") '$6$uPdhX/Zf$GhShpI0WBBLbDVRkGrOjcnmseqzlduCrXdX0prmlMIMtF/1XlgBKtl4ptpyxJDzvqCQCHeK5iNW1tvEETGmYz0' >>>
From above we tried the first password as "Passw0rd" and the second password "GuessMe". However, as you can see above, none of these combinations produced a value that matched our original from the "/etc/shadow" file which is "$6$uPdhX/Zf$Kp.rcb4AWwtx0EJq235tzthWXdIEoJnhZjOHbil3od1AyMf3t8Yi6dAPlhbHVG9SLx5VSIPrXTZB8ywpoOJgi."
At this point, we can continue trying this process entering each password manually until we find a match or we can simply automate this process with a dictionary. Let's choose the latter.
First we need a dictionary. You can find many dictionaries online but let's just create one of our own. To do, let's add 10 words to a file called "SecurityNik.lst".
root@securitynik:~# echo "Passw0rd" >> SecurityNik.lst root@securitynik:~# echo "GuessMe" >> SecurityNik.lst root@securitynik:~# echo "admin" >> SecurityNik.lst root@securitynik:~# echo "root" >> SecurityNik.lst root@securitynik:~# echo "1234567890" >> SecurityNik.lst root@securitynik:~# echo "Password1" >> SecurityNik.lst root@securitynik:~# echo "ftp" >> SecurityNik.lst root@securitynik:~# echo "root" >> SecurityNik.lst root@securitynik:~# echo "SecurityNik" >> SecurityNik.lst root@securitynik:~# echo "toor" >> SecurityNik.lst
When we perform a "cat" on the file, we see:
root@securitynik:~# cat SecurityNik.lst Passw0rd GuessMe admin root 1234567890 Password1 ftp root SecurityNik toor
Let's now code up our password cracker:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #!/usr/bin/env python3.7 # passwordCracker.py # Author: Nik alleyne # Author Blog: www.securitynik.com # Date: 2019-02-15 import crypt from subprocess import call from sys import exit, argv # This function handles usage information def usage(): print("password_file: A file consisting of passwords you would like to use.") print("./passwordCraker.py <password_file>") exit(0) # This function checks to see if the username is found within the file def passwordCracker(passwordFile): # Store the password we are trying to crack as a variable passwordToCrack = "$6$uPdhX/Zf$Kp.rcb4AWwtx0EJq235tzthWXdIEoJnhZjOHbil3od1AyMf3t8Yi6dAPlhbHVG9SLx5VSIPrXTZB8ywpoOJgi." print("[*] we will be looking for a match for password '{}'".format(passwordToCrack)); print("[*] Starting password cracking ...") print("[*] Loading password file '{}' into memory ...".format(passwordFile)) # Load the file entered on the command line into memory passwordFile = open(passwordFile, 'r') # Store salt as variable passwordSalt = "$6$uPdhX/Zf$" passwordFound = False; # Read the file line by line for line in passwordFile.readlines(): passwordFound = crypt.crypt(line.strip(),salt=passwordSalt) if ( passwordFound == passwordToCrack.strip() ): print("[+] MATCH FOUND! Password is:{}".format(line).strip()) print("[+] Password {} \n MATCHES \n Password {} ".format(passwordToCrack,passwordFound)) exit(0) else: print("[-] Trying password:{}".format(line).strip()) if __name__ == '__main__': call("clear") print("passwordCrakcer.py") print("Author: Nik Alleyne") print("Author Blog: www.securitynik.com") # Check the number of arguments being entered on the command line if ( len(argv) != 2 ): usage() # calls the passwordCracker function passwordCracker(argv[1]) |
The above code, helps to give us a better understanding of how password cracking works.
Now while we went through this process manually and writing our own code, the reality is, there are tools which can make this process easier for you. More specifically the three that I can immediately recommend are:
1. John the Ripper
2. Hashcat
3. Cain and Abel
While the above tools are helpful, it is important that you understand how some of these tools works and thus I hope this post contributed to making that learning process easier.
References:
https://en.wikipedia.org/wiki/Salt_(cryptography)
https://docs.python.org/3/library/crypt.html
https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
Python Cheat Sheet Updated for 2022 - from Libraries to Internet Modules (pcwdld.com)
No comments:
Post a Comment