6.2 File Attributes and Permissions
Now that we have a basic understanding of how filesystems work,
we'll turn our attention to understanding how
filesystems influence the security of a Unix system. Nearly all of
this discussion will be concerned with the metadata that a filesystem
contains—the filenames, permissions, timestamps, and access
control attributes.
6.2.1 Exploring with the ls Command
You can use the ls
command to list all of the files in a directory. For instance, to
list all the files in your current directory, type:
% ls
instructions invoice letter more-stuff notes stats
%
Actually, ls alone won't list
all of the files. Files and directories beginning with a
dot
(".") are hidden from the
ls command but are shown if you use ls
-a:
% ls -a
. .. .indent instructions invoice letter notes more-stuff stats
%
The entries for "." and
".." refer to the current directory
and its parent directory, respectively. The file
.indent is a hidden
file. If you use ls -A instead of ls
-a, you'll see
hidden
files, but "." and
".." will not be shown.
You can get a more detailed listing by using the ls
-lF command:
% ls -lF
total 161
-rw-r--r-- 1 sian user 505 Feb 9 13:19 instructions
-rw-r--r-- 1 sian user 3159 Feb 9 13:14 invoice
-rw-r--r-- 1 sian user 6318 Feb 9 13:14 letter
-rw------- 1 sian user 15897 Feb 9 13:20 more-stuff
-rw-r----- 1 sian biochem 4320 Feb 9 13:20 notes
-rwxr-xr-x 1 sian user 122880 Feb 9 13:26 stats*
%
The first line of output generated by the ls
command (total 161 in the example above) indicates
the number of KBs taken up by the files in the directory. Each of the
other lines of output contains the fields, from left to right, as
described in Table 6-2.
Table 6-2. ls output
-
|
The file's type; for regular files, this field is
always a dash
|
rw-r—r—
|
The file's permissions
|
1
|
The number of "hard" links to the
file; the number of "names" for the
file
|
sian
|
The name of the file's owner
|
user
|
The name of the file's group
|
505
|
The file's size, in bytes
|
Feb 9 13:19
|
The file's modification time
|
instructions
|
The file's name
|
The ls -F option makes it easier for you to
understand the listing by printing a special character after the
filename to indicate what it is, as shown in Table 6-3.
Table 6-3. ls -F tag meanings
(blank)
|
Regular file
|
*
|
File has the execute bit set, typical of executable programs or
command files
|
/
|
Directory
|
=
|
Socket
|
@
|
Symbolic link
|
>
|
A door, which is a special construct in Sun's
Solaris that is currently in
development; used for interprocess communication
|
|
|
A FIFO (a First-In, First-Out buffer, which is a special kind of
named pipe)
|
%
|
A whiteout
|
Thus, in the directory shown earlier, the execute bit of the file
stats is set; the rest of the files are regular
files.
The ls command has dozens of options. Because
different people typically like to see different pieces of
information when they list files, you may wish to read the manual
page for the ls command that is on your system
and then set up aliases so that you will have these options run by
default when you type "ls." For
instance, Spaf has an alias "lf"
that runs ls with the options
-FA, an alias
"ll" that runs
ls with the options -FAl,
and "lb" that runs
ls with the options -FAbx
(the -b switch shows printable octal
representations of nonprinting characters, and the
-x switch sorts filenames across rows rather
than down columns).
6.2.2 File Times
The times shown with the ls
-l command are the modification times of the file
contents, frequently called the file's
mtime.
You can obtain the time of last access (the
atime)
by providing the -u option (for example, by
typing ls -lu). These times are automatically
updated by the Unix operating system.
Knowing when a file was last modified or accessed can be important in
many circumstances. For example, if a person has been using your
account, you can look at the mtimes of files to
infer which files the person modified. Unfortunately, the
mtime and atime
can't strictly be trusted, because they can be
changed by the file's owner or the
superuser by calling a function
(utimes( )) within the Unix kernel. This
function exists so that archive programs like
tar and unzip can restore a
file's modification time in addition to its
contents. Additionally, the times reflect the system clock at the
time of access or modification, so if the clock is incorrect or is
changed, the times may not be accurate.
Because a file's mtime and
atime cannot be trusted, system administrators
and security professionals need to be in the habit of checking the
inode change time
(ctime) using the ls -c
option; for example, ls -lc. As with the mtime
and the atime, the ctime is automatically
updated by the operating system—in this case, whenever a change
is made to the inode of the file. But unlike with
mtime and atime,
unprivileged users cannot change a file's
ctime. The ctime reflects
the time of last writing, protection change, or change of owner. An
attacker may change the mtime or
atime of a file, but the
ctime will usually be correct.
Note that we
said "usually." A clever attacker
who gains superuser status can change the
system clock and then touch the inode to force a misleading ctime on
a file. Furthermore, an attacker can change the ctime by writing to
the raw disk device and bypassing the operating system checks
altogether. And if you are using
Linux with the ext2 filesystem, an
attacker can modify the inode contents directly using the
debugfs command.
For this reason, if the superuser account on your system has been
compromised, you should not assume that any of the three times stored
with any file or directory are correct.
|
Some programs will change the ctime on a file without actually
changing the file itself. This can be misleading when you are looking
for suspicious activity. The
file command is one such offender. The
discrepancy occurs because file opens the file
for reading to determine its type, thus changing the atime on the
file. By default, most versions of file then
reset the atime to its original value, but in so doing change the
ctime. Some security scanning programs use the
file program within them (or employ similar
functionality), and this may result in wide-scale changes in ctime
unless they are run on a read-only version of the filesystem.
|
|
6.2.3 File Permissions
The
file permissions on each line of the ls listing
tell you what the file is and what kind of file access (that is, the
ability to read, write, or execute) is granted to various users on
your system.
Here are two examples of file permissions:
-rw-------
drwxr-xr-x
The first character of the
file's mode field indicates the type of file
(described in Table 6-4).
Table 6-4. File types
-
|
Plain file
|
d
|
Directory
|
D
|
Solaris door construct
|
c
|
Character device (tty or printer)
|
b
|
Block device (usually disk or CD-ROM)
|
l
|
Symbolic link (BSD or SVR4)
|
s
|
Socket (BSD or SVR4)
|
= or p
|
FIFO (System V, Linux)
|
The next nine characters taken in groups of three indicate
who on your computer can do
what with the file. There are three kinds of
permissions:
- r
-
Permission to read
- w
-
Permission to write
- x
-
Permission to execute
Similarly, there are three classes of permissions:
- Owner
-
The file's owner
- Group
-
Users who are in the
file's group
- Other
-
Everybody else on the system (except the superuser)
In the ls -l command
privileges are
illustrated graphically (see Figure 6-2).
The terms read, write,
and execute have very specific meanings for
files, as shown in Table 6-5.
Table 6-5. File permissions
r
|
Read
|
Read access
means exactly that: you can open a file with the open( )
system call and you can read its contents with
read( ).
|
w
|
Write
|
Write access means that you can overwrite
the file with a new one or modify its contents. It also means that
you can use write( ) to make the file longer, or
truncate( ) or ftruncate( )
to make the file shorter.
|
x
|
Execute
|
If a
file's execute bits are set, you can run it by
typing its pathname (or by running it with one of the family of
exec( ) system calls). How the program is
executed depends on the first two bytes of the file.
The first two bytes of an executable file are assumed to be a
magic number indicating the nature of the file. Some
numbers mean that the file is a certain kind of machine code file.
The special two-byte sequence "#!"
means that it is an executable script of some kind (the remainder of
the first line specifies the program that should execute the script).
Anything with an unknown value is assumed to be a shell script and is
executed accordingly.
|
File permissions apply to devices, named sockets, and FIFOs exactly
as they do for regular files. If you have write access, you can write
information to the file or other object; if you have read access, you
can read from it; and if you don't have either
access, you're out of luck.
File permissions do not apply to
symbolic links. Whether you can read the
contents of a file pointed to by a symbolic link depends on that
file's permissions, not the link's.
In fact, symbolic links are almost always created with a file
permission of "rwxrwxrwx" (or mode
0777, as explained later in this chapter). These file permissions are
then ignored by the operating system.
Note the following facts about file permissions:
You can have execute access without having read access. In such a
case, the program can be run by a person without giving them
permission to read the contents of the file or make a copy of the
program. This ability is useful in case you wish to hide the function
of a program, but you should not depend on this behavior, as there
are ways on some operating systems to circumvent the protection.
If you have read access but not execute access, you can then make a
copy of the file and run it for yourself. The copy, however, will be
different in two important ways: it will have a different absolute
pathname, and it will be owned by you, rather than by the original
program's owner.
On some versions of Unix, an executable command script must have both
its read bit and its execute bit set to allow people to run it.
On Solaris systems, there may be
an additional character following the permission characters:
-rwx--x--x+ 3 spaf spaf 24219 May 17 00:52 example
The + symbol indicates that this file (or other
item) has an extended ACL associated with it. An
Access Control List (ACL) provides
a more comprehensive set of permissions on the file than can be
described with the single user/single group model. ACLs are discussed
later in this chapter.
Because file permissions determine who can read and modify the
information stored in your files, they are your primary method for
protecting the data that you store on your Unix system.
Most people think that file permissions are pretty basic stuff.
Nevertheless, many Unix systems have had security breaches because
their file permissions are not properly set, and several provide
automated tools for checking the permissions of important system
files on a regular basis.
|
Sun's NFS servers
allow a client to read any file that has either the read or the
execute permission set. They do so because there is no difference,
from the NFS server's point of view, between a
request to read the contents of a file by a user who is using the
read( ) system call and a request to execute the
file by a user who is using the exec( ) system
call. In both cases, the contents of the file need to be transferred
from the NFS server to the NFS client. (For a detailed description,
see Chapter 15.)
|
|
6.2.3.1 A file permissions example
Consider the directory listing presented earlier in this chapter:
% ls -lF
total 161
-rw-r--r-- 1 sian user 505 Feb 9 13:19 instructions
-rw-r--r-- 1 sian user 3159 Feb 9 13:14 invoice
-rw-r--r-- 1 sian user 6318 Feb 9 13:14 letter
-rw------- 1 sian user 15897 Feb 9 13:20 more-stuff
-rw-r----- 1 sian biochem 4320 Feb 9 13:20 notes
-rwxr-xr-x 1 sian user 122880 Feb 9 13:26 stats*
-------r-x 1 sian user 989987 Mar 6 08:13 weird-file
%
In this example, any user on the system can read the files
instructions, invoice,
letter, or stats because
they all have the letter r in the
"other" column of the permissions
field. The file notes can be read only by user
sian or by users who are in the
biochem group. And only
sian can read the information in the file
more-stuff.
A more interesting set of permissions is present on
weird-file. User sian owns
the file but cannot access it. Members of group
user also are not allowed access. However, any
user except sian and who is also
not in the group user can
read and execute the file. Some variant of these
permissions is useful in some cases where you want to make a file
readable or executable by others, but you don't want
to accidentally overwrite or execute it yourself. If you are the
owner of the file and the permissions deny you access, it does not
matter if you are in the group, or if other bits are set to allow the
access.
Of course, the superuser can read any file on the system, and anybody
who knows Sian's password can log in as
sian and read her files (including
weird-file, if sian changes
the permissions first).
6.2.4 Directory Permissions
Unix stores the contents of directories in
nodes that are similar to the nodes used for regular files, but they
are specially marked so that they can be modified only by the
operating system.
As with other files, directories have a full complement of security
attributes: owner, group, and permission bits. But because
directories are interpreted in a special way by the filesystem, the
permission bits have special meanings (see Table 6-6).
Table 6-6. Permissions for directories
r
|
Read
|
You can use the opendir( ) and
readdir( ) functions (or the
ls command) to find out which files are in the
directory.
|
w
|
Write
|
You can add, rename, or remove entries in that directory.
|
x
|
Execute
|
You can
stat the contents of a directory (e.g., you can
determine the owners and the lengths of the files in the directory).
You also need execute access to a directory to make that directory
your current directory or to open files inside the directory (or in
any of the directory's subdirectories).
|
If you want to prevent other users from reading the contents of your
files, you have two choices:
You can set the permission of each file to 0600, so only you have
read/write access.
You can put the files in a directory and set the permission of that
directory to 0700, which prevents other users from accessing the
files in the directory (or in any of the directory's
subdirectories) unless there is a hard link to each file from
somewhere else.
Note the following:
You must have execute access for a directory to make it your current
directory (via cd or chdir)
or to change to any directory beneath (contained in) that directory.
If you do not have execute access to a directory, you cannot access
the files within that directory, even if you own them.
If you have execute access to a directory but do not have read
access, you cannot list the names of files in the directory (e.g.,
you cannot read the contents of the directory). However, if you have
access to individual files, you can run programs in the directory or
open files in it. Some sites use this technique to create
secret files—files that users can access
only if they know the files' full pathnames.
To unlink a file from a directory, you need to have write
and execute access to that directory, but not to
the file itself.
If you have read access to a directory but do not have execute
access, you can display a short listing of the files in the directory
(ls); however, you will not be able to find out
anything about the files other than their names and inode numbers
(ls -i) because you can't
stat the files. Remember that the directory
itself contains only name and inode information. This processing can cause quite a bit of confusion if you are not
expecting it. For example:
% ls -ldF conv
dr------ 4 rachel 1024 Jul 6 09:42 conv/
% ls conv
3ps.prn bizcard.ps letterhead.eps retlab.eps
% ls -l conv
conv/3ps.prn not found
conv/bizcard.ps not found
conv/letterhead.eps not found
conv/retlab.eps not found
total 0
%
One of the most common questions asked by new
Unix users is "How do I delete a file whose name
begins with a dash? If I type rm -foo, the
rm command treats the filename as an
option." There are two simple ways to delete such a
file. The first is to use a relative pathname:
% rm ./-foo
%
A second way is to supply an empty option argument, although this
does not work under every version of Unix. With some versions of
rm, an empty option is a single hyphen. On
others, it's a double hyphen:
% rm - -foo
% rm -- -foo
If you have a file that has control characters in it, you can use the
rm command with the -i
option and an asterisk, which gives you the option of removing each
file in the directory—even the ones that you
can't type.
% rm -i *
rm: remove faq.html (y/n)? n
rm: remove foo (y/n)? y
%
The -i option may also be helpful when you are
dealing with files with
Unicode characters
that appear to be regular letters in your locale, but that
don't match patterns or names you use otherwise.
A great way to discover files with control characters in them is to
use the -q
option to the Unix ls command (some systems also
support a useful -b option). You can, for
example, alias the ls command as ls
-q. Files that have control characters in their filenames
will then appear with question marks:
% alias ls ls -q
% ls f*
faq.html fmMacros fmdictionary fo?o
faxmenu.sea.hqx fmMacrosLog.backup fmfilesvisited
%
|
|