One of the problems with writing articles about security-related
issues 
is the fear that someone will use what you have written
to attack 
a system. The good side is that the more system administrators
know 
about how the tools work, the better able they will
be to protect 
their systems from attack.
This article focuses on the UNIX password encryption
system. I describe 
how the system works and discuss some of the methods
the bad guys 
use to circumvent it.
Ensuring that users select good passwords is the administrator's
primary 
mechanism for controlling access to the machine. This
is the most 
common breakpoint in any computing environment where
the password 
is set by the user. The opposite  scenario, in which
the user has 
no control over password assignment, often results in
the user writing 
the password down somewhere, immediately snapping the
security chain.
Good passwords are at least six characters long and
contain a mix 
of upper- and lower-case characters, a number, and,
potentially, a 
control character. Many versions on UNIX also accept
a space as a 
valid character in a password. Bad passwords violate
one or more of 
these guidelines. In addition, a password consisting
of any piece 
of information that can be found out about a user, or
of the name 
of a visible object on the user's desk, forms a gaping
hole just waiting 
to be exploited.
Communicating the guidelines for creating good passwords
to users 
is one side of this issue; getting the operating system
to enforce 
them is the other.
Many versions of UNIX provide for password aging. This
mechanism controls 
when users can change their passwords by means of a
value inserted 
into the password file after the encrypted password.
This value defines 
the minimum period of time that must pass before a user
can change 
a password and the maximum period of time that can elapse
before the 
password has expired. A timeline provides a good representation
of 
the concept.
Password aging control information is stored with the
encrypted password as a series of printable characters.
The controls 
are included after the password, preceded by a comma.
The characters 
represent:
When the password was most recently changed.
See the sidebar "Using Password-ese" for examples
of this mechanism.
The aging control mechanisms recognize two special conditions:
one 
which forces the user to change the password on next
login, and one 
which prevents the user from being able to change it.
To force a user to change a password, as in the case
of a new user, 
the user's password field would be modified to include
a comma 
followed by two periods representing the maximum and
minimum time 
frames. These values force the user to change the password
at the 
next login. When the password has been changed, the
"force" 
control information is removed from the password entry.
The second special case prohibits a user from being
able to change 
a password. This condition is established by setting
the maximum value 
to be less than the minimum value (i.e., first <
second). In this 
case, the user is informed that the password cannot
be changed.
Some of the newer, more secure versions of UNIX now
on the market 
use the term "password lifetime." This denotes
a grace period 
after the maximum time period has elapsed during which
the user may 
still login using the expired password. Once the lifetime
has been 
reached, the account will be disabled.
The password lifetime mechanism doesn't prevent a user
from changing 
a password and then changing it back to the old one
later. Only a 
few UNIX system versions keep track of the passwords
a user has used. 
The actual process of implementing password aging is
version dependent. 
To implement it on your system, consult your system
documentation.
The program in Listing 1, pwexp.pl, provides advance
notice 
of password expiration dates, so that users can be prepared
for the 
day when the system demands a new password. Note, however,
that this 
version of the program is for standard System V UNIX,
where a shadow 
password file is not used.
pwexp.pl addresses the aging mechanism that was implemented
in versions of UNIX up to System V Release 3.2. At this
level, some 
variations took place in the interests of increasing
system security. 
The AT&T camp moved to using the /etc/shadow file
for storing 
the password information, while the SCO camp moved to
using the Trusted 
Computing Base facilities form SecureWare. In SCO's
UNIX 3.2v4 product, 
the aging control information may be in /etc/passwd,
/etc/shadow, 
or the Trusted Computing Base files, depending upon
which level of 
security you configure.
How Passwords Are Encrypted
The real issue at hand is how the UNIX password mechanism
is implemented. 
At one time, the passwords were stored in an unecrypted
format, and 
only the administrator and system software had access
to the file. 
The problem came when the password file (/etc/passwd)
was being 
edited. Since most editors create a temporary file for
editing purposes, 
during this time the file would be world-readable, giving
the passwords 
for all of the accounts away.
As a result, a method of encrypting the passwords using
a one-way 
encryption algorithm and storing the encrypted values
instead of the 
clear text was provided. However, the security of the
system is only 
as good as the encryption method chosen.
When a user logs into a UNIX system, the getty program
prompts 
for username and then executes the login program. The
login program 
prompts for the password, but does not decrypt it. In
fact, the login 
program encrypts the password, and then compares the
newly encrypted 
value to the one stored in /etc/passwd. If they match,
then 
the user supplied the correct one.
So how does it work? The UNIX encryption method for
password encryption 
is accessed via the system call crypt(3) (because of
U.S. licensing 
issues, the crypt routines may not be available on your
machine).
The actual value stored in /etc/passwd results from
using the 
user's password to encrypt a 64-bit block of zeroes
via the crypt(3) 
call. The "clear text" is the user's password,
which is the 
key to the operation. The text being encrypted is 64
bits of zeroes, 
and the resulting "cipher text" is the encrypted
password.
The crypt(3) algorithm is based upon the Data Encryption
Standard 
(DES) developed by the National Institute of Standards
and Technology 
(NIST). In normal operation, according to the DES, a
56-bit key, such 
as eight 7-bit characters, is used to encrypt the original
text, commonly 
called "clear text." This clear text is typically
64 bits 
in length. The resulting cipher text cannot be decrypted
easily without 
knowledge of the original key.
The UNIX crypt(3) call uses a modified version of this
method 
by stating that the clear text be encrypted in a block
of zeroes. 
The process is complicated by taking the resulting cipher
text and 
encrypting it again with user's password as the key.
This process 
is performed 25 times, and, when it is complete, the
resulting 64 
bits are split into 11 printable characters and then
saved in the 
password file.
Despite the fact that source for crypt can be obtained
from 
many vendors (even though the distribution of this is
limited outside 
the United States), there is no known method for translating
the cipher 
text or encrypted value back to its original clear text.
Robert Morris, Sr., and Ken Thompson, who originally
implemented the 
UNIX crypt(3) technology, were afraid that with the
advent 
of hardware DES chips, the security of the UNIX system
could easily 
be bypassed. By using a "grain of salt," they
managed to disarm 
this threat.
The "grain of salt" is a 12-bit number which
is used to modify 
the result of the DES function. The value of this number
ranges from 
0 to 4095. The result is that each possible password
could be represented 
in any one of 4096 ways in the password file. Multiple
users on the 
same machine could be using the same password, and no
one, including 
the system manager, would be the wiser.
When a user runs the /bin/passwd program to establish
a new 
password, the /bin/passwd program picks a salt value,
based 
upon the time of day, which is then  used to modify
the user's password.
To prevent problems in the unlikely case that the user's
next login 
generates the same salt value, UNIX stores the salt
in /etc/passwd 
as well. In fact, this value makes up the first two
characters of 
the encrypted password.
The Validity of the Password Cracker
A password cracker is a program that attempts to "guess"
the 
passwords in the /etc/passwd file by comparing them
to words 
in a dictionary. The success of the cracker program
is dependent upon 
the CPU resources, the quality of the dictionary, and
the fact that 
the user has a copy of /etc/passwd.
It is fairly easy to write a password cracker: approximately
60 lines 
of C or 40 lines of Perl code will do it. If, as part
of your attempt 
to provide for better passwords on your system, you
decide to write 
such a program, be warned that you may be inviting disaster.
Since 
an efficient cracker program could be stolen and subsequently
used 
to gain access to other machines, if your program works,
you may have 
further compromised the security of your machine. (Even
as I was writing 
this article, one such program was posted to comp.sources.misc.
The author clearly states in his documentation that
he assumes no 
responsibility for the use of his program, but yet claims
that it 
is highly efficient.)
A much better approach is to protect the system using
the logical 
security tools.
Making /bin/passwd More Intelligent
Over the last couple of years, as secure versions of
UNIX have evolved, 
/bin/passwd has undergone changes. Indeed, some of the
older 
versions were rather intelligent, and could pick up
some of the common 
problems, such as passwords that were too short, didn't
include numbers, 
etc.
A number of UNIX manufacturers now provide passwd programs
that will validate the usability of the password. These
programs check 
for length, username, circular shifts, and common words
(without implementing 
a dictionary examination).
In addition, /bin/passwd can be configured to generate
passwords 
and to check for obviousness in those provided by the
user.
Unfortunately, many UNIX systems still in use today
do not offer these 
advantages, and therefore must be coaxed to provide
them, so we enter 
the realm of system security for the programmer.
Programmer Security
Rewriting /bin/passwd is not a simple job: password
aging, 
salts, and file access are just three of the issues
involved. Neither 
is it really feasible to build a wrapper around the
/bin/passwd 
program.
Unlike many programs, which simply read from standard
input to get 
data from the user and the keyboard, /bin/passwd reads
from 
the generic device /dev/tty. This strategy protects
the system 
from intruder programs that attempt to make /bin/passwd
"believe" 
that input is coming from the keyboard.
Furthermore, the wrapper could not be written as a shell
script, but 
would require either the use of C (or another language
that allows 
for the use of setuid system calls) or the SUID bit
on the executable's 
permissions. When the program is not a binary executable,
SUID bits 
are ignored because there is no way to ensure that the
code being 
executed is what the programmer wrote, or that /bin/sh
is not 
itself a SUID program running the commands with the
authority of the 
user running the the shell.
The book Programming PERL, by Larry Wall and Randal
Schwartz, 
has such a program. It is 15 pages of PERL source code,
and makes 
a valiant effort to provide for all of the possibilities
that should 
be evaluated. The program in Listing 2 (with its configuration
file, 
pwd.cfg, in Listing 3), named pwd.pl, is an example
of what needs to be done to make /bin/passwd more intelligent.
If you are seriously considering installing a "smarter"
version 
of /bin/passwd, I suggest using the implementation from
Programming 
PERL. The program I present in Listing 2 is an example
only, and 
while it works, I wouldn't bet my life on it.
The examples from Programming PERL are available from
a number 
of places, including the host ftp.uu.net, in /published/nutshell/perl/perl.tar.Z.
I would prefer to see UNIX vendors increase the level
of thoroughness 
in /bin/passwd rather than leave it to users to do.
Too many 
things can go wrong, and quite a lot about the /bin/passwd
program isn't documented. The Santa Cruz Operation,
for one, and AT&T 
with the Multi-Level Security (MLS) features, all provide
smarter 
versions of /bin/passwd and some form of additional
password 
security.
Above all, be wise about the passwords you choose --
they are the 
most vital link to system access.
About the Author
Chris Hare is Ottawa Technical Services Manager for
Choreo 
Systems, Inc. He has worked in the UNIX environment
since 1986 and 
in 1988 became one the first SCO authorized instructors
in Canada. 
He teaches UNIX introductory, system administration,
and programming 
classes. His current focus is on networking, Perl, and
X.