MIT course "Security of computer systems". Lecture 4: "Separation of privileges", part 1

Original author: Nikolai Zeldovich, James Mykens
  • Transfer
  • Tutorial

Massachusetts Institute of Technology. Lecture course # 6.858. "Security of computer systems." Nikolai Zeldovich, James Mykens. year 2014


Computer Systems Security is a course on the development and implementation of secure computer systems. Lectures cover threat models, attacks that compromise security, and security methods based on the latest scientific work. Topics include operating system (OS) security, capabilities, information flow control, language security, network protocols, hardware protection and security in web applications.

Lecture 1: “Introduction: threat models” Part 1 / Part 2 / Part 3
Lecture 2: “Control of hacker attacks” Part 1 / Part 2 / Part 3
Lecture 3: “Buffer overflow: exploits and protection” Part 1 /Part 2 / Part 3
Lecture 4: "The division of privileges" Part 1 / Part 2 / Part 3

Today, we’ll talk about privilege sharing, since we’ve ended up with a buffer overflow at a certain level, but we’ll still go back to it. We will not talk about the details of how to use buffer overflows, but switch to reducing this problem and talk about how to develop a system in which buffer overflow will not be a big problem for you, like other vulnerabilities.



So today we’ll talk about privilege sharing as a method to create a more secure system, and in the lecture materials we mention a web server called OKWS . This is not the most telling example of separation of rights, but the system is described there well enough to understand how all its parts work. But this does not mean that you should go right now, download OKWSand launch your website.

So, before we get into the details of OKWS and Unix permissions , let's just see what privilege sharing is and why is it such a good idea? Last week James showed that if you write a program in C, you will almost inevitably have something bad or wrong in it. The problem is that if you have a large enough application and there is some kind of vulnerability present in it, then attackers can connect to the program, send requests to this application, trick it and do “bad” things.

Any application has access privileges. This means that it includes a lot of data that can be obtained with access. You can even delete these files, as you guys did in lab # 1. The problem is that a vulnerability in this large application may allow an attacker to change some of this data or to get enough privileges to manage the program if you are not careful.
In this lecture we will look at what privilege separation is trying to do. It is necessary to take the program, divide it into parts and make sure that each of the individual elements has only the necessary privileges in order to properly perform its work.



On the left we have a program of 3 parts, and on the right data, also consisting of three parts. Properly assigned privileges mean that each part of the application has access only to its part of the data. And if we have a vulnerability of program X, then it will allow to take control of only one part of the data and will not be able to affect the data in the other two parts.
So this idea of ​​sharing privileges is extremely powerful. It does not specifically address the problem of buffer overflows or other vulnerabilities; it is just general requirements for the architecture of software products to ensure that vulnerabilities in one place of the system do not affect its other parts. Privilege sharing is used quite widely. So, to ensure the isolation of components within a program, virtual machines are often used.

You can take your large system and divide it into a bunch of VMs to isolate individual parts, but you can also use Unix to actually perform this isolation with "cutting." Unix provides quite a few mechanisms that OKWS actually uses to separate privileges.

Many applications actually use the privilege sharing practice. You guys probably used SSH, or "secure shell" quite often. It is a network protocol that is used for remote control of the OS and file transfer. He uses privilege separation in many of his components to make sure that his encryption keys are not solved and the server will not be compromised. More relevant for you is the Chrome web browser, in which privilege sharing is also quite widely implemented. So, if there is some kind of "bug" in the work of Chrome, the enemy will not be able to gain complete control over your computer.

This is a very brief summary of what privilege sharing is and why OKWSis an interesting example. However, it is a more illustrative example than an important piece of software.

So OKWS , as I mentioned, will use Unix permissions and some sort of Unix mechanisms to separate different components. It is important for us to understand how the Unix security mechanisms work. Unix as a tool for privilege sharing is not only important for understanding OKWS , it is just like any other isolation tool, for example, UID , VM , containersor any similar technology, allows you to understand the details of the process. Because there are many difficult parts of the process of obtaining access rights, and you can deal with an attacker who takes advantage of the vulnerability of any of these parts. Therefore, we will look at Unix in sufficient detail to understand what it is and how it should look in a particular security mechanism.

Perhaps, historically, Unix is ​​the best example of how to build a security mechanism. Its security mechanism arose in the process of satisfying the need to separate users from each other in a single Unix system. In this case, it was believed that there are a lot of users who use the same computer, and you need to keep them apart from each other. Thus, it is not necessarily a general purpose mechanism, but still one of the most common and widely used. So, Chrome is trying to use many mechanisms for the separation of privileges from Unix.

When you think about the protection mechanism, you should think about its principles, which mean that there is someone with privileges or rights, and Unix initiates or supports these rights. Therefore, I think that the subject, or subject, of Unix is ​​a process, because a process is supported, because every operation or request that we consider from a security point of view should be allowed or forbidden. It will probably be an operation invoked by a process by making a syscall system call . What matters here is how we describe what privileges this process has.

Next, there is an object on which our process acts as a subject. He can modify objects, read them, watch them. In the OS there are many objects, the protection of which is worth worrying about. What objects do you think we should worry about?

Audience: about files!

Professor: correctly, about files and directories. What else?



Audience: About network sockets!

Prof: yes, great about network sockets. Anything else going on in the system?

Audience: other processes.

Professor:Right. In fact, this is similar to what the application or user should take care of, but there are different internal system components that you must also protect. Therefore, the process itself is not the subject that makes the system call, it is also something that another process can act on. He can kill him or create a new one. Therefore, you need to figure out what the rules of perception of a process as an object can be manipulated. What other things might worry us?

Audience: environment variables.

Professor:I think that they are probably not a subject that you can change, in the sense of controlling OC and having some kind of security policy. I think that environment variables are just a kind of state of a process contained in memory. But, I think, more generally, we are concerned about this part of the process that is contained in memory - environment variables, stacks, arguments, this is also quite important. Probably, in the memory of the process there are many things sensitive to interference from outside. What else?

Audience: file descriptors in general.

Professor: there is another internal circumstance that is of great importance. The files that are on the disk should worry us. But there is also such an operational tool as a file descriptor, which is OKWStries to use widely, and we will see what they are. What other things would you like to protect in the operating system?



Audience: hardware, or hardware.

Professor: yes, hardware requires no less protection than abstract things provided by the OS, we don’t want our processor to “freeze” for some reason when executing the program.

Audience: You should also consider protecting peripheral devices!

Professor: Oh, yes! So, additional devices, you are right, especially on a desktop computer, there are a lot of superfluous things there: a USB drive, a webcam, probably the display itself - you will want to protect some of this, because the applications connected with them do not have to “walk” "All over your screen.

I think, in fact, all these objects are not on the server side, they are just close enough to it. On your phone, a microphone is probably also a very important object that you also want to protect.

But I will leave this list, because then we will talk mainly about server applications, but you are absolutely right about the list of objects. I think that for OKWS this is probably a more or less exhaustive list of things we could take care of, or at least that OKWS uses .

So let's talk about how the OS kernel decides when a process can do something with any of these objects. Therefore, at a high level, we mainly think of the process as a subject with privileges granted by this principle, and the principle in the Unix system is a rather complicated thing.

There is something called User ID , which is a 32-bit integer. There is a group ID , which is also a 32-bit integer. In fact, there is no particular reason why they should be different.



It would be nice if they just made up a single set of 32-bit integers, but, unfortunately, Unix divides them into two categories. There are integers User ID, and Group ID integer values . When we talk about a process that has certain privileges, it means a process associated with a specific uid value . As a rule, a process has one uid , as well as a list of gid group identifiers that this process has. For historical reasons, it turned out that they are combined into one gid , and then combined into a list of other identifiers. Roughly speaking, a process can exercise the privileges represented by all of these ids. So if the uid grants access to something, the process can do anything with it.

Now let's talk about files, directories and other types of objects. So what happens to the files, or rather, how to create Unix permissions to work with files? Everything is relatively simple with files, you are concerned about the operations you can do with them: reading, writing, possibly performing, as well as the ability to change permissions or other security properties.

Audience: breaking ties!

Professor: yes, disconnection, unlink - do you think this is a property of the file or directory itself? In fact, this distinction is a bit unclear. When Unix thinks about deleting a file, it is more concerned with the directory, because in Unix the file is really an inodeor inode. Therefore, in Unix you can have several hard links to inodes and when you unplug a specific Unix file name using unlink, you actually destroy only one of the file names, but it may have other names and other links to it. In fact, it is important whether you are allowed to change the directory pointing to the file and not to do anything with the inode of the file itself. So usually, the unlink , link , rename, and create operations are directory-related operations, so create affects both the directory and the new file. Therefore, we must find out which rules apply there.



In order to decide that someone can read or write a file, we are going to insert some permissions, or bits, into the inode file . In Unix, each inode , which is ultimately a file or directory, for security purposes has several interesting fields. Here is the user ID and the group ID, which we say owns the file or owns the directory. Thus, you can manage all the files in your home directory due to the fact that Unix has your uid .
In Unix, there is also a set of permission bits that can be considered as part of the matrix, in basic design they look like r (read), w (write), and x(performance). We can specify these permissions for different subjects, and in Unix they are specified for the owner owner , that is, for the uid inode , for the group group that owns the file, that is, for gid , and for all others - other .

You can fill this 3 by 3 binary matrix, where 1 means permission to perform a specific action, and 0 prohibits its execution:



This is how Unix stores permissions. There is a traditional way of coding these things, which you will see often and which is probably worth mentioning. In Unix, this matrix is ​​encoded as an octal number, so each line here should be considered as the base number 8, so our matrix in this encoding will look like this: r is 4 bits, w is 2 bits, x is 1 bit, respectively, owner is this is 6 bits, and group and other each contain 4 bits.



You will often see such designations in the lecture materials, so you can say that this file has a resolution of 6, 4, 4, that is, the owner can read and write the file, and the group owner and others can only read it.

These notations tell us when to read, write, and execute a file. What about changing the resolution for this file? This is not exactly a fair question, but what do you guys think about this? How should we decide that someone should be able to change these permissions, because this may also be necessary? Any thoughts on that?

Audience: if this person has access to the file?

Professor:it may also depend on access privileges. On the other hand, you can create a writable file overwritable , which you want to someone to share, so that he could read, append, and modify your file, but then it also means that you will suddenly be able to change the permissions to make the file is not writable, or assign just myself.

Therefore, the creators of Unix decided that if you have a file, that is, your uid corresponds to the uid listed in the file, then by default you can change the permissions. Otherwise, you cannot. So if you only have gid and this grouphas all the permissions in the file, you still can not change the permissions for this file. You can simply read, rewrite, do anything with it, but without the uid you cannot change the permissions.

Directories in Unix follow the same rules. Thus, detaching unlink and linking link records in a directory means having permission to write to that directory. If you want to rename a file, then you probably need to have rights to write to the directory where you get it from and to write to the directory where you put it. In some cases, hard links may cause problems, and these details are highlighted in the lecture materials.

In fact, in the catalog there is another interesting operation - search. Thanks to her, you can simply find the file in the directory. Unix encodes execute permissions as the ability to implement search for directories, so having execute permission for a directory actually means the ability to search for a specific file name. It may be that you do not need to have permission to the directory to search for the file name, but if you do not have permission to read, you will not be able to view the contents of the directory, that is, to find the file. This is useful in some situations when you need to restrict actions with some files or hide them from the user.

Let's take an example. What happens in Unix if I enter the open command ("/ etc / password")? What does the system kernel check on my behalf when I command it to make a system call?

Audience: does it check if you have permission to perform, etc.?

Professor: Yes, to a certain extent this is the case. I need to do something, etc.

Audience: and then perform the specified slash!

Professor: yes, actually I need to look at what / etc indicates ? So if I don’t understand root permissions, it’s not going to work.

Audience: then you need to read / etc / password .



Professor:Yes, it makes sense. Here you have a little puzzle. Suppose MIT creates a group for all people associated with the 6.858 course, and other groups for all the TAs in MIT, which in Unix terminology is designated as gids , but they are not included in the 6.858 group of TAs for some stupid reason. How can I create a file that will only be available for a group of 6.858 TAs?

Suppose I have 6.858 gid and TAs gid, but I can insert only one gid into the file .

Audience: you would not be able to do this, because here you can have TAs, not 6.858 TAs.

Professor:Yes it's true. Although there are students in the 6.858 group who are the TAs of other classes, so maybe this is not really cool. But, nevertheless, let's try to somehow make the intersection of these groups. For this we can use the permissions mechanism.
You can create the file / foo / bar / grades , while foo owns it, or sets the gid for the group 6.858 and can make it executable only for this group. Therefore, if you are not in this group, you cannot even search for files in the / foo directory . And then I would set permissions for / bar , which would set gidfor TAs, and also make it executable for this group. Therefore, if you cannot follow the path of this directory / foo / bar / , then you will not get access to the grades rating file . Thus, we use some kind of file isolation mechanism.



Audience: if, for example, only 6.858 gid had permissions on the rating file itself, could TA connect it to some other directory and allow someone to access it in 6.858?

Professor:Yes, it's true. That way, you can worry about other things, such as leaks, so Unix basically doesn’t try to apply these kinds of transitive security properties, which means that if one process has access to some data, or it has some privileges, it can delegate these privileges to anyone he wants. There are other types of systems called MACS - mandatory access control systems, mandatory access control systems. Perhaps we will talk about them later, but in general they actually implant such a transitive property: if I give it to you, you will not be able to give it to other people. That is, you are stuck in one place. These are peculiar chains, so you cannot go anywhere else.

On Unix, this is usually not the case, and so TA could not hard link this file due to another stupid rule that Unix used for a hard link. It lies in the fact that only the owner of the file can rigidly associate it with something else. This is partly due to the fact that Unix uses quotas, and these quotas apply to those who own the file. Therefore, if you create a giant file, I can hard link its copy to my directory. Then you can delete this file, but I still have a complete copy of it, and now the file system will think that I own it. So in reality, you will not be able to permanently delete this file, because I have a link to it. In this case, there is an unfortunate combination of Unix mechanisms.

But in general, you should worry about such things as transitivity, for example, when someone was not a TA, and therefore we deleted it. However, it can hide the link to the rating file somewhere, so this may not be the ideal option.

So, we briefly reviewed everything related to files and directories in Unix.

There are things closely related to files and directories — these are file descriptors. File descriptors are widely used in OKWS , and in Unix the file descriptor is an open file. The security check in Unix is ​​that first of all, when you try to open a file, permission to access the file is checked. As soon as the file is open, from now on you will have a certain “drive” for this file, with which you can perform any operations with this file.

Thus, the rules for accessing a file descriptor are as follows: if you have an open file descriptor in your process, then you can access it. And security checks are not applied in the sense that to get this file descriptor you just need to open this file. If a process sends you a file descriptor, or the parent process passes it to the child process, or the transfer occurs via Unix sockets - no matter how you managed to get the file descriptor, you can still read and write whatever you want, security checks have already been made at its creation.

So, in fact, descriptors are the useful ability of Unix to grant someone privileges that they would not otherwise have.

In OKWSThere are many components that need access to a specific socket or file. And one of the ways to do this, without giving them direct access to reading and writing this file in the file system, is that someone else opened the file, created a file descriptor, and then transferred it to this additional component. That way, you can say for sure that this is the only file descriptor you will ever have. And no one else can try to do anything in the file system, which can lead to dangerous consequences.

In fact, the descriptor has pretty simple rules. If you have a file descriptor, you can do whatever you want with it.

What about processes? What are the rules there? What can you do with the process? On Unix, this is pretty simple. You can create a process, you can kill it, you can debug it - for it there is a mechanism in Unix called ptrace .



And the rules are relatively simple. That way, you can always create a process, except that the child process will get the same user ID as you, so you cannot create a process with a different default user ID. So you cannot create, for example, a web process using gid for one of the TAs, the operating system kernel simply will not allow you to do this.

If you want to kill a process, you basically need to have the same user ID as this process. All things with one userid are isolated from things with other user IDs. The same rule applies to ptrace - a process with the same uid can debug processes with the same uid .

Actually in the ptrace mechanismLinux had some interesting bugs. For example, if you debug the process, and then it switched and gained more privileges, then you could somehow trick the kernel to retain the debugging privilege for this process, even after it became more privileged. Then you could do something with his memory and capture it for yourself. But in any case, the basic principle of the system is that only processes with the same ID can interact with each other.

27:50 min.

Continuation:

MIT course "Computer systems security". Lecture 4: "Separation of privileges", part 2


Full version of the course is available here .

Thank you for staying with us. Do you like our articles? Want to see more interesting materials? Support us by placing an order or recommending to friends, 30% discount for Habr's users on a unique analogue of the entry-level servers that we invented for you: The whole truth about VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps from $ 20 or how to share the server? (Options are available with RAID1 and RAID10, up to 24 cores and up to 40GB DDR4).

Dell R730xd 2 times cheaper? Only we have 2 x Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 TV from $ 249 in the Netherlands and the USA! Read aboutHow to build the infrastructure of the building. class c using servers Dell R730xd E5-2650 v4 worth 9000 euros for a penny?

Also popular now: