Special File Permissions


In addition to the basic permissions discussed earlier, you can also set three special permission bits on files and directories:

  • SUID bit Generally referred to as the SUID bit because of the name of the API call used, this bit changes the user ID on execution. When a program is executed with the SUID bit set, the process will have the same rights as the owner of the file being executed.

  • SGID bit Generally referred to as the SGID bit because of the API call used, this bit changes the group ID on execution. It operates the same as the SUID bit but inherits rights of the group of the owner of the file. If set on a directory, it means that when a new file is created in the directory, the new file's group owner will be the same as the directory's group owner.

    NOTE

    Because of shell scripts' inherent lack of tight security, Linux has disabled the SUID/SGID support for them: You can set the bits, but they have no effect. Should you have the need for a SUID/SGID script, use Perl instead. See man perlsec for more information.


  • Sticky bit In older Unix kernels, this bit was used to trigger a program to "stick" in memory after it is finished (so the next time the application is executed, it is already in memory); now this usage is obsolete with the advent of virtual memory. When set on a directory, the sticky bit ensures nonroot users can only delete files they own in that directory. The sticky bit is applicable only to the world permission setting of a directory; it has no effect when applied to a file.

NOTE

Often, the SUID bit is used by system applications or scripts so that the process may access system resources as root. On the other hand, the SGID bit is not frequently used by system programs but is mostly used by system administrators to set up shared directories.


CAUTION

You should closely monitor programs and scripts that set the SUID and/or SGID bit. It is quite common for a hacker to exploit some vulnerability and then leave behind a root SUID program in place as a backdoor. The key here is to use applications such as Tripwire (see Chapter 12, "Intrusion Detection"), Bastille, and seccheck (see Chapter 13, "System Security") and keep track of your system!


To set any of these three special permission bits, chmod requires a fourth digit. This value is specified as the most significant (left-most) digit, and its possible values are listed in Table 6.8. For example, chmod 1777 testDir means the owner, group, and world have full read, write, and execute rights to testDir, and the sticky bit is also set for the world permission. The ls output would look like this:

 Athena:/home/admin # chmod 1777 testDir Athena:/home/admin # ls -l testDir drwxrwxrwt  2 root admin 48 2005-01-19 17:35 testDir 

Table 6.8. Special Permission Mode Codes

OCTAL DIGIT

BINARY VALUE

DESCRIPTION

0

000

SUID, SGID, and sticky bits are not set

1

001

Sticky bit set

2

010

SGID bit set

3

011

SGID and sticky bits set

4

100

SUID bit set

5

101

SUID and sticky bits set

6

110

SUID and SGID bits set

7

111

SUID, SGID, and sticky bits are set


The corresponding chmod command using a textual value is chmod a+rwx,o+t testDir. The symbols for the special modes displayed by ls reflect whether the corresponding execute bit is also set. For example, if the sticky bit is set but the world's execute bit is not set, a symbol T is displayed instead of t. Table 6.9 summarizes the special mode symbols displayed depending on the execute bit setting.

Table 6.9 . Special Permission Textual Representation
 

EXECUTE BIT NOT SET

EXECUTE BIT SET

SUID

--S --- ---

--s --- ---

SGID

--- --S ---

--- --s ---

Sticky

--- --- --T

--- --- --t


NOTE

When you set these special permission modes using their textual values in chmod, use lowercase characters, such as s and t, and not the uppercase ones. The case distinction is used by ls to display the different permission combinations.


Security Implications of SUID/SGID

It is worth discussing the need for SUID and SGID programs and scripts in the Linux/Unix world, even when they can be Trojan horses left behind by a hacker. First, consider the /etc/passwd file. Only the file owner (root) has write access (rw-r--r--) to it. Yet as an ordinary user, you can modify the contents of this file, albeit in a very limited way, using the passwd and chsh commands.

An examination of the permission bits of the /usr/bin/passwd program shows that both the SUID and execute bits are set (rwsr-xr-x) for the file owner. This indicates that the passwd utility is a root SUID program: It's a SUID program because of the s flag in the permission bits, and it's a root SUID program because root owns the file. Thus, when anyone runs the passwd program, the user temporarily gains the privileges of the root userbut only for the duration of the program's execution and only from within that program. Without such a mechanism, many system administration tasks can become unnecessarily complex due to the security implications. For instance, how would you effectively secure the /etc/shadow file and yet allow users to update their own passwords?

On the other hand, the SUID API call can be used to lower a user's privileges instead of increasing them. For instance, for an IP-based service to bind to one of the privileged ports, it needs to run as root. However, after the port is bound, the application no longer needs to have root privileges; it can use the SUID call to change the process's UID to that of a nonprivileged user. Or a program may run as root, but it can spawn processes that run at a lower privileged level for security reasons. An example is the Apache web server; its suEXEC utility (see http://httpd.apache.org/docs-2.0/suexec.html) executes CGI and SSI programs as user wwwrun and group www (the default setting on SLES 9) instead of as the owner of the main Apache process, which generally runs as root.

NOTE

For an application to be a SUID program, it must make the SUID or similar API call (there are a number of variants of the SUID call), and the file permission bit must be set as such. Simply setting the SUID bit on a program does not automatically make it a SUID program.


There's an identical mechanism for group ownership. For instance, if you examine the permissions for /usr/bin/uucp, you'll see s flags for both the user and group (r-sr-sr-x). Thus, when you run uucp (Unix-to-Unix CoPy), you temporarily gain the rights of the owning user (uucp) and the owning group (uucp).

SUID scripts are generally more dangerous than SUID programs. This is largely due to the fact that running a script first invokes a shell. If the script is SUID root, the invoked shell will run with root privileges. It is possible, after the shell is invoked but before the script runs, to interrupt the kernel and replace the file that the shell is going to execute. The replaced file could be any executable shell script, including another shell (which, in this case, would be a root shell). Due to these security implications, Linux systems have long since disabled support for SUID/SGID shell scripts. If you really need a script that does SUID/SGID, develop it using Perl with the taint mode enabled.

TIP

When a Perl script file has its SUID and/or SGID bits set, the Perl interpreter automatically enters a paranoid mode and performs a set of special security checks to detect possible tainted data, such as verifying that directories specified in the PATH variable are not writable by others. You can enable this taint mode explicitly by using the -T command-line flag at the beginning of the script, that is, #!/usr/bin/perl -T. This flag is strongly suggested for server programs and any program run on behalf of someone else, such as a CGI script. When taint mode is turned on, it is on for the remainder of your script.


You can use applications such as Tripwire, Bastille, and seccheck to automate searching for and reporting on questionable SUID/SGID programs and scripts.

But if you're a consultant who just walked on to a client's site doing a security audit, the following commands could be useful:

  • To obtain a list of all SUID or SGID files (programs and scripts), use the following:

     # find / -type f -perm +ug=s -exec ls -l {} \; 

  • To find all root SUID files, use this command:

     # find / -type f -owner root -perm +u=s -exec ls -l {} \; 

  • Check for a SUID or SGID script only by looking at the first two bytes in the file to see whether they're #! (the so-called magic bytes), indicating it's a script file:

     # find / -type f -perm +ug=s -print0 2> /dev/null | \ perl -n0e 'chomp; open(FILE, $_); read(FILE,$magic,2); \ print $_,"\n" if $magic eq "#!"; close(FILE);' 

TIP

Keep the number of SUID and SGID programs on your system to a minimum. The main focus here should be on root SUID programs. Nonroot SUID and SGID programs present less of a risk but can still be a source of security breach.


TIP

If you are unsure whether a program or script should have its SUID/SGID bit set, or you have determined that one or more SUID files or directories are unnecessary, disable them with chmod u-s,g-s name. Make sure you keep a record of what you have modified so the changes may be reversed at a later time should the need arise.


SGID and File Sharing

With SLES, as long as a user is a member of the group that has group ownership to a file or directory, he or she can access it according to the group permission settings; it doesn't matter if that user's primary group is different. For example, the group owner of the /usr/share/projectDestiny directory is destiny, and the group has been granted read, write, and execute permissions. User carol is a member of the users, audio, video, and destiny groups, and her primary group is users. As long as carol is a member of the destiny group, she will have full access to the projectDestiny directory. The same goes with the other users. However, this has one administrative shortcoming and one security flaw.

Although the destiny members have full rights to the directory, the files they create will bear group ownership corresponding to the primary group of the users. For instance, files created by Carol will bear a group owner of users because that is her primary group. If, at some point, you need to locate all her files relating to the Destiny project that were moved to a different directory (the mv command does not change the ownership information), it would be very difficult, administratively, unless there is some "marker" you can use. On the other hand, if the files Carol created in the /usr/share/projectDestiny directory all have destiny as the group owner, you can easily use the find command to locate them should they be moved. For example, the following command locates all files with user owner carol and group owner destiny that are not located in the /usr/share/projectDestiny directory:

 # find / -path '/usr/share/projectDestiny' -prune -o \ -user carol -group destiny -exec ls -ld {} \; 

Now, the potential exists for a security backdoor. The default SLES-installed umask is 022, which means world has read and execute permissions to directories; this means world users can see the filenames in there. Carol creates a file in /usr/share/projectDestiny with a permission of 644 (rw-r--r--). Because the file is in a shared directory and may need to be updated by other members of the destiny group, Carol dutifully changes the file permission to 664 (rw-rw-r--) or even to 660 (rw-rw----). However, the file's group owner is usersCarol's primary group. Along comes Eric, who is not with the Destiny project but is in the users group. As long as /usr/share/projectDestiny has the world execute permission bit set, Eric can modify Carol's file because of the group ownership.

You can, of course, rectify this potential security hole by removing world access to the directory entirely. However, an easier solution is to use the SGID bit because it solves both the administrative difficulty and the group owner issue concurrently. When the SGID bit is set on a directory, every time a new file is created in the directory, the new file's group owner is set to be the same as the directory's group owner. Therefore, files created by Carol, for instance, will automatically be assigned destiny as the group owner, and can only be modified by Carol or other members of the destiny group. And to keep the world users from snooping around the directory, you can revoke all the world permissions.

NOTE

With ext2 and ext3 type filesystems, a mount option provides the same functionality as setting the SUID bit on directories. When mounted with the grpid (or bsdgroups) option specified, the Linux kernel treats all directories found on that ext2/ext3 filesystem as if the SGID bit were set.


TIP

A good group file-sharing scheme is one that uses a dedicated group as the group owner of the directory and the directory's permission mask set as 2770 (rwxrws---). Only users who need to have access to the folder are made members of the group. The user owner of the directory should be the group or project leader.


A SUID Sample Program

Here is a simple program to illustrate how easily you can write a root SUID program. It takes just five short lines of C code:

 #include <stdio.h> main (void) {     setuid(0);     setgid(0);     system("/bin/bash"); } 

Assuming you place the preceding lines in a file called become-root.c, you can follow these steps to compile and turn this code into a root SUID program:

1.

From a terminal session, compile the preceding C code using the following command (assuming you have the gcc package installed):

 # gcc -o become-root become-root.c 

2.

Set the file's user and group owner to root:

 # chown root:root become-root 

3.

Set the necessary bits using chmod:

 # chmod u+s,g+s become-root 

You need to perform the last two steps as root.

Now, whenever you run become-root, even as an unprivileged user, your current identity will be switched to root (both UID and GID), and you can verify that identity with the id command. Just type exit to return to the previous identity.

WARNING

You can see from the preceding example how easy it is to create a root SUID program that executes "some command." Some malicious person can easily substitute the "/bin/bash" command for something really nasty such as "/bin/rm -frdv /"! Therefore, if you don't know where a SUID/SGID (root or not) program comes from or what it will do exactly, do not run it!


TIP

If you find some file to be suspicious, do not execute it. You can dump all the strings in the file and look for some interesting stuff using the strings command like this:

 Athena:/home/admin # strings become-root /lib/ld-linux.so.2 SuSE libc.so.6 system setgid _IO_stdin_used __libc_start_main setuid __gmon_start__ GLIBC_2.0 PTRhP /bin/bash 

As you can see from the output, strings showed references to setgid, setuid, system, and /bin/bash, suggesting this is a SUID program of some sort. When you use strings, it is relatively easy to figure out what files the binary wants to open, if there are any special messages (such as "Gotcha!" as Trojan horses tend to contain), and so on.


The system() command in the preceding example can also be used to execute a script, and not just commands. Therefore, if you decide that you need a SUID shell script and don't want to use Perl, you can modify the example slightly and use it as a "wrapper" for your script. You may be tempted to pass the script's path and name from the command line so you have a generic wrapper. However, this approach can be dangerous. If some disgruntled user stumbles upon it, he or she could use it to execute some nasty script or command that will ruin your day. It is, therefore, strongly recommended that you hard-code the script's path and name in the program instead of passing it as a command-line option. Ensure the script's permissions are set so that they cannot be modified by anyone else except you. Furthermore, keep all your custom SUID/SGID scripts and programs in a "safe" place, as discussed in the next section.

Securing Against SUID Programs

The primary way of interacting with a Linux system is through the filesystem; even hardware devices, such as the terminal console, are represented by a (special) file on the filesystem. Thus, when an intruder gains access to a system, it is desirable to limit what he or she can do with the files available to him or her. One way to accomplish this is to use restrictive filesystem mount options; for example, the nosuid option disallows the SUID and SGID bits from taking effect.

When a filesystem is mounted with the nosuid option, the Linux kernel will ignore any SUID and SGID bits that have been set on files and directories found on that filesystem. You can specify the nosuid option as part of the mount command when mounting a filesystem manually. For example,

 Athena:/home/admin # mount -o nosuid /dev/hda4 /mnt 

results in all files and directories found in /mnt having their SUID and SGID bits ignored. But you can use this command instead:

 Athena:/home/admin # mount -o nosuid,grpid /dev/hda4 /mnt 

This way, you can enforce implied SGID on all directories. The equivalent entry in /etc/fstab would look something like this:

 /dev/hda4     /mnt     ext2     defaults,nosuid,grpid   1  2 

By carefully considering your requirements and dividing up your storage into multiple filesystems, you can utilize these mount options to provide some level of security against rogue SUID programs and scripts. You can further enhance the security by using the nodev and noexec mount options.

In a typical multiuser system, it is unlikely that users will need to execute SUID binaries or create device files in their home directories. Therefore, a separate filesystem, mounted with the nodev and noexec options, could be created to house the users' home directories. In addition, if you've determined that your users will not need to run programs stored in their home directoriesa good policy to have because it cuts down on the installation of possible virus- infected or unlicensed programsyou can use the noexec mount option as well. Similar considerations should be given to /tmp and /var. It is unlikely that any process will legitimately need to execute any binaries or access device files from those directories.

TIP

Locking down world-writable directories with noexec, nosuid, and nodev mount options helps prevent the possibility of an intruder leaving a Trojan horse in common directories. The malicious user may be able to install the program, but it cannot actually run, with or without the proper permission settings.


CAUTION

The nodev mount option may break services running in chroot jails. Often, a service needs to access device nodes such as /dev/null and /dev/log. If the filesystem used by the chrooted service was mounted with nodev, such access would be denied, and the service may fail to run to completion.


As a word of warning, do not consider a filesystem mounted with noexec to be totally safe. It will prevent an average user from running an executable binary or script from it. However, a seasoned user can still circumvent the restriction by passing the script through its interpreter (such as perl /script/on/noexec/filesystem).

In Linux kernels prior to 2.6, you can use the dynamic runtime library linker, /lib/ld-linux.so.* (where * is the version number of the currently available ld-linux.so), to execute binaries residing on such a filesystem. Although this is no longer an issue with the 2.6 Linux kernel (which SLES 9 is based on) and later, it in no way guarantees that no one can run an executable from a noexec-mounted filesystem.

Sticky Business

Traditionally, the sticky bit on an executable binary file tells the Unix kernel that after the concerned application has finished executing, it should remain in the swap space rather than being purgedthus the term sticky. This made operational sense when disk access speeds were slow and memory was expensive; keeping frequently used programs in such a state provided shorter program startup times. However, with the development of ever-faster disk drives and memory access technologies (paging instead of swapping, for instance), the sticky bit is no longer required. As a matter of fact, although still supporting its specification via the chmod program for backward compatibility, newer versions of Unix no longer respect the flag; Linux never used the flag on files from the beginning.

On the other hand, support of sticky bits on directories is alive in Linux/Unix. A directory with this bit set enables users to rename or remove only those files that they own within that directory (other directory permissions permitting). It is usually found on world-writable directories used to store temporary files (such as /tmp and /var/spool/cups/tmp) and prevents users from tampering with each other's files. You can use the following command to locate files or directories with the sticky bit set:

 # find / \( -type f -o -type d \) -perm +o=t \ -exec ls -ld {} \; 2>/dev/null 

TIP

From a security standpoint, all world-writable directories should have their sticky bit set. If a world-writable directory does not have its sticky bit set, you should consider whether it really needs to be world-writable or whether the use of groups or ACLs (see the next section "Extended File Attributes") will work better for your situation. You can generate a list of world-writable directories that don't have their sticky bit set by using this command:

 # find / -type d -perm -o+w -not -perm -a+t \ -exec ls -ld {} \; 2>/dev/null 




    SUSE LINUX Enterprise Server 9 Administrator's Handbook
    SUSE LINUX Enterprise Server 9 Administrators Handbook
    ISBN: 067232735X
    EAN: 2147483647
    Year: 2003
    Pages: 134

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net