Illuminating shadow passwords

Why shadow passwords? Simply put, the shadow password scheme addresses the major shortcoming of the original Unix password-handling scheme, the fact that the password list was stored as a world-readable file.

Why shadow passwords? Simply put, the shadow password scheme addresses the major shortcoming of the original Unix password-handling scheme, the fact that the password list was stored as a world-readable file.

The encoding mechanism for Unix passwords was (and is) very secure, being a one-way algorithm and therefore easy to apply but impossible to reverse. However, the password file itself is vulnerable to a cracking technique known as a dictionary attack, in which all the words from a large dictionary file are encoded and compared with the encoded password (readable by any user, remember) in

<font face="Courier">/etc/passwd</font>

This dictionary file is usually based on a normal English-language dictionary, with the addition of slang and weak passwords like "gandalf," "xyzzy," "qwerty," or even (God help us) "password." If the two match, then the original unencoded word is the password.

This may sound simple, but it takes a while to run the tens, or hundreds, of thousands of dictionary entries against a single password. Still, it is not extremely difficult with today's high-performance computing systems. Shadow passwords retain the Unix password mechanism and its backward compatibility with the huge Unix application base, while preventing the dictionary attack.

An overview

Let's take a look at the various components of the shadow password system. It uses four files:

  • <font face="Courier">/etc/passwd</font>
  • <font face="Courier">/etc/shadow</font>
  • <font face="Courier">/etc/group</font>
  • <font face="Courier">/etc/login.defs</font>

/etc/passwd

The

<font face="Courier">/etc/passwd</font>

file is the same standard colon-delimited file used since the Unix days, but with a slight difference: The second field, which previously contained the password, now holds only an

<font face="Courier">x,</font>

which indicates the actual encrypted password is now stored elsewhere.

Rules for good passwords

Do not use:

  • The account name
  • Any word found in a dictionary
  • Names of people or things
  • Publicly available information about yourself, e.g. your phone number
  • Keyboard sequences like "qwerty"

Do use:

  • Longer passwords -- at least six characters is a good rule
  • A mixture of numbers and letters
  • A mixture of uppercase and lowercase letters

The maximum practical length for a password (if you do not have MD5 capability) is eight characters. You can use longer passwords without MD5, but only the first eight characters are significant. So "qwertyuiZ13xi" is not a good password because it is effectively just "qwertyui," an easily guessable keyboard sequence.

The shadow password suite, like the older Unix method, uses the seventh GECOS field of

<font face="Courier">/etc/passwd</font>

as an extension mechanism for adding other fields of information.

This field contains the user's full name. On systems with user disk quotas enabled, the flags for

  • <font face="Courier">ulimit</font>
  • <font face="Courier">mask</font>
  • <font face="Courier">niceness</font>

can also be set there.

<font face="Courier">ulimit</font>

controls the maximum size for user-created files.

<font face="Courier">umask</font>

is the permissions mask for file creation, expressed as an octal number. For example, a

<font face="Courier">umask</font>

of 077 means files I create have permissions of 600 -- readable and writable by me, but not accessible to other users.

<font face="Courier">niceness</font>

is the priority with which the user's background jobs will run. The priority range is -20 (the highest priority) to 19 (the lowest).

Although it is common to include general user information in the password file (as in the sample below), I would not recommend doing so on a machine connected to the Internet. Unix and Linux can retrieve user information through a simple command/protocol named finger. If you are going to store general user information in this fashion, turn off the finger protocol.

Below are a sample

<font face="Courier">/etc/password</font>

file and a sample

<font face="Courier">/etc/shadow</font>

file.

<font face="Courier">
#sample /etc/password file
<BR>
root:x:0:0:root:/root:/bin/bash
<BR>
bin:x:1:1:bin:/bin:
<BR>
daemon:x:2:2:daemon:/sbin:
<BR>
adm:x:3:4:adm:/var/adm:
<BR>
lp:x:4:7:lp:/var/spool/lpd:
<BR>
sync:x:5:0:sync:/sbin:/bin/sync
<BR>
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
<BR>
halt:x:7:0:halt:/sbin:/sbin/halt
<BR>
mail:x:8:12:mail:/var/spool/mail:
<BR>
news:x:9:13:news:/var/spool/news:
<BR>
uucp:x:10:14:uucp:/var/spool/uucp:
<BR>
operator:x:11:0:operator:/root:
<BR>
games:x:12:100:games:/usr/games:
<BR>
ftp:x:14:50:FTP User:/home/ftp:
<BR>
nobody:x:99:99:Nobody:/:
<BR>
postgres:x:500:500:The Postgres Daemon:/usr/local/pgsql:/bin/bash
<BR>
jd:x:501:501:Mr. Poet,XXX NE Sandy Blvd. #XXX,555-555-555,Not
<BR>
aChance:/home/jd:/bin/bash
<BR>
<BR>
#sample /etc/shadow file
<BR>
root:$1$uOi3eTo9asedfg8923,$r4gQvkI9rHQoM1O9k0:11013:0:99999:7:-1:
<BR>
-1:134550548
<BR>
bin:*:10740:0:99999:7:::
<BR>
daemon:*:10740:0:99999:7:::
<BR>
adm:
<BR>
*:10740:0:99999:7:::
<BR>
lp:*:10740:0:99999:7:::
<BR>
sync:*:10740:0:99999:7:::
<BR>
shutdown:*:10740:0:99999:7:::
<BR>
halt:*:10740:0:99999:7:::
<BR>
mail:
<BR>
*:10740:0:99999:7:::
<BR>
news:*:10740:0:99999:7:::
<BR>
uucp:*:10740:0:99999:7:::
<BR>
operator:*:10740:0:99999:7:::
<BR>
games:*:10740:0:99999:7:::
<BR>
ftp:
<BR>
*:10740:0:99999:7:::
<BR>
nobody:*:10740:0:99999:7:::
<BR>
postgres:$1$XvHPKfI8724lsakh$fjOokJYwVL1i8F1:10741:-1:99999:-1:-1:
<BR>
-1:135506940
<BR>
jd:$1$1p68Iasdf&lsdg123keKF$S0TCCk04bzf1tD.:11109:-1:99999:-1:
<BR>
-1:
<BR>
-1:134539500
<BR>
<BR>
</font>

/etc/shadow

The

<font face="Courier">/etc/shadow</font>

file stores the encoded password, as well as other information that enhances the standard Unix password scheme to include support for password aging. This limits how long a user can keep the same password for an account before it has to be changed for the sake of increased security.

<font face="Courier">/etc/shadow</font>

is readable and writable by root, and readable by the group

<font face="Courier">shadow</font>

No other users have access.

/etc/group

The

<font face="Courier">/etc/group</font>

file is another old standard that designates groups of users within Unix and Linux systems. Each line starts with a group name, a field for passwords, a unique group identifier, and a list of user accounts that belong to the group. Like the

<font face="Courier">/etc/passwd</font>

file, the password field simply contains an

<font face="Courier">x</font>

The real group password is held in

<font face="Courier">/etc/gshadow</font>

Below are a sample

<font face="Courier">/etc/group</font>

file and an example

<font face="Courier">/etc/gshadow</font>

file.

<font face="Courier">
#sample /etc/group file
<BR>
guide-submit:x:527:
<BR>
faq-submit:x:528:
<BR>
vios:x:529:
<BR>
kde:x:530:
<BR>
php3:x:531:
<BR>
php4:x:532:
<BR>
books:x:533:
<BR>
debian:x:534:
<BR>
kdevelop:x:535:
<BR>
python:x:536:
<BR>
gnome:x:537:
<BR>
jlx:x:538:
<BR>
<BR>
#sample /etc/gshadow file
<BR>
root:::root
<BR>
bin:::root,bin,daemon
<BR>
daemon:::root,bin,daemon
<BR>
sys:::root,bin,adm
<BR>
adm:::root,adm,daemon
<BR>
tty:::
<BR>
disk:::root
<BR>
lp:::daemon,lp
<BR>
mem:::
<BR>
kmem:::
<BR>
wheel:::root
<BR>
mail:::mail
<BR>
news:::news
<BR>
uucp:::uucp
<BR>
man:::
<BR>
games:::
<BR>
dip:::
<BR>
ftp:::
<BR>
nobody:::
<BR>
users:::
<BR>
floppy:x::
<BR>
xfs:x::
<BR>
named:x::
<BR>
console:x::
<BR>
utmp:x::
<BR>
pppusers:0RVNSlf/RWmsA::jd
<BR>
popusers:x::
<BR>
slipusers:x::
<BR>
postgres:x::
<BR>
</font>

/etc/login.defs

The

<font face="Courier">/etc/login.defs</font>

file is the master control file for the shadow password suite. You need to edit this file to configure the various options for the shadow password system.

In addition to the aforementioned files, there are also a handful of programs used with the shadow password system. The list below shows the man pages and the sections associated with these various commands or files. To read man pages within a particular section, you must specify the section. For example, to view section 8 of the man page for pwconv, you would type

<font face="Courier">man pwconv -S 8.</font>

Additional programs:

  • Program (man page)
  • login(1)
  • passwd(1)
  • su(1)
  • sulogin(8)
  • chage(1)
  • pwconv(8)
  • pwunconv(8)
  • grpconv(8)
  • grpunconv(8)

Getting shadow passwords

It is unlikely that shadow passwords are not installed on your Linux machine. However, just in case you are still running Red Hat 5.2 or another older distribution (such as older slackware versions) with the traditional password system, the source package is available at the sites listed in Resources. The shadow password suite now uses GNU autoconf. If you decide to upgrade your previous authentication system to support the shadow scheme, be sure to read all readme and install files included with the software. Incorrect installation of the shadow suite can break your authentication and cause severe problems with your system.

Configuring shadow passwords

The master configuration file for shadow passwords is

<font face="Courier">/etc/login.defs</font>

Table 1 includes the whole file and examines each option and its default value(s).

Option Default Details
FAIL_DELAY 3 Delay in seconds after a login failure before the system allows another attempt
DIALUPS_CHECK_ENAB Yes Enables additional passwords upon dialup lines specified in <font face="Courier">/etc/dialups</font> .
FAILLOG_ENAB Yes Enables logging and display of <font face="Courier">/var/log/faillog</font> login failure info.
LOG_UNKFAIL_ENAB No Enables display of unknown usernames when login failures are recorded.
LOG_OK_LOGINS No Enables logging of successful logins (the logs are stored in <font face="Courier">/var/log/wtmp</font> ).
LASTLOG_ENAB Yes Enables logging and display of <font face="Courier">/var/log/lastlog</font> login time information.
MAIL_CHECK_ENAB Yes Enables checking and display of mailbox status upon login. Disable this option if the shell startup files already check for mail ( <font face="Courier">mailx -e</font> or equivalent).
OBSCURE_CHECKS_ENAB Yes Enables additional checks upon password changes.
PORTTIME_CHECKS_ENAB Yes Enables checking of time restrictions specified in <font face="Courier">/etc/porttime</font> .
QUOTAS_ENAB Yes Enables setting of <font face="Courier">ulimit</font> , <font face="Courier">umask</font> , and <font face="Courier">niceness</font> from <font face="Courier">passwd gecos</font> field.
SYSLOG_SU_ENAB Yes  
SYSLOG_SG_ENAB Yes Enables syslog logging of <font face="Courier">su</font> activity in addition to sulog file logging. SYSLOG_SG_ENAB does the same for newgrp and sg.
CONSOLE <font face="Courier">/etc/securetty</font>  
#CONSOLE console:tty01:tty02:tty03:tty04 Either full pathname of a file containing device names or a colon-delimited list of device names. Root logins will be allowed only on these devices.
SULOG_FILE <font face="Courier">/var/log/sulog</font> All <font face="Courier">su</font> activity is logged to the file defined here.
MOTD_FILE <font face="Courier">/etc/motd</font> Colon-delimited list of message-of-the-day files displayed upon login.
ISSUE_FILE <font face="Courier">/etc/issue</font> A file holding a short message displayed before each login prompt.
FTMP_FILE <font face="Courier">/var/log/btmp</font> Login failures are logged here in a utmp format.
NOLOGINS_FILE <font face="Courier">/etc/nologin</font> This file, if present, prevents non-root logins. The contents of the file are displayed when login is denied, so it's a good idea to write in an explanation.
SU_NAME <font face="Courier">su</font> The command name to display when running <font face="Courier">su -</font> .
MAIL_DIR <font face="Courier">/var/spool/mail</font>  
#MAIL_FILE <font face="Courier">.mail</font> This is the directory ( <font face="Courier">MAIL_DIR</font> ) or file ( <font face="Courier">MAIL_FILE</font> ) where mail is stored. This is used for the "you have new mail" message displayed upon logging in. If both are defined, <font face="Courier">MAIL_DIR</font> takes precedence.
HUSHLOGIN_FILE <font face="Courier">/etc/hushlogins</font>  
HUSHLOGIN_FILE <font face="Courier">.hushlogin</font> If this file exists, all the normal messages displayed during the login sequence are suppressed. A full pathname indicates hushed mode will be used if the user's name or shell is in that file; a bare filename indicates hushed mode will be used if a file of that name exists in the user's home directory.
ENV_SUPATH PATH= <font face="Courier">/usr/local/sbin:<BR>/usr/local/bin:<BR>/sbin:/usr/sbin:<BR>/bin:/usr/bin</font> The default PATH settings for superuser.
ENV_PATH PATH= <font face="Courier">/usr/local/bin:<BR>/bin:/usr/bin</font> The default PATH settings for normal users.
TTYGROUP tty  
TTYPERM 0620 Terminal permissions: respectively, the group which owns device tty, and the permissions on the device file. If the write program on your system is <font face="Courier">setgid</font> to a special group which owns the terminals, then TTYGROUP should be set to the group number and TTYPERM to 0620. Otherwise, leave TTYGROUP commented out and set TTYPERM to either 622 or 600.
ERASECHAR 0177 This is a login configuration initialization. ERASECHAR is the default ERASE character. Terminal ERASE character (' <font face="Courier">\010</font> ' = backspace).
KILLCHAR 025 This is a login configuration initialization. KILLCHAR is the default KILL character. Terminal KILL character (' <font face="Courier">\025</font> ' = CTRL/U).
UMASK 022 This is a login configuration initialization. UMASK is the default mask that will be applied to the permissions of all new files created during this login. For example, a <font face="Courier">umask</font> of 077 means an ordinary file will have default permissions of 600.
#ULIMIT 2097152 This is a login configuration initialization.
ULIMIT Default <font face="Courier">ulimit</font> value. ULIMIT is the maximum file size under this login. Precede the value with <font face="Courier">0</font> to get octal, <font face="Courier">0x</font> to get hexadecimal.
PASS_MAX_DAYS 99999 The maximum number of days a password may be used.
PASS_MIN_DAYS 0 The minimum number of days allowed between password changes.
PASS_MIN_LEN 5 The minimum acceptable password length.
PASS_WARN_AGE 7 The number of days' warning given before a password expires.
SU_WHEEL_ONLY No If this is set to <font face="Courier">yes</font> , the user must be listed as a member of the first gid 0 group in <font face="Courier">/etc/group</font> (called root on most Linux systems) to be able to <font face="Courier">su</font> to uid 0 accounts. If the group doesn't exist or is empty, no one will be able to <font face="Courier">su</font> to uid 0.
#CRACKLIB_DICTPATH <font face="Courier">/var/cache/cracklib<br>/cracklib_dict</font> The path to the dictionaries if the suite has been compiled with cracklib support.
UID_MIN 1000 The minimum value for automatic uid selection in useradd.
UID_MAX 60000 The maximum value for automatic uid selection in useradd.
GID_MIN 100 The minimum value for automatic gid selection in groupadd.
GID_MAX 60000 The maximum value for automatic gid selection in groupadd.
LOGIN_RETRIES 5 Maximum number of login retries if password fails.
LOGIN_TIMEOUT 60 Maximum time in seconds before a login session expires -- in other words, the amount of time allowed between entry of username and entry of password.
PASS_CHANGE_TRIES 5 Maximum number of attempts to change password if initially rejected.
PASS_ALWAYS_WARN Yes Warns about weak passwords even if you are root. This will not stop root from self-assigning a bad password; it just informs root that the password is weak.
PASS_MAX_LEN 8 Number of significant characters in the password for <font face="Courier">crypt()</font> .
CHFN_AUTH Yes Require password before <font face="Courier">chfn/chsh</font> can make any changes.
CHFN_RESTRICT <font face="Courier">frwh</font> Defines which fields may be changed by regular users using <font face="Courier">chfn</font> . The letters represent full name, room number, work phone, and home phone. If not defined, no changes are allowed.
LOGIN_STRING <font face="Courier">%s's Password:</font> Determines the password prompt ( <font face="Courier">%</font> will be replaced by username).
MD5_CRYPT_ENAB No Only works if compiled with MD5_CRYPT defined: if set to <font face="Courier">yes</font> , new passwords will be encrypted using the MD5-based algorithm compatible with the algorithm used by recent releases of FreeBSD. It supports passwords of unlimited length and longer salt strings. Set this option to <font face="Courier">no</font> if you need to copy encrypted passwords to systems that don't understand the new algorithm.
#CONSOLE_GROUPS floppy:audio:cdrom List of groups to add to the user's supplementary group set when logging in on the console (as determined by the CONSOLE setting). There is usually no default, though Red Hat creates the above default. Use with caution -- it is possible for users to gain permanent access to these groups, even when not logged in on the console. (How to do it is left as an exercise for the reader.)
DEFAULT_HOME No Allows or disallows login if you can't cd to the home directory.
ENVIRON_FILE <font face="Courier">/etc/environment</font> If this file exists and is readable, the system will read the login environment from it. Every line should be in the form <font face="Courier">name=value.</font>
USERDEL_CMD <font face="Courier">/usr/sbin/userdel_local</font> If defined, this command runs when you remove a user. It should remove any at, cron, and print jobs owned by the user (passed as the first argument).
NO_PASSWORD_CONSOLE tty1:tty2:tty3:tty4:tty5:tty6 If defined, specify either the full pathname of a file containing device names or a colon-delimited list of device names. No password is required to log in on these devices.
TTYTYPE_FILE <font face="Courier">/etc/ttytype</font> Declares terminal types for particular tty lines. A typical file might look like:

linux tty1

linux tty2

linux tty3

linux tty4

wyse30 ttyS4

vt100 ttyp0

vt100 ttyp1

vt100 ttyp2

vt100 ttyp3

Password administration

User accounts are locked and unlocked using the

<font face="Courier">passwd</font>

command. The

<font face="Courier">-l</font>

flag locks them, the

<font face="Courier">-u</font>

flag unlocks them. For example,

<font face="Courier">$ passwd -l joe</font>

will lock the

<font face="Courier">joe</font>

account so the user can no longer log in.

The passwd program does some checking for poor passwords when a user attempts to change his/her password. Poor passwords will be rejected. The program doesn't use a dictionary, but a set of simple algorithms that can detect common flaws in passwords. A password can't be a palindrome, more than half the characters should be different, there should be a mix of letters and numbers, letters should be mixed-case, and it should not be too short. For example, a password consisting only of lower-case letters must be eight characters; if there is a mix of case, it can be seven or eight characters.

The root user maintains password-aging information using the

  • <font face="Courier">-x</font>
  • <font face="Courier">-n</font>
  • <font face="Courier">-w</font>
  • <font face="Courier">-i</font>

options to the

<font face="Courier">passwd</font>

command.

The

<font face="Courier">-x</font>

option sets the maximum number of days that a password will be valid. After this time, the user is prompted upon logging in to change his/her password. If the user somehow evades this, he/she will not be able to log in again.

The

<font face="Courier">-n</font>

option sets the minimum number of days before a password may be changed.

The

<font face="Courier">-w</font>

option sets the length in days of the warning period the system allows a user before invalidating his/her password. The user will receive a warning message informing him/her of the amount of time until the password must be changed.

The

<font face="Courier">-i</font>

option sets the number of days the system should wait to disable an account after the password expires.

Group passwords are administered using the

<font face="Courier">-g</font>

flag with the

<font face="Courier">passwd</font>

command. To change a group password, use the

<font face="Courier">-g</font>

option alone. Only root or the group administrator can do this. To remove a group password, use the

<font face="Courier">-r</font>

option with the

<font face="Courier">-g</font>

option. To restrict a group, use

<font face="Courier">-R</font>

with

<font face="Courier">-g</font>

.

Conclusion

The shadow password suite is a great improvement on the older Unix mechanism, but is still vulnerable if users do not pick good passwords. The importance of a good password cannot be underestimated. Working with shadow passwords is straightforward, since they build directly upon the older system.

This story, "Illuminating shadow passwords" was originally published by ITworld.

Copyright © 2001 IDG Communications, Inc.

7 inconvenient truths about the hybrid work trend
Shop Tech Products at Amazon