Hacker's are always looking for new ways to exploit systems and exfiltrate passwords, even in hashed form. Sophisticated brute-force attacks powered by high-end GPUs can perform millions of password attempts per second. But Ubuntu and Debian users aren't completely helpless. There are ways to harden the hashed password to better defend against Hashcat attacks.
Root privileges are usually required to access the /etc/shadow file in Ubuntu and Debian systems where hashed passwords are stored. An attacker extracting this data would suggest they already have root privileges. Root-level access could be acquired without knowing the target's password by exploiting the operating system or physically exploiting the device.
For example, Linux kernel vulnerabilities are disclosed several times a year and never require knowing the target's password to gain a root shell. Likewise, the single-user mode feature is often abused to embed nefarious cronjobs. It can be configured with only a few minutes of physical access to the target device and doesn't require a password.
If an attacker has acquired root access by other means, why would they still need the sudo password? Well, there could be many reasons for this. The attacker may be trying to do one of the following.
- Pivot to other devices or services on the network, as well as learn the password scheme in use (e.g., Hunter321).
- Dump encrypted passwords stored in Chrome or Firefox browsers. These encrypted passwords are sometimes secured by the user's login password.
- Check for password reuse against popular social media and banking websites.
- Physically access the device to log in. If the attacker used single-user mode to extract the password hash, they may be trying to crack it to log in when the target device is unattended.
There's really no telling how far an attacker can pivot with a single password that's been reused across accounts, websites, and network services.
The /etc/shadow file stores information about the target's password, salt, hashing algorithm, password expiration date, and so on. You can execute the below grep command using the $USER variable, and the terminal will automatically search for the target's username in the /etc/shadow file.
sudo grep $USER /etc/shadow
The sections are separated by colons (:) as shown below. We'll be focusing on section 2. The other sections aren't relevant to defending against Hashcat (brute-force) attacks, so I'll skip over them for now.
tokyoneon : $6$oHP9lHDM$DyxrXl6U/t3A91eA4FWpc4n/Tn3tI.Cb1YRZT/p76kdcyTUiWTNMBDp1YrCFpJJtBRxfh71aGOZZHcXfY9qeN0 : 17762 : 0 : 99999 : 7 : : : ----1-----|-----------------------------------------------------2----------------------------------------------|---3---|-4-|---5---|-6-|-7-|-8-|
Section 2 is further separated by dollar signs ($) into three section.
These sections consist of the hash type (1), salt (2), and hashed password (3). The 6 hash type indicates SHA-512, but type 5 (SHA-256) is also common. Salts are random values used to help create strong, unique hashes. By today's standards, this hashed password is stored in a relatively secure form. But it can still become the subject of a targeted brute-force attack.
Out of curiosity, I wanted to learn how many passwords a second Hashcat can perform against the above hash created in Ubuntu 18. This was tested with a generic Nvidia GeForce GTX 1060 GPU. The GPU isn't high-end, but standard in many consumer desktops these days. It wouldn't be unreasonable to believe most hackers with dedicated password-cracking machines are capable of performing more computations per second with a superior GPU.
hashcat -a 3 -m 1800 /tmp/password_hash.txt ?l?l?l?l?l?l
hashcat (v5.1.0) starting... OpenCL Platform #1: NVIDIA Corporation ====================================== * Device #1: GeForce GTX 1060 3GB, 754/3018 MB allocatable, 9MCU Session..........: hashcat Status...........: Running Hash.Type........: sha512crypt $6$, SHA512 (Unix) Hash.Target......: $6$oHP9lHDM$DyxrXl6U/t3A91eA4FWpc4n/Tn3tI.Cb1YRZT/p...Y9qeN0 Time.Started.....: Tue Mar 5 02:25:23 2019 (15 secs) Time.Estimated...: Tue Mar 5 03:36:19 2019 (1 hour, 10 mins) Guess.Mask.......: ?l?l?l?l?l?l  Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 72631 H/s (403.13ms) @ Accel:1024 Loops:512 Thr:32 Vec:1 Recovered........: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.........: 884736/308915776 (0.29%) Rejected.........: 0/884736 (0.00%) Restore.Point....: 0/11881376 (0.00%) Restore.Sub.#1...: Salt:0 Amplifier:3-4 Iteration:3072-3584 Candidates.#1....: barier -> bjuhgi Hardware.Mon.#1..: Temp: 62c Fan: 35% Util:100% Core:1847MHz Mem:3802MHz Bus:16 [s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>
The above Hashcat command is performing a Mask attack (-a 3) using the SHA-512 Unix hash type (-m 1800) with every possible six-letter lowercase (?l) combination. As we can see, it can perform 72,631 hashes per second (H/s). At this rate, it would only take one hour to try every six-letter combination of lowercase characters. And as we learned previously, six-character passwords are extremely common. At 72,600 H/s, cracking eight- and nine-character password hashes are very much within the realm of reality with a generic Nvidia GPU.
Of course, using a long and complex password would thwart most brute-force attacks. But let's take a different approach by increasing the hash's "SHA-rounds." SHA-rounds (better known as iterations) are used as a "slowdown factor," which essentially forces CPUs and GPUs to take significantly longer when computing a single password attempt. The higher this value is, the longer Hashcat will have to work to crack the hash.
By default, Ubuntu and Debian use the SHA-512 crypt method with 5,000 SHA-rounds. As we see in the above Hashcat output, 5,000 SHA-rounds equates to almost 73,000 password attempts per second. Which isn't good news for Ubuntu and Debian users. Fortunately, the number of SHA-rounds can be manually increased to better defend against brute-force attacks. This can be done using the chpasswd command.
Chpasswd, like passwd, is a password management utility. It was designed to change many passwords in bulk while being able to specify the hash type and number SHA-rounds (among other things). To harden a password hash with chpasswd, use the below command.
If your CPU is older than an Intel i3, don't use more than 750,000 SHA-rounds. Intel i7 users should not exceed 30,000,000 SHA-rounds. Significantly increasing this value can require a lot of CPU processing power and take minutes (maybe hours) to complete. Interrupting the command before it's finished could cause the system to become unstable. Use the below command with caution as setting the value too high can make it difficult to log in or break the system. Gradually increase the number of SHA-rounds if you wish to test the limitations of your CPU.
sudo chpasswd -s 10000000 -c SHA512 <<< username:password; history -c
The above chpasswd command will use 10,000,000 SHA-rounds (-s) with the SHA-512 crypt method (-c). The <<< characters denote a string being used as the input data. In this case, the input is the username and desired password. To prevent the new password from appearing in the terminal history, append (;) the history command to clear (-c) it.
Now, grep the /etc/shadow file again to find a new section between the hash type and salt that reads rounds=10000000. This is an indication the chpasswd command was successful.
sudo grep $USER /etc/shadow
Let's feed this new hash with 10,000,000 SHA-rounds into Hashcat and observe the number of password attempts it can perform.
hashcat -a 3 -m 1800 /tmp/hardened_password_hash.txt ?l?l?l?l?l?l
hashcat (v5.1.0) starting... OpenCL Platform #1: NVIDIA Corporation ====================================== * Device #1: GeForce GTX 1060 3GB, 754/3018 MB allocatable, 9MCU [s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => s Session..........: hashcat Status...........: Running Hash.Type........: sha512crypt $6$, SHA512 (Unix) Hash.Target......: $6$rounds=10000000$cHi6OvAYRy$x8Z0kLn.JYAPOWQkH3RMy...2i3G30 Time.Started.....: Tue Mar 5 03:16:28 2019 (7 secs) Time.Estimated...: Tue Jul 30 05:46:22 2019 (147 days, 1 hour) Guess.Mask.......: ?l?l?l?l?l?l  Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 24 H/s (410.36ms) @ Accel:1024 Loops:512 Thr:32 Vec:1 Recovered........: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.........: 0/308915776 (0.00%) Rejected.........: 0/0 (0.00%) Restore.Point....: 0/11881376 (0.00%) Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:8704-9216 Candidates.#1....: sarier -> sjuhgi Hardware.Mon.#1..: Temp: 56c Fan: 29% Util:100% Core:1873MHz Mem:3802MHz Bus:16 [s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>
Only a mere 24 hashes per second can be guessed against this hardened hash, which can make weak passwords like "zxcvbn" resilient against Hashcat, taking weeks to crack the hash.
Now, this isn't a recommendation or argument to use weak passwords with 10,000,000 SHA-rounds. Reader's should increase the number of SHA-rounds in addition to using strong passwords. I'm using an absurdly high value in this article to demonstrate how far this kind of hardening can be taken. But any SHA-rounds value over the default 5,000 will help defend against brute-force attacks. Even if only a little.
SHA-round values anywhere over 1,000,000 will most likely make brute-forcing a completely insufficient attack vector. Higher values make it very difficult for an attacker on the system to learn the password. Increasing the SHA-rounds greatly diminishes the number of passwords per second Hashcat can perform.
The major disadvantage to increasing the SHA-rounds is the amount of CPU processing required to execute a single sudo command or log in to the account. Higher SHA-rounds (e.g., 10,000,000) can take up to 10 seconds to compute a sudo command on a modern Intel i7 CPU. Older CPUs could take significantly longer. The trick is to find a sweet spot where it only takes about two seconds to compute the SHA-rounds. This way, brute-force attackers are still thwarted but it doesn't take forever to execute a single sudo command.