Most of us are familiar with usernames and passwords, the most common tool to secure information from unauthorized access. However, not everyone is familiar with the security requirements for strong passwords and because of this, many user passwords can be easily guessed.
What is a password and how are they validated?
Passwords are a memorized secret to confirm an identity (authorization) and have been used in various forms since ancient times. In the earliest days of computing, they were stored as plain text and simply checked against what a user typed in at login. This method has serious security implications if the password store is breached as an attacker immediately knows all passwords for users on the system, regardless of length or complexity.
stored_value = user_typed_password
alice:superman bob:password1 charlie:Fall2019
To improve upon this, password hash functions were introduced in the 1970’s to require storage of only the result of a cryptographic operation on the input data (the password). These functions are designed to be one-way operations meaning that if the password store is breached, an attacker cannot simply reverse the operation to identify the plaintext. The attacker must run different possible passwords through the function and check if the result matches the hash in order to determine what the original password was. An attacker also has the option of precomputing hashes for a variety of common inputs (e.g. all words in the dictionary) and then simply checking them against the list.
stored_value = md5(user_typed_password)
alice:$1$GLYHSR228wBAkRNvszBcq bob:$1$qRY8xKlXT1hpwSbHLHz1F1 charlie:$1$099M/j2rhUjhJNhubIDer.
Security was further improved in the 1980’s with the introduction of password salt. This addresses a weakness when a password hash list is leaked and an attacker can generate the hash of a possible password and check it against the entire list at once. Salting adds a small, unique value before each stored hash and adds this value to what the user types. This means that an attacker has to compute a hash for each user rather than the whole set at a time which considerably slows them down. This method also mitigates the risk of precomputed hashes (rainbow tables) as the attacker doesn’t know the salt for a given hash ahead of time.
stored_value = md5(salt + user_typed_password)
alice: $1$UrrgPCS4$fYVkQbmimV4BvRA3qgGvt. bob:$1$EsGn7ajE$VYOlDX65VEmqkWADSXBt20 charlie:$1$u89C7Lrn$tsZoknNc1UMtHVKxdhXTf0
Additionally, passwords can be stored in plaintext encrypted with some form of reversible encryption (e.g. AES). Brute force attacks against the encryption key itself are nearly impossible but if the encryption key can be obtained from memory or unsecured configuration file, this method is as weak as plaintext.
Unix systems store passwords hashed and (usually) salted in the
/etc/shadow files. /etc/passwd stores all the user data and attributes required during login. Additionally, the GECOS field contains general user information such as name and phone number. /etc/shadow stores the actual hashed user passwords and the additional properties related to the password.
Only the root user and privileged processes can read from it directly. Unprivileged processes must authenticate using the PAM (Pluggable Authentication Modules) library, which checks if the user password is correct without exposing the password hash.
- Password field (x indicates that the encrypted password is stored in /etc/shadow file).
- Reserved User ID (ID 0 is reserved for the root).
- Group ID.
- Gecos field contains additional info such as user’s full name, email, phone number.
- Absolute path of the home directory, where the user will be after he/she logs in.
- Absolute path to the shell the user uses.
- Password hash:
Usually stored in the format
$id$salt$hash, where the id identifies the hashing algorithm: $1$ is MD5 $2$ is bcrypt $5$ is SHA-256 $6$ is SHA-512
- Days since last password change in Unix time.
- The minimum number of days required between password changes.
- The maximum number of days the password is valid.
- The number of days before password expiration that user is warned that his/her password must be changed.
Types of password attacks
Password attacks generally break down into online cracking and offline cracking. With online cracking the attacker attempts to authenticate against a remote service. Login attempts are typically limited to only a few per second and most systems are logged and will lock out attackers after 5-10 failed attempts. This method is generally only useful if the attacker has a good guess of a user’s password.
If the attacker has access to password hashes like shown above, they can attempt to crack the password offline where specialized software is used to run password attempts through the same algorithm as the actual application. Speed is limited only to processing power and depending on the algorithm and available resources, thousands to billions of password attempts per second against are possible with no fear of being locked out.
The simplest but most time-consuming type of attack is brute force where the attacker tries all possible combinations in a given keyspace, for example all possible 4 character passwords.
aaaa aaab aaac …
Brute force attacks are guaranteed to find the correct password, but the amount of work increases exponentially with length.
Also known as a wordlist attack, is a straightforward attack, which simply reads a text file (dictionary) line by line and tries every line as a possible password candidate. The dictionary can be derived from common words in the language, previously cracked passwords, or target-specific information. Note that using a large wordlist is not the same as using an effective wordlist; basic reconnaissance can help you to learn about the target and find a matching wordlist or you can create a custom wordlist by using crunch or an online wordlists generator.
Basically, a recompilation of a dictionary, where each word of a dictionary is appended to each word in a dictionary.
For example, if the dictionary contains these words:
one two three four
The password candidates would be:
oneone onetwo onethree onefour twoone twotwo twothree twofour threeone threetwo threethree threefour fourone fourtwo fourthree fourfour
A hybrid attack is a combination of a dictionary attack and a Brute-force attack where each word in the dictionary is modified according to a set of rules.
If you have a dictionary with the word
password in it, a hybrid attack could create a cracking list with all the possible combinations of the word with three numbers before and after.
password001 password002 password003 ... password999 001password 002password ... 999password
Another problem in password security nowadays is password complexity. Keep in mind, the easier the password is to remember - the easier it is to guess for the attacker. Passwords written on sticky notes or stored in plain text negate the security of the password, no matter how sophisticated it is. To make passwords more memorable, people re-use the same passwords over and over again. Also, the most common and the worst ideas for passwords are:
- Pet names
- A notable date, such as a wedding anniversary
- A family member’s birthday
- Your child’s name
- Another family member’s name
- Your birthplace
- A favorite holiday
- Something related to your favorite sports team
- The name of a significant other
- The word “Password”
The password strength is measured in its effectiveness against brute-force attacks - it estimates the average number of attacker trials to guess the correct password. The strength of the password can be increased by increased length, complexity, entropy and security design.
Password Cracking Tools
Crunch is a wordlist generator (installed on Kali Linux by default) which can generate a wordlist from a given character set or a pattern.
It has multiple generation modes:
- To create a dictionary with certain symbols:
root@kail:~# crunch 5 5 12345 -o output.txt Crunch will now generate the following amount of data: 18750 bytes 0 MB 0 GB 0 TB 0 PB Crunch will now generate the following number of lines: 3125 crunch: 100% completed generating output root@kail:~# head output.txt 11111 11112 11113 11114 11115 11121 11122 11123 11124 11125
- To create a dictionary from a certain pattern:
root@kail:~# crunch 9 9 qwe RTY 123 \#\@ -t Pa@s,o^d% -o output.txt Crunch will now generate the following amount of data: 540 bytes 0 MB 0 GB 0 TB 0 PB Crunch will now generate the following number of lines: 54 crunch: 100% completed generating output root@kail:~# head output.txt PaqsRo#d1 PaqsRo#d2 PaqsRo#d3 PaqsRo@d1 PaqsRo@d2 PaqsRo@d3 PaqsTo#d1 PaqsTo#d2 PaqsTo#d3 PaqsTo@d1
- To create a dictionary by shuffling different strings:
root@kail:~# crunch 1 1 -p Range Force Pass Crunch will now generate the following amount of data: 90 bytes 0 MB 0 GB 0 TB 0 PB Crunch will now generate the following number of lines: 6 ForcePassRange ForceRangePass PassForceRange PassRangeForce RangeForcePass RangePassForce
John the Ripper
John the Ripper or just John is a password cracking tool which supports most of the commonly used types of hashes. It only works with salted hashes and it brute-forces passwords that are shorter than 8 characters.
john [hash file] --wordlist=[wordlist path]
John will load the hashes, analyze the type of hash and identify salts. Afterward, it will proceed with the attack. Some of them might take a while as John the Ripper has a huge variety of attack modes, rules, filters, and utilities. As John itself works only with hashes, it can not work with encrypted files. That is when its utilities come in handy.
Unshadow is a function to optimize the cracking of the user passwords. It combines the files passwd and shadow in a single file, so John can use the data from Gecos field to enhance the wordlist.
unshadow /etc/passwd /etc/shadow > unshadowed.txt
Converts compressed and password protected files from *.zip and *.rar to the suitable John format, which contains the password hash.
zip2john [compressed file] > [hashfile]
Hydra is another popular password recovery tool and is often referred to the same application area as John the Ripper, despite Hydra being an online password cracker.
It supports numerous protocols to attack and is intended for password brute forcing on remote systems.
root@kali:~# hydra -l root -P /usr/share/wordlists/rockyou.txt -t 6 ssh://192.168.1.1 Hydra v7.6 (c)2013 by van Hauser/THC & David Maciejak - for legal purposes only Hydra (http://www.thc.org/thc-hydra) starting at 2014-05-19 07:53:33 [DATA] 6 tasks, 1 server, 1003 login tries (l:1/p:1003), ~167 tries per task [DATA] attacking service ssh on port 22
Patator was developed as a more flexible alternative to other brute-force tools such as THC Hydra. As patator is not as user-friendly as some of the other tools, let’s break down the example syntax.
patator http_fuzz auth_type=basic url=http://example.com user_pass=admin:FILE0 0=wordlist.txt -x ignore:code=401
This command interprets into use HTTP Brute-force module to bypass basic authentication at target example.com for the user admin using the entries of wordlist.txt as password candidates, and ignore 401 Unauthorized responses.
One of the common tools which offer multiple attack modes for effective password recovery. It supports CPU and GPU-acceleration which helps to crack hashes in a shorter time. The principle of work in most of the password recovery tools is similar - by picking a possible candidate for a password from the predefined wordlist.
hashcat [-m] [-a] [-o file] [hash-file] [wordlist]
-m - type of hash; -a - attack mode; -o - path for the output file;
root@server:~# hashcat -m 0 hashes rockyou.txt --force hashcat (v4.0.1) starting... OpenCL Platform #1: The pocl project ==================================== * Device #1: pthread-Intel(R) Xeon(R) CPU E7- 4870 @ 2.40GHz, 256/739 MB allocatable, 1MCU Hashes: 8 digests; 8 unique digests, 1 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Rules: 1 Dictionary cache built: * Filename..: rockyou.txt * Passwords.: 14344391 * Bytes.....: 139921497 * Keyspace..: 14344384 * Runtime...: 3 secs
Hopefully you now have a basic understanding of how passwords are stored and cracked. With these techniques in mind, some good advice for creating a password is that:
- It must be at least 8 characters long (12+ is better)
- It must contain upper and lower case characters, digits and special characters.
- You must not store your password anywhere, except in your mind (consider a password manager to limit the number you have to memorize)
- Use two-factor authentication where possible.
- You can use a passphrase to easily remember complex passwords.