R. King Ables
Named for the giant, invader-filled wooden horse of
Greek mythology,
a trojan horse is an unauthorized program which seems
to be legitimate
but in reality is a disguised mechanism that helps an
invader gain
access.
If the would-be invader can leave a seemingly innocent
program (the
software analog of the horse) in a directory where someone
with privileges
might run it, then it can let its soldiers out to do
its dirty work
before the privileged user suspects anything.
To minimize the risk of this sort of security breach
you must be more
skeptical than the residents of Troy: don't trust appearances.
Specifically:
Don't use programs as root unless necessary
Watch out for programs that are "setuid root"
Some programs need to have root privileges to function
properly. UNIX's
setuid mechanism allows a program whose setuid mode
bit is active
to (legitimately) run with root privileges even though
the user does
not have that level of privilege (see the chmod(1) command
for more information).
A number of system programs need to run with the setuid
bit active,
but users rarely have any reason to have a setuid program
in their
home directory. Therefore, the number of setuid programs
on a UNIX
system should be small and easily inventoried. The following
command
will generate a list of all the setuid programs on your
system.
find / -type f -perm -4000 -exec ls -lg {};
If you keep the output of this command, re-execute it
on a regular basis, and compare the new output to the
list you've
kept, you can easily spot any setuid programs that have
been changed
or added to your system.
This command will record, among other things, the last-write
date
for each file. This is valuable information, but not
sufficient. An
invader may have been able to make a change to a file
and prevent
the last-write date from being updated. You can detect
this violation
by examining the file's checksum (using the sum(1) command).
Finally, the consensus in the UNIX community is that
setuid root shell
scripts are a huge security hole and that no system
should ever contain
one. By running file on each file found by the above
command,
you can identify readable text files that might be shell
scripts.
The cksuid script (Listing 1) demonstrates these functions.
Not only does it keep the byte count and latest update
times (from
the ls(1) command), but it also adds a checksum of each
file
and the output of the file(1) command to the entry.
If any
of this information has changed when the script is run
again, the
script will display the conflicting entries.
Take care in setting the path for root
Generally, users find it convenient to name their current
directory
in their path, allowing them to easily execute freshly-compiled
programs
or other "local" commands.
But when you are operating as root, you can't afford
this convenience.
For example, an authorized user could create a bogus
ls in
his or her home directory. The substitute ls would,
of course,
list the contents of the directory (omitting the ls
file itself)
but might also perform other unauthorized tasks that
require superuser
privileges. To violate the system's security, the culprit
user need
only convince someone with root access to cd to his
home directory
(as root) and do an ls (which is not unthinkable). If
the root
user's path includes the current directory ahead of
system directories,
the ls program in that directory will be executed rather
than
the one in /bin. The listing of the contents of the
directory
will be generated, but the user's other functions (including,
perhaps,
assigning unauthorized privileges to the user's account)
will also
be performed by a privileged user.
The rule, inconvenient or not, is never include the
current
directory in root's path. To execute something in the
current directory
as root, you will simply have to type ./prog instead
of just
prog to execute it.
To implement this rule, you should check the initialization
files
for root (/.profile or /.login and /.cshrc depending
on your preferred shell) and make sure that they don't
add "."
to the value of either the PATH or path variables. It
is also generally
a good idea to explicitly set the path at the beginning
of any script
that root will execute (as we did in the cksuid script
of Listing 1).
Verify the checksum of files in system directories
While unlikely, it's not impossible to place some subtle
trojan horses
directly in system programs. To guard against this form
of trojan
horse, generate a list of all executable system files
and their checksums
and verify it against a known list on a regular basis.
This will identify
any system programs that have been changed.
This test is so similar to checking for setuid files
that we can modify
the cksuid script to check all files in certain system
directories.
We will make the following changes to the cksuid script:
remove the -perm -4000 from the find command so that
all files in the
directories are found
The result is the cksysfiles script in Listing 2.
Don't let users write in system directories
Only the system administrator (operating as the root
user) should
be able to modify files in system directories (such
as /bin).
If a regular user could modify these files, introducing
a trojan horse
into a system would be extremely simple. By default,
new UNIX systems
deny write access to regular users in these directories,
but this
was not always true. Especially on older systems, you
should examine
the log file produced by the first execution of the
cksysfiles
script to make sure no system files are writable by
anyone but the
owner.
Watch out for "smart" terminals
While problems with terminals are not as common today
as they were
a few years ago, "smart" terminals still pose
a potential
security problem.
Some of these terminals are so powerful that it is a
fairly simple
matter to configure them to capture or redirect certain
data, such
as a user's response to the login prompt.
The only real defense to this security hole is to be
careful about
what kind of terminals your organization purchases and,
especially,
what kind of terminal you use when doing work as the
root user.
Beware of the "fake" login
A related and very effective trojan horse is the fake
login
program. Any operating system (not just UNIX) where
users login and
use terminals in public places is very vulnerable to
this form of
attack.
In this form of the trojan horse, the culprit user writes
a program
that simulates the particular system's login process.
The culprit
then leaves the program running on a terminal and a
new, unsuspecting
user comes up to the terminal and attempts to login.
Everything looks
right, but the login attempt fails (and the fake login
program
exits). The user, assuming he or she simply mistyped
the password,
tries again and gets in. What they don't know is that
their first
attempt has been logged and their account has now been
compromised.
One possible defense is to kill inactive processes,
but this turns
out to be quite difficult in practice. UNIX has no built-in
way to
detect and terminate an inactive process (certain command
shells provide
a way that the user can set a timeout variable and be
logged off from
inactivity, but it is purely voluntary).
While it is possible to find processes that have been
idle for some
specific amount of time, it is much more difficult to
determine whether
or not this idle time is legitimate. With the advent
of windowing
systems for workstations and programs that manage multiple
"virtual"
windows for ASCII terminals, one cannot assume that
idle processes
are dangerous: the user may simply be using another
window.
Moreover, in the busy installations most at risk, another
user will
use the terminal soon after the first user leaves it
free. Thus the
fake login process probably would not sit idle long
enough
to be detected as idle.
Fake login attacks are more of a problem in the academic
community
than in the corporate community and are very difficult
to defend against.
If, as a user, you notice you didn't get logged in properly
in your
first attempt, it would be wise to change your password.
Examine things you get from "the net"
Just as the PC world always warns against running binary
programs
when you don't necessarily trust the source, so the
UNIX world should
be careful to guard against viruses or trojan horses
from outside
sources. In the UNIX world, programs are more traditionally
distributed
in source form, but this doesn't mean that illicit functionality
may
not be hidden deep in the source code.
Any programs pulled from "the net" (or anywhere
outside the
local environment) should be manually examined to make
sure they perform
no "questionable" functions. Yes, this examination
is time-consuming,
but it is the only way to guarantee that the program
works as advertised.
The cardinal rule is: never run a program from the net
as root
until you have made certain that it doesn't do anything
unauthorized.
Don't use the tar as root
Never read information off tapes from outside sources
as root. tar,
in particular, will retain all ownerships and modes
of files it reads.
If someone creates a tape on another system with setuid
root files
and you read this tape as root, the files that you provide
to the
user will also be setuid root. Read these files as your
own user id
and manually change the mode and ownership of any files
necessary
(after you ascertain the legitimacy of the need).
Don't use programs as root unless necessary
You should only su to root to do the commands you need
to do
as root and then exit the root shell. The more time
you spend as the
root user, even doing seemingly safe things, the more
chance you have
of running some program that shouldn't be run. There
are other hazards,
too: an unexpected bug in a familiar program could wreak
havoc if
it was able to make its mistakes with full privileges;
you might even
forget who and where you are and type a command you
didn't really
mean.
A Helpful Tool
One of the most widely-used publicly available programs
to help a
UNIX system administrator identify and fix security
holes is the cops
package, written by Dan Farmer. cops is a collection
of small,
easy-to-understand tools that check for these and other
security problems.
Even if you don't use the programs as provided, they
will be useful
learning tools when developing your own security measures.
cops is available via anonymous FTP from cert.sei.cmu.edu
(192.88.209.5) or archive.cis.ohio-state.edu (128.146.8.52).
In both cases, cops can be found in the pub/cops directory.
The latest version (1.04) was also recently posted to
the USENET newsgroup
alt.sources.
Where to Read More
Information about these and other security topics can
be found in
the following sources.
Spafford, Gene and Garfinkel, Simson, Practical UNIX
Security,
O'Reilly and Associates, Inc., 1991. (1-800-338-6887).
David A. Curry, "Improving The Security Of Your
Unix System,"
SRI International, April 1990.
This paper is available via anonymous FTP from ftp.uu.net
(137.39.1.9)
in the doc/security/info directory or from cert.sei.cmu.edu
(192.88.209.5) in the pub/info directory. In both cases,
security-doc.txt.Z is a compressed ASCII text version
of the
paper and security-doc.tar.Z is a compressed tar file
containing the source for the paper as well as a PostScript
output
file.
Dennis M. Ritchie, "On the Security of Unix,"
AT&T Bell Laboratories.
This paper is shipped with many versions of UNIX documentation
now
and is also available via anonymous FTP from ftp.uu.net
(137.39.1.9)
in the doc/obi/BSD/doc/smm/17.security directory as
security.ms.Z.
This is a compressed troff(1) source file and requires
troff
ms macros.
Russell L. Brand, "Coping with the Threat of Computer
Security
Incidents -- A Primer from Prevention through Recovery,"
December
1990.
This paper is available via anonymous FTP from ftp.uu.net
(137.39.1.9)
in the doc/security/info/primer directory. It is also
available
from cert.sei.cmu.edu (192.88.209.5) in the pub/info/primer
directory.
About the Author
King Ables has been a UNIX user since 1980 and has
been managing
systems or developing system management and networking
tools since
1983. He is currently doing system and network management
development
for HaL Computer Systems in Austin, TX.