9.8 Creating a New Domain

     

In general, it's unwise to create overly large domains, especially domains that include unrelated programs. The traceroute_t domain considered in the preceding sections is perhaps such an overweight domain, since it relates to both the traceroute and Nmap programs. These programs perform a few somewhat similar operations, but they're not closely related . Because they're part of a single domain, a vulnerability in either program could enable an intruder to gain control of the entire domain. Let's presume that we prefer to avoid that fate and see what's required to create a domain specific to the Nmap program.

To do so, we'll follow a procedure that also works in most similar cases:

  1. Determine what files are related to the domain.

  2. Determine the security contexts of these files.

  3. Decide what security contexts are appropriate for the new domain.

  4. Create a basic TE file.

  5. Create a basic FC file that specifies proper labels for files related to the domain.

  6. If necessary, delete conflicting specifications from other FC files.

  7. Load the revised policy and label the domains.

  8. Repeat the following steps as needed:

    1. Test the program.

    2. Tweak the TE or FC files as needed.

9.8.1 Determine What Files Are Related to the Domain

As the procedure directs, let's start by finding out what files are related to Nmap:

 #  rpm -ql nmap  /usr/bin/nmap /usr/share/doc/nmap-3.50 /usr/share/doc/nmap-3.50/COPYING /usr/share/doc/nmap-3.50/README /usr/share/doc/nmap-3.50/copying.html /usr/share/doc/nmap-3.50/nmap-fingerprinting-article.txt /usr/share/doc/nmap-3.50/nmap.deprecated.txt /usr/share/doc/nmap-3.50/nmap.usage.txt /usr/share/doc/nmap-3.50/nmap_doc.html /usr/share/doc/nmap-3.50/nmap_manpage.html /usr/share/man/man1/nmap.1.gz /usr/share/nmap /usr/share/nmap/nmap-os-fingerprints /usr/share/nmap/nmap-protocols /usr/share/nmap/nmap-rpc /usr/share/nmap/nmap-service-probes /usr/share/nmap/nmap-services 

We find four sorts of files:

  • The Nmap executable, /usr/bin/nmap

  • Nmap documentation files, which live in /usr/share/doc/nmap

  • The Nmap man page, /usr/share/man/man1/nmap.1.gz

  • Nmap data files, which live in /usr/share/nmap

9.8.2 Determine the Security Contexts of the Files

Next, let's see what security contexts are currently assigned:

 #  ls -Z /usr/bin/nmap  -rwxr-xr-x+ root     root     system_u:object_r:traceroute_exec_t /usr/bin/nmap #  ls -Z /usr/share/doc/nmap-3.50/  -rw-r--r--+ root     root     system_u:object_r:usr_t          COPYING -rw-r--r--  root     root     system_u:object_r:usr_t          copying.html -rw-r--r--  root     root     system_u:object_r:usr_t          nmap.deprecated.txt -rw-r--r--  root     root     system_u:object_r:usr_t          nmap_doc.html -rw-r--r--  root     root     system_u:object_r:usr_t          nmap-fingerprinting-  article.txt -rw-r--r--  root     root     system_u:object_r:usr_t          nmap_manpage.html -rw-r--r--  root     root     system_u:object_r:usr_t          nmap.usage.txt -rw-r--r--  root     root     system_u:object_r:usr_t          README #  ls -Z /usr/share/man/man1/nmap.1.gz  -rw-r--r--+ root     root     system_u:object_r:man_t          /usr/share/man/man1/nmap.1.gz #  ls -Z /usr/share/nmap/  -rw-r--r--  root     root     system_u:object_r:traceroute_t   nmap-os-fingerprints -rw-r--r--  root     root     system_u:object_r:traceroute_t   nmap-protocols -rw-r--r--+ root     root     system_u:object_r:traceroute_t   nmap-rpc -rw-r--r--  root     root     system_u:object_r:traceroute_t   nmap-service-probes -rw-r--r--  root     root     system_u:object_r:traceroute_t   nmap-services 

9.8.3 Decide on Appropriate Security Contexts for the New Domain

Files having the usr_t and man_t types are readable by ordinary users, but writable only by privileged users. So it appears that the documentation files and the man page have reasonable security contexts.

Let's establish new contexts for the executable and data files. We'll use nmap_t as the type of the data files and nmap_exec_t as the type of the executable.

9.8.4 Create a Basic TE File

To assign the proper security contexts, let's first create a simple TE file, domains/program/nmap.te :

 ################################# # # Rules for the nmap_t domain. # # nmap_t is the domain for the nmap program. # nmap_exec_t is the type of the corresponding program. # type nmap_t, domain; type nmap_exec_t, file_type, sysadmfile, exec_type; 

Our TE file currently does nothing more than define the types we'll use to properly label the files related to the domain. We'll add additional declarations later. In particular, we'll add a declaration that allows processes executing nmap_exec_t programs to transition to the nmap_t domain. We'll also add declarations that specify the operations processes in the nmap_t domain are authorized to perform and the operations that other domains can perform on nmap_t objects. Like the nmap_t domain, most domains have at least two associated types: one associated with the domain itself and one used as an entry point to the domain. Many domains have additional types used to restrict permissions further.

9.8.5 Create a Basic FC File

Next, let's create the FC file, file_contexts/program/nmap.fc :

 # nmap /usr/bin/nmap       --  system_u:object_r:nmap_exec_t /usr/share/nmap.*       system_u:object_r:nmap_t 

When the filesystem is labeled, the FC file will cause the Nmap program and its associated documentation files to be assigned the specified contexts.

9.8.6 Delete Conflicting Specifications from Other FC Files

Conflicting FC specifications could result in incorrectly labeled files. To avoid conflicts, let's remove the following extraneous lines from the traceroute.fc file:

 /usr/bin/nmap       --  system_u:object_r:traceroute_exec_t /usr/share/nmap.*       system_u:object_r:traceroute_t 

9.8.7 Load the Revised Policy and Label the Domains

Now, let's install our new policy and relabel the related files:

 #  make load  #  setfiles file_contexts/file_contexts /usr/bin/nmap  #  setfiles file_contexts/file_contexts /usr/share/nmap  #  ls -dZ /usr/bin/nmap /usr/share/nmap/  -rwxr-xr-x+ root     root     system_u:object_r:nmap_exec_t    /usr/bin/nmap drwxr-xr-x  root     root     system_u:object_r:nmap_t         /usr/share/nmap/ 

The output of the ls command verifies that the security contexts were correctly revised.

9.8.8 Test and Revise the TE and FC Files as Needed

Now, let's try executing the Nmap command and see what sorts of errors arise:

 #  id -Z  root:sysadm_r:sysadm_t #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 13:49 PDT Interesting ports on bill-a31 (127.0.0.1): (The 1658 ports scanned but not shown below are in state: closed) PORT    STATE SERVICE 22/tcp open  ssh Nmap run completed -- 1 IP address (1 host up) scanned in 0.510 seconds 

When we run the program as system administrator, it appears to work fine. However, let's see what happens when we run the program as a user other than the administrator:

 #  id -Z  root:staff_r:staff_t #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 13:50 PDT Unable to find nmap-services!  Resorting to /etc/services socket trobles in massping : Permission denied 

As you might expect, the program fails. Indeed, we should hope that it does so, because otherwise SELinux would not be properly enforcing its policies. Let's discover what's necessary to coax our new nmap_t domain into working for a nonadministrative user.

First, let's examine the system log for relevant AVC messages. We find a message similar to the one we found in the situation described in the preceding section:

 avc:  denied  { create } for  pid=9533 exe=/usr/bin/nmap scontext=root:staff_r:staff_t tcontext=root:staff_r:staff_t tclass=rawip_socket 

Resolve the problem as we did earlier, by authorizing users in the staff_r role to access the domain.

 role staff_r types nmap_t; 

Also authorize an automatic type transition to nmap_t when the Nmap executable is loaded:

 domain_auto_trans(staff_t, nmap_exec_t, nmap_t) 

Again, load the revised policy and test the program. This time, it segfaults:

 #  nmap -sT 127.0.0.1  Segmentation fault 

Inspecting the system log, we find the relevant AVC message:

 avc:  denied  { use } for  pid=9607 exe=/usr/bin/nmap path=/dev/pts/1 dev= ino=3 scontext=root:staff_r:nmap_t tcontext=root:system_r:sshd_t tclass=fd 

This message indicates that the program was unable to access the pseudoterminal device, /dev/pts/1 . Recall that before moving Nmap to its own domain, it executed from the traceroute_t domain without problems. So the traceroute_t domain probably contains a declaration that authorizes access to the pseudoterminal. By studying the TE file for the traceroute_t domain, we discover the declaration needed in our new domain:

 allow traceroute_t privfd:fd use; 

Add the declaration, load the revised policy, and try again. The program appears to suffer from the same problem. But inspecting the system log turns up a new AVC message:

 avc:  denied  { read write } for  pid=9661 exe=/usr/bin/nmap path=/dev/pts/1 dev= ino=3 scontext=root:staff_r:nmap_t tcontext=root:object_r:staff_devpts_t tclass=chr_file 

Now that Nmap can use the file descriptor, it needs read and write access to the related device file. Again consulting the TE file for traceroute_t , we discover and add a declaration authorizing read and write access to the terminal:

 allow nmap_t { ttyfile ptyfile }:chr_file rw_file_perms; 

This time, after loading the new policy, we obtain an unfamiliar error:

 #  nmap -sT 127.0.0.1  nmap: error while loading shared libraries: libssl.so.4: cannot open shared object file: Permission denied 

This message indicates that our domain is unable to access shared libraries. Let's add a macro invocation that authorizes such access:

 uses_shlib(nmap_t) 

After loading the new policy, we obtain a somewhat familiar error:

 #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 21:21 UTC Unable to find nmap-services!  Resorting to /etc/services Unable to open /etc/services for reading service information QUITTING! 

This resembles the error we encountered in the preceding section, when Nmap was unable to read /usr/share/nmap/nmap-services . However, now Nmap also seems unable to read /etc/services . Inspecting the system log uncovers related log entries:

 avc:  denied  { create } for  pid=9821 exe=/usr/bin/nmap scontext=root:staff_r:nmap_t tcontext=root:staff_r:nmap_t tclass=unix_stream_socket avc:  denied  { read } for  pid=9821 exe=/usr/bin/nmap name=localtime dev=dm-0 ino=32810 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:locale_t tclass=file avc:  denied  { create } for  pid=9821 exe=/usr/bin/nmap scontext=root:staff_r:nmap_t tcontext=root:staff_r:nmap_t tclass=unix_stream_socket avc:  denied  { read } for  pid=9821 exe=/usr/bin/nmap name=nsswitch.conf dev=dm-0 ino=32811 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:etc_t tclass=file avc:  denied  { read } for  pid=9821 exe=/usr/bin/nmap name=passwd dev=dm-0 ino=34492 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:etc_t tclass=file avc:  denied  { search } for  pid=9821 exe=/usr/bin/nmap name=nmap dev=dm-4 ino=100533 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:nmap_t tclass=dir avc:  denied  { search } for  pid=9821 exe=/usr/bin/nmap name=root dev=dm-0 ino=262145 scontext=root:staff_r:nmap_t tcontext=root:object_r:staff_home_dir_t tclass=dir avc:  denied  { read } for  pid=9821 exe=/usr/bin/nmap name=services dev=dm-0 ino=32797 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:etc_t tclass=file 

Understanding how to resolve these errors might be overwhelming, were it not for our strategy of studying the domain traceroute_t . After some consideration, we settle on the following additional lines:

 can_network(nmap_t) allow nmap_t self:{ rawip_socket netlink_socket } create_socket_perms; allow nmap_t self:unix_stream_socket create_socket_perms; read_locale(nmap_t) allow nmap_t etc_t:file  { getattr read }; allow nmap_t nmap_t:dir  { search }; allow nmap_t nmap_t:file { getattr read }; 

The first line invokes a macro that generates declarations authorizing network access. The second and third lines authorize specific network operations ”namely, creating raw and stream sockets. The fourth line authorizes reading locale information, such as localtime . The fifth line authorizes access to etc_t files, such as nsswitch.conf . Finally, the sixth and seventh lines authorize access to nmap_t directories and files.

Unfortunately, after loading the new policy, we discover that our work is not yet done:

 #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 14:36 PDT socket trobles in massping : Operation not permitted 

At least Nmap now prints a different error message. That's some indication of progress. Studying the system log turns up the following AVC messages:

 avc:  denied  { search } for  pid=9972 exe=/usr/bin/nmap name=root dev=dm-0 ino=262145 scontext=root:staff_r:nmap_t tcontext=root:object_r:staff_home_dir_t tclass=dir avc:  denied  { search } for  pid=9972 exe=/usr/bin/nmap name=root dev=dm-0 ino=262145 scontext=root:staff_r:nmap_t tcontext=root:object_r:staff_home_dir_t tclass=dir avc:  denied  { search } for  pid=9972 exe=/usr/bin/nmap dev= ino=1 scontext=root:staff_r:nmap_t tcontext=system_u:object_r:proc_t tclass=dir avc:  denied  { net_raw } for  pid=9972 exe=/usr/bin/nmap capability=13 scontext=root:staff_r:nmap_t tcontext=root:staff_r:nmap_t tclass=capability 

Our problems now seem to relate to accessing our home directory, which has type staff_home_dir_t ; accessing /proc ; and using special capabilities. Address the home directory problem by adding

 allow nmap_t staff_home_dir_t:dir {search }; 

To access the files within a directory, a process must be able to:

  • Search the directory.

  • Get the attributes of, and read, the files contained in the directory.

So, to fix the problem accessing /proc , add:

 allow nmap_t proc_t:dir search; allow nmap_t proc_t:file { getattr read }; 

However, it's not necessary to be prescient. If we failed to authorize the getattr and read operations, Nmap would fail with an AVC message that would prompt us to authorize them.

Finally, to authorize use of special capabilities, add:

 allow nmap_t nmap_t:capability { net_raw }; 

After compiling and loading the revised policy and testing Nmap, we find a new error message:

 #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 14:47 PDT pcap_open_live: socket: Permission denied There are several possible reasons for this, depending on your operating system: LINUX: If you are getting Socket type not supported, try modprobe af_packet or recompile  your kernel with SOCK_PACKET enabled. *BSD:  If you are getting device not configured, you need to recompile your kernel with  Berkeley Packet Filter support.  If you are getting No such file or directory, try  creating the device (eg cd /dev; MAKEDEV <device>; or use mknod). SOLARIS:  If you are trying to scan localhost and getting '/dev/lo0: No such file or  directory', complain to Sun.  I don't think Solaris can support advanced localhost scans.  You can probably use "-P0 -sT localhost" though. QUITTING! 

It appears that our new domain lacks the ability to create sockets. A glance at the log confirms this hypothesis. Add a declaration authorizing the creation of sockets:

 allow nmap_t self:packet_socket create_socket_perms; 

After compiling and loading the policy, we find that Nmap now works correctly:

 #  nmap -sT 127.0.0.1  Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-06-01 14:49 PDT Interesting ports on bill-a31 (127.0.0.1): (The 1658 ports scanned but not shown below are in state: closed) PORT    STATE SERVICE 22/tcp open  ssh Nmap run completed -- 1 IP address (1 host up) scanned in 0.473 seconds 

Because we implemented our domain iteratively, it may be hard to grasp the big picture. So that you can review the result of our effort, here's the complete TE file for the nmap_t domain:

 ################################# # # Rules for the nmap_t domain. # # nmap_t is the domain for the nmap program. # nmap_exec_t is the type of the corresponding program. # type nmap_t, domain; type nmap_exec_t, file_type, sysadmfile, exec_type; role staff_r types nmap_t; domain_auto_trans(staff_t, nmap_exec_t, nmap_t) allow nmap_t privfd:fd use; allow nmap_t { ttyfile ptyfile }:chr_file rw_file_perms; uses_shlib(nmap_t) can_network(nmap_t) allow nmap_t self:{ rawip_socket netlink_socket } create_socket_perms; allow nmap_t self:unix_stream_socket create_socket_perms; read_locale(nmap_t) allow nmap_t etc_t:file  { getattr read }; allow nmap_t nmap_t:dir  { search }; allow nmap_t nmap_t:file { getattr read }; allow nmap_t staff_home_dir_t:dir {search }; allow nmap_t proc_t:dir search; allow nmap_t proc_t:file { getattr read }; allow nmap_t nmap_t:capability { net_raw }; allow nmap_t self:packet_socket create_socket_perms; 

However, unless we're very lucky, we're not yet done. It's likely that additional testing will disclose other permissions that must be added to the TE file. You can now see why many SELinux policies work less than perfectly . Like almost all computer software, they're generally developed using a write-test-revise process that doesn't differ much from cut-and-try. Unusual inputs or circumstances can reveal the need for permissions that haven't been anticipated or provided.



SELinux. NSA's Open Source Security Enhanced Linux
Selinux: NSAs Open Source Security Enhanced Linux
ISBN: 0596007167
EAN: 2147483647
Year: 2003
Pages: 100
Authors: Bill McCarty

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