User Authentication: Passwords in Linux
Table of Contents
Abstract: This chapter is about how computer systems authenticate users. We focus on the password system of Linux in detail. Cryptography forms the backbone of any password system.
1 DES Encoding of Passwords
An encoding method used in most Unix and older Linux distributions is based on Data Encryption Standard (DES) format. This format limits passwords to eight characters and provides a modest 56-bit level of encryption. Unix crypt() function (not the crypt(1) program) is based on the Data Encryption Standard (DES). The encoded version of the plain text password is computed as follows.
- It takes the first 8 characters of the password, assembles a 56-bit key from the low 7-bits of each of these 8 characters.
- Using this key, a block of 64-zero-bits is encrypted into a 64-bit code using DES.
- The above step is repeated 25 times.
- The resulting 64-bit code appended with two 0-bits. The result is split into 11 six-bit numbers.
- Each six-bit number
x
is stored as achar q[x]
from the sequenceq
defined as., /, 0-9, A-Z, a-z
of 64 printable characters. - This computation is perturbed with a randomly generated value called the salt, a two-character value chosen from q.
- The salt value is prepended resulting in a sequence of 13 characters.
Because of the salt, any particular password could be stored in 4096
(2*28) different ways. As an example, the admittedly weak password
hello
was encoded in two different attempts yielding the following
two results: (i) pwsS8k.3HrN8E
(ii) BNApDvUheWPoc
When a user logs in and supplies a plain text password, the salt is first retrieved from the stored encoded password. Then the user-supplied password is encoded with the salt value, and then compared with the encoded password. A match authenticates the user.
The algorithm used to encode the password field is a one way hash function. The computation is easy in the encoding direction, but very time consuming to calculate in the reverse direction. It is computationally infeasible (but not impossible) to take a randomly encoded password and recover the original password. However, on any system with 10+ users, some of the passwords will be common words and a cracker resorts to a dictionary attack.
2 The Linux Password Shadow System
On a Linux system (without the Shadow Suite installed), user
information including passwords is stored in the /etc/passwd
file. The password is stored in an <i>encoded format. A typical
user's entry in a non-shadowed /etc/passwd
file has the
following format (colons separate the various fields) :
loginName:encodedpasswd:UID:GID:fullName:homeDirectory:shell
Linux distributions now default to using shadow passwords. The
encloded passwords are no longer stored in /etc/passwd
, but in
/etc/shadow
Here is the info on these files taken from a home Linux
PC.
-rw-r--r-- 1 root root 2331 Apr 23 11:25 /etc/passwd.txt -rw-r----- 1 root shadow 1614 Apr 23 11:25 /etc/shadow.txt
Note the read-write permissions shown. The /etc/passwd
file is
required to be publicly readable because many legacy programs extract
the various fields stored in the password file. The /etc/shadow
file structure is the same as that of /etc/passwd
but has different
interpretation for the fields:
loginid:encodedpasswd:lastchange:mindays:maxdays:warn:unused:expire
If the encoded passwd field is empty, the user is logged in without having to enter a password.
Modern Linux distributions now use either the Message-Digest Algorithm (MD5) or SHA512. MD5 passwords do not eliminate the threat of password cracking. They just make cracking passwords much more time consuming.
An MD5 password is stored in the /etc/shadow
file as
follows. Example lines from machine M1:
student:$1$l67ia9iK$x80ABcEExHYMVpMx.Bls5.:13749:0:99999:7::: jsmith:$1$Y4.kjoQ2$GIuEZcnQVPYi7RPWrQRTE.:14036:0:99999:7::: jtripper:$1$WH2SxqnX$rL0J6JYshB3wl6yBm90Bd1:13887:0:99999:7:::
The encoded password field contains three dollar signs. Between the
first pair of $-symbols is referred to as the "magic" and is used to
determine if this is a MD5 hash (crypt id 1, \(1\) = yes) or not. The
second pair encloses ( =$l67ia9iK$
) the salt. The characters following
the third dollar upto the colon, namely x80ABcEExHYMVpMx.Bls5.
is
the MD5 hash of the student's plaintext password.
Note that MD5 is now breakable. Some stats from an MD5Crack Website in
2010: Cracking 5081455 MD5 hashes/sec. Current time needed to break
all 1 to 8 char long passwords that use [a-zA-Z0-9]{1,8}
497 days,
[a-z0-9]{1,8}
6 days.
Since MD5 is considered "broken", Linux distributions have moved to
using salted SHA512 password hashes (crypt id 6, i.e., $6$
), which
are several orders of magnitude more difficult to brute-force or
generate rainbow tables for. Example lines from machine M2:
root:$6$vPVevCXV$Pj2yIpQhprsMifm7i4X7F6IioqAQxJCyrhNjH4zK0fGYUc2gWjGJjobIwRp7wT5spTlLEywDW0ySmgB0XkVBs/:15401:0:99999:7::: ceg442091:$6$03bKILGu$pgsg2fOTpYyhcPGSaJZfbVEFPgyle5YtGR1wY2ChuxSv7C4lEfdES26qAXa9UHqt04ap5v0AXF0DuWMXdeaWY0:15295:0:99999:7::: ceg235013:$6$T6Yj4GYP$MjioJv3VqkU5WOx5gruV2fSHgitkSHMLvSx5M.KL5JCDsVIVKqf3uo0DGTV.CLar0dW4eV5VYTzbfSi9rA1g8/:15398:0:99999:7:::
The lines below are the same as above but split into muliple lines for readability:
root:$6$vPVevCXV$Pj2yIpQhprsMifm7i4X7F6IioqAQxJCyrhNjH4zK0fG YUc2gWjGJjobIwRp7wT5spTlLEywDW0ySmgB0XkVBs/:15401:0:99999:7::: ceg442091:$6$03bKILGu$pgsg2fOTpYyhcPGSaJZfbVEFPgyle5YtGR1wY2Ch uxSv7C4lEfdES26qAXa9UHqt04ap5v0AXF0DuWMXdeaWY0:15295:0:99999:7::: ceg235013:$6$T6Yj4GYP$MjioJv3VqkU5WOx5gruV2fSHgitkSHMLvSx5M.KL5JCDs VIVKqf3uo0DGTV.CLar0dW4eV5VYTzbfSi9rA1g8/:15398:0:99999:7:::
3 Pluggable Authentication Modules (PAM)
The two important programs /bin/login
and /bin/su
are supported by
PAM. The following is an ls -l listing of /etc/pam.d/
. These are
plain text config files for the corresponding commands. Ignore the
dates, but note the sizes.
-rw-r--r-- 1 root root 197 Nov 23 2009 atd -rw-r--r-- 1 root root 384 Jun 24 2011 chfn -rw-r--r-- 1 root root 92 Jun 24 2011 chpasswd -rw-r--r-- 1 root root 581 Jun 24 2011 chsh -rw-r--r-- 1 root root 1256 Apr 14 01:32 common-account -rw-r--r-- 1 root root 1280 Apr 14 01:32 common-auth -rw-r--r-- 1 root root 1572 Apr 14 01:32 common-password -rw-r--r-- 1 root root 1514 Apr 14 01:32 common-session -rw-r--r-- 1 root root 1467 Apr 14 01:32 common-session-noninteractive -rw-r--r-- 1 root root 527 Oct 20 2011 cron -rw-r--r-- 1 root root 69 Aug 22 2011 cups -rw-r--r-- 1 root root 648 Sep 23 2011 gdm -rw-r--r-- 1 root root 495 Sep 23 2011 gdm-autologin -rw-r--r-- 1 root root 56 Sep 26 2011 gnome-screensaver -rw-r--r-- 1 root root 345 Aug 17 2011 kdm -rw-r--r-- 1 root root 389 Aug 17 2011 kdm-np -rw-r--r-- 1 root root 4585 Jun 24 2011 login -rw-r--r-- 1 root root 92 Jun 24 2011 newusers -rw-r--r-- 1 root root 520 Aug 18 2011 other -rw-r--r-- 1 root root 92 Jun 24 2011 passwd -rw-r--r-- 1 root root 105 Aug 5 2011 polkit-1 -rw-r--r-- 1 root root 168 Feb 4 2011 ppp -rw-r--r-- 1 root root 370 Nov 21 2011 proftpd -rw-r--r-- 1 root root 84 Jul 28 2011 samba -rw-r--r-- 1 root root 1272 Apr 6 2010 sshd -rw-r--r-- 1 root root 2305 Jun 24 2011 su -rw-r--r-- 1 root root 95 Nov 24 11:31 sudo -rw-rw-r-- 1 root root 104 Jan 21 01:05 webmin -rw-r--r-- 1 root root 108 Jun 10 2011 xscreensaver