TrustedBSD : Mandatory Access Control (Part 3) – Policy: MAC BIBA
For our 3rd part of the tutorial, we are going to cover one of the MAC policies. The first one is MAC BIBA. This policy controls the upward flow of information. In otherwords, it can restrict a subject (a user or process), from various abilities (We will explain this in more detail later).
First, we need to make sure that the module loads. We need to add it to the loader, and keep some network interfaces from being blocked.
We need to add these lines to the /boot/loader.conf:
The first interface OID, allows all interfaces to be used by the system, and the users. If we want to restrict some interfaces, we can use the 2nd OID to do so. We simply list the interfaces we want to allow access, with a space in between.
Next, we reboot into single-user mode to enable labeling.
# tunefs -l enable / # exit
Basic Understanding of MAC BIBA
Now that we have our system set up to use the biba module, let’s start seeing how this all works. First we need to make a biba test user. I will of course continue to use my faithful “MacUser”. Be sure that /sbin and /usr/sbin are in your user’s path, otherwise use ‘whereis’ when trying to find commands that aren’t found in your path.
Now we need to alter the label in out login.conf (reffer to Part 2 on how to apply classes and labels):
Let’s first take a look at the label we added, “biba/low(low-low)”. Normally, in this case, we would use biba/low for our label, but just to show you there is more to it, we added the “(low-low)”. First things first, the BIBA module has three special labels to simplify the labeling process; biba/high, biba/low, and biba/equal. Biba/high is the highest of all labels, and always higher than all. The biba/high level is also the default label for basically everything on the filesystem, and the default user class. Biba/low, of course, is the lowest of all labels. Last, biba/equal, is the label to omit a subject(user), or object(file/process), from the biba module. How the module works, is that if subject’s integrity is equal the object’s integrity level, then the subject has full control. If the subject’s integrity level is greater than the object’s, the subject loses read ability, but still holds the ability to write to the object. Although, if the subject’s integrity level is less than the object’s, the subject will have read access, but no ability to write. Now, let’s see how this works.
> whoami MacUser > getpmac biba/low(low-low) # getpmac biba/high(low-high) # touch /home/MacUser/test # touch /home/MacUser/test2 # chown MacUser:MacUser /home/MacUser/test > ls -lZ -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 09:59 test -rw-r--r-- 1 root MacUser biba/high 0 Jul 31 09:59 test2 > cat test > echo test > test test: Permission denied. > rm test override rw-r--r-- MacUser/MacUser for test? y rm: test: Permission denied
So we first check our user’s BIBA integrity level with getpmac. We then create our test files, and set ownership with our root-type user. Just like ps, ls has the “Z” option to show MAC labels. As we see both files are given the default label of biba/high. As our user, we first test out ability to read the file, and the our ability to write. As we can see, we can read the file, but cannot write to the file. Not only that, we cannot remove the file, and to add, we see that rm sees that the permissions are higher, and asks us if we would like to ovverride the permissions. Of course, we cannot.
# setfmac biba/low /home/MacUser/test # cat /home/MacUser/test cat: /home/MacUser/test: Permission denied > cat test > echo testing > test > rm test rm: test: Permission denied
Next, we change the label of the test file to biba/low with another tool, “setfmac”. Setfmac works by setting the label to the file(s), in that order (setfmac [label] [file1] [file2]). Now that it is not equal to the integrity of the root-type user (biba/high), that user cannot read the file. As our regular user, we have full access to the file since it’s integrity is now equal to our user’s. As we can see right after, we still cannot remove the file.
# setfmac biba/equal /home/MacUser/test* # cat /home/MacUser/test1/test testing > cat test testing > echo testingagain >> test > echo testing > test2 test2: Permission denied. > rm test rm: test: Permission denied
Last, we test the biba/equal label on the file. The object, or the file, now ignores the policy, and allows all users the ability to read and write to the file, regardless of the label, because it is now equal to all. Now wait, we can’t write to “test2”, nor can we remove “test”. Before you tell me this is a dirty trick, I have to point out that I must push this over and over again, so that you don’t become confused with the policies. Remember, the MAC policies overlay the UNIX DAC permissions. Remember our ‘ls’ output? Who owned test2? That’s right root still owns it.
# setfmac -R /home/MacUser biba/low > rm test > # cd /home/MacUser /home/MacUser: Permission denied
So what about the test file we can’t remove? Do you remember that I said that “biba/high” is the default integrity label for objects? MacUser’s home directory was one of those objects. So, after we set MacUser’s home directory recursively to “biba/low”, we can now delete the test file. After that, we try to change to the home directory with our root-type user. What? Root doesn’t have access? While root would have access to change the label, we now have the ability to alienate root from the list of all-knowning, snooping admins.
Before we get into the more complicated policy integrity levels, we need to cover setting labels, and the access we have. Remember the range in the level surrounded in parethesis? This range of integrity levels is used for the processes we use. When we want to have a process access an object of a different integrity level, we can do so if that integrity level is in our range of levels. Still confused? That’s ok, let’s take a look at a few examples.
# getpmac biba/high(low-high) > getpmac biba/low(low-low)
Ok, let’s look at our user’s labels, and focus on the ranges. The root type user has low to high. The regular user has low-low. Now, if you remember in the last tutorial, we used “setpmac” to set the label for a process. We are going to do the same thing here, except we are going to set the label as we initiate the process. Continuing from the examples before, we’ll start off with test files again.
> ls -lZ total 8 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test4 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5
In the MacUser home directory, I simply touched three new files to the directory as our regular user.
# setpmac biba/low setfmac biba/high /home/MacUser/test4
To explain what we just did, remember that we do not have access to physically go into the directory, but since we know what file we want to change, we can still write a label to it when making the process equal to the object integrity. Had we tried to do this without setting the process integrity, we would have failed, and gained an error. So, now that we have changed the label of that file, let’s take a look at it.
# setpmac biba/low ls -lZ MacUser/ total 8 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3 -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 13:09 test4 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5
What we are doing is simply making the process seem like a user with biba/low integrity. As a note, to be complete, you can use the biba/equal to bypass any label, but let’s not get into that habit. You’ll see why later. So, what about our regular user? Is it restricted to where it can’t do anything at all? Well, it is quite limited, and it would be futile to even bother with the setpmac command, since it doesn’t have a range to use at all, but there are a few things to keep in mind. First, any object in an object that is the same level of the user, can be changed to the integrity level of the user.
> setfmac biba/low test4 > ls -lZ total 8 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3 -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 13:09 test4 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5
Since the home directory is still marked with biba/low, the user was able to change the integrity level to a matching level. If it was still biba/high, we would encounter an error like so.
setfmac: mac_set_link(test4, biba/low): Operation not permitted
Although the user has full control, it cannot change it to a higher integrity level. If the user had an intregrity level range of (low-high), we could have used the setpmac command to change to biba/high, or even biba/equal. In a situation like this, we could essentially set a user to biba/low(low-high), and root type users to biba/high(high-high), only permitting root to do it’s admin duties, and the user not having to worry about nosy admin.
Interfaces and BIBA
While we allowed intrefaces to work, we have to understand that doesn’t mean that everybody can use them.
> ifconfig dc0 dc0: flags=8843<up,broadcast,running,simplex,multicast> mtu 1500 options=8 inet 192.168.1.180 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:04:5a:6f:1d:0c maclabel biba/high(high-high) media: Ethernet autoselect (100baseTX ) status: active
We see that the default label, like everything else is biba/high, but the behaviour that we see is a bit different. The first part of the label handles the allowed labels for receiving traffic, while the range tells the interface what traffic can be transmitted.
> ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1): 56 data bytes ping: sendto: Permission denied ....
As we can see, we can’t do either from the MacUser. Changing the transmit should help.
# ifconfig dc0 maclabel "biba/high(low-high)" > ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1): 56 data bytes
Well, we can transmit, but we can’t see anything coming back of course. We now need to change the transmit permissions, but since the default user label is biba/high, we will just set it to equal.
# ifconfig dc0 maclabel "biba/equal(low-high)"
Now we have the ability to ping transmit, and receive the incoming replies.
More Advanced Policy Integrity Levels
Now that we have the basics down, it’s time for us to start looking at setting integrity levels by hand, and using numerical values.
Let’s first take a look at the numerical labels.
Instead of using special labels that say, greater/less than all, we are going to set our own grades of integrity, and a set of compartments that a class can access. Let’s break that last label down into descriptions.
Let’s change our labels a bit, and make a second one of top of that. I’m going to assign the class “testing” with MacUser, and “testing2” with MacUser2.
Now, let’s observe how things work out.
Could not chdir to home directory /home/MacUser: Permission denied > getpmac getpmac: Command not found. > /usr/sbin/getpmac biba/5(low-high) > /usr/sbin/getfmac /home/MacUser /home/MacUser: biba/low /usr/sbin/setpmac biba/low /usr/sbin/setfmac biba/5 MacUser> ls -lZ total 10 drwxr-xr-x 4 MacUser MacUser biba/5 512 Jul 31 14:15 MacUser drwxr-xr-x 2 MacUser2 MacUser biba/high 512 Jul 6 14:49 MacUser2
First we see that we couldn’t even get into our own directory, and due to that, we lost our ability to read our .cshrc, which holds our path. So, we then get the label of our user and the directory by using the full path of getpmac, and getfmac. Now that we know what the integrity level is, we change the label of our home directory to match our new label, without the containers.
2> setpmac biba/5 setfmac biba/6 MacUser2/
2> chmod 775 /home/MacUser2 > cd /home/MacUser2 > setpmac biba/6 touch test > setpmac biba/6 touch test2 > setpmac biba/6 touch test3 > setpmac biba/6 chmod 664 * > setpmac biba/6 setfmac biba/5:3 test > setpmac biba/6 setfmac biba/5:4 test2 > setpmac biba/6 setfmac biba/5:2+3 test3 > ls -lZ total 4 -rw-rw-r-- 1 MacUser MacUser biba/5:3 0 Jul 31 17:22 test -rw-rw-r-- 1 MacUser MacUser biba/5:4 0 Jul 31 15:03 test2 -rw-rw-r-- 1 MacUser MacUser biba/5:2+3 0 Jul 31 15:03 test3 2> ls -lZ ls: test: Permission denied ls: test2: Permission denied ls: test3: Permission denied total 0
Just to skim the surface, we created a few files in MacUser2’s home directory. We then changed the labels to grade 5, with compartment 2+3 and 2+3+4. The effective grade of MacUser is 5, while MacUser2’s effective grade is 6. As you can see, since it’s grade is larger than the grade of the objects, it cannot read them. So, we need to alter our presence to even view the details of the files.
2> setpmac biba/5 ls -lZ total 4 -rw-rw-r-- 1 MacUser MacUser biba/5:3 0 Jul 31 17:22 test -rw-rw-r-- 1 MacUser MacUser biba/5:4 0 Jul 31 15:03 test2 -rw-rw-r-- 1 MacUser MacUser biba/5:2+3 0 Jul 31 15:03 test3
Now, notice that we didn’t specify the compartment for our process. Since we can read, and view files being at a lower integrity, setting to the integrity grade without the compartments shows us the files and their attributes. If we set the matching compartments of the files as well, we could have full access.
Now, the purpose of the compartments is to allow certain users in a grade to be able to have access to certain files on a “need to know” basis. If the subject (user/process), meets all of the qualifications, they can have full access to the file. You could set the compartments, and once again fork the permissions across a single grade. The compartment feature has the ability to have up to 256 compartments by default. So, in retrospect, you could have an infinite ability to isolating the ability of each user if needed.
As we can see, the biba module can be used to help restrict users even more, making sure that information doesn’t go anywhere it shouldn’t. While we only skimmed the surface of the advanced features of the module, we will see them in a later tutorial. As a side note, be very careful with your labels, and always test before you put them into serious system play. Until later, enjoy, and have fun!
MAC_BIBA Other Important OIDs
security.mac.biba.interfaces_equal: 0|1 – set interfaces to biba/equal (Default 0 off)
security.mac.biba.ptys_equal: 0|1 – set ptys to biba/equal (Default 0 Off)
security.mac.biba.max_compartments: 256 – max compartments (Default 256. Must be set at boot time)
security.mac.biba.label_size: 112 – (Default 112. Must be set at boot time)