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.