19.7 Administrative Techniques for Conventional Passwords

If you're a system administrator stuck using conventional Unix passwords, then you will find this section helpful. It describes a number of techniques that you can use to limit the danger of conventional passwords on your computer.

19.7.1 Assigning Passwords to Users

Getting users to pick good passwords can be very difficult. You can tell users horror stories and you can threaten them, but some users will always pick easy-to-guess passwords. Because a single user with a bad password can compromise the security of the entire system, some Unix administrators assign passwords to users directly rather than letting users choose their own.

To prevent users from changing their own passwords, all that you have to do is change the permissions on the /bin/passwd program that changes people's passwords.[15] Making the program executable only by people in the staff group, for example, will still allow staff members to change their own passwords, but will prevent other people from doing so:

[15] This technique requires changing permissions on any other password-changing software, such as yppasswd and nispasswd.

# chgrp staff /bin/passwd
# chmod 4750 /bin/passwd

Use this approach only if staff members are available 24 hours a day. Otherwise, if a user discovers that someone has been using her account, or if she accidentally discloses her password, the user is powerless to safeguard the account until she has contacted someone on staff.

Some versions of Unix may have an administrator command that will allow you to prevent selected users from changing their passwords.[16] Thus, you do not need to change the permissions on the passwd program. You only need to disable the capability for those users who cannot be trusted to set good passwords on their own.

[16] On AIX, the root user can prevent ordinary users from changing their passwords by running pwdadm -f ADMIN user or by editing /etc/security/passwd.

For example, in SVR4 Unix, you can prevent a user from changing his password by setting the aging parameters appropriately (we discuss password aging later in this chapter). For example, to prevent Kevin from changing his password, you might use the command:

# passwd -n 60 -x 50 kevin

Note, however, that Kevin's password will expire in 50 days and will need to be reset by someone with superuser access.

19.7.2 Constraining Passwords

You can easily strengthen the passwd program to disallow users from picking easy-to-guess passwords?such as those based on the user's own name, other accounts on the system, or a word in the Unix dictionary. So far, however, many Unix vendors have not made the necessary modifications to their software. There are some freeware packages available on the Internet, including npasswd and passwd+, which can be used for this purpose; both are available at popular FTP archives. Another popular system is anlpasswd, which has some advantages over npasswd and passwd+, and can be found at info.mcs.anl.gov. However, some of these software packages haven't been updated in years, and may require considerable effort to install on your system.

Some versions of Unix, most notably the Linux operating system, come supplied with npasswd or a PAM module that performs equivalently. Other vendors would do well to follow this example.

An approach that is present in many versions of Unix involves putting constraints on the passwords that users can select. Normally, this approach is controlled by some parameters accessed through the system administration interface. These settings allow the administrator to set the minimum password length, the number of non-alphabetic characters allowed, and so on. You might even be able to specify these settings per user, as well as per system.

19.7.3 Password Generators

Under many versions of Unix, you can prevent users from choosing their own passwords altogether. Instead, the passwd program runs a password generator that produces pronounceable passwords. To force users to use the password generator under some versions of System V Unix, select the Accounts Defaults Passwords menu from within the sysadmsh administrative program.

Most users don't like passwords that are generated by password generators. Despite claims of the programs' authors, the passwords really aren't that easy to remember. Besides, most users would much rather pick passwords that are personally significant to them. Alas, these passwords are also the ones that are easiest to guess.

Two more problems with generated passwords are that users frequently write them down to remember them, and the password generator programs themselves can be maliciously modified to generate "known" passwords.

There are several freely available password generators that you can download and install on your system. The mkpasswd program by Don Libes is one such program that can be found in many of the online archives mentioned in Appendix D.

Instead of using password generators, you may want to install password "advisors"?programs that examine user choices for passwords and inform the users if the passwords are weak. There are commercial programs that perform this procedure, including some integrated with other security tools, and various freeware and shareware filters such as passwd+. In general, these products may do comparisons against dictionaries and heuristics to determine if the candidate password is weak. However, note that these products suffer from the same set of drawbacks as password crackers?they can be modified to secretly record the passwords, and their knowledge base may be smaller than that used by potential adversaries. If you use an "advisor," don't be complacent!

19.7.4 Shadow Password Files

When the Unix password system was devised, the simple security provided by the salt was enough. Computers were slow (by present standards), and hard disks were small. At the rate of one password encryption per second, the system would have taken three years and three months to encrypt the entire 25,000-word Unix spelling dictionary with every one of the 4,096 different salts. Simply holding the database would require more than 10 GBs of storage?well beyond the capacity of typical Unix platforms at the time

The advantage to a computer criminal of such a database, however, would be immense. Such a database would reduce the time needed to do an exhaustive key search for a password from seven hours to a few seconds. Finding accounts on a computer that has weak passwords would suddenly become a simple matter.

Today, many of the original assumptions about the difficulty of encrypting passwords have broken down. For starters, the time necessary to calculate an encrypted password has shrunk dramatically. Modern workstations can perform up to tens of thousands of password encryptions per second. Now you can even store a database of every word in the Unix spelling dictionary encrypted with every possible salt on a single 10 GB hard disk drive, or?with compression?on a single DVD.

Because of these developments, placing even encrypted passwords in the world-readable /etc/passwd file is no longer secure.[17] There is still no danger that an attacker can decrypt the passwords actually stored?the danger is simply that an attacker could copy your password file and then systematically search it for weak passwords. As a result, all modern Unix systems have shadow password files.[18]

[17] The /etc/passwd file must be world-readable because many, many programs need to consult it for UID-to-account name mappings, home directories, and username information. Changing the permissions breaks quite a few essential and convenient services.

[18] Shadow password files have been a standard part of AT&T Unix since the introduction of SVR4 and are standard in nearly every modern version of Unix and Linux. A number of add-on shadow password systems are available for older versions of Unix; installing them requires having the source code to your Unix system.

Shadow password files hold the same encrypted passwords as the regular Unix password file; they simply prevent users from reading each other's encrypted passwords. Shadow files are protected so that they cannot be read by regular users; they can be read, however, by the setuid programs that legitimately need access. For instance, SVR4 uses the file /etc/shadow , with protected mode 600, owned by root; SunOS uses the file /etc/security/passwd.adjunct, in which the /etc/security directory is mode 700; and BSD-based systems use a file called /etc/master.passwd. (Mac OS 10.2 is alone among modern versions of Unix in not providing shadow password facilities.) The regular /etc/passwd file has special placeholders in the password field instead of the regular encrypted values. Some systems substitute a special flag value, while others have random character strings that look like regular encrypted passwords; would-be crackers can then burn a lot of CPU cycles trying dictionary attacks on random strings.

If your system does not have shadow passwords, then you should take extra precautions to ensure that the /etc/passwd file cannot be read anonymously over the network.

If you use shadow password files, you should be sure that there are no backup copies of the shadow password file that are publicly readable elsewhere on your system. Copies of passwd are sometimes left (often in /tmp or /usr/tmp) as editor backup files and by programs that install new system software. A good way to avoid leaving copies of your password files on your system is to avoid editing them with a text editor, or to exercise special care when doing so.

19.7.5 Password Aging and Expiration

Some Unix systems allow the system administrator to set a "lifetime" for passwords.[19] With these systems, users whose passwords are older than the time allowed are forced to change their passwords the next time they log in. If a user's password is exceptionally old, the system may prevent the user from logging in altogether.

[19] Different systems use different procedures for password aging. For a description of how to set password lifetimes on your system, consult your system documentation.

Password aging can improve security. Even if a password is learned by an attacker and the account is surreptitiously used, that password will eventually be changed. Password aging can also help you discover when people have access to passwords and accounts that aren't properly registered. In one case we know about, a computer center started password aging, and four users suddenly discovered that they were all using the same account?without each other's knowledge! The account's password had simply not been changed for years, and the users had all been working in different subdirectories.

Users sometimes defeat password-aging systems by changing an expired password to a new password and then back to the old password. A few password-aging systems check for this type of abuse by keeping track of old and invalid passwords. Others prevent it by setting a minimum lifetime on the new password. Thus, if the password is changed, the user is forced to use it for at least a week or two before it can be changed again?presumably back to the old standby.[20] If you use password aging, you should explain to your users why it is important for them to avoid reusing old passwords.

[20] This is a bad idea, even though it is common on many SVR4 systems. It prevents the user from changing a password if it has been compromised, and it will not prevent a user from cycling between two favorite passwords again and again.

Under SVR4, you can set password aging using the -n (minimum days before the password can be change) and -x (maximum number of days) options (e.g., passwd -n 7 -x 42 sally). Setting the aging value to -1 disables aging.

Old-Style Password Aging

Older versions of Unix had a form of password aging available, but it was usually not documented well, if it was documented at all. We describe it here for the sake of completeness and as a historical record.

To enable the old-style password aging, you would append a comma and two base-64 digits to the end of the password field in the /etc/passwd file for each user. The comma was not valid as part of an encoded password, and signalled that password aging was to be enabled for that user. The two digits encoded the aging parameters that are now set with the -x and -n options of the SVR4 passwd command, as described previously. The base-64 encoding is the same as that used for encoding passwords, and is described in Section

The first digit after the comma represented the number of weeks until the password expired (from the beginning of the current week). The second digit represented the minimum number of weeks that the password had to be kept before it could be changed again. These values would be calculated by the system administrator and then edited into the appropriate locations in the passwd file. After being set, the user would be prompted to choose a new password the next time he or she logged in. Then two more digits would be appended to the field in the file; these two digits would also be updated each time the passwd command was run successfully. These two digits encoded, in base-64, the time of the most recent password change, expressed as a number of weeks since the beginning of 1970. These digits were usually expressed in reverse order, as if base-64 wasn't obscure enough!

Putting simply a ",." at the end of a password field would require the password to be changed at the very next login. Most systems would then remove these characters, although we have heard that on some dimly remembered system, the characters would be changed into ",.z" (allow changes anytime, expire this one in 64 weeks).

Few systems were shipped with software to ease the task of calculating and setting these values manually. As another drawback, the users were given no warning before a password expired?the user logged in and was forced to change the password right then and there. Everyone we know who experienced the mechanism hated it, and we do not believe it was widely used. The SVR4 mechanism is a great improvement, although still not ideal.

We recommend that you avoid using the -n option of the password aging command! Configuring your system so that users are prevented from changing their password is foolish. Users can accidently disclose their passwords to others?for example, they might say their new password out loud when they are typing it in for the first time. If users are required to wait days or weeks before changing their passwords again, then their accounts will be vulnerable.

Password aging should not be taken to extremes. Forcing users to change their passwords more often than once every few months is probably not helpful. If users change their passwords so often that they find it difficult to remember what their current passwords are, they'll probably write down these passwords. Imagine a system that requires users to change their passwords every day. Expiration times that are too short may make the security worse rather than better. Furthermore, it engenders discontent?feelings that the security mechanisms are annoying rather than reasonable. You may have good passwords, but having users who are constantly angry about the security measures in place almost certainly negates any benefits gained.

On the other hand, if you want your users to change their passwords every minute, or every time that they log in, then you probably should use a one-time password system, such as those described in Section 19.6 earlier in this chapter.

19.7.6 Cracking Your Own Passwords

A less drastic approach than preventing users from picking their own passwords is to run a program periodically to scan the password file or database for users with passwords that are easy to guess. Such programs, called password crackers, are (unfortunately?) identical to the programs that bad guys use to break into systems. The most widely used password cracker for Unix may well be a program named Crack.

The theory of running password crackers is simple: the bad guys are going to be running them, so you might as well run them first and fix the problems before they are discovered by a potential attacker.

Shadow password files provide some protection against password cracking. In theory, shadow password files prevent users on your system from accessing the encrypted passwords of other users. But shadow password schemes are not perfect: if an attacker manages to become root, he will almost certainly copy your shadow password file so that he can probe for additional vulnerabilities.

Of course, if you are on a computer that does not use shadow password files, you should absolutely be running programs like Crack on a regular basis?after all, your users are almost certainly doing so.[21]

[21] There is really no way to know if your users are running Crack because the password file could be copied to another computer and cracked there.

Before you run a password cracker on your system, be sure that you are authorized to do so. You may wish to get the authorization in writing. Running a password cracker may give the impression that you are attempting to break into a particular computer. Unless you have proof that you were authorized to run the program, you may find yourself facing unpleasant administrative actions or possibly even prosecution for computer crime. In 1993, Randal Schwartz, a respected author of Perl books, was convicted of three felonies in Oregon for running Crack on the password file of one of Intel's divisions while working as a system administrator for one division and a consultant for another. The Oregon Supreme Court allowed the conviction to stand in 2001; Randal's sentence included 5 years of probation, 480 hours of community service (later commuted to 240), 90 days of deferred jail time (later suspended), and $68,000 of restitution to Intel. Joetest: a simple password cracker

To understand how a password-cracking program works, consider the program in Example 19-1, which simply scans for accounts that have the same passwords as their usernames. From Chapter 4, remember that such accounts are known as "Joes." The program must be run as root if you have shadow password files installed on your system.

Example 19-1. Single password cracker
 * joetest.c:
 * Scan for "joe" accounts -- accounts with the same username
 * and password.

#include <stdio.h>
#include <pwd.h>
int   main(int argc,char **argv)
    struct     passwd *pw;

    while(pw=getpwent( ) ){
        char     *crypt( );
        char     *result;

        result = crypt(pw->pw_name,pw->pw_passwd);
            printf("%s is a joe\n",pw->pw_name);

Here is the same program in Perl:

# joetest
while (($name,$passwd) = getpwent) {
                print "$name is a joe\n" if (crypt($name,$passwd) eq $passwd);

Here is a slightly more sophisticated password cracker:

# super joetest
while (($name,$passwd) = getpwent) {
                print "$name has no password\n" if !$passwd;
                print "$name is a joe\n" if (crypt($name,$passwd) eq $passwd);
                print "$name is a JOE\n" if (crypt(uc($name), $passwd) eq $passwd);
                print "$name is a Joe\n" if (crypt(ucfirst($name), $passwd) 
                        eq $passwd);
                print "$name is a eoj\n" if (crypt((scalar reverse $name), $passwd)
                        eq $passwd);

If you have the time, type in the above program and run it. You might be surprised to find a Joe or two on your system. (In August 2002 we ran this program on a computer with 1,200 user accounts and found four "eoj" accounts.) Or simply get Crack, which will scan for these possibilities, and a whole lot more.[22]

[22] Or cracklib, the library version, suitable for linking into your own applications. The dilemma of password crackers

Because password crackers are used both by legitimate system administrators and computer criminals, they present an interesting problem: if you run the program, a criminal might find its results and use them to break into your system! And, if the program you're running is particularly efficient, it may be stolen and used against you. Furthermore, the program you're using could always have more bugs or have been modified so that it doesn't report some bad passwords that may be present; instead, such passwords might be silently sent by electronic mail to an anonymous repository out of the U.S.

Instead of running a password cracker, a better approach is to prevent users from picking bad passwords in the first place. But this goal is not always reachable: some users refuse to pick good passwords, and some systems make it impossible to test user passwords before they are adopted. For these reasons, many system administrators are forced to run a cleanup operation?that is, run password crackers on a regular basis and disable accounts when they find poor passwords.

If you run a program like Crack and find a bad password, you should disable the account immediately, because an attacker could also find it.

If you run a password cracker and don't find any weak passwords, don't assume that there are no bad passwords to find! You might not have as extensive a set of dictionaries as the people working against you: while your program reports no weak passwords found, outsiders might still be busy logging in using cracked passwords found with their Inuit, Basque, Klingon, and Middle Druid dictionaries. Or an attacker may have booby-trapped your copy of Crack so that discovered passwords are not reported but are instead sent to a computer in New Zealand for archiving. For these reasons, use password cracking in conjunction with user education, rather than as an alternative to it.

19.7.7 Algorithm and Library Changes

If you have the source code to your system, you can alter the crypt( ) library function to dramatically improve the resistance of your computer to password cracking. Here are some techniques you might employ:

  1. Change the number of encryption rounds from 25 to something over 200. This change will make the encryption routine operate more slowly, which is good. More importantly, it will make encrypted passwords generated on your computer different from passwords generated on other systems. This foils an attacker who obtains a copy of your /etc/passwd file and tries to crack it on a remote computer using standard software.

  2. Add a counter to the crypt( ) library call that keeps track of how many times it has been called within a single process. If a user's program calls it more than 5 or 10 times, log that fact with syslog, being sure to report the user's login name, tty, and other pertinent information. Then start returning the wrong values![23] This is especially useful when combined with the first item.

    [23] Many site administrators feel uncomfortable with this advice to modify a system library to return wrong values. However, in our experience, few (if any) programs need to run crypt( ) more than a few times in a single process unless those processes are attempting to crack passwords. On the other hand, when we have worked with sites that have had problems with password cracking, those problems have stopped immediately when the crypt( ) routine was modified to behave in this manner. If you feel uncomfortable having some programs silently fail, you may wish to end their silence, and have them send email to the system administrator or log a syslog message when the crypt( ) routine is run more than a few times.

  3. Stop using crypt( ) at all. Systems that support PAM can be easily configured to encrypt passwords using the MD5 message digest algorithm with a salt. If you use MD5 and your users use (or can be made to use) long and uncommon passphrases, rather than short passwords, you can make your password file virtually impossible to crack.

If you decide to modify crypt( ) itself, there are some issues to be aware of:

  1. If your system uses shared libraries, be sure to update the crypt( ) in the shared library; otherwise, some commands may not work properly.

  2. If your system does not use shared libraries, be sure to update the crypt( ) function in your file libc.a so that people who write programs that use crypt ( ) will get the modified version.

  3. Be sure to re-link every statically linked program that uses crypt( ) so that they all get the new version of the routine.

  4. Some programs legitimately need to call the crypt( ) routine more than 10 times in a single process. For example, the Apache web server needs to call crypt( ) to verify passwords that are stored in encrypted form. For programs like these, you will need to provide a means for them to run with a version of the crypt( ) function that allows the function to be run an unlimited number of times.

Do these techniques work? Absolutely. In the early 1990s there was a computer at MIT on which guest accounts were routinely given away to members of the local community. Every now and then, somebody would use one of those guest accounts to grab a copy of the password file, crack it, and then trash other people's files. (This system didn't have shadow passwords either.) The day after the above modifications were installed in the system's crypt( ) library, the break-ins stopped and the system's administrators were able to figure out who was the source of the mischief. Eventually, though, the system administrators gave up on modifications and went back to the standard crypt( ) function. This is because changing crypt( ) has some serious drawbacks:

  1. The passwords in your /etc/passwd file will no longer be compatible with an unaltered system, and you won't be able to trade /etc/passwd entries with other computers.[24]

    [24] This may be an advantage under certain circumstances. Being unable to trade encrypted passwords means being unable to have "bad" passwords on a computer that were generated on another machine. This is especially an issue if you modify your passwd program to reject bad passwords. On a sweep of numerous computers at one major lab, one set of machines was found to have uncrackable passwords, except for the passwords of two accounts that had been copied from other machines.

  2. If your site transfers /etc/passwd entries between machines as a means of transferring accounts, then you will need to have the same crypt( ) modifications on each machine.

  3. If you use NIS, NIS+, LDAP, or another distributed authentication database, then you must use the same crypt( ) algorithm on all of the machines on your network.

  4. You'll need to install your changes every time the software is updated, and if you cease to have access to the source, all of your users will have to set new passwords to access the system.

  5. This method depends on attackers not knowing the exact number of rounds used in the encryption. If they discover that you're using 26 rounds instead of 25, for example, they can modify their own password-breaking software and attack your system as before. This may require you to keep your library source code unreadable to non-root users. (However, this scenario is unlikely to happen in most environments: the cracker is more likely to try to break into another computer?hardly a drawback at all!)

  6. If an insider knows both his cleartext password and the encrypted version, he can also determine experimentally how the algorithm was changed.

While increasing the number of rounds that the encryption algorithm performs is a relatively safe operation, don't alter the algorithm used in the actual password mechanism unless you are very, very confident that you know what you are doing. It is easy to make a change you think is adding complexity, only to make things much simpler for an attacker who understands the algorithm better than you do.

19.7.8 Account Names Revisited: Using Aliases for Increased Security

As we described earlier in this chapter, you can give accounts almost any name you want. The choice of account names will usually be guided by a mixture of administrative convenience and user preference. You might prefer to call the accounts something mnemonic so that users will be able to remember other usernames for electronic mail and other communications.

At the same time, you can achieve slightly better security by having nonobvious usernames. This method is a form of security through obscurity. If an attacker does not know a valid username at your site, she will have greater difficulty breaking in. If your users' account names are not known outside your site and are nonobvious, potential intruders have to guess the account names as well as the passwords. This strategy adds some additional complexity to the task of breaking in, especially if some of your users have weak passwords.

If you use obscure account names, you need a way to protect those account names from outsiders while still allowing your users to access electronic mail and participate in Usenet and web discussions. The way to do this is with aliasing.

If you configure one machine to be your central mail and news site, you can set your software to change all outgoing mail and news to contain an alias instead of the real account name. This is probably what you should do if you decide to install a firewall between your site and the outside network.

For example, your mailer could rewrite the From: line of outgoing messages to change a line that looks like this:

From: paula@home.acs.com

to look like this:

From: Paula.Harris@ACS.COM

This address is also the electronic mail address Paula would put on her business cards and correspondence. Incoming mail to those addresses would go through some form of alias resolution and be delivered to her account. You would also make similar configuration changes to the Usenet software. There is an additional advantage to aliasing?if an outsider knows the names of his correspondents but not their account names (or machine names), he can still get mail to them.

If you take this approach, other network services, such as finger and who, must similarly be modified or disabled.[25] You must also be certain to educate your users about what name they should present to outside correspondents.

[25] Discussing all of the various mailers and news agents that are available and how to modify them to provide aliasing is beyond the scope of this book. We suggest that you consult the O'Reilly & Associates books on electronic mail and news to get this information.

Many large organizations use some form of aliasing. For example, mail to people at AT&T Bell Laboratories that's addressed to First.Last@att.com will usually be delivered to the right person, even though that individual's username is almost certainly not First.Last.

    Part VI: Appendixes