Chapter 14
Passwords

Passwords are a hacker's best friend. They can be guessed, intercepted, stolen, and reused to gain access to services or systems. They are often the keys to sensitive data, yet far too often they're unsuited for the task at hand. People often select weak passwords, like the name of their pet, favorite sports team, or significant dates that can be easily guessed.

People who design systems can also make poor decisions. What if it was more intuitive for people to generate stronger passwords? Beyond this, there is also the issue of storing passwords as hashes so that authentication can take place.

In this chapter, we take a look at password hashes, what they are, and how to crack them in order to obtain the plaintext passwords that they're supposed to protect. Throughout this book, you have seen ways that you might reach a system's /etc/shadow file. We have also examined how to extract hashes from a Windows system and from other types of databases. Now let's try to crack the passwords from these files.

Hashing


Hashing is the process of taking input of arbitrary size, such as a string of text, a password, or a file, and producing output of a fixed size—for example, a number, often displayed as hexadecimal or base64. Hashing has different applications in computing. It is used in data structures (such as a blockchain, the underlying structure of cryptocurrencies) to check the integrity of communications and to store passwords. Naturally, it is this last application that we will focus on here.

If you sign up for an online service, supplying some personal details including your email address and password, what happens to that password? Ideally, it will be transmitted (along with your other information) over HTTPS to the service, where a secure hashing algorithm or function is applied to the password. The result of this algorithm will be a hash.

The search engine DuckDuckGo (duckduckgo.com) can be used to generate hashes of different kinds quickly, and you may find it useful to use this for experimentation and learning. Submitting the search query sha512 mypassword will result in the following output:

a336f671080fbf4f2a230f313560ddf0d0c12dfcf1741e49e8722a234673037d
c493caa8d291d8025f71089d63cea809cc8ae53e5b17054806837dbe4099c4ca

This is a hash of the plaintext mypassword. The algorithm used to create this hash is SHA512. Remember that this output is a number, displayed in hexadecimal. You can imagine something similar taking place when you submit your password to a web application. The original password will be discarded, and the hash will be stored in a database. At least, that is what should happen (along with some additional measures that we will get to shortly).

Whenever you subsequently sign in to the online service, a similar series of events will take place. Your password will be transmitted over HTTPS, hashed, and then this hash will be compared to the hash stored in the database. If there's a match, you'll be logged in. This is similar to when you log in to a UNIX-like operating system (OS), only the database is a flat file: /etc/shadow. At least this is how it should happen, but all too often the passwords are stored by some applications insecurely and not hashed at all.

One of the security benefits of hashes is that they can be created quickly, with modest computing power, yet they take a much longer time to derive the plaintext. In fact, secure hashing functions are said to be one-way because you cannot simply enter a password, or private key, to recover the plaintext. Theoretically, if a malicious party gains access to a database full of hashes, then that's all they have—hashes. It shouldn't be possible to derive a password simply by looking at its hash. Hashes usually cannot be used to log in, because the hash of a hash should not equal the original hash!

Contrast hashing to encrypting. If a database full of encrypted passwords is discovered, then there is a way to decrypt them. (The process of encryption is reversible; otherwise HTTPS, SSL/TLS, and various other secure communication protocols wouldn't work.) It might be the case that a single key (or password) is all that it takes to decrypt them all. Organizations have been known to store passwords in this way (or bizarrely, without any attempt to obfuscate the plaintext). This is a mistake that could prove costly in the event of a breach.

Ideally, a secure hashing function will produce a unique hash for every unique input, but this is not always the case. Older hashing algorithms have been found to produce the same hash for different input. This is known as a collision, and it means that an algorithm should not be used where security is important, as two or more different passwords could be used to log in to a user's account!

The Password Cracker's Toolbox


Here is the password cracker's toolbox, a collection of utilities that can be used to recover the plaintext password from an encrypted or hashed password:

  • Hashcat
  • John the Ripper (also known as John)
  • Ophcrack and RainbowCrack (for rainbow table–based cracking)
  • L0phtcrack and LCP (Windows utilities for cracking hashes)
  • Cain & Abel (for cracking hashes on Windows systems)
  • HashID (originally a hash identifier)
  • CeWL (word list generator)
  • Word lists
  • Hash tables
  • Rainbow tables

Cracking


Even though hashing is said to be a one-way function, it is possible to obtain users' original passwords from databases containing hashes. Remember when we looked at have I been pwned (HIBP) as part of the open-source intelligence (OSINT) activities at the start of this book? HIBP has a database of password hashes against which you can compare your own passwords to see whether they have been leaked in a breach.

How does a cracker take a list of hashes and turn them into passwords? In theory, the idea is simple. Take a list of common passwords and work your way through the list, hashing each password as you go. After hashing each password, compare that hash to the leaked hashes. If you get a match, it means that you've identified a correct password. To be more accurate, you've identified a string of characters that, when hashed, results in the same hash as found in your “stolen” list.

Tools have been created for this very purpose. John the Ripper is a tool specifically designed to crack stored password files of UNIX-like systems. We will use John the Ripper shortly.

Here are some MD5 hashes of weak passwords:

  • 5f4dcc3b5aa765d61d8327deb882cf99
  • bdc87b9c894da5168059e00ebffb9077
  • 4cb9c8a8048fd02294477fcb1a41191a
  • e10adc3949ba59abbe56e057f20f883e

To demonstrate how cracking hashes works in practice, we will use a tool called Hashcat (hashcat.net/hashcat ), which claims to be the “world's fastest and most advanced password recovery utility.” Hashcat is highly configurable, with many different options that can be included on the command line. Before running the tool, add the previous hashes (or some of your own) to a text file, one hash per line. Then try running this command:

hashcat -m 0 hashes.txt /usr/share/wordlists/rockyou.txt

This may not work for a number of reasons. To begin, you will need to make sure that a file called hashes.txt exists in the current directory and that /usr/share/wordlists/rockyou.txt also exists. Rockyou.txt is one of the word lists included with Kali Linux. In case you do not have these word lists installed, you can simply enter apt install wordlists. You will also need to extract the rockyou archive.

You may see an error such as the following, in which case add the --force option, which is OK to use for learning purposes.

* Device #1: Not a native Intel OpenCL runtime. Expect massive speed loss.
 You can use --force to override, but do not report related errors.
No devices found/left.

If you intend to do some serious cracking, you will likely want to run Hashcat on your host OS and allow it to make direct use of your graphical processing unit (GPU) for better performance. The complete command should look like this:

hashcat -m 0 --force hashes.txt /usr/share/wordlists/rockyou.txt

The -m option is used to specify the type of hashes in the file, hashes.txt. In this case, 0 has been used to specify raw MD5. You should see output similar to the following when running Hashcat successfully:

hashcat (v5.1.0) starting…
 
OpenCL Platform #1: The pocl project
====================================
* Device #1: pthread-Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz, 1024/2960 MB allocatable, 1MCU
 
Hashes: 4 digests; 4 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
 
Applicable optimizers:
* Zero-Byte
* Early-Skip
* Not-Salted
* Not-Iterated
* Single-Salt
* Raw-Hash
 
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
 
ATTENTION! Pure (unoptimized) OpenCL kernels selected.
This enables cracking passwords and salts> length 32 but for the price of drastically reduced performance.
If you want to switch to optimized OpenCL kernels, append -O to your commandline.
 
Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.
 
* Device #1: build_opts '-cl-std=CL1.2 -I OpenCL -I /usr/share/hashcat/OpenCL -D LOCAL_MEM_TYPE=2 -D VENDOR_ID=64 -D CUDA_ARCH=0 -D AMD_ROCM=0 -D VECT_SIZE=8 -D DEVICE_TYPE=2 -D DGST_R0=0 -D DGST_R1=3 -D DGST_R2=2 -D DGST_R3=1 -D DGST_ELEM=4 -D KERN_TYPE=0 -D _unroll'
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes…..: 139921507
* Keyspace..: 14344385
 
e10adc3949ba59abbe56e057f20f883e:123456
5f4dcc3b5aa765d61d8327deb882cf99:password
4cb9c8a8048fd02294477fcb1a41191a:changeme
ef749ff9a048bad0dd80807fc49e1c0d:Password1234
 
Session……….: hashcat
Status………..: Cracked
Hash.Type……..: MD5
Hash.Target……: hashes.txt
Time.Started…..: Thu May 9 13:09:22 2019 (0 secs)
Time.Estimated…: Thu May 9 13:09:22 2019 (0 secs)
Guess.Base…….: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue……: 1/1 (100.00%)
Speed.#1………: 1717.7 kH/s (0.27ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered……..: 4/4 (100.00%) Digests, 1/1 (100.00%) Salts
Progress………: 539648/14344385 (3.76%)
Rejected………: 0/539648 (0.00%)
Restore.Point….: 538624/14344385 (3.75%)
Restore.Sub.#1…: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1….: SHYANNE1 -> Monique4
 
Started: Thu May 9 13:09:20 2019
Stopped: Thu May 9 13:09:24 2019

The tool provides a lot of output. However, perhaps the part you're most interested in is that which has been highlighted. The highlighted part of the output shows the hashes and the passwords that generated them. You can see that using weak passwords in combination with a dated hashing algorithm, such as MD5, offers little protection over plaintext—it just adds a few hours of inconvenience for the hacker, depending on the strength of the password.

What if a more secure hashing algorithm is used? Let's try cracking this SHA512 hash with Hashcat:

ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baea
e6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413

You will need to change the -m option to 1700 to denote raw SHA512.

* Runtime…: 2 secs
 
ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae69
56df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413:123456

You will notice that Hashcat takes only a little while longer—a matter of seconds—to crack these hashes. The same weak passwords have been hashed with a more secure algorithm. Nevertheless, they are still weak passwords. Improving the hashing algorithm does little to protect users with weak passwords. Hashcat has cracked these hashes quickly by hashing the passwords in the supplied word list and then comparing these hashes to those in the hashes.txt file.

What happens if there are passwords that are not in your word list? By default, John the Ripper will try a word list first, before moving on to “incremental” mode. It will produce a hash from every combination of characters within a defined set of rules and compare each hash in turn. It will find any passwords that use a random combination of characters up to a certain length. As you can imagine, this will take some time if the program starts with a string of aaaaaa and works its way through every alphabetical combination up to zzzzzzzzzzzzzzzz, or whatever length you specify.

What if you want to include numbers and special characters in your generation rules as well? There are a lot of potential combinations, each of which needs to be hashed and compared. Suddenly, cracking passwords is starting to sound a little tedious. This is not necessarily a problem for a malicious hacker, because this method will still uncover any weak passwords in the stolen database. Users who used short passwords, which contain only alphabetical characters, may soon find their accounts compromised, while those that picked passwords with a higher level of entropy would not.

How do we crack as many passwords as possible, as quickly as possible? One way is to invest in better hardware—graphics cards or custom chips for cracking, for instance. We will come to this later in this chapter. Another approach is to use a precomputed list of hashes, known as a hash table, or a complex variation of this known as a rainbow table.

Hash Tables and Rainbow Tables


Instead of generating hashes and comparing them to those in a database on the fly, why not use a list of precomputed hashes to save on processing time? You could take a list of common passwords, hash them, and store the results in a file to create a lookup table or hash table. This is the idea behind crackstation.net.

You could also take every combination of characters up to a certain limit, hash them, and store them in the same way. The result would be a very large file (depending on the number of combinations included), but after the initial creation of the table, time and processing power would be saved on all future cracking attempts. You just need enough disk space to store your tables—at least one table of hashes for every popular hashing algorithm. Hash tables should not be confused with rainbow tables, which are a little more complicated.

The idea behind a rainbow table is to allow the hashes of longer, more complex passwords to be stored, benefiting from a time-memory trade-off technique by accessing previously stored calculations from a file. To do this, rainbow tables use chains that consist of alternating plaintext strings and hashes. There may be hundreds of thousands of hashes and plaintext strings in a chain, and the table will consist of many chains. The table does not store every value in the chain, however, just a random seed value for the chain, which could be aaaaaaaa. The final value of the chain is also stored. At runtime, the chain is re-created, so plenty of processing power is still required.

To create the chain, the seed value at the start of the chain is hashed using the same hashing algorithm against which the rainbow table is intended to be used. Then the hash of the seed value has a reduction function applied. A reduction function can be any function that converts the hash into something that is usable for a password. A simple example would be to apply base64 encoding to the hash and then clip the end of the output so that it is within the given size restrictions. The output from the reduction function is hashed again, producing a new hash, and the process of hashing and reducing continues for the length of the chain.

To crack a password hash, the hash in question has the same process as previously described applied to it. Each link in the chain is compared with the final value of the chain, and if there is a match, it means that somewhere in the chain the plaintext password exists.

A hash table can, and should, be used to store the hashes of common passwords. It should take fractions of a second to crack a password hash that exists in this table.

A rainbow table makes a trade-off between disk space and processing power to allow a cracker to recover complex passwords—that is, nondictionary words. A rainbow table, unlike a hash table, does not contain every possible hash created by every combination of characters. It stores only the seed and end values for each chain that allows hashes to be generated. The result is still a huge file, but a hash table containing every precomputed hash would be much larger. Rainbow tables are an example of a cryptanalytic time-memory trade-off, an idea first published by Martin Hellman in 1980 and improved upon by Ron Rivest and then by Philippe Oechslin. Oechslin invented rainbow tables, and he is also one of the developers of Ophcrack. You can read Hellman's paper, “A Cryptanalytic Time – Memory Trade-Off,” at ee.stanford.edu/~hellman/publications/36.pdf, and you can read Oechslin's “Making a Faster Cryptanalytic Time-Memory Trade-Off” at lasec.epfl.ch/pub/lasec/doc/Oech03.pdf.

For a more detailed explanation of rainbow tables, check the Wikipedia entry at en.wikipedia.org/wiki/Rainbow_table.

If you come across older hashes, such as Microsoft's flawed LANMAN hash (which is not a true hashing function, as it is reversible) or MD5, and you are using a rainbow table, it may only be a matter of seconds to get the password. You can find pregenerated rainbow tables online, and Ophcrack comes with a small selection of some for common Windows hashes like LANMAN.

Adding Salt


If an attacker finds several hashes and is able to “crack” some of them—that is, guess the correct plaintext—then once one password has been guessed, if any other user on the system has used the same password, then the attacker now also knows the plaintext of those hashes, as the attacker just needs to search for the same hash. A salt gets around this problem, meaning that badpassword1232 and badpassword123 do not result in the same hash. This can slow down cracking attempts, and where large salts are used in conjunction with strong passwords, hash tables and rainbow tables become impractical forms of attack. This is because a table is required for every salt in use, which greatly increases the amount of disk space required.

Salts should be randomly generated for each hash. Suppose a user chooses a password of mypassword1234 to protect their account. As an MD5 hash, it will look like this:

b191429eb39ee4c5358f87a3462cb541

Now let's add a salt. For demonstration purposes, any pseudorandom number generator will do. You could use www.random.org, which allows users to create all sorts of random numbers in different formats, but it is highly ill-advised as a security function. Here are 10 bytes generated using a random byte generator:

5cd43bbf3ff15df4b03f

Now take the original plaintext password, and concatenate these random bytes:

mypassword12345cd43bbf3ff15df4b03f

Finally, hash this entire series of characters. Here's the MD5 hash of mypassword12345cd43bbf3ff15df4b03f:

c141d651ef63ebfa3cbc921441503e81

When a salt has been used, a hash is said to be salted. In contrast, where no salt has been used, a hash is sometimes referred to as raw. If any of the other millions of users of our hypothetical database happened to use the same password of mypassword1234 and as long as unique random salts were used for every hash, then cracking attempts will be slowed down somewhat because, despite having the same password, each user would have a unique hash consisting of the password and salt.

The salt does not need to be remembered by a person or stored in your password manager. It is usually stored alongside the hash in the database of the website or service that you are accessing. The salt is not secret, as a password should be, and it is needed whenever the user logs in with their password. This means you can still crack passwords using a tool like Hashcat or John the Ripper. John will detect that salts have been used and use them when generating hashes. Adding salts to hashes in a database of passwords should be considered mandatory for applications being developed with security in mind. There are different ways of applying salts. Sometimes, the plaintext will be hashed and then hashed again with a salt. This is just one variation of salt use.

Into the /etc/shadow


Now let's take a look at a Linux shadow file and attempt to crack the password hashes within. For this, we will use the shadow file from our vulnerable mail server, which contains a number of users with no password. If you extract only users with passwords, you'll be left with the following:

root:$6$GoW/Ulto$H6vTUsHXKsEjU4JNIR2MJebQ25iI8UC84HZeCHb9J9jMfDUC7xqJbWik0O.kBlf0XB6IjszxBP9CNOJWZFlDq1:17181:0:99999:7:::
cyrus:ttFfjt7KRsGP6:17181:0:99999:7:::
peterp:pATfNCwRanDjY:17181:0:99999:7:::
johnk:DzPcnj3NPsX1Y:17181:0:99999:7:::
charliew:VxvogCke/Q7Mo:17181:0:99999:7:::
roberta:zQdcTcfU2NVaQ:17181:0:99999:7:::
sarahk:Yy.jZjZKD3zWM:17181:0:99999:7:::
jennya:JjwPBOd1Vailc:17181:0:99999:7:::

There are a few things to point out here. First, notice that the root user's line (the first line of the file) is longer than the other users. This is because the root user's password has been hashed using a different algorithm than the others. SHA512 has been used, which is denoted by the $6$ at the start of the string. Actually, the dollar sign is usually used as a separator in shadow files to split the hash string into three components as follows:

equation

The root user's hash string is as follows. The dollar-sign separators have been highlighted here:

$6$GoW/Ulto$H6vTUsHXKsEjU4JNIR2MJebQ25iI8UC84HZeCHb9J9jMfDUC7xqJbWik0O.kBlf0XB6IjszxBP9CNOJWZFlDq1

The other password hashes in the mail server's shadow file do not use this format. They use a different and very insecure algorithm. You'll soon discover what this is with the help of John.

You might also be wondering about the various characters used in these hashes. They are not hexadecimal. Hashes in shadow files are often encoded, similar to the base64 used by web applications, but they are not quite the same. The 64 characters used are A–Z, a–z, 0–9, a period ( .), and a forward slash ( /).

The hash string that uses dollar signs as separators is part of a longer line—nine fields in total—which uses a colon as a separator.

equation

Here's what the other fields in that string mean:

  1. The number of days since the start of Unix time (01/01/1970) when the password was last changed.
  2. The number of days until the password can be changed.
  3. The number of days before the password must be changed. A value of 99999, as shown earlier, indicates that the user will not be forced to change their password.
  4. The number of days of advance warning that a user is given before being forcing to change their password.
  5. The number of days after the password expires when the account will be disabled.
  6. The number of days since the start of Unix time that the account has been disabled.
  7. The final field is reserved for future use.

Launching John with its default settings is straightforward. You just need to supply a shadow file. To begin, try removing the root user line from the shadow file (always make a copy of shadow files before manipulating them) so that all hashes are of the same type, and then supply the edited file to John as follows:

john mailserver.shadow

When John starts, you will see output similar to the following, before any cracked hashes are displayed:

Using default input encoding: UTF-8
Loaded 7 password hashes with 7 different salts (descrypt, traditional crypt(3) [DES 256/256 AVX2-16])

John has detected the type of encryption in use. You can see the words traditional crypt (3) here. Check out the man page for crypt ( man crypt) on your Kali Linux VM for some information about this. These passwords were encrypted using the Unix crypt() function, which is based on the Data Encryption Standard (DES) algorithm. Believe it or not, the passwords contain a tiny two-character (12-bit) salt. The crypt()function takes the user's password and repeatedly encrypts it to create the output.

The algorithm is flawed, however, and it should no longer be used, as computers can perform this calculation very quickly today. Nonetheless, what it does is to take 7 bits from each of the first eight characters of the user's password to create a 56-bit key. Anything beyond the first eight characters of a password is discarded! This 56-bit key is used to encrypt a constant value repeatedly—often a string consisting entirely of zeros. The result of this repeated encryption is a series of 13 printable ASCII characters, with the first two characters representing the salt and the rest of the characters denoting the hash.

Debian used to use this same system to protect its shadow file. At one time, there were plenty of people using it, setting long, complex passwords, but they were unaware that only the first eight characters were stored!

Perhaps you remember 3DES from Chapter 8, “Virtual Private Networks.” 3DES improves on DES by using DES several times, resulting in a larger key space of 112 bits. This is still not considered secure enough by today's standards. The Advanced Encryption Standard (AES) is now preferred over DES or 3DES for encrypting files or communications.

We have gone slightly off-topic here, since we're now in the realm of encryption rather than hashing. Remember that hashing and encryption are different processes: Encryption should be reversible with a key, but hashing should not be reversible. Confusion sometimes arises because certain hashing algorithms (such as the crypt function used to hash the mail server's passwords) are based on encryption algorithms.

Modern shadow files should not contain such weakly hashed passwords. You are more likely to see entries such as the root user's password hash (shown in the previous screen output of a shadow file). John has no problem detecting this type of hash (a salted SHA512 hash), so have a go at cracking it if you want! You will need to paste that hash back into the shadow file that you altered or supply a file to John containing only the root password hash. John, like Hashcat, can be set up to utilize your system's graphics card (see Figure 14.1), which is recommended if you plan on doing a lot of password cracking.

Snapshot of GPU cracking with John the Ripper.

Figure 14.1: GPU cracking with John the Ripper

You can tell John the format of the supplied hashes by entering the following:

 john --format=Raw-MD5 admin.txt

John is well suited to cracking a number of other types of files and not just shadow file entries. Here's an example of password hashes, as stored by MySQL, which you could try supplying to John:

mysql> SELECT DISTINCT CONCAT(user, ':', password) FROM mysql.user;
+------------------------------------------------------------+
| CONCAT(user, ':', password) |
+------------------------------------------------------------+
| root:*FE68E6FDAF9B3EA41002EF1E28BE4A6EAF3A1158 |
| debian-sys-maint:*02B9399FC6A06E4D09A609700C0B259750F352BA |
+------------------------------------------------------------+
2 rows in set (0.00 sec)

Different Hash Types


When hashing passwords, it is important that a suitably strong algorithm be used. A good algorithm should produce unique output for each input. When two unique inputs produce the same output, a collision occurs. Algorithms such as Message Digest 5 (MD5) and Secure Hash Algorithm 1 (SHA-1) were once used in security applications, but they have since been shown to exhibit collisions. In other words, it is theoretically possible to log in to a user's account using something other than the password they chose! You should be on the lookout for places where such algorithms are used—they are unquestionably not secure—and seeing them in use by your client should be highlighted.

Let's examine some commonly used hashing algorithms and how they appear. As you will see, it is often possible to determine the hashing algorithm used based purely on the length of the string that is produced. If you are unsure, you can use the HashID tool. For basic usage, use the following command:

hashid <FileContainingHash>

If you want to check the type of hash used on the root user's password, you would need to make sure that only the hash string is in this file—additional text-like usernames and colons will stop HashID from working. Feeding HashID a file containing the following string will work:

$6$GoW/Ulto$H6vTUsHXKsEjU4JNIR2MJebQ25iI8UC84HZeCHb9J9jMfDUC7xqJbWik0O.
kBlf0XB6IjszxBP9CNOJWZFlDq1

MD5

Once popular, this algorithm should no longer be used for any security purpose. You may still find it in the wild, however, in which case it poses a serious security risk that should be reported. MD5 hashes (encoded as hexadecimal) look like this:

1bc29b36f623ba82aaf6724fd3b16718

In an /etc/shadow file (MD5 can also be used in this context), you would see something like this:

$1$ja26g4Pi$eGHKAXkdsQHQeGkpousRk.

Remember that the dollar signs are separators. This shadow file hash string consists of a 1, which indicates MD5, a salt of ja26g4Pi, and then the hash itself.

SHA-1

Version 1 of SHA should no longer be used because of it being vulnerable to collisions, but again, you may still see it in use. Here's an example:

d1ff8c1243807824b5349918340ad4b0036aed67

SHA-2

Version 2 of SHA is widely used at the time of this writing, and it comes in different variants or bit lengths. SHA-2 is certainly recommended over MD5 and SHA-1. The number proceeding SHA (SHA256/384/512) tells you the bit length. The larger the number of bits, the stronger the hashing function. SHA512 is widely used and currently recommended. Here are some examples of hashes.

SHA256

Here's an SHA256 hash displayed as hex:

d6140805ec182805fbd76c8a4cdce71b9478676957796c722ec596cd4d91040f

SHA512

Here's an SHA512 hash displayed as hex:

89ad667b10f0d7f594788e8f4211a32e8dc61ef24ea42065a9600a1b12f91691364ee
3767bd2788512fbe8a206c4249795b24e9a1ceee33265f57ae755492019

In an /etc/shadow file, you should expect to see something like the following:

$6$3cw3tPaa$Ya9Q7rnFf90FO0/nJWVTqeT5AA.IiIsJjdgtt67GTkTVu42HGGlBVZ5
JuQWfvZP1WVz/9sHaW7N0HZyabA4ac.

The 6 is used to specify SHA512, and a salt of 3cw3tPaa has been used.

bcrypt

Earlier, we saw that the mail server's shadow file contained values generated by the Unix crypt() function (which uses DES). Bcrypt is a different encryption function that is based on the Blowfish cipher. Blowfish, like DES, is designed for encryption, and although not as flawed as DES, bcrypt has been shown to exhibit weaknesses. Bcrypt is used by OpenBSD, arguably the most secure UNIX-like distribution in existence, as well as by some Linux distributions. It is also used by Ruby on Rails (an open source web application framework). Here's an example of a bcrypt hash as you might see it in a shadow file. Note that although the same dollar-sign separators are used, the fields are not the same for a bcrypt hash as for some other hashes.

$2b$12$FPWWO2RJ3CK4FINTw0Hi8OiPKJcX653gzSS.jqltHFMxyDmmQ0Hqq

The first field, 2b, denotes bcrypt. The second field denotes the cost factor, which in this case is 12. This means that the 212 iterations of bcrypt's key derivation function (which will be explained shortly) are applied to the supplied password and a randomly generated salt. The first 22 characters of the third field are the salt, and the remaining characters are the hash.

CRC16/CRC32

The Cyclic Redundancy Check (CRC) algorithm has been used for a long time to generate checksums. It should never be used to generate a secure hash. It is unlikely that you'd see it being used for this purpose, but we include it here as it is a commonly used algorithm that sometimes is mistakenly used as a hash function.

PBKDF2

Password-Based Key Derivation Function (Version) 2 (PBKDF2) is a key derivation function, which is commonly used for password hashing. Key derivation functions are used to generate, or derive, a secret key from an existing secret key or password. Key derivation functions are often made deliberately slow, so as to slow down any brute-force attempts. They create a stronger, more secure secret key than the original key or password, using a technique known as key-stretching. This can be used to produce a derived key that is longer than the original password, or in a different format altogether.

The hash generated by the key derivation function is hashed, and then that hash is hashed again. This process can be repeated hundreds or thousands of times. This means that whenever a user logs on to the system, their supplied password must be hashed the same number of times and the end results compared. This makes logging on a marginally slower process for the normal user, and not just those attempting to brute-force accounts. Think about the time it takes for your password to be checked when decrypting your hard drive. This is a common place where PBKDF2 is used. PBKDF2 and other key derivation methods are not hashing algorithms in their own right. They will use some other hashing algorithm, such as SHA-2, and then use the stretching process to increase the complexity of performing a brute-force attack against the hash.

Collisions

All the way back in 2010, two researchers named Tao Xie and Dengguo Feng proved that collisions in MD5 were possible. Look at the two strings of data shown here:

0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942f
eb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef
 
0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942
feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef

These strings are the same, except for the highlighted block that reads 55cb in the first example, and 5dcb in the second. If you were to create an MD5 hash of both, it would result in the same hash as follows:

cee9a457e790cf20d4bdaa6d69f01e41

This shows that two different pieces of input (very similar, yes, but crucially not identical) produce exactly the same hash. This is a collision, and it means that two (or more) different passwords could result in the same hash. This indicates it may be possible to log on to a user's account using a number of different passwords—not just the one actual password. You might think that this is unlikely, but consider the processing power of modern computers and how quickly they can generate hashes and compare strings to see if they match.

Consider the implications of a collision when it comes to file downloads. In Chapter 3, “Building Your Hack Box,” we explained why checking the integrity of a download is important. MD5 was often used for this purpose, but collisions mean that a malicious party could alter an executable file so that it includes malware and still produces the same hash. This is why secure hashing algorithms are required for checking file or communications integrity too.

Pseudo-hashing


Embedded hardware and systems where storage space is tight often take shortcuts when it comes to security. Instead of hashing passwords, or even encrypting them, they might use a function that produces something that looks like a password hash but is actually nothing more than an encoding string. One example of this is the Cisco Type 7 “encryption” method, which is used on some Cisco network devices. Passwords stored in this way can be trivially reversed to their original plaintext format. These devices used a hard-coded key of tfd;kfoA,.iyewrkldJKD to encode passwords using XOR.

It is an easy mistake to view some data in a table or file and assume that because it looks like it is hashed or encrypted, it actually is! For this reason, you should also apply decoding to data that you find (even just decoding something as base64 can often yield results), as you have seen when looking at web applications. Research the piece of hardware or system that you are testing, just as you would look for flaws in software and services that you find running on a server. You may find some information that allows you to decode strings easily.

Here's an extract of a configuration file taken from a Cisco network switch that uses type 7 passwords:

version 12.2
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname HHSwitch
!
!
banner motd ^C
 HackerHouse Hands-On Hacking Core Switch
^C
!
boot-start-marker
boot-end-marker
!

Further down in the configuration file are some “hashed” type 7 passwords:

enable secret 7 022E055800031D09435B1A1C5747435C
 
 
!
username admin password 7 022E055800031D09435B1A1C

These passwords look like they've been hashed or encrypted, but they're actually just obfuscated and can be decoded using a tool from our website: www.hackerhousebook.com/files/cisco_type7.pl. All that you need to do to run this Perl script is enter the following command:

perl cisco_type7.pl

The script will prompt you for the encoded password:

[+] Cisco 'Type 7' Password Decrypt Tool
[-] Encrypted password?

Paste in the type 7 password “hash” ( 022E055800031D09435B1A1C), et voilà, you will be instantly presented with the plaintext shown here:

[-] Encrypted password? 022E055800031D09435B1A1C
[-] Result: HackerHouse

You might find a config file such as this in a PXE boot area accessible via Trivial File-Transfer Protocol (TFTP) or left in a technical team member's home directory. Hunting file shares for these types of configurations has yielded great results over the years, and it is strongly advised that whenever you gain access to a network, you locate the technicians responsible for managing internetworking equipment and their stored files.

Microsoft Hashes


Since Windows XP, the Security Account Manager (SAM) stores users' passwords. SAM is a database file (stored in C:WindowsSystem32configSAM) on which the Windows kernel keeps a permanent exclusive lock, as long as Windows is running. The file is also encrypted, which makes copying it from disk, for the purpose of cracking it later, more difficult. It is possible to recover hashes from the system's RAM, though, or dump these files provided that you have sufficient rights. Older systems may still be using the flawed LM (short for LANMAN or LAN Manager) hash, while newer systems typically use the NT Lan Manager (NTLM) hash.

With LM hashes, if your password is longer than seven characters but less than 14 characters, two hashes would be created—one for the first seven characters and another for the next seven. Characters were converted to uppercase before being hashed, which made passwords case-insensitive.

Despite Microsoft making the move to an improved system, NTLM, some systems continued to use LM hashes far longer than was safe. This was especially true for organizations that migrated from one OS to the next—for example, Windows Server 2000 to Windows Server 2003 to Windows Server 2008, where security settings were retained from previous configurations. It is trivial to derive the plaintext from an LM hash. It takes mere seconds today with a suitable rainbow table. John comes in handy again when it comes to LM hashes. Here are a few examples that you may want to have a go at:

Administrator:500:D44EC5619C72E05617306D272A9441BB:C9BC6781D1A47512D5D67CAE96258462:::
Guest:501:NO PASSWORD*********************:NO PASSWORD*********************:::
adams:1001:55D7D9FACAAEAC5B09752A3293831D17:A696A6F4DB4BC1178159BE94D4F3EC54:::
jessep:1005:AFF26CC5635ED7916D3A627C824F029F:4A3A3C836B4AAA3B306E5BC434E22345:::
peterh:1002:2212B147D8D319BE88D7822268471CBA:116D0D5AE69780B85E25548284337832:::
stepha:1006:NO PASSWORD*********************:1DF28481C07E99BD11E75B7CE6682BF5:::
thorw:1003:F6622C9A18770B73AAD3B435B51404EE:454F248AA982FB52AEB2034B402B6523:::
walterw:1004:443D5FCB03764D6E92B4C01E7F2E6D90:FC3DE6DDFF4A4D5F68A645001F881644:::

You'll likely see messages from John about the hash types it has detected, and you may notice that John appears to crack some of these hashes and then stops or pauses. Pressing Enter on your keyboard will tell John to report its status, and you can cancel the attempt by pressing Ctrl+C. Use the show option to display the cracked passwords in full once finished or interrupted as follows:

 john --show lanman.txt

John will display the supplied password hash file, but this time showing cracked passwords alongside the usernames. You'll also be told the number of hashes cracked and the number remaining. John automatically records the progress of attempts and will resume where it left off in the event of an interruption.

Try running John with the format option. This will override John's hash format detection. For NTLM hashes, you can use NT as follows:

john --format=NT lanman.txt

For LM hashes, use the LM format:

john --format=LM lanman.txt

You can use the format option alongside the show option. For example:

john --show --format=NT lanman.txt

Here are some NTLM hashes:

Administrator:500:NO PASSWORD*********************:A87F3A337D73085C45F9416BE5787D86:::
Guest:501:NO PASSWORD*********************:NO PASSWORD*********************:::
andyp:1009:NO PASSWORD*********************:420A8B79934C0663B6F532FB0DB16535:::
carrm:1008:NO PASSWORD*********************:5AA88493BB25E1F8357B4565D53DC6A0:::
ericb:1010:NO PASSWORD*********************:BA5EE5061DE675F63F8E7BD022074063:::
marko:1012:NO PASSWORD*********************:1B853BB23B463809C43DCD73DBD52D88:::
pedron:1007:NO PASSWORD*********************:56780793B7CFC4983E85C658D0F9A32A:::
thomasz:1011:NO PASSWORD*********************:1E7A9FB12F8E387A1117D4CEE28F630B:::

Remember that there are other tools that you can use for obtaining and cracking Windows hashes such as 0phcrack (ophcrack.sourceforge.net) and Cain & Abel (www.oxid.it/cain.html), for example.

Guessing Passwords


One way of obtaining passwords is to find hashes and crack those hashes to derive the plaintext. There are other ways to get ahold of (or verify) users' passwords, though. One way is to attempt a brute-force attack using a tool like Hydra, as you previously saw in Chapter 6, “Electronic Mail,” which uses a word list to attempt to log in repeatedly via brute-force. If you are going to be spending any amount of time attempting to brute-force in this way, you should spend some time thinking about, and generating, custom lists of passwords. A file containing tens of thousands of passwords (or more) will take a long time for a tool like Hydra to work through, assuming that this tool is able to continue running without being blocked. It makes sense to put commonly used passwords at the top of your list. People still use weak passwords like “123456” and “Password1” (yes, they really do, if permitted). You will find lists online where people have attempted to collate the most commonly used passwords. Days of the week, easy-to-remember numbers, dates, keyboard sequences (like 1qaz2wsx), girl's names, boy's names, and sports team's names are among the most commonly used passwords we have found over the years.

You should also consider your client and any individual's circumstances or preferences when it comes to guessing passwords. If an application imposes a policy such as, “You must use at least one uppercase letter, one lowercase letter, one numerical value, and one special character,” you know that all the passwords in your list should adhere to this rule too. You might, therefore, mutate the commonly used “Password” or “password” so that it becomes “ P4ssw0rd!” and add that to your list, as well as variants, which people seemingly like to choose. This need not be done manually, as the function is built into tools like John the Ripper.

Another approach is to scour your client's website or other online presence for interesting words that employees might use in their passwords. There is a tool called CeWL ( digi.ninja/projects/cewl.php) that will do this for you—that is, crawl a website and output a list of words that you can include in your word list.

Word lists can be found in abundance online. Try those included with Kali Linux as a starting point before checking out others—such as openwall.com/passwords/wordlists, which offers password lists in multiple languages. A common mistake made by amateur hackers is not taking into account the language and region of the targeted system.

As discussed in Chapter 4, “Open Source Intelligence Gathering,” in some cases you may end up spending a fair amount of time profiling your target, viewing their public postings on social media, and so forth. You might find information there, such as the names of children, pets, or a favorite sports team that you can add to your list. You will also want to include passwords that you have previously cracked, which have come from other sources, such as /etc/shadow files on other machines, and that you believe should be used for the current situation.

The methods described here need not be applied in isolation. You will need to combine various approaches to get the best results when it comes to brute-force attacks. Your word lists can also be used with tools like Hashcat and John.

The Art of Cracking


The activity of gathering password hashes and cracking them can be considered an art in its own right. Many consider it a hobby and invest in dedicated equipment for this very purpose. GPUs are well suited to the task of generating hashes for the purpose of hash comparison. They tend to be better than CPUs for this task because the processing of graphical output is similar in many ways to the algorithms used for generating hashes. Processing is done in parallel, rather than in serial. There are other pieces of equipment, such as application-specific integrated circuits (ASICs) and field-programmable gate arrays (FPGAs), that people who are serious about cracking use (see Figure 14.2). ASICs are manufactured for a particular purpose, such as mining cryptocurrency or cracking hashes, and they can do a single job much more efficiently than a multipurpose integrated circuit such as a CPU, or even a GPU. FPGAs are similar, but they can be reprogrammed and are more customizable after manufacturing, which is why they're called field programmable.

Photo depicts FPGA used for cracking hashes.

Figure 14.2: FPGA used for cracking hashes

You may have come across cracking-as-a-service (CaaS) or cloud cracking. These services allow you to upload your hash and have someone else's system crack it for you. You could use Amazon Web Services' GPUs, for instance, which are supported by Kali Linux. Building and maintaining your own cracking rig, using multiple high-end graphics cards or dedicated hardware, can be rather expensive. Using these cloud-based services offers an alternative, cheaper option, although you need to consider the implications of uploading your client's password hashes to a remote site or service.

You will also come across sites that offer cash rewards for cracking hashes, and you can upload your own hashes to these sites, offering a bounty to the person who successfully cracks it for you. Your client may not be too happy about this type of arrangement, and you may even be in breach of contract for doing so. It is never recommended that you upload other people's password data to third-party services. As a best practice, you should build your own systems or make use of a cloud system privately to perform this task.

Random Number Generators


Random numbers are extremely important when it comes to computer security because they add entropy (or randomness) to hashed or encrypted data, making it less likely that patterns will be detected. If patterns can be seen in data—for example, certain characters hashed or encrypted in a certain way—then those patterns can be analyzed with a view to “breaking” the encryption scheme in use. Brute-force parlance calls this a stop condition. This is the basic concept behind work done by the Allied forces during World War II to decipher messages encrypted using the Nazis' Enigma machine (see Figure 14.3).

Photo depicts a German Enigma machine.

Figure 14.3: A German Enigma machine

Source: upload.wikimedia.org/wikipedia/commons/e/e4/Commercial_ENIGMA_-_National_Cryptologic_Museum_-_DSC07755.JPG

Hashes must also contain a sufficient amount of entropy to prevent collisions and to reduce the likelihood that they can be reversed. In the same way, adding more entropy to your everyday passwords makes them more difficult to brute-force or crack.

You will often see the term pseudorandom number generator, and not random number generator, because computers cannot produce truly random numbers by themselves. Computers are designed to act consistently and predictably—that is their nature. We want programs to execute exactly the same way, every time, and we want the output of calculations to be accurate—100 percent accurate—all of the time! The trade-off here is that the components of a computer are not well suited to producing random output, and typically, specialist hardware is required to produce a true random number, often referred to as a hardware security module (HSM). Having said that, modern computers are rather good at producing output that would fool most of us and is pseudorandom enough for cryptographic purposes.

Summary


Although some hashing algorithms are based on encryption algorithms, do not confuse hashing with encrypting. The two are distinct operations. Hashing takes plaintext and applies a one-way function that should be as difficult as possible to reverse. By design, encryption needs to be reversed, but only by someone providing the correct credentials and in possession of a secret key.

When conducting a penetration test for a client, if there is an opportunity to attempt to crack passwords, you'll want to start as soon as possible to ensure that it does not slow down your engagement, ideally using a machine that can work away in the background. Leaving password cracking until the end is not a good idea, as you may miss opportunities to access hosts once your testing window time has expired. The longer you leave a password-cracking tool running, the greater the chance of uncovering passwords. With a long enough timeline, the survival rate for all things drops to zero.

As technology improves and the arms race between secure hashing algorithms and methods to crack them continues, be aware that what you recommend to clients will change over time. Once upon a time, DES, LM hashes, and MD5 were considered secure enough to protect passwords, yet they are laughable by today's standards and should be avoided for any application in favor of secure alternatives like SHA512.

You might not always crack the password hashes that you find successfully, but if you've carried out your checks properly, you can be sure that your client's users are, at the least, not using weak passwords. You can also ensure that the current best practice is being employed when it comes to the safe storage of password hashes. Do not be disheartened if your dictionary attacks, custom word lists, or rainbow tables do not bear fruit at first. Remember, all good things come to those who brute-force.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.161.116