Shadows are there to protect your Passwords (How Shadow-Utils is storing your password in Linux)

Computers_Password_guessing_041153_

Our world would have been exponentially more peaceful if there was no fear of theft. We would’ve left our doors open but still enjoyed our privacy and security. Unfortunately looking at the current scenario, that’s a rather impossible fiasco. And hence the need for doors and locks.

A similar case is applicable for the digital world where we have to assure complete data security. The simplest yet most important way to protect ones data even today remains with the use of passwords and robust access management systems. 
 

Password is defined as:

“A password is a word or string of characters used for user authentication to prove identity or access approval to gain access to a resource (example: an access code is a type of password), which should be kept secret from those not allowed access”

So we create Login credentials (account id with a corresponding password) for every valid user. This password can be utilized every time the user wants to access that particular resource. But we will have to store the password somewhere securely so as to assure complete secrecy/security of this username/password combination. Definitely storing the password in plain text is not a great idea and also we have to make sure this password file or database is out of the reach from everyone.

So the solution lies in encoding/encryption/hashing of the password and then storing it into a secured location. Even then there is a possibility to get the real password back from the encrypted one. With all the advanced tools and superlative computation resources available nowadays it’s only a matter of time before most encryption or hashing mechanisms can be reverse engineered. But that’s out of scope of this particular article.

In initial era of Unix, password storage was done in /etc/passwd file. An /etc/passwd file has the following format: 

username:passwd:UID:GID:full_name:directory:shell

Adding major risk to this is that, file was world readable. That simply meant any user who has the access to the system could read that file. Now the question arises why can’t we change the permissions of this file. Let’s see what happens.

Firstly lets take a closer look at permissions of the /etc/passwd file and try to modify them:

root@etcHacked:~# ll /etc/passwd
-rw-r--r-- 1 root root 1956 Dec 14 01:17 /etc/passwd
root@etcHacked:~# chmod 600 /etc/passwd
root@etcHacked:~# ll /etc/passwd
-rw------- 1 root root 1956 Dec 14 01:17 /etc/passwd
root@etcHacked:~# su - etc-hacked 
I have no name!@etcHacked:~$

Oops !!! What happened ? If we want to change the user now, we will not get the username, home directory or custom shell anything. So we suppose these things get stored in /etc/passwd file and we have to keep this file readable for everyone. But of course we need to arrange an alternate way to store the password. The solution came in the form of Shadow-Utils Package.

Shadow-Utils Package

Shadow-Utils is a package for improving system security by moving the encrypted passwords (normally found in /etc/passwd) to /etc/shadow which is readable only by root. Most of the Linux machines comes with pre-installed Shadow-Utils. Now lets see the permission of /etc/shadow file.

root@etcHacked:~# ll /etc/shadow
-r-------- 1 root shadow 1040 Dec 14 01:17 /etc/shadow
root@etcHacked:~# cat /etc/shadow 
etc-hacked:$1$4hx$XLjr/pkLpIjbwhrxmuQyb.:16418:0:99999:7::: 

As we can see only root has the permission of 'r'(read) for the /etc/shadow file. Now as far as the content of /etc/shadow is concerned we can see an output having several fields.
Each field is separated by a colon (:). There are a number of fields:

  1. User name. This must match up with a user name in /etc/passwd; it is the key.
  2. Password. This field is a hash of the password (not the actual password itself) combined with an id (specifying which form of encryption was used) and with a salt.
  3. Last changed date. This is the day that the password was last set (in days since January 1, 1970) also called as UNIX Time.
  4. Minimum days. This is the minimum number of days that a password must be active before a password can be changed again. A user’s password cannot be changed by them until this number of days has elapsed.
  5. Maximum days. This is the maximum number of days for a password to be valid. Once the maximum number of days has elapsed, the user is forced to change their password.
  6. Warn days. Before a password expires, warn the user this many days ahead of time.
  7. Inactive days. Once a password has expired, it will be disabled after this many days.
  8. Expire date. On this date (in days since January 1, 1970), the account is disabled and the login can no longer be used.

Rather than trying to compute the date from the number of days since 1970, use the chage command:

root@etcHacked:~# chage -l root
Last password change : Dec 14, 2014
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
root@etcHacked:~# 

How the password is stored and verified upon Login

If we look closely the second field that is the hashed password then perhaps we can find out more.

$1$4hx$XLjr/pkLpIjbwhrxmuQyb

The password hash comes in three parts, separated by dollar signs ($):

  • Id. This identifies the encryption hash method used. A value of
  • 1 denotes MD5
  • 2 or 2a is Blowfish
  • 3 is NT Hash
  • 5 is SHA-256
  • 6 is SHA-512.
  • Salt. This is used by the encryption algorithms, and could be up to 16 characters. It adds and extra level of strength to hash by combinining itself with the original password.
  • Hash. The actual “password” (or hash) is last. MD5 uses 22 characters, SHA-256 uses 43, and SHA-512 uses 86.

So in our case the Hashing algorithm is MD5($1$), Salt value is 4hx and PASSWORD+SALT is XLjr/pkLpIjbwhrxmuQyb. By chance if you want to crosscheck your password by hashing it manually with the salt you can run following command. Here -1 tells us the hashing algorithm that is MD5 in our case.

root@etcHacked:~# openssl passwd -1 -salt 4hx root
$1$4hx$XLjr/pkLpIjbwhrxmuQyb.
root@etcHacked:~# 

If the password entry is missing entirely (which means no password) or it is a locked account.

Now once you enter your password on login page of Linux the password is hashed with salt and matched with the stored value of /etc/shadow, if it is matched then here you go the desktop of your machine.

Benefits we get by using Salt

Salt makes it more time-consuming to crack a list of passwords. However, it does not make cracking a password using dictionary attacks exponentially harder while also increasing the cost of such an operation exponentially higher. Even if the attacker has access to both the hashed password and the salt, when running the dictionary attack, the attacker can simply use the known salt when attempting to crack the password.

To understand the difference between cracking a single password and a set of them, consider a single password file that contains hundreds of usernames and passwords. Without a salt, an attacker could compute hash(attempt[0]), and then check whether that hash appears anywhere in the file. The likelihood of a match, i.e. cracking one of the passwords with that attempt, increases with the number of passwords in the file. If salts are present, then the attacker would have to compute hash(salt[a] . attempt[0]), where “.” denotes concatenation, compare against entry A, then hash(salt[b] . attempt[0]), compare against entry B, and so on. This defeats "reusing" hashes in attempts to crack multiple passwords.

Salts also make dictionary attacks and brute-force attacks for cracking large numbers of passwords much slower (but not in the case of cracking just one password). Without salts, an attacker who is cracking many passwords at the same time only needs to hash each password guess once, and compare it to all the hashes. However, with salts, each password will likely have a different salt; so each guess would have to be hashed separately and compared for each salt, which is considerably slower than only comparing.

Another small advantage of using salt is that two users can chose same string of password. By salting the passwords with two random characters, the odds are that even if two accounts use the same password, no one can discover this by reading password files.

Leave a Comment