Read LPI Linux Certification in a Nutshell Online
Authors: Adam Haeder; Stephen Addison Schneiter; Bruno Gomes Pessanha; James Stanger
Tags: #Reference:Computers
Why is there anx
in
the password field (field 2) of the previous example? When Unix was
originally designed, the
/etc/passwd
file stored a
user’s encrypted password string in field 2 of
/etc/passwd
. The password was encrypted using an
algorithm known as a one-way hash (the
crypt
algorithm), meaning that while it was trivial to convert a string to a
hashed value, it was mathematically difficult (i.e., it would take an
extremely long time) to convert the hashed value back to the original
string. This is a common function of algorithms used in the security
world, especially for things such as passwords. If you can’t determine
the original password when you only know the hashed value, then we don’t
have to worry about the security around the hashed value itself, because
it is too difficult mathematically to derive the password from the
hashed value. So this hashed value can be stored in a world-readable
file such as
/etc/passwd
without compromising the
security of the system.
If it’s very difficult to derive a password from its hashed value,
how does the system know I’m typing in the right password when I log in?
The login process on a Linux system follows these steps:
Prompt user for a username and password.
Look in
/etc/passwd
to see whether the
user account exists.
If it does, encrypt the string given as the password using the
crypt
algorithm.
Compare the encrypted string given by the user with the
encrypted string stored in field 2 of the
/etc/passwd
entry for that username. If they
match, then the user gave the correct password, and she is allowed
to log in. If they did not match, present an error and ask the user
for the password again.
In this way, a Linux system is able to determine whether a user
provided the correct password without having to “recover” the original
password from the encrypted string.
Although this solution is effective, it does pose security risks.
By storing the encrypted string in the world-readable
/etc/passwd
file, any user on the system has access
to every other user’s encrypted password. It may be extremely difficult
for a user to mathematically derive the original password from the
encrypted string, but she can use the same
crypt
algorithm to encrypt random strings and compare the resultant encrypted
string with the encrypted strings for other users (following the same
process
that the login program
uses). If the user is patient enough and tries enough combinations of
letters and numbers, she could eventually find a string that, after
encryption, exactly matches the encrypted string for a user account.
This is called a
brute force attack
, because the
user is forced to try every possible combination of potential passwords
to determine which one is correct.
If this seems like a daunting and time-consuming task, that’s
because it is. Or at least it was, if we’re talking about the computing
power that was available to the average user in the 1960s through the
1980s. However, as the 1980s turned into the 1990s, and computers not
only got much faster but also much cheaper, the average user had access
to relatively powerful computational machines that could encrypt strings
and compare them against other encrypted strings at the rate of
thousands (or hundreds of thousands) per second. This posed a problem
for the system administrators of the day; the encrypted hash was stored
in a world-readable file (
/etc/passwd
), and every
user could now copy this file, take it back to their personal computers,
and run brute force attacks against it.
The solution to this was to move the encrypted password string to
a file that is not world-readable. Thus the concept of
shadow
passwords
was born, and the file
/etc/shadow
was created. This file contains not
only the encrypted password but also other user account fields that are
important (such as password age and account expiration dates), without
requiring a modification to the format of
/etc/password
. Plus, only the root user can read
/etc/shadow
, preventing brute force attacks by
normal users.
The
/etc/shadow
file is colon-delimited, like
/etc/passwd
, and contains the fields described in
Table 22-2
.
Table 22-2. Fields in /etc/shadow
Field | Name | Description |
---|---|---|
1 | Username | Must match a username in |
2 | Password | Encrypted password string. Other
|
3 | Last Changed | The number of days (since January 1, |
4 | Minimum | The number of days before a user may |
5 | Maximum | The number of days a user can keep the |
6 | Warn | The number of days before password |
7 | Inactive | The number of days after password |
8 | Expire | A number indicating when the account |
9 | Reserved | Reserved for possible future |
Here is the section of
/etc/shadow
that corresponds to the section
of
/etc/passwd
listed
previously:
root:$1$8jp/RdHb$D1x/6Xr2.puE0NX3nIgdX/:14617:0:99999:7:::
bin:*:13993:0:99999:7:::
daemon:*:13993:0:99999:7:::
adm:*:13993:0:99999:7:::
lp:*:13993:0:99999:7:::
adamh:$1$IqH21LHP$BJPha9o6/XoOsSoJfWLfZ0:14617:0:99999:7:::
These are actual encrypted password strings. Break out your
favorite brute-force password-cracking program and see if you can
figure out the passwords.
We can see from this file that the root account has a password,
the password was last changed 14,617 days after January 1, 1970, this
user can change her password at any time, she does not have to change
her password until 99,999 days after January 1, 1970, and if her
password is ever set to expire, she will start getting notices 7 days
before the actual expiration.
You can use the
date
command to determine the
actual dates those integer values represent:
#echo "The password for the root account was last changed \
on `date -d "1970/01/01 +14617 days"`"
The password for the root account was last changed \
on Fri Jan 8 00:00:00 CST 2010
#echo "The password for the bin account was last changed \
on `date -d "1970/01/01 +13993 days"`"
The password for the bin account was last changed \
on Thu Apr 24 00:00:00 CDT 2008
The accounts for
bin
,
daemon
,
adm
, and
lp
are all examples of system accounts. These
accounts are never meant to have interactive logins; they exist to run
system processes and to maintain ownership of files. The*
in the encrypted password fields means that
these accounts are disabled from logging in interactively.
Although this file is a text file and can be edited directly to
modify these values, the command
/usr/bin/chage
should be used to maintain the password aging settings for
accounts.
So far, the security concerns we have discussed regarding
a Linux system have all revolved around the filesystem. Since everything
in Linux is a file, this makes sense. However, security isn’t solely
concerned with which user can access what resource at what time.
Security must also take into consideration the sharing of resources
among users (both system and human users). A good security administrator
will ensure that no insecure SUID or SGID binaries exist on his system
that could give a normal user root access. But what measures are in
place to ensure that a normal user doesn’t run so many processes that a
server is ground to a halt? What exists to make sure a user doesn’t open
so many network sockets that no memory is available to allocate to new
connections? At first these might seem like capacity planning issues,
but when we are dealing with systems that reside in a hostile
environment (such as the Internet), they become the responsibility of
the security administrator.
The Linux kernel has the ability to control many limits on what
users can and can’t do. These limits are defined in the file
/etc/security/limits.conf
and are viewed or
modified interactively by the
ulimit
command.
ulimit
is a command built into the bash shell, so
it does not exist as a separate binary on a Linux system.
Previous chapters have discussed the importance of the
/bin/ps
command. It is vitally important that a
system administrator knows exactly what processes are running on her
machine and why. The first step toward maintaining a secure system is
knowledge about that system. However, in this age of always-connected
systems, understanding processes by themselves is not enough; you must
also understand how they interact across the network. This can be
accomplished with these Linux utilities:
netstat
,
nmap
, and
lsof.
su
su[OPTION]... [-] [USER [ARG]...]
The
su
command (short for
s
ubstitute
u
ser) allows
you to run a shell with substitute user and group IDs. It is most
commonly used to allow a normal user to “become” the root user
(assuming they know the root password). It is also used by the root
user to “become” a regular user.
Make the shell that is spawned a login shell (i.e.,
process
.bash_profile
and set appropriate
login environment variables, such as
$PATH
)
COMMAND
Pass a single command to the shell, useful for one-line
commands that need to be run as
root
.
A normal user becoming root:
$whoami
adam
$su -
Password:#
whoami
root
Running a command as the root user:
$wc -l /etc/shadow
wc: /etc/shadow: Permission denied
$su -c wc -l "/etc/shadow"
Password:48 /etc/shadow
Root becoming a regular user:
#whoami
root
#su – adam
$whoami
adam
The
-
(or
-l
) option
to
su
determines whether or not the new shell
is a login shell. The most obvious impact of this decision is the
$PATH
variable. The most common usage of
su
is for a regular user to become the root
user, to enable that user to run a command or perform a task that
only
root
can do. By default, the
$PATH
environment variable contains different
directories for the root user than for regular users. Specifically,
the directories
/sbin
and
/usr/sbin
store binary programs that only the
superuser should run. Regular users can read these directories, but
it doesn’t make sense to have those directories in a regular user’s
$PATH
, because they will never need to use
them.
If a regular user uses the command
su
to
become root, the
$PATH
environment variable
does not change, because this is not a login shell. This means that
the directories
/sbin
and
/usr/sbin
are not in that user’s
$PATH
. This is often a source of confusion for
new system administrators. Note the following example:
$whoami
adam
$su
Password:#
fdisk –l /dev/sda
bash: fdisk: command not found
#which fdisk
/usr/bin/which: no fdisk in
(/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/adam/bin)
#exit
$su –
Password:#
fdisk –l /dev/sda
Disk /dev/sda: 200.0 GB, 200049647616 bytes
....etc....
#which fdisk
/sbin/fdisk
#echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:\
/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
Initially, the
fdisk
command by itself
did not work because it was not in the
$PATH
variable. Once the user returned to her user shell and used
su
to become
root
, the
$PATH
environment variable then contained the
/sbin
and
/usr/sbin
directories, so
fdisk
was found.