
ruid=0,euid!=0,suid=0
ruid=0,euid=0,suid=0
ruid!=0,euid!=0,suid!=0
ruid=0,euid!=0,suid!=0
ruid!=0,euid=0,suid=0
ruid=0,euid=0,suid!=0
ruid!=0,euid=0,suid!=0
ruid!=0,euid!=0,suid=0
(a) An FSA describing which user IDs carry the root privilege. For clarity, we do not
show the labels on the transitions.
before
exec
after
exec
popen | system | execl | execv | ...
other
other
popen |
system |
execl |
execv |
...
(b) An FSA describing whether the process
has called any of execl, execv, system,
popen, etc.
Figure 2. Two FSAs describing Property 1 (“A process should drop privilege from all its user IDs before
calling
execl
,
execv
,
popen
,or
system
”). In these FSAs the privileged user ID is root and the
unprivileged user ID is non-root. In other situations, however, we may need to use an alternative
FSA where the privileged user ID is also non-root.
system calls on any path, which we encode in Property 3:
Property 3 A program should not pass the same file name
to two system calls on any path
6
.
The system calls in Property 3 include: chdir,
chmod, chroot, creat, execve, lchown, link,
lstat, mkdir, mknod, mount, open, pivot
root,
quotactl, readlink, rename, rmdir, stat,
statfs, symlink, truncate, umount, unlink,
uselib, utime, utimes.
3.1.4. Avoid Attacks on Standard File Descriptors
Normally when a Unix process is created, it has three
open file descriptors: 0 for standard input (stdin), 1 for
standard output (stdout), and 2 for standard error (stderr).
Many C programs and some library functions, such as
perror, write error messages to stderr, assuming that
stderr is opened to a terminal (tty). If, however, stderr is
opened to a sensitive file, then the messages will be writ-
ten to the sensitive file, damaging the file or even allowing
an adversary to take control over the system. For exam-
ple, suppose the victim program in Figure 5(a) is installed
setuid-root. The adversary runs the attack program in Fig-
6
We could make this property stronger by including library functions
that take file names as arguments.
ure 5(b), which closes its stderr and then executes the vic-
tim program. Then, when the victim program opens the
password file /etc/passwd, because Unix opens a file to
the smallest closed file descriptor, the file will be opened
to file descriptor 2, i.e., stderr. Later, when the victim pro-
gram writes an error message to stderr, the message enters
/etc/passwd. Since the message contains a string coming
from the adversary, the adversary can choose the string to
be a valid entry in the password file that allows him to log
in as root.
The avoid this attack, a prudent program should observe
the following property:
Property 4 Do not open a file in writing mode to stdout
or stderr, no matter which file descriptors are open when
the process starts
7
.
A popular defense to this vulnerability is to open /dev/null
three times at the beginning of the program so that no files
can be opened to stderr.
7
We could make the property stronger by ensuring that the program
does not open any file in reading mode to stdin. We have not experi-
mented with this modification.
Komentarze do niniejszej Instrukcji