Computer systems usually have peripheral devices attached to them. These devices may be involved with I/O (terminals, printers, modems); they may involve mass storage (disks, tapes); and they may have other specialized functions. The UNIX paradigm for devices is to treat each one as a file, some with special characteristics.
UNIX devices are represented as inodes, identical to files. The inodes represent either a character device or a block device (described in the sidebar) . Each device is also designated by a major device number, indicating the type of device, and a minor device number, indicating which one of many similar devices the inode represents. For instance, the partitions of a physical disk will all have the same major device number, but different minor device numbers. For a serial card, the minor device number may represent which port number is in use. When a program reads from or writes to a device file, the kernel turns the request into an I/O operation with the appropriate device, using the major/minor device numbers as parameters to indicate which device to access.
UNIX usually has some special device files that don't correspond to physical devices. The /dev/null device simply discards anything written to it, and nothing can ever be read from it - a process that attempts to do so gets an immediate end-of-file condition. Writing to the /dev/console device results in output being printed on the system console terminal. And reading or writing to the /dev/kmem device accesses the kernel's memory. Devices such as these are often referred to as pseudo-devices .
Device files are one of the reasons UNIX is so flexible and popular - they allow programmers to write their programs in a general way without having to know the actual type of device being used. Unfortunately, they also can present a major security hazard when an attacker is able to access them in an unauthorized way.
For instance, if attackers can read or write to the /dev/kmem device, they may be able to alter their priority, UID , or other attributes of their process. They could also scribble garbage data over important data structures and crash the system. Similarly, access to disk devices, tape devices, network devices, and terminals being used by others all can lead to problems. Access to your screen buffer might allow an attacker to read what is displayed on your screen. Access to your audio devices might allow an attacker to eavesdrop on your office without your knowing about it.
In standard configurations of UNIX , all the standard device files are located in the directory /dev. There is usually a script (e.g., MAKEDEV ) in that directory that can be run to create the appropriate device files and set the correct permissions. A few devices, such as /dev/null , /dev/tty , and /dev/console , should all be world-writable, but most of the rest should be unreadable and unwritable by regular users. Note that on some System V systems, many of the files in /dev are symbolic links to files in the /devices directory: those are the files whose permissions you need to check.
Check the permissions on these files when you install the system, and periodically thereafter. If any permission is changed, or any device is accessible to all users, you should investigate. This research should be included as part of your checklists.
Unauthorized Device Files
Although device files are normally located in the /dev directory, they may, in fact, be anywhere on your system. A common method used by system crackers is to get on the system as the superuser and then create a writable device file in a hidden directory, such as the /dev/kmem device hidden in /usr/lib and named to resemble one of the libraries. Later, if they wish to become superuser again, they know the correct locations in /dev/kmem to alter with a symbolic debugger or custom program to allow them that access. For instance, by changing the code for a certain routine to always return true, they can execute su to become root without needing a password. Then, they set the routine back to normal.
You should periodically scan your disks for unauthorized device files. The ncheck command, mentioned earlier, will print the names of all device files when run with the -s option. Alternatively, you can execute the following:
# find / \( -type c -o -type b \) -exec ls -l {} \;
If you have NFS -mounted directories, use this version of the script:
# find / \( -local -o -prune \) \( -type c -o -type b \) -exec ls -l {} \;
Note that some versions of NFS allow users on remote machines running as root to create device files on exported volumes. [27] This is a major problem. Be very careful about exporting writable directories using NFSDEVICE FILESFILESDEVICE (see Chapter 20 , for more information).
[27] Of course, these modifications cannot be made if the filesystem is exported read only.