Intrusion Detection: Network Security beyond the Firewall
(Publisher: John Wiley & Sons, Inc.)
Author(s): Terry Escamilla
ISBN: 0471290009
Publication Date: 11/01/98

Previous Table of Contents Next


The type of link—symbolic or hard link—affects the way access control routines behave. For example, the system call access() will follow the symbolic link and operate on the file named in the link. Using the files shown previously, access(B) really is interpreted as access(A). Other routines do not follow the link and work with the file it points to, but operate on the symbolic link itself. If you call chown(B), the owner of the symbolic link will be changed, not the owner of file A. This may seem like a confusing mess, but if you do not understand these internals, you will not understand the potential threats.

Can a hacker exploit link counts? If you delete file B, the data bits are still accessible via file A! Are there other hacks that exploit the intricacies of hard links and symbolic links? Yes, and you’ll see some of these in Chapter 8, “UNIX System Level IDSs.” Will access control mechanisms protect you from these configuration problems? If they could, you wouldn’t need to install intrusion detection systems.

Increasing Your Privileges or Capabilities

In addition to using file permission bits such as SUID or SGID to change who you are on a system, UNIX variants provide library or kernel routines for changing UIDs and GIDs associated with a process. When SUID or SGID bits are set, the system automatically calls one of these routines on your behalf when setting up the process’ context before execution. Because changing credentials can lead to increased capabilities on the system, limitations exist on how UIDs and GIDs can be changed. Two commonly available routines are setuid() and setgid(), which are passed a single integer parameter to change the UID or GID of a process respectively. The outcome of invoking one of these routines depends on the credentials associated with the calling process:

  All three IDs—RUID, EUID, and SSUID—are changed if the process has superuser (root) capabilities.
  If the value passed in as a parameter is the same as either the RUID or SSUID, the EUID is changed to the parameter value. To change the EUID to the RUID, pass in the RUID as the parameter. Setting the EUID to SSUID is accomplished similarly.
  If neither case is met, the routine returns an error.

Depending on whether your version of UNIX supports POSIX or is derived from BSD or System V UNIX, other ID manipulation routines are available including seteuid() and setegid(), which set only the effective UID and GID respectively. As before, the outcome of the request depends on the privileges of the requesting process. Normal users can set only the EUID to the value stored in RUID or SSUID. When called by a privileged user process, these routines set only the EUID or EGID, unlike setuid(), which changes the RUID and SSUID, too.

The RUID, EUID, and SSUID are set to your assigned UID by the login process, which is a privileged program. The RUID normally never changes. Under usual circumstances, the EUID is changed only by the exec() routine when the SUID bit is set for a program file, and you execute that file. An unprivileged user cannot set the EUID to an arbitrary value. Therefore, when you start another process or run a program from your login shell, the EUID is inherited and remains unchanged unless the file’s SUID bit is set. The EUID value is copied into the SSUID field by exec() after interpretation of the SUID bit for the file. In other words, if the file’s SUID bit is set, the UID of the file’s owner is stored into both the SSUID and the EUID. The EUID then can be set to either the RUID or the SSUID depending on the needs of the program. Why is this necessary?

Good programming practices dictate that SUID and SGID programs escalate privileges only for the fewest program statements necessary. A program requiring SUID should first set the EUID to the value stored in the RUID (the invoking user’s ID). Privileged resource accesses are not permitted with these settings, and the program is relatively safe from exploits with these settings. Only when the privileged operations are needed should the program call setuid() using SSUID as the parameter to increase the program’s privileges. When the privileged section of code is complete, the EUID should be set back to the less powerful RUID. Similar comments apply to changing GIDs associated with a process.

You should know that many UNIX hacks originate with SUID or SGID programs. Buffer overflow attacks against SUID or SGID programs appear almost daily, especially when the file’s owner is the root user. The typical attack is to overflow a buffer for the program in a way that loads executable statements onto the stack. The common attack is to load statements that will start another shell from the SUID program, essentially launching a shell or window with root privileges.

One of the most important aspects of your access control policy is to tightly limit which users are allowed to run SUID or SGID programs. This control can be very difficult to maintain with only permission bits. A user normally may not have access permissions for a SUID program. However, if that user does have access to a SGID program whose group in turn has permissions to run the SUID program, the transitive behavior will violate your policy. These types of complex relationships are difficult to protect against using only permission bits for files and real (or effective) user IDs. What is more desirable is a mechanism for always tracing the access request to the a particular initial user regardless of transitions in EUID or EGID.

Another choice is to remove all SUID and SGID programs on the system. This process is essentially what happens on multilevel operating systems that rely on itemized privileges for users. The file and directory permission bits are not overloaded to include SUID or SGID semantics in these systems. If multilevel solutions are not feasible, other improvements are still possible. The discussion on Memco SeOS later in this chapter describes one alternative.


Previous Table of Contents Next