|
![]() |
|
||||||||||
|
Unix PasswordsIn this lab you will try several methods of attacking a file to find user passwords. Objectives
Background Unix passwords are hashed with the crypt() function. The crypt function takes a plaintext password and a "salt". The salt is used to ensure that users with the same password will most likely not have the same encrypted password. The system randomly chooses the salt, hashes it along with the password, and then stores the salt in the password file so that it remembers what to add the next time the user's password needs to be verified. crypt() hashes the plaintext password and salt, and returns the encrypted password. The salt is traditionally stored as the first two letters of the encrypted password. When programming in C you need to compile with the -lcrypt command to link in the crypt() function. Do a "man crypt" or see the link below to find out more. Password hashes were traditionally computed using a variant of DES and stored in a world-readable file called /etc/passwd. This made it easy for various services to require user passwords - they could hash the entered password and check it for themselves. The disadvantage of this approach was that anyone on the system could copy the password file to another machine and spend as long as they wanted guessing passwords. This is known as an off-line attack. Within the last 10 years or so, Unix systems have prevented these off-line attacks by keeping the hashes in a separate file, /etc/shadow, which only root can read. Now an attacker has to try passwords on-line, and the system can log his failed attempts. The other limitation of the original crypt() function is that it only accepts 56 bits of input. This effectively limited passwords to 8 (7-bit) characters. In 1998, the Electronic Frontier Foundation showed that 56-bit passwords could be completely brute-forced in a reasonable amount of time with reasonably cheap hardware (Read about the EFF DES cracker here). Consequently, many variants of Unix now use MD5 to hash user passwords, allowing passwords of arbitrary length. Additionally, the output of the normal MD5 function is run back in as input, hashing it again. This is done 1000 times. Why? It's a constant-factor tradeoff in CPU cycles for security - verifying a valid password by the system takes 1000 times longer, but so does trying an invalid one. If a cracker gets ahold of the /etc/shadow file, an attack that would take 1 day on single-round MD5 passwords takes almost 3 years with 1000-round hashes. An easy way to break a poorly chosen password is the dictionary attack. In a dictionary attack you encrypt all the words of a dictionary with the salt and compare the result with the encrypted password you are trying to break. If the dictionary attack doesn't recover the password, a simple substitution attack is sometimes used. Some of the most common substitutions in passwords are 0 for O or o, 1 for l or I, and 3 for e or E. With this attack you will need to use the dictionary attack, but replace occurences of the commonly substituted letter with the corresponding number. You can also try appending or prepending one or two digit numbers to the dictionary words. The brute force attack is an exhaustive attack; for good passwords of sufficient length, it's completely impractical. Every possible combination of legal letters is encrypted and matched against the encrypted password to see if it's a match. Samples Password Files In past semesters we have collected passwords from students in the class. You will see how easy it is to break most common passwords by attempting to crack the passwords that we have collected. A histogram of which passwords were broken the easiest will be posted, to show which passwords are strong and which ones are weak. No student names will be associated with the passwords, but these are real passwords used by students in the CS department at BYU. Note that both password files contain the same passwords, but are hashed differently.Passoff Requirements (Demonstrate in-person to a TA that you have fulfilled these)
Suggestion: Rules:
Resouces One of the best dictionary sites can be found at: Access Data. You can download and use any of their dictionaries, but remember that sometimes a smaller english dictionary is better, because it allows you to do more substitutions and number appending. They also offer several language dictionaries, common password dictionaries, common name dictionaries, etc. I would start with the small "English Lover's Dictionary" just to be sure your code is working. The man page on crypt() is very useful. Note that by default it performs DES, but under the "GNU Extension" section it talks about how to make crypt() do MD5. Example Code of How to Hash Using DES and MD5 Here is a simple program that demonstrates how to hash: Hasher For example, to hash the password "password" with the salt "st" (using DES) run the program as follows: [cs465ta@ta-14]$ ./hasher password ststqZw66BRck1U Notice that the first two characters in the hash are your two character salt. Also note that using DES only the first eight characters of the password are hashed (the hash of the password "passwordthatisverylong" is the same hash as the previous example): [cs465ta@ta-14]$ ./hasher passwordthatisverylong st stqZw66BRck1U Now, to hash the password "password" with salt "yoursalt" using MD5: [cs465ta@ta-14]$ ./hasher password '$1$yoursalt$' $1$yoursalt$7/tmQXmlhL0pYfN/fyBZS1 Notice that the entire password is hashed using MD5 (not just the first eight characters): [cs465ta@ta-14]$ ./hasher passwordthatisverylong '$1$yoursalt$' $1$yoursalt$Q6SC8nsu19v0q.GOf5WbB0 |
|||||||||||