Last month's installment covered many aspects of password protection. This month's installment goes on to explain several other aspects of system security.
Besides password protection, file ownerships and protection modes are the other major component of traditional UNIX security. Although far from a perfect solution, a carefully set up and maintained file-system will provide a great deal of protection from harm in the event that a non-root account is compromised. File-system security includes these considerations:
Correct ownerships and protections for system files: command binaries, shared libraries, and so on. Such files generally should be owned by root or another system user like bin and by a system group such as system or bin. They should not be group, or world, writable. Some files, such as the shadow password file, should be restricted to owner access only.
The same considerations apply to the directories where system files are stored. Keep in mind that write access to a directory allows you to modify any file within it regardless of the ownership or protections of the individual file (although SETGID access on a directory restricts users' access to their own files, as for /tmp).
SETUID and SETGID files deserve special scrutiny. They should be kept to a minimum and be thoroughly tested prior to installation. Any newly appearing SETUID root files should be regarded with extreme suspicion. The following command will locate all SETUID and SETGID files on the system:
# find / -type f \ \( -perm -2000 -o -perm -4000 \) -ls
User home directory trees should also contain no group, or world-writable subdirectories.
User login and shell configurations files—.login, .profile, .cshrc, and so on—should also be owned by each user and writable only by their owner.
Group memberships must be designed with care so that users are given access only to those files and directories they need.
Any tampering with system binaries, libraries, configuration files, and other vital data must be detected right away.
All of these can be summarized into just two overriding principles:
Know what normal is (and get your system to that state). This is made somewhat more difficult on Linux systems because there is considerable variation in system file ownership among the various distributions, so you will have to make some of those decisions yourself.
Make sure it stays that way by continuously monitoring it and performing regular backups.
The Tripwire facility from the COAST project at Purdue University can take care of the second step. Tripwire can record the correct state of the file-system and then, some time later, compare the current configuration with the saved one and report on any differences. It can consider external attributes of a file such as its ownership, protection, size, inode number (this would change if a file were replaced using standard UNIX commands), inode creation date, and file modification date.
However, since it is possible to modify a file without changing any of these items, Tripwire also calculates a number of file signatures for each file. In general, a file signature is a value computed using the contents of the file. Tripwire can compute file signatures using up to 10 different algorithms of varying complexity and corresponding difficulty in forging.
While it is possible to alter a file and still retain the same file signature for a single algorithm—in fact, it is relatively easy to do so for lower quality file signatures such as traditional checksums—altering a file without changing two or more different file signatures is a very hard problem indeed. When Tripwire checks the file-system, it can compare multiple file signatures for each file, thereby virtually ensuring that any alteration will be detected.
Tripwire has been ported to Linux, and it builds easily. After you have finished compiling the executables, it is important to run the test suite the package provides to ensure that everything is operating properly. The following command initiates the test suite:
# make test
To get started, you first run Tripwire in its initialization mode (tripwire -init). It is essential that you do so on a system known to be clean; ideally, Linux will have been reinstalled from the original media. In this mode, Tripwire creates a database listing the current attributes and file signatures you have requested for the files specified in its configuration file. During this initial run, you should compute as many different file signatures as you have CPU cycles to apply, including at least two different highly secure algorithms. You should also set up the configuration file to include as much of the system as possible, so you'll have data even for files you won't necessarily be watching on a regular basis should you ever need it.
The database will need to be similarly updated whenever an operating system upgrade occurs (given the rebuild rate for Linux kernels, that could be pretty often on some systems). Once the database is created, it must be stored in such a way that it cannot be tampered with under any circumstances (otherwise, a hacker could, for example, replace a file and also alter the information corresponding to it in the database). The Tripwire documentation suggests placing it on physically write-protected media, such as a locked diskette or removable disk, which is taken out of the drive when it is not in use. When the database is protected in this way, even changes made from a compromised root account can be detected. If possible, the Tripwire software itself should also be similarly protected.
After the initial database is created, Tripwire may be used to check the integrity of the file-system. How regularly you run Tripwire in this mode depends on the needs of your system and site, but I would recommend doing so nightly if at all possible. Figure 1 gives an example of the sort of report that Tripwire produces.
deleted: -rwxr-xr-x root 77828 Aug 23 22:45:43 1995 /usr/bin/refer added: -rwxr-xr-x root 10056 Mar 19 12:33:11 1995 /etc/passwd.save changed: -rwxr-xr-x root 155160 Apr 28 15:56:37 1995 /usr/bin/perl ### Attr Observed (what it is) Expected (what it should be) ### =========== ============================= ============================= /usr/bin/perl st_size: 155160 439400 st_mtime: Fri Feb 17 12:10:47 1995 Fri Apr 28 12:33:11 1995 md5 (sig1): 1Th46QB8YvkFTfiGzhhLsG 2MIGPzGWLxt6aEL.GXrbbM>
On this system, the executable for the refer command is missing, a new file (/etc/passwd.save) has appeared (from Tripwire's point of view, anyway), and the executable for Perl has changed size, modification time, and file signature (computed with the MD5 algorithm). All these changes are important and should be investigated, although none of them conclusively indicates unauthorized activities (refer could have been deleted accidentally, /etc/passwd.save could have been created as a backup by a system administrator, and Perl could have been rebuilt since Tripwire's database was last updated).
Tripwire's configuration file (conventionally named tw.config) is very flexible and allows you to specify exactly what files and directories are checked and what attributes and/or file signatures are compared, in as much detail as you like.
Tripwire does an excellent job of monitoring the file-system for any changes. However, there are other system functions that also bear watching. The Computer Oracle and Password System (COPS) performs several useful tests of system security, and I recommend obtaining it and running it regularly. COPS is most useful for checking the following items:
The syntax and content of the password and group files.
Anonymous ftp setup.
User environments: umask values and PATH variable definitions as defined in users' login configuration files.
Searches for known-to-be-insecure versions of commands by comparing the dates of system executables with data from CERT advisories.
In addition to Tripwire and COPS, the following other facilities can be very useful for system security monitoring:
The /var/adm/sulog file, which contains records of each use of the su command (successful and unsuccessful). It should be examined regularly.
The syslog facility: many subsystems log messages via syslog. Its configuration file, /etc/syslog.conf, specifies what types of messages are recorded as well as their destination log file.
Data gathered by the optional accounting facility can be useful for some kinds of detective work. In order to use this subsystem, you will need to install the accounting and quota kernel patches, rebuild the kernel, and compile programs in the accounting utilities package.
The Computer Incident Advisory Capability (CIAC) has created the Merlin program as an easy-to-use graphical front end to several security monitoring packages including COPS, Crack and Tripwire.
So far, we have focused on security issues that arise in the context of a single computer system. However, most systems are connected to networks, and so must deal with the variety of threats which arise from that context.
Standard TCP/IP offers only limited mechanisms for controlling network access, and they are designed for convenience of access rather than true network security. In its standard form, the /etc/hosts.equiv file contains a list of systems trusted by the local host, and users with the same user name on one of these remote systems can log into the local system via the network without having to provide a password.
Under normal circumstances, this makes sense. The problem comes when an account on a remote system has been compromised; trusting that system then puts your own system at risk as well. Of course, this problem is magnified many times when it is a remote root account that has been broken into. For this reason, it is a very bad idea to allow password-less root access between systems, and the /etc/hosts.equiv mechanism does not do so (however, the other method for setting up account equivalence does),
Each entry in a .rhosts file contains a hostname and (optionally) one or more user names. It allows password-less access to the local account from the listed remote user names (or to a user with the same user name, if the entry contains only a hostname). For example, when the following .rhosts file is in user chavez's home directory, it will allow user vasquez on hamlet and user chavez on romeo to log in to her account via the network without a password:
hamlet vasquez romeo
The problem with the TCP/IP notion of trusted systems is that trusting another system has implications beyond the interactions between the local system and the trusted remote system. Inevitably, trust operates in a transitive fashion: if system A trusts system B, and system B trusts system C, then to some extent, system A trusts system C whether it wants to or not and whether it knows it or not. Such chains can go on indefinitely, and hackers are notoriously good at exploiting them.
Accordingly, the following precautions will minimize the risks of trusted network access to your system:
Include the minimum number of hosts in /etc/hosts.equiv.
Make sure there is no [cw]+[ecw] entry in hosts.equiv (this acts as a wildcard and trusts every system in the universe).
Use the - entries supported by the Linux version of this file as appropriate. A hostname preceded by a minus sign in /etc/hosts.equiv requires a password from every user from that system who wants to log in to the local system. It also nullifies any entries for that host in all .rhosts files on the system. Thus, this mechanism serves as a ways to override transitive trust.
The Linux version of /etc/hosts.equiv allows hostnames to be optionally followed by a username, which gives that user password-less access to any non-root account on the local system. I don't recommend using this feature.
No /.rhosts file should exist on the system; remote root access should always require a password (if it is allowed at all).
Monitor users' ~/.rhosts regularly for inappropriate entries.
The traditional hosts.equiv mechanism allows for only the crudest level of access control. The TCP Wrappers package, which is included with nearly every Linux distribution, provides for much more detailed control over which remote hosts use what local network services, as well as the ability to track and record network-based system access.
The TCP Wrappers package provides the tcpd daemon which introduces an additional layer between inetd, the primary TCP/IP daemon, and the score of subdaemons that it manages. Daemons for services like the telnet facility are started on an as-needed basis by inetd; once TCP Wrappers is installed, requests for telnet services go to it first and are granted only if the system configuration allows it.
Once the tcpd daemon is built, you simply modify inetd's configuration file, /etc/inetd.conf, placing any and all of its subdaemons under tcpd's control. For example, Figure 2 shows how to change the entry for the telnet daemon to use TCP Wrappers.
#service socket protocol wait? user program arguments telnet stream tcp nowait root /usr/sbin/in.telnetd
is changed to:
#service socket protocol wait? user program arguments telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd
Access to network resources is controlled by TCP Wrappers' configuration files, /etc/hosts.allow and /etc/hosts.deny. The first file contains entries specifying which hosts may use which services:
in.telnetd : hamlet romeo in.fingerd : LOCAL EXCEPT juliet
The first entry says that telnet requests from hamlet and romeo will be honored, and the second entry says that remote finger commands may be run from any local system except juliet (a local system is defined as one not containing a period in its name).
The hosts.deny file contains entries denying specific services:
netstat : fool in.tftpd : ALL ALL : ALL
The first entry denies the use of the netstat service to host fool, the second entry disables the trivial ftp facility, and the third entry acts as a catch-all, denying everything that hasn't been explicitly allowed to everyone.
When tcpd considers a request for network services, it uses the following process:
If hosts.allow authorizes its use, the request is granted. The first applicable line in the file is used.
If no entry in hosts.allow applies, then hosts.deny is consulted. If that file denies the service, the request is denied, and again the first applicable line in the file is used.
If no entry in either file applies, the request is granted (note that an ALL:ALL entry in hosts.deny prevents this case from coming into play).
TCP Wrappers logs its activity to the syslog subsystem via its daemon facility. It generates lots of data which can be cumbersome to examine manually. The swatch package provides a useful way of automatically sorting through any output stream for events you specify in advance, and it is very useful in conjunction with TCP Wrappers.
The network should be examined for potential security problems on a regular basis just like the local system. The once notorious Satan program provides one way of doing so. Satan is designed to look for network vulnerabilities from the outside in. It looks for a variety of problems, including:
The availability of notoriously insecure network services, such as rexd and old versions of sendmail.
The setup of any ftp and/or tftp facilities.
A variety of NFS vulnerabilities.
X server vulnerabilities.
For those concerned about the misuse of such a powerful tool, the Gabriel and Courtney packages attempt to detect suspicious uses of Satan itself.
We've covered a wide variety of threats to system security in this article. Don't let the sheer number of them overwhelm you. All you can do is protect your system as well as is currently possible and make frequent backups so that you can recover quickly in the event that your best efforts are not enough. Remember that system security is an ongoing process, not something you can take care of once and then forget about. And as in all of life, there are no guarantees.