Capsicum and Casper
Zaborski, Mariusz
Capsicum is a sandbox framework in the FreeBSD operating systems and it's based on the capabilities concept. Programs running in a sandbox don't have access to any global namespaces. For some applications this limitation could be too restraining. So how developers handle those exceptions with Capsicum? Capsicum is a lightweight OS capability and sandbox framework implementing a hybrid capability system model. As mentioned before after entering the sandbox we don’t have access to any global namespaces (such as path names, so we can’t open files in a sandbox). The main idea behind Casper is to replace standard libc functions (those which are using global namespaces) with wrappers which allow for using those functions in sandboxed programs in secure and controlled way. When Casper was first implemented it was a daemon in operating system (called casperd(8)). But this implementation created a lot of problems because zygotes inherits all capabilities from the daemon not from the process which will use it. Author recent work was to change Casper architecture. The best way will be forking zygotes from the original process which run it. This is how libcasper was created. The implementation was possible thanks to mechanism like pdfork(2), which allows us to fork inside the other process but without being afraid that it will react with standard wait(2) functions. The talk will cover Capsicum architecture basics and compare it to well known security frameworks such as seccomp and to new models like pledge. The main part of the talk will be presentation of Casper and its architecture. Old one in which Casper is a demon and new one in which we transformed it into a library.
 Okay, so I think we can start. My name is, hello, welcome everybody. My name is Mariusz Zaborski and my presentation will be about Capsicum and Casper and in general about some of the sandboxes frameworks. We will be discussing the problems with the sandboxes tried to solve and also the problems with the create. So like I mentioned, my name is Mariusz Zaborski. I work at Will Systems Company. We are doing cool stuff there. We have two pretty fun appliance, one of which is TLS and SSL decryptor and second is for monitor privilege user sessions. And I'm also a free BSD cometer from this one here. So the plan is first we will discuss do we need sandbox at all. Maybe we don't need a sandbox and we just can go to home and everything is fine. We will be discussing few sandbox methods like second, pledge and Capsicum. And we will be discussing two very interesting projects which was built around the Capsicum, Cloud API and Casper. So I'm working mostly on security and as you can see, working security is really, really dangerous place to work right now. So let's start. So do we need a sandbox? Let's think about some program, very simple program like for example, CAD. If we would find a buffer overflow or any other vulnerability in that program, we would gain access to all our data. Attacker would gain access to all our data. He can read our emails. He would see all our photos. He could even send those photos over the Internet. He could for example start SSHD and look into our computer and so on and so on. Every time when we are talking about such access, unauthorized access when program has access to every other data without any control, we are talking about ambient authority. So do we fight with ambient authority? Not only we are also trying to just mitigate the problems. Like we are trying to solve some problems with different techniques. For example, we develop NX bits which are special bits which you can send on memory page which says that this part of memory cannot be executable and we was trying to mitigate in this way buffer overflows or vulnerabilities. But when we did that, the researchers came out with so-called return-oriented programming which basically means that we are looking for some parts of codes, so-called gadgets in other parts of memory and we built from that our exploit. So mitigations techniques are fine. We should have them but they not solve our problems. They make it only harder to exploit them. So two of my colleagues, Genwal Conwind and Mateusz Jurczyk did a very interesting test of a few of the popular programs and just by fusing. So fusing is technique where you take up some of the valid data which program understands and start to change randomly some data there. Only by that they found like over 1,000 bugs in FMPEG. FMPEG if you don't know it's a very popular video codec. So only by fusing they found over 1,000 bugs. That means that all of those bugs was fixed and I'm not sure secure running FMPEG on my computer just on their operating system because if it has so much in so simple way bugs in finding some simple way, how many does it have at all? Or even if it has like 100 bugs fixed, I'm wondering how many new bugs were created while they was fixed. So I hope I convinced you a little bit that we need sandboxes and they solved some of our problems. So we will look at one of the oldest sandbox which is called Seccom. It was developed for Linux. So Seccom has two types. You can run Seccom in two different modules. One of them is called streak module which allow you for very, very little kind of syscalls like read, write, exit. So when you enter such sandbox you cannot do a lot with that. On the other hand we have filter mode which allows you to define which syscalls in your operating system are allow it. And even it allows you to define which arguments for the syscalls are allow it or not. So this is example of using Seccom. It's example from SSHD. As you can see I truncated it even because there was a lot of more. It's not easy to use that. And there are probably also a lot of, you can do a lot of mistakes while developing such, using such sandbox. But also you need to maintain all this list of syscalls which allow it or disallow it in your program. So developers came out with Leap Seccom which simplifies a little bit the usage of Seccom. But it's still, but it's still you need to maintain all those rules. Seccom is very, very popular use. It was developed in 2005 so it had a lot of time to be widely used. For example, it's used in Chrome or Firefox. So one of the most recently work was done in OpenBSD. It's called the so-called pledge. And pledge is in my opinion very similar to Seccom. Difference that you don't get, you don't need to define all those filters. The authors of pledge did define them for you. They just, you just use one of filters that they give you or multiple of filters. So the idea behind pledge was that every program, every program you can divide into two parts. One which is called initialization phase and second which is the main loop. In its initialization phase, you are just initializing data that you need. So you open some files, you're preparing the environment and so on and so on. And after this phase, there is main loop which are you doing every more complicated or less complicated things in that. So pledge has very simple interface. You can just put the promises, how they called it, into the syscall and you are in the sandbox. And any other syscalls which are not in those promises are done. They also, in their interface, they also had proposed the white path argument which is right now not implemented. But idea behind that is if you define some white path in this pledge call, you can access those files. But like I said before, it's still not implemented. One of how authors like to mention very often pledge is to use it in over 400 programs. So it's used quite widely in OpenBSD project. So we have like 25 promises. Restedisle for example which is very, very popular because it's allowing you some basic operations in your operating system. It also gives you the end air path which allows you to read only or your data on the disk. Others two very interesting promises is INET which allows you to open the sockets to the servers, connect, accept the connection from others. And this is one which I would like you to remember for a moment. And other promises is PRODS and EXIT which allows you to fork and then execute some program. And this also I would like that you remember them for a moment. So this is how the pledge is used in CUT. And as you can see, it's very easy to use. You just need to analyze which promises the program need. So CUT is very simple. It just needs some allocations. This is why the IO promises. And it also needs some access to our disk. This is why the air path promises. And this program sandboxes pretty well. We cannot for example read, we can read arbitrary files from if we would find some vulnerability in CUT but we cannot do a lot of that, a lot of more. We can read, we cannot send those data, we cannot override this data. Things look fine. So here is also the list of some of the bigger programs which are using pledge. We can see even X servers on the list or CISLOGD. But pledge unfortunately have some issue. One of them which is very annoying that if you use PRODS and EXIT promises, then you are started a new process without the sandbox. So you just escape from the sandbox, right? This not feel right in my opinion. Other things is hard coded paths in kernel. There are a lot of them which allows you for example open files like etetze local time or read link from etetze malloc.conf. And this is also a little bit tricky because if you would like to use other library, for example for time zones or other malloc library and it would need to use some other files than those, then you need to patch the kernel to use them. Otherwise maybe instead of doing that maybe you could do the white paths argument but it's still not implemented so you don't have any other choice right now. And I'm not sure if one template is enough for doing all the programs around the operating system. For example, we can imagine, I don't know, mail program which needs to read all our files on the disk. So we need to air path promises. We need to write some files on our disk so we need a vpath promises. And now we are a little bit in problem because it also needs to connect to the server to read data from the server, right? So we could do that in initialization phase and everything works fine but what if we lose this connection? We need to reconnect to this program, right? To the server. So we have two choices or we will leave these premises which allows us to connect to the random servers or we will do the exec and prods solutions which allows us to escape from the sandbox. So we have some sandbox techniques but as you can see it's not allowing us, it's not allowing us from example which I give with CAD that we can still read all our data from the disk and send them over the internet. And I didn't mention that the pledge is used in over 400 programs but even every fourth program so around 100 programs are using the exit and path promises so in my opinion all the 100 programs are not secure and also we need to consider that some of the combinations of promises also don't guarantee us any secure. Okay, so now we will discuss a little bit of Capsicum. So Capsicum we can divide into two parts. One of them is tiny sandbox so when you are running the cup entered which is a Cisco which enables the sandbox, you don't have access to any global namespaces. You cannot read from the disk, you cannot see other programs, you cannot enter to jail, you cannot see jails and so on and so on. You don't have access to any other global namespaces. And another part of Capsicum is capability. So when Capsicum was developed the authors seen that file descriptors are pretty good at managing the right. So they add additional layer to be able to even more limit the descriptors. So we have in Capsicum around 80 capabilities rights which are per descriptor and you can say for example that this descriptor, for example the log descriptor, the descriptor which is the descriptor to the file with log is opened only. That means that even if attacker would break our, break to our process, it still don't have access. He cannot jump to the file and delete for example the language saying that something malicious was on our program. So we can have more standard also rights like cup read or cup write which says just that from this descriptor we can only read or we can only write. So in Capsicum we have two different ways to obtain more capabilities or in general get some capabilities. One of them is to do this in the initialization phase. That means before similar in pledge, like in pledge, if we, before entering the sandbox we just open the files, we open the connection that we need and so on and so on. Other method is by delegation but first I will show you how the Capsicum can be used with initialization phase. So here we have example how the unique program is sandboxed. As you can see it's a little bit harder than in pledge but we have here limited our descriptors. One of them is basically we first check which argument we should limit or this is the IO or we should open some ARC file descriptor. We limit this descriptor and then we just enter to capability mode. As you can see also we check in special way the Erno value because we can have Capsicum compile in the kernel or not. We just need to check if Erno is analysis and if it's not that means that some other error was. So other example of getting more rights in sandboxed process is by using delegation. So we can have some more privilege process which has right to some resources. For example he can read from file system or he can resolve DNS or he have connection to database and so on and so on. And we need to then we for example connect to this such process or we fork from this process and we need to establish some IPC between those process. For example we say that this process when I send you this message you should return me this or this or this. This reduce our TCP because the main problem the main algorithm the most complicated algorithm for example codecs or whatever is still running in the sandbox but the simplest task like giving me the next descriptor to the file or giving me some data from the database is still done in privilege process. So by this we just reduce the TCP that we need to very careful check. So Capsicum is not used very widely unfortunately. It is used in few of the base system tools like before mentioned Unique or TCP dump. It's also used in our package system and we also have a patch for Chromium to sandbox. Yeah but packages also not in place. I mean few of them and then okay. Let's go. So unfortunately Capsicum also have some issues. First of all it's very it has very high barriers to enter. You need to know a lot of things before you enter. You need to know how what are the scripts how they work. You need to know maybe if you are doing the privilege if you're doing the delegation you need to know how to manage the IPC and so on and so on. So it's a little bit harder to start but and unfortunately also it has some troubles for example with LPC. A lot of LPC function is not allowed in capability mode and it's hard sometimes to see at first that this function you cannot do in Capsicum. Maybe you need to change the architecture of your program or do it somehow else. But also some third libraries also are not helping you because if they're using some global namespace you need to know that probably you need to go to source code see if that's if this library is doing something fancy maybe change this in the library or maybe you need to again do the delegation thing. And we also in Capsicum sometimes use some funny magic calls for example here with local time and time which basically means if you first call local time it's cache at its local time.con file. So if you first run the local time before entering the capability mode you fetch the file and you can then in capability mode use multiple local time multiple times. You need to do this call before entering the capability mode. So Capsicum is very, very interesting framework. It's have some issue and it's sometimes hard to use it in programs that are already which are already implemented. Capsicum is very beautiful and very easy to write when you design all the program from beginning to use that Capsicum. So like I mentioned before in Capsicum all you are trying to do is to minimize the part of TCB that you need to review in a secure way. And you need to be sure that this part is quite secure. This is what we are trying to accomplish. Okay, so now I will tell you a little bit about Cloud ABI which is kind of new thing. I believe it has two years maybe. So Cloud ABI is designed for Cloud. Now its name is... The idea behind Cloud ABI is that you can take some arbitrary binary which you would compile before and put it to the server and all the things with this binary is doing is in capability mode. So the files which are created in Cloud ABI are cross-platform. So you can take for example some binary which was compiled on Linux, go to the free BSE and run it with Cloud ABI. So first thing of Cloud ABI is that he has like special running environment. He has special Cloud ABI run and then we gave some binary which we want to give it and then we give a special YAM file which describes what this environment should prepare for our program. It should... If it should open... Here is the list of what YAM files is supported. If it should for example open as some socket or it should open as some directory or maybe some file and so on and so on. These all things can be defined in this YAM file. So the second part of Cloud ABI is the new Lipsy or so-called Cloud Lipsy which removes all not capability-friendly functions like open or stats or weight and so on and allows only the capability-friendly functions like PD-weight or on open app. It also removes all functions which are considered unsecure for example SDR-CP-IGREC which does just copy the data without checking the length of it. So all those files are removed and which we gained from that, all functions was removed and what we gained from that is that when we are compiling our binary we get compilations errors that if this function in our program is not capsicum-friendly. So for example if we would use in our program open SSL or something similar and this open SSL opens for example the random and it's not allowed in capsicum, it's not allowed in capsicum we would get error while compilation time. Then in normal capsicum without Cloud ABI and in pledge or second or whatever all the different sandbox we don't have that. We just need to wait when the code will be executed and check if it's fail or not fail or maybe it works. Okay so Casper was my recent work which I was spending a lot of time on so basic idea of Casper is to provide an API which is sandbox friendly. So we are preparing the functions which will delegate for you some task to external process. So if you want for example resolve DNS or open some files you can ask Casper for do that for you. You don't need to create a separate process because it's very common for example that you need to implement DNS service to resolve the DNS. A lot of program needs that. So Casper is trying to do that for you. So first implementation was the demon approach. It was CasperD. We was using clip and V as EPC. It wasn't changed later. It was divided in four parts. One was the services which I mentioned which are the implementation of all this resolving or open files. The task that should be done for you. There was a Casper file in ETC which provides the list of services which was available in operating system. We had LIPCaspsicum which was just EPC to communicate with Casper. And we had LIPCasper which was the library which was used by services to implement the functionality. So the approach which was taken was that CasperD would start with operating system. It would fork first to create so-called Zygote. It was a very lively process. It didn't use a lot of memory. It didn't have open any descriptors and so on and so on. It was done to be very quickly to fork from it again. So if process needs some services then it's using new domain socket it could connect to the Casper and ask for some services. Then Casper would fork the Zygote and translate one of those Zygotes to the service and then pass the service to the process and Casper could wait for another program, another process to connect and try to ask for another service. This approach unfortunately had a lot of different issues. For example Casper was started in the beginning of the system and it was because he was in the beginning of the operating system and we could have two approaches. Or he could be running a through or he could run a special CasperD user or whatever. Because we didn't know the process which would connect to the Casper from the user A, B or some other user. We couldn't know that. So we had different credentials. This was easy solved because we could send and secure the credentials by unique domain socket and then you set with and set the git functions to change those permissions. This issue was solved. And unfortunately other problems wasn't solved so easy. For example the resource limit or working directory. When Casper was started it was running from the root. The program was in the different directory. If you try to open the file, for example, named mails or whatever, it will try to open the files in the root directory, not in your directory. For different maclabels and different humus, all things should be synchronized between the process and with the CasperD. Other issue, CPU set. If you said that grab should work only on this CPU, yeah, it would work but Casper would work on different CPU. You cannot limit the Casper that way. Another interesting problem is with so-called process substitution which is available in shell. When you use special syntax, you can pass to the program the descriptor to the data that you want to read. So if you would do open in the directory like dfd something, you would duplicate the descriptor which was passed to you by the shell. So here we have example with div. If we would do the cut A and cut B, the data would be on the descriptor 11 and the descriptor 14. If you would just open them, you would duplicate the descriptor and use those. If you delegate such path to the Casper, he doesn't know those descriptors. He was running from the different process. He didn't know what the descriptor 11 and 14 is or he could know and you would leak some private Casper data. And that's not all. He also could change the routing table per process which means that you want to say that this dcp-dump should use this routing table. And Casper, of course, would not use that because he was running from the different process. He didn't know that. And if you, for example, would send Casper, you would ask Casper to resolve DNS for you or doing other stuff, he would not respect this routing table. Because we had a different process which wasn't connected, the only connection was the unix domain socket, it was very hard to audit or key trace such communication between such process. And of course, there was one point of failure. If Casper d would fail in your operating system, then you would most likely not use sandbox. If you maybe will not even notice that Casper is not working and, for example, for months you would not use Casper on sandboxing at all. So one of the solutions which was proposed to do that is to make some special system call or make some special flags to unix domain sockets which allow you to copy all of those credentials, all of the settings from one process to another process. Maybe it should be all the way only by route, but this also didn't solve our problem, we would need to send also the descriptor tables and so on. So this was one of the solutions which was proposed, we didn't go that way. We did go in other direction and before I describe the new solution, I also would like to tell you a little bit about process descriptors. So process descriptors were also created around the capsicum. The main idea behind process descriptors is that when you fork, you not only get the feed to the process, but you also get the descriptors to this process. So you can, for example, KQ pull or select on this process and wait when this process will fail or other stuff. And there is also plan to implement a pedawate which will just wait on this, in this particular descriptor. But what is the most interesting in this for us is that if you end this process descriptor, of course, capsicum friendly because you are using descriptor, you are not using the global pit table, so you can watch the process, what he's doing. What is very interesting is that if wait was called in your program with the minus one argument, which means I don't care which child of mine will fail or give some other signal, I don't care, I just want to fetch the first child that will fail. The PD fork will not, the process with process descriptor will not be in this group. If the process with the process descriptor would fail, it will not be noticed by wait process. Of course, if you're using wait with the pit which was given while forking, you can still do that. So the new architecture was to, we changed the architecture and we decided to fork from the actual process, not like before connecting to the demo. We also reduced from a few of the libraries. We now have just libCasper, which is the EPC between Casper and services, and we have just services. Now, if you want to use some, sorry, if you want to use some Casper services, you need to link them to the library. And what is very interesting also, API didn't change at all. And we managed to solve all of the problems which I described with the previous approach. Now if you fork from the same process, you have the same credentials, you have the same MAC labels and so on and so on and so on. One of the things is that if you call the cap init with forks which create the Casper, it will, if you do that, you cannot change your settings because it will not be propagated to the other process. But this is the limit which we can accept for now. And before you could disable Casper globally. If you didn't want Casper, you just go to the services and disable it and then you would use the process without the cap-sic-comand Casper. Now you don't have that choice. You can change that by recompiling your binary and disable Casper. So now we start from the process. So if you need, if process need Casper, it just call cap init, then Casper is forked and also still use Zygote like before. If process needs some service, it's asking the Casper for that. He clones the Zygote, he creates the service, he pass the service to the process and if Casper is no more needed, it just dies. In this approach, we still have all the flexibility which we had before in previous approach. We still can go and delegate Casper at all to another service. So we can send Casper over a unique domain socket to the other process. So those are actual Ali services in our operating system, for example, which I mentioned before, DNS services which allows you to resolve DNS. You can, or system random which provides you some random numbers or random buffers to your process which is also very interesting. You can limit Casper even further. That means that, for example, if you want to resolve DNS only in IPv4, you can tell Casper to do that. If your program will try to resolve in IPv6, Casper will not allow that. If you want, for example, resolve DNS only in FreeBSD.org and FreeBSD.U or whatever, then you also can tell Casper that those are the domains that you want to resolve now other. So if you have, for example, your name application, you can define that only this E-MAP server can be resolved. So here is how the Casper is used. We need to, like I mentioned before, we need to create first the Casper instance by calling CappInit. Then we open the system DNS service which is done by CappServiceOpen. Then we can limit the service by using CappDNSTypeLimit and CappDNSFamilyLimit. In this example, we are limiting, for example, only to use IPv4 and IPv6. And after that, we also need to change the call from getHosbyName to getHosbyName. As you can see, the interface is very similar to the original. The difference is that only the Casper connection. As you can see here, all the time you need to do the special check. If I'm using Casper, am I compiled with Casper or am I not? If not, use the standard library. If you are using Casper, then use this special call. So which I'm working now, and unfortunately I wasn't able to commit that to 11, is LeapCasperMock which hides all that into the library. So when you will call Capp getHosbyName or getHosbyAdr, it will just know if you are compiling with Casper or not. Inside the library, it will tell you connect to the Casper or do the standard function. So we will reduce the amount of work which is needed to be done to capsicumize the application. That said, we have still some ongoing work. We would like to lower the bar which is needed to use Cappsicum and Casper. As you can see, you need to know a lot of things right now. You need to know also some hacks, for example, which I presented before with local time, which isn't very nicely. We also are working still on system file system which allows you to access the file system namespace to open the files, to create files and so on. I believe I implemented like two or three services like that already. I believe Pavel would have done also at least one. But we have still performance issue which comes from the libNV which we are using right now. But we have our Google Summer of Code student who is working on improving that. But we also would like to improve auditing for Casper because right now if you don't run the code, you will not know if your function will fail or not. And maybe we could do something more to provide you more information if this code will work or not. Okay. So thank you very much. Maybe there are some questions. Please. Yes. If I'm not sure if old B is supporting now the multiprocess debugging or not. So basically if the debugger is supporting the multiprocess debugging, it's fine. You just need to check which process you want to debug. Yes. Is there any new model for Casper which 3DSP is to set it to? It's in 11. Is there any new actual program in 11. Everyone. Everyone which are. Okay. Maybe not everyone. I've been reported to the zoo. Right. So, I'm going to show you some programs which are using Capsicum. So TCP dump and KD dump and pink are using Casper and Capsicum. Yes. So, I'm going to show you some programs which are using Capsicum. I'm going to show you some programs which are using Capsicum. I would also say that I'm not sure we would need to check that to be 100% sure. Are there any other questions? Yes? So basically, it will depend So basically, it will depend on which library did you link. If you would link to the libCasper standard library, then the libraries will know that you are linking to this library, so please use Casper. If you will link to the libCasper mock, then this means you don't want to reall casper and use just the normal instructions. Okay, so thank you very much for your attention and see you guys.
 Okay, so I think we can start.  My name is, hello, welcome everybody.  My name is Mariusz Zaborski and my presentation will be about Capsicum and Casper and in general  about some of the sandboxes frameworks.  We will be discussing the problems with the sandboxes tried to solve and also the problems  with the create.  So like I mentioned, my name is Mariusz Zaborski.  I work at Will Systems Company.  We are doing cool stuff there.  We have two pretty fun appliance, one of which is TLS and SSL decryptor and second is for  monitor privilege user sessions.  And I'm also a free BSD cometer from this one here.  So the plan is first we will discuss do we need sandbox at all.  Maybe we don't need a sandbox and we just can go to home and everything is fine.  We will be discussing few sandbox methods like second, pledge and Capsicum.  And we will be discussing two very interesting projects which was built around the Capsicum,  Cloud API and Casper.  So I'm working mostly on security and as you can see, working security is really, really  dangerous place to work right now.  So let's start.  So do we need a sandbox?  Let's think about some program, very simple program like for example, CAD.  If we would find a buffer overflow or any other vulnerability in that program, we would  gain access to all our data.  Attacker would gain access to all our data.  He can read our emails.  He would see all our photos.  He could even send those photos over the Internet.  He could for example start SSHD and look into our computer and so on and so on.  Every time when we are talking about such access, unauthorized access when program has  access to every other data without any control, we are talking about ambient authority.  So do we fight with ambient authority?  Not only we are also trying to just mitigate the problems.  Like we are trying to solve some problems with different techniques.  For example, we develop NX bits which are special bits which you can send on memory  page which says that this part of memory cannot be executable and we was trying to mitigate  in this way buffer overflows or vulnerabilities.  But when we did that, the researchers came out with so-called return-oriented programming  which basically means that we are looking for some parts of codes, so-called gadgets  in other parts of memory and we built from that our exploit.  So mitigations techniques are fine.  We should have them but they not solve our problems.  They make it only harder to exploit them.  So two of my colleagues, Genwal Conwind and Mateusz Jurczyk did a very interesting test  of a few of the popular programs and just by fusing.  So fusing is technique where you take up some of the valid data which program understands  and start to change randomly some data there.  Only by that they found like over 1,000 bugs in FMPEG.  FMPEG if you don't know it's a very popular video codec.  So only by fusing they found over 1,000 bugs.  That means that all of those bugs was fixed and I'm not sure secure running FMPEG on my  computer just on their operating system because if it has so much in so simple way bugs in  finding some simple way, how many does it have at all?  Or even if it has like 100 bugs fixed, I'm wondering how many new bugs were created while  they was fixed.  So I hope I convinced you a little bit that we need sandboxes and they solved some of  our problems.  So we will look at one of the oldest sandbox which is called Seccom.  It was developed for Linux.  So Seccom has two types.  You can run Seccom in two different modules.  One of them is called streak module which allow you for very, very little kind of syscalls  like read, write, exit.  So when you enter such sandbox you cannot do a lot with that.  On the other hand we have filter mode which allows you to define which syscalls in your  operating system are allow it.  And even it allows you to define which arguments for the syscalls are allow it or not.  So this is example of using Seccom.  It's example from SSHD.  As you can see I truncated it even because there was a lot of more.  It's not easy to use that.  And there are probably also a lot of, you can do a lot of mistakes while developing such,  using such sandbox.  But also you need to maintain all this list of syscalls which allow it or disallow it  in your program.  So developers came out with Leap Seccom which simplifies a little bit the usage of Seccom.  But it's still, but it's still you need to maintain all those rules.  Seccom is very, very popular use.  It was developed in 2005 so it had a lot of time to be widely used.  For example, it's used in Chrome or Firefox.  So one of the most recently work was done in OpenBSD.  It's called the so-called pledge.  And pledge is in my opinion very similar to Seccom.  Difference that you don't get, you don't need to define all those filters.  The authors of pledge did define them for you.  They just, you just use one of filters that they give you or multiple of filters.  So the idea behind pledge was that every program, every program you can divide into two parts.  One which is called initialization phase and second which is the main loop.  In its initialization phase, you are just initializing data that you need.  So you open some files, you're preparing the environment and so on and so on.  And after this phase, there is main loop which are you doing every more complicated or less  complicated things in that.  So pledge has very simple interface.  You can just put the promises, how they called it, into the syscall and you are in the sandbox.  And any other syscalls which are not in those promises are done.  They also, in their interface, they also had proposed the white path argument which is  right now not implemented.  But idea behind that is if you define some white path in this pledge call, you can access  those files.  But like I said before, it's still not implemented.  One of how authors like to mention very often pledge is to use it in over 400 programs.  So it's used quite widely in OpenBSD project.  So we have like 25 promises.  Restedisle for example which is very, very popular because it's allowing you some basic  operations in your operating system.  It also gives you the end air path which allows you to read only or your data on the disk.  Others two very interesting promises is INET which allows you to open the sockets to the  servers, connect, accept the connection from others.  And this is one which I would like you to remember for a moment.  And other promises is PRODS and EXIT which allows you to fork and then execute some program.  And this also I would like that you remember them for a moment.  So this is how the pledge is used in CUT.  And as you can see, it's very easy to use.  You just need to analyze which promises the program need.  So CUT is very simple.  It just needs some allocations.  This is why the IO promises.  And it also needs some access to our disk.  This is why the air path promises.  And this program sandboxes pretty well.  We cannot for example read, we can read arbitrary files from if we would find some vulnerability  in CUT but we cannot do a lot of that, a lot of more.  We can read, we cannot send those data, we cannot override this data.  Things look fine.  So here is also the list of some of the bigger programs which are using pledge.  We can see even X servers on the list or CISLOGD.  But pledge unfortunately have some issue.  One of them which is very annoying that if you use PRODS and EXIT promises, then you  are started a new process without the sandbox.  So you just escape from the sandbox, right?  This not feel right in my opinion.  Other things is hard coded paths in kernel.  There are a lot of them which allows you for example open files like etetze local time  or read link from etetze malloc.conf.  And this is also a little bit tricky because if you would like to use other library, for  example for time zones or other malloc library and it would need to use some other files  than those, then you need to patch the kernel to use them.  Otherwise maybe instead of doing that maybe you could do the white paths argument but  it's still not implemented so you don't have any other choice right now.  And I'm not sure if one template is enough for doing all the programs around the operating  system.  For example, we can imagine, I don't know, mail program which needs to read all our files  on the disk.  So we need to air path promises.  We need to write some files on our disk so we need a vpath promises.  And now we are a little bit in problem because it also needs to connect to the server to  read data from the server, right?  So we could do that in initialization phase and everything works fine but what if we lose  this connection?  We need to reconnect to this program, right?  To the server.  So we have two choices or we will leave these premises which allows us to connect to the  random servers or we will do the exec and prods solutions which allows us to escape from the  sandbox.  So we have some sandbox techniques but as you can see it's not allowing us, it's not  allowing us from example which I give with CAD that we can still read all our data from  the disk and send them over the internet.  And I didn't mention that the pledge is used in over 400 programs but even every fourth  program so around 100 programs are using the exit and path promises so in my opinion all  the 100 programs are not secure and also we need to consider that some of the combinations  of promises also don't guarantee us any secure.  Okay, so now we will discuss a little bit of Capsicum.  So Capsicum we can divide into two parts.  One of them is tiny sandbox so when you are running the cup entered which is a Cisco  which enables the sandbox, you don't have access to any global namespaces.  You cannot read from the disk, you cannot see other programs, you cannot enter to jail,  you cannot see jails and so on and so on.  You don't have access to any other global namespaces.  And another part of Capsicum is capability.  So when Capsicum was developed the authors seen that file descriptors are pretty good  at managing the right.  So they add additional layer to be able to even more limit the descriptors.  So we have in Capsicum around 80 capabilities rights which are per descriptor and you can  say for example that this descriptor, for example the log descriptor, the descriptor  which is the descriptor to the file with log is opened only.  That means that even if attacker would break our, break to our process, it still don't  have access.  He cannot jump to the file and delete for example the language saying that something  malicious was on our program.  So we can have more standard also rights like cup read or cup write which says just that  from this descriptor we can only read or we can only write.  So in Capsicum we have two different ways to obtain more capabilities or in general  get some capabilities.  One of them is to do this in the initialization phase.  That means before similar in pledge, like in pledge, if we, before entering the sandbox  we just open the files, we open the connection that we need and so on and so on.  Other method is by delegation but first I will show you how the Capsicum can be used  with initialization phase.  So here we have example how the unique program is sandboxed.  As you can see it's a little bit harder than in pledge but we have here limited our descriptors.  One of them is basically we first check which argument we should limit or this is the IO  or we should open some ARC file descriptor.  We limit this descriptor and then we just enter to capability mode.  As you can see also we check in special way the Erno value because we can have Capsicum  compile in the kernel or not.  We just need to check if Erno is analysis and if it's not that means that some other  error was.  So other example of getting more rights in sandboxed process is by using delegation.  So we can have some more privilege process which has right to some resources.  For example he can read from file system or he can resolve DNS or he have connection  to database and so on and so on.  And we need to then we for example connect to this such process or we fork from this  process and we need to establish some IPC between those process.  For example we say that this process when I send you this message you should return  me this or this or this.  This reduce our TCP because the main problem the main algorithm the most complicated algorithm  for example codecs or whatever is still running in the sandbox but the simplest task like  giving me the next descriptor to the file or giving me some data from the database is  still done in privilege process.  So by this we just reduce the TCP that we need to very careful check.  So Capsicum is not used very widely unfortunately.  It is used in few of the base system tools like before mentioned Unique or TCP dump.  It's also used in our package system and we also have a patch for Chromium to sandbox.  Yeah but packages also not in place.  I mean few of them and then okay.  Let's go.  So unfortunately Capsicum also have some issues.  First of all it's very it has very high barriers to enter.  You need to know a lot of things before you enter.  You need to know how what are the scripts how they work.  You need to know maybe if you are doing the privilege if you're doing the delegation you  need to know how to manage the IPC and so on and so on.  So it's a little bit harder to start but and unfortunately also it has some troubles for  example with LPC.  A lot of LPC function is not allowed in capability mode and it's hard sometimes to see at first  that this function you cannot do in Capsicum.  Maybe you need to change the architecture of your program or do it somehow else.  But also some third libraries also are not helping you because if they're using some  global namespace you need to know that probably you need to go to source code see if that's  if this library is doing something fancy maybe change this in the library or maybe you need  to again do the delegation thing.  And we also in Capsicum sometimes use some funny magic calls for example here with local  time and time which basically means if you first call local time it's cache at its local  time.con file.  So if you first run the local time before entering the capability mode you fetch the  file and you can then in capability mode use multiple local time multiple times.  You need to do this call before entering the capability mode.  So Capsicum is very, very interesting framework.  It's have some issue and it's sometimes hard to use it in programs that are already which  are already implemented.  Capsicum is very beautiful and very easy to write when you design all the program from  beginning to use that Capsicum.  So like I mentioned before in Capsicum all you are trying to do is to minimize the part  of TCB that you need to review in a secure way.  And you need to be sure that this part is quite secure.  This is what we are trying to accomplish.  Okay, so now I will tell you a little bit about Cloud ABI which is kind of new thing.  I believe it has two years maybe.  So Cloud ABI is designed for Cloud.  Now its name is...  The idea behind Cloud ABI is that you can take some arbitrary binary which you would  compile before and put it to the server and all the things with this binary is doing is  in capability mode.  So the files which are created in Cloud ABI are cross-platform.  So you can take for example some binary which was compiled on Linux, go to the free BSE  and run it with Cloud ABI.  So first thing of Cloud ABI is that he has like special running environment.  He has special Cloud ABI run and then we gave some binary which we want to give it and then  we give a special YAM file which describes what this environment should prepare for our  program.  It should...  If it should open...  Here is the list of what YAM files is supported.  If it should for example open as some socket or it should open as some directory or maybe  some file and so on and so on.  These all things can be defined in this YAM file.  So the second part of Cloud ABI is the new Lipsy or so-called Cloud Lipsy which removes  all not capability-friendly functions like open or stats or weight and so on and allows  only the capability-friendly functions like PD-weight or on open app.  It also removes all functions which are considered unsecure for example SDR-CP-IGREC which does  just copy the data without checking the length of it.  So all those files are removed and which we gained from that, all functions was removed  and what we gained from that is that when we are compiling our binary we get compilations  errors that if this function in our program is not capsicum-friendly.  So for example if we would use in our program open SSL or something similar and this open  SSL opens for example the random and it's not allowed in capsicum, it's not allowed  in capsicum we would get error while compilation time.  Then in normal capsicum without Cloud ABI and in pledge or second or whatever all the  different sandbox we don't have that.  We just need to wait when the code will be executed and check if it's fail or not fail  or maybe it works.  Okay so Casper was my recent work which I was spending a lot of time on so basic idea  of Casper is to provide an API which is sandbox friendly.  So we are preparing the functions which will delegate for you some task to external process.  So if you want for example resolve DNS or open some files you can ask Casper for do  that for you.  You don't need to create a separate process because it's very common for example that  you need to implement DNS service to resolve the DNS.  A lot of program needs that.  So Casper is trying to do that for you.  So first implementation was the demon approach.  It was CasperD.  We was using clip and V as EPC.  It wasn't changed later.  It was divided in four parts.  One was the services which I mentioned which are the implementation of all this resolving  or open files.  The task that should be done for you.  There was a Casper file in ETC which provides the list of services which was available in  operating system.  We had LIPCaspsicum which was just EPC to communicate with Casper.  And we had LIPCasper which was the library which was used by services to implement the  functionality.  So the approach which was taken was that CasperD would start with operating system.  It would fork first to create so-called Zygote.  It was a very lively process.  It didn't use a lot of memory.  It didn't have open any descriptors and so on and so on.  It was done to be very quickly to fork from it again.  So if process needs some services then it's using new domain socket it could connect to  the Casper and ask for some services.  Then Casper would fork the Zygote and translate one of those Zygotes to the service and then  pass the service to the process and Casper could wait for another program, another process  to connect and try to ask for another service.  This approach unfortunately had a lot of different issues.  For example Casper was started in the beginning of the system and it was because he was in  the beginning of the operating system and we could have two approaches.  Or he could be running a through or he could run a special CasperD user or whatever.  Because we didn't know the process which would connect to the Casper from the user  A, B or some other user.  We couldn't know that.  So we had different credentials.  This was easy solved because we could send and secure the credentials by unique domain  socket and then you set with and set the git functions to change those permissions.  This issue was solved.  And unfortunately other problems wasn't solved so easy.  For example the resource limit or working directory.  When Casper was started it was running from the root.  The program was in the different directory.  If you try to open the file, for example, named mails or whatever, it will try to open  the files in the root directory, not in your directory.  For different maclabels and different humus, all things should be synchronized between  the process and with the CasperD.  Other issue, CPU set.  If you said that grab should work only on this CPU, yeah, it would work but Casper would  work on different CPU.  You cannot limit the Casper that way.  Another interesting problem is with so-called process substitution which is available in  shell.  When you use special syntax, you can pass to the program the descriptor to the data that  you want to read.  So if you would do open in the directory like dfd something, you would duplicate the descriptor  which was passed to you by the shell.  So here we have example with div.  If we would do the cut A and cut B, the data would be on the descriptor 11 and the descriptor  14.  If you would just open them, you would duplicate the descriptor and use those.  If you delegate such path to the Casper, he doesn't know those descriptors.  He was running from the different process.  He didn't know what the descriptor 11 and 14 is or he could know and you would leak some  private Casper data.  And that's not all.  He also could change the routing table per process which means that you want to say that  this dcp-dump should use this routing table.  And Casper, of course, would not use that because he was running from the different  process.  He didn't know that.  And if you, for example, would send Casper, you would ask Casper to resolve DNS for you  or doing other stuff, he would not respect this routing table.  Because we had a different process which wasn't connected, the only connection was the unix  domain socket, it was very hard to audit or key trace such communication between such  process.  And of course, there was one point of failure.  If Casper d would fail in your operating system, then you would most likely not use sandbox.  If you maybe will not even notice that Casper is not working and, for example, for months  you would not use Casper on sandboxing at all.  So one of the solutions which was proposed to do that is to make some special system  call or make some special flags to unix domain sockets which allow you to copy all of those  credentials, all of the settings from one process to another process.  Maybe it should be all the way only by route, but this also didn't solve our problem, we  would need to send also the descriptor tables and so on.  So this was one of the solutions which was proposed, we didn't go that way.  We did go in other direction and before I describe the new solution, I also would like  to tell you a little bit about process descriptors.  So process descriptors were also created around the capsicum.  The main idea behind process descriptors is that when you fork, you not only get the  feed to the process, but you also get the descriptors to this process.  So you can, for example, KQ pull or select on this process and wait when this process  will fail or other stuff.  And there is also plan to implement a pedawate which will just wait on this, in this particular  descriptor.  But what is the most interesting in this for us is that if you end this process descriptor,  of course, capsicum friendly because you are using descriptor, you are not using the global  pit table, so you can watch the process, what he's doing.  What is very interesting is that if wait was called in your program with the minus one  argument, which means I don't care which child of mine will fail or give some other signal,  I don't care, I just want to fetch the first child that will fail.  The PD fork will not, the process with process descriptor will not be in this group.  If the process with the process descriptor would fail, it will not be noticed by wait  process.  Of course, if you're using wait with the pit which was given while forking, you can still  do that.  So the new architecture was to, we changed the architecture and we decided to fork from  the actual process, not like before connecting to the demo.  We also reduced from a few of the libraries.  We now have just libCasper, which is the EPC between Casper and services, and we have just  services.  Now, if you want to use some, sorry, if you want to use some Casper services, you need  to link them to the library.  And what is very interesting also, API didn't change at all.  And we managed to solve all of the problems which I described with the previous approach.  Now if you fork from the same process, you have the same credentials, you have the same  MAC labels and so on and so on and so on.  One of the things is that if you call the cap init with forks which create the Casper,  it will, if you do that, you cannot change your settings because it will not be propagated  to the other process.  But this is the limit which we can accept for now.  And before you could disable Casper globally.  If you didn't want Casper, you just go to the services and disable it and then you would  use the process without the cap-sic-comand Casper.  Now you don't have that choice.  You can change that by recompiling your binary and disable Casper.  So now we start from the process.  So if you need, if process need Casper, it just call cap init, then Casper is forked  and also still use Zygote like before.  If process needs some service, it's asking the Casper for that.  He clones the Zygote, he creates the service, he pass the service to the process and if Casper  is no more needed, it just dies.  In this approach, we still have all the flexibility which we had before in previous approach.  We still can go and delegate Casper at all to another service.  So we can send Casper over a unique domain socket to the other process.  So those are actual Ali services in our operating system, for example, which I mentioned before,  DNS services which allows you to resolve DNS.  You can, or system random which provides you some random numbers or random buffers to your  process which is also very interesting.  You can limit Casper even further.  That means that, for example, if you want to resolve DNS only in IPv4, you can tell Casper  to do that.  If your program will try to resolve in IPv6, Casper will not allow that.  If you want, for example, resolve DNS only in FreeBSD.org and FreeBSD.U or whatever, then  you also can tell Casper that those are the domains that you want to resolve now other.  So if you have, for example, your name application, you can define that only this E-MAP server  can be resolved.  So here is how the Casper is used.  We need to, like I mentioned before, we need to create first the Casper instance by calling  CappInit.  Then we open the system DNS service which is done by CappServiceOpen.  Then we can limit the service by using CappDNSTypeLimit and CappDNSFamilyLimit.  In this example, we are limiting, for example, only to use IPv4 and IPv6.  And after that, we also need to change the call from getHosbyName to getHosbyName.  As you can see, the interface is very similar to the original.  The difference is that only the Casper connection.  As you can see here, all the time you need to do the special check.  If I'm using Casper, am I compiled with Casper or am I not?  If not, use the standard library.  If you are using Casper, then use this special call.  So which I'm working now, and unfortunately I wasn't able to commit that to 11, is LeapCasperMock  which hides all that into the library.  So when you will call Capp getHosbyName or getHosbyAdr, it will just know if you are  compiling with Casper or not.  Inside the library, it will tell you connect to the Casper or do the standard function.  So we will reduce the amount of work which is needed to be done to capsicumize the application.  That said, we have still some ongoing work.  We would like to lower the bar which is needed to use Cappsicum and Casper.  As you can see, you need to know a lot of things right now.  You need to know also some hacks, for example, which I presented before with local time,  which isn't very nicely.  We also are working still on system file system which allows you to access the file system  namespace to open the files, to create files and so on.  I believe I implemented like two or three services like that already.  I believe Pavel would have done also at least one.  But we have still performance issue which comes from the libNV which we are using right  now.  But we have our Google Summer of Code student who is working on improving that.  But we also would like to improve auditing for Casper because right now if you don't  run the code, you will not know if your function will fail or not.  And maybe we could do something more to provide you more information if this code will work  or not.  Okay.  So thank you very much.  Maybe there are some questions.  Please.  Yes.  If I'm not sure if old B is supporting now the multiprocess debugging or not.  So basically if the debugger is supporting the multiprocess debugging, it's fine.  You just need to check which process you want to debug.  Yes.  Is there any new model for Casper which 3DSP is to set it to?  It's in 11.  Is there any new actual program in 11.  Everyone.  Everyone which are.  Okay.  Maybe not everyone.  I've been reported to the zoo.  Right.  So, I'm going to show you some programs which are using Capsicum.  So TCP dump and KD dump and pink are using Casper and Capsicum.  Yes.  So, I'm going to show you some programs which are using Capsicum.  I'm going to show you some programs which are using Capsicum.  I would also say that I'm not sure we would need to check that to be 100% sure.  Are there any other questions?  Yes?  So basically, it will depend  So basically, it will depend on which library did you link.  If you would link to the libCasper standard library, then the libraries will know that  you are linking to this library, so please use Casper.  If you will link to the libCasper mock, then this means you don't want to reall casper  and use just the normal instructions.  Okay, so thank you very much for your attention and see you guys.
Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_0_47.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_48_107.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_108_155.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_156_719.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_720_1463.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_1464_2627.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_2628_2819.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_2820_3611.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_3612_3995.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_3996_5483.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_5484_7583.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_7584_7931.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_7932_9167.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_9168_10103.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_10104_10547.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_10548_10895.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_10896_11159.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_11160_14387.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_14388_15911.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_15912_17207.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_17208_17555.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_17556_22427.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_22428_22535.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_22536_24179.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_24180_25451.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_25452_26279.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_26280_27335.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_27336_28055.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_28056_30275.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_30276_31007.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_31008_31055.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_31056_31283.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_31284_35387.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_35388_35963.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_35964_36239.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_36240_38195.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_38196_38687.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_38688_41519.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_41520_41723.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_41724_42803.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_42804_44315.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_44316_44555.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_44556_45035.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_45036_45467.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_45468_45635.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_45636_46007.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_46008_48779.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_48780_50903.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_50904_52943.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_52944_54011.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_54012_56903.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_56904_58151.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_58152_59987.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_59988_60155.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_60156_60251.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_60252_60455.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_60456_60575.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_60576_60635.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_60636_61391.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_61392_63299.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_63300_64223.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_64224_64775.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_64776_66347.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_66348_68687.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_68688_70139.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_70140_70187.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_70188_70235.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_70236_70283.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_70284_70331.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_70332_73835.png Capsicum_and_Casper_fairy_tale_about_solving_secur_60HqpCvZaMA_73836_73851.png
Okay, so I think we can start. My name is, hello, welcome everybody. My name is Mariusz Zaborski and my presentation will be about Capsicum and Casper and in general about some of the sandboxes frameworks. We will be discussing the problems with the sandboxes tried to solve and also the problems with the create. So like I mentioned, my name is Mariusz Zaborski. I work at Will Systems Company. We are doing cool stuff there. We have two pretty fun appliance, one of which is TLS and SSL decryptor and second is for monitor privilege user sessions. And I'm also a free BSD cometer from this one here. So the plan is first we will discuss do we need sandbox at all. Maybe we don't need a sandbox and we just can go to home and everything is fine. We will be discussing few sandbox methods like second, pledge and Capsicum. And we will be discussing two very interesting projects which was built around the Capsicum, Cloud API and Casper. So I'm working mostly on security and as you can see, working security is really, really dangerous place to work right now. So let's start. So do we need a sandbox? Let's think about some program, very simple program like for example, CAD. If we would find a buffer overflow or any other vulnerability in that program, we would gain access to all our data. Attacker would gain access to all our data. He can read our emails. He would see all our photos. He could even send those photos over the Internet. He could for example start SSHD and look into our computer and so on and so on. Every time when we are talking about such access, unauthorized access when program has access to every other data without any control, we are talking about ambient authority. So do we fight with ambient authority? Not only we are also trying to just mitigate the problems. Like we are trying to solve some problems with different techniques. For example, we develop NX bits which are special bits which you can send on memory page which says that this part of memory cannot be executable and we was trying to mitigate in this way buffer overflows or vulnerabilities. But when we did that, the researchers came out with so-called return-oriented programming which basically means that we are looking for some parts of codes, so-called gadgets in other parts of memory and we built from that our exploit. So mitigations techniques are fine. We should have them but they not solve our problems. They make it only harder to exploit them. So two of my colleagues, Genwal Conwind and Mateusz Jurczyk did a very interesting test of a few of the popular programs and just by fusing. So fusing is technique where you take up some of the valid data which program understands and start to change randomly some data there. Only by that they found like over 1,000 bugs in FMPEG. FMPEG if you don't know it's a very popular video codec. So only by fusing they found over 1,000 bugs. That means that all of those bugs was fixed and I'm not sure secure running FMPEG on my computer just on their operating system because if it has so much in so simple way bugs in finding some simple way, how many does it have at all? Or even if it has like 100 bugs fixed, I'm wondering how many new bugs were created while they was fixed. So I hope I convinced you a little bit that we need sandboxes and they solved some of our problems. So we will look at one of the oldest sandbox which is called Seccom. It was developed for Linux. So Seccom has two types. You can run Seccom in two different modules. One of them is called streak module which allow you for very, very little kind of syscalls like read, write, exit. So when you enter such sandbox you cannot do a lot with that. On the other hand we have filter mode which allows you to define which syscalls in your operating system are allow it. And even it allows you to define which arguments for the syscalls are allow it or not. So this is example of using Seccom. It's example from SSHD. As you can see I truncated it even because there was a lot of more. It's not easy to use that. And there are probably also a lot of, you can do a lot of mistakes while developing such, using such sandbox. But also you need to maintain all this list of syscalls which allow it or disallow it in your program. So developers came out with Leap Seccom which simplifies a little bit the usage of Seccom. But it's still, but it's still you need to maintain all those rules. Seccom is very, very popular use. It was developed in 2005 so it had a lot of time to be widely used. For example, it's used in Chrome or Firefox. So one of the most recently work was done in OpenBSD. It's called the so-called pledge. And pledge is in my opinion very similar to Seccom. Difference that you don't get, you don't need to define all those filters. The authors of pledge did define them for you. They just, you just use one of filters that they give you or multiple of filters. So the idea behind pledge was that every program, every program you can divide into two parts. One which is called initialization phase and second which is the main loop. In its initialization phase, you are just initializing data that you need. So you open some files, you're preparing the environment and so on and so on. And after this phase, there is main loop which are you doing every more complicated or less complicated things in that. So pledge has very simple interface. You can just put the promises, how they called it, into the syscall and you are in the sandbox. And any other syscalls which are not in those promises are done. They also, in their interface, they also had proposed the white path argument which is right now not implemented. But idea behind that is if you define some white path in this pledge call, you can access those files. But like I said before, it's still not implemented. One of how authors like to mention very often pledge is to use it in over 400 programs. So it's used quite widely in OpenBSD project. So we have like 25 promises. Restedisle for example which is very, very popular because it's allowing you some basic operations in your operating system. It also gives you the end air path which allows you to read only or your data on the disk. Others two very interesting promises is INET which allows you to open the sockets to the servers, connect, accept the connection from others. And this is one which I would like you to remember for a moment. And other promises is PRODS and EXIT which allows you to fork and then execute some program. And this also I would like that you remember them for a moment. So this is how the pledge is used in CUT. And as you can see, it's very easy to use. You just need to analyze which promises the program need. So CUT is very simple. It just needs some allocations. This is why the IO promises. And it also needs some access to our disk. This is why the air path promises. And this program sandboxes pretty well. We cannot for example read, we can read arbitrary files from if we would find some vulnerability in CUT but we cannot do a lot of that, a lot of more. We can read, we cannot send those data, we cannot override this data. Things look fine. So here is also the list of some of the bigger programs which are using pledge. We can see even X servers on the list or CISLOGD. But pledge unfortunately have some issue. One of them which is very annoying that if you use PRODS and EXIT promises, then you are started a new process without the sandbox. So you just escape from the sandbox, right? This not feel right in my opinion. Other things is hard coded paths in kernel. There are a lot of them which allows you for example open files like etetze local time or read link from etetze malloc.conf. And this is also a little bit tricky because if you would like to use other library, for example for time zones or other malloc library and it would need to use some other files than those, then you need to patch the kernel to use them. Otherwise maybe instead of doing that maybe you could do the white paths argument but it's still not implemented so you don't have any other choice right now. And I'm not sure if one template is enough for doing all the programs around the operating system. For example, we can imagine, I don't know, mail program which needs to read all our files on the disk. So we need to air path promises. We need to write some files on our disk so we need a vpath promises. And now we are a little bit in problem because it also needs to connect to the server to read data from the server, right? So we could do that in initialization phase and everything works fine but what if we lose this connection? We need to reconnect to this program, right? To the server. So we have two choices or we will leave these premises which allows us to connect to the random servers or we will do the exec and prods solutions which allows us to escape from the sandbox. So we have some sandbox techniques but as you can see it's not allowing us, it's not allowing us from example which I give with CAD that we can still read all our data from the disk and send them over the internet. And I didn't mention that the pledge is used in over 400 programs but even every fourth program so around 100 programs are using the exit and path promises so in my opinion all the 100 programs are not secure and also we need to consider that some of the combinations of promises also don't guarantee us any secure. Okay, so now we will discuss a little bit of Capsicum. So Capsicum we can divide into two parts. One of them is tiny sandbox so when you are running the cup entered which is a Cisco which enables the sandbox, you don't have access to any global namespaces. You cannot read from the disk, you cannot see other programs, you cannot enter to jail, you cannot see jails and so on and so on. You don't have access to any other global namespaces. And another part of Capsicum is capability. So when Capsicum was developed the authors seen that file descriptors are pretty good at managing the right. So they add additional layer to be able to even more limit the descriptors. So we have in Capsicum around 80 capabilities rights which are per descriptor and you can say for example that this descriptor, for example the log descriptor, the descriptor which is the descriptor to the file with log is opened only. That means that even if attacker would break our, break to our process, it still don't have access. He cannot jump to the file and delete for example the language saying that something malicious was on our program. So we can have more standard also rights like cup read or cup write which says just that from this descriptor we can only read or we can only write. So in Capsicum we have two different ways to obtain more capabilities or in general get some capabilities. One of them is to do this in the initialization phase. That means before similar in pledge, like in pledge, if we, before entering the sandbox we just open the files, we open the connection that we need and so on and so on. Other method is by delegation but first I will show you how the Capsicum can be used with initialization phase. So here we have example how the unique program is sandboxed. As you can see it's a little bit harder than in pledge but we have here limited our descriptors. One of them is basically we first check which argument we should limit or this is the IO or we should open some ARC file descriptor. We limit this descriptor and then we just enter to capability mode. As you can see also we check in special way the Erno value because we can have Capsicum compile in the kernel or not. We just need to check if Erno is analysis and if it's not that means that some other error was. So other example of getting more rights in sandboxed process is by using delegation. So we can have some more privilege process which has right to some resources. For example he can read from file system or he can resolve DNS or he have connection to database and so on and so on. And we need to then we for example connect to this such process or we fork from this process and we need to establish some IPC between those process. For example we say that this process when I send you this message you should return me this or this or this. This reduce our TCP because the main problem the main algorithm the most complicated algorithm for example codecs or whatever is still running in the sandbox but the simplest task like giving me the next descriptor to the file or giving me some data from the database is still done in privilege process. So by this we just reduce the TCP that we need to very careful check. So Capsicum is not used very widely unfortunately. It is used in few of the base system tools like before mentioned Unique or TCP dump. It's also used in our package system and we also have a patch for Chromium to sandbox. Yeah but packages also not in place. I mean few of them and then okay. Let's go. So unfortunately Capsicum also have some issues. First of all it's very it has very high barriers to enter. You need to know a lot of things before you enter. You need to know how what are the scripts how they work. You need to know maybe if you are doing the privilege if you're doing the delegation you need to know how to manage the IPC and so on and so on. So it's a little bit harder to start but and unfortunately also it has some troubles for example with LPC. A lot of LPC function is not allowed in capability mode and it's hard sometimes to see at first that this function you cannot do in Capsicum. Maybe you need to change the architecture of your program or do it somehow else. But also some third libraries also are not helping you because if they're using some global namespace you need to know that probably you need to go to source code see if that's if this library is doing something fancy maybe change this in the library or maybe you need to again do the delegation thing. And we also in Capsicum sometimes use some funny magic calls for example here with local time and time which basically means if you first call local time it's cache at its local time.con file. So if you first run the local time before entering the capability mode you fetch the file and you can then in capability mode use multiple local time multiple times. You need to do this call before entering the capability mode. So Capsicum is very, very interesting framework. It's have some issue and it's sometimes hard to use it in programs that are already which are already implemented. Capsicum is very beautiful and very easy to write when you design all the program from beginning to use that Capsicum. So like I mentioned before in Capsicum all you are trying to do is to minimize the part of TCB that you need to review in a secure way. And you need to be sure that this part is quite secure. This is what we are trying to accomplish. Okay, so now I will tell you a little bit about Cloud ABI which is kind of new thing. I believe it has two years maybe. So Cloud ABI is designed for Cloud. Now its name is... The idea behind Cloud ABI is that you can take some arbitrary binary which you would compile before and put it to the server and all the things with this binary is doing is in capability mode. So the files which are created in Cloud ABI are cross-platform. So you can take for example some binary which was compiled on Linux, go to the free BSE and run it with Cloud ABI. So first thing of Cloud ABI is that he has like special running environment. He has special Cloud ABI run and then we gave some binary which we want to give it and then we give a special YAM file which describes what this environment should prepare for our program. It should... If it should open... Here is the list of what YAM files is supported. If it should for example open as some socket or it should open as some directory or maybe some file and so on and so on. These all things can be defined in this YAM file. So the second part of Cloud ABI is the new Lipsy or so-called Cloud Lipsy which removes all not capability-friendly functions like open or stats or weight and so on and allows only the capability-friendly functions like PD-weight or on open app. It also removes all functions which are considered unsecure for example SDR-CP-IGREC which does just copy the data without checking the length of it. So all those files are removed and which we gained from that, all functions was removed and what we gained from that is that when we are compiling our binary we get compilations errors that if this function in our program is not capsicum-friendly. So for example if we would use in our program open SSL or something similar and this open SSL opens for example the random and it's not allowed in capsicum, it's not allowed in capsicum we would get error while compilation time. Then in normal capsicum without Cloud ABI and in pledge or second or whatever all the different sandbox we don't have that. We just need to wait when the code will be executed and check if it's fail or not fail or maybe it works. Okay so Casper was my recent work which I was spending a lot of time on so basic idea of Casper is to provide an API which is sandbox friendly. So we are preparing the functions which will delegate for you some task to external process. So if you want for example resolve DNS or open some files you can ask Casper for do that for you. You don't need to create a separate process because it's very common for example that you need to implement DNS service to resolve the DNS. A lot of program needs that. So Casper is trying to do that for you. So first implementation was the demon approach. It was CasperD. We was using clip and V as EPC. It wasn't changed later. It was divided in four parts. One was the services which I mentioned which are the implementation of all this resolving or open files. The task that should be done for you. There was a Casper file in ETC which provides the list of services which was available in operating system. We had LIPCaspsicum which was just EPC to communicate with Casper. And we had LIPCasper which was the library which was used by services to implement the functionality. So the approach which was taken was that CasperD would start with operating system. It would fork first to create so-called Zygote. It was a very lively process. It didn't use a lot of memory. It didn't have open any descriptors and so on and so on. It was done to be very quickly to fork from it again. So if process needs some services then it's using new domain socket it could connect to the Casper and ask for some services. Then Casper would fork the Zygote and translate one of those Zygotes to the service and then pass the service to the process and Casper could wait for another program, another process to connect and try to ask for another service. This approach unfortunately had a lot of different issues. For example Casper was started in the beginning of the system and it was because he was in the beginning of the operating system and we could have two approaches. Or he could be running a through or he could run a special CasperD user or whatever. Because we didn't know the process which would connect to the Casper from the user A, B or some other user. We couldn't know that. So we had different credentials. This was easy solved because we could send and secure the credentials by unique domain socket and then you set with and set the git functions to change those permissions. This issue was solved. And unfortunately other problems wasn't solved so easy. For example the resource limit or working directory. When Casper was started it was running from the root. The program was in the different directory. If you try to open the file, for example, named mails or whatever, it will try to open the files in the root directory, not in your directory. For different maclabels and different humus, all things should be synchronized between the process and with the CasperD. Other issue, CPU set. If you said that grab should work only on this CPU, yeah, it would work but Casper would work on different CPU. You cannot limit the Casper that way. Another interesting problem is with so-called process substitution which is available in shell. When you use special syntax, you can pass to the program the descriptor to the data that you want to read. So if you would do open in the directory like dfd something, you would duplicate the descriptor which was passed to you by the shell. So here we have example with div. If we would do the cut A and cut B, the data would be on the descriptor 11 and the descriptor 14. If you would just open them, you would duplicate the descriptor and use those. If you delegate such path to the Casper, he doesn't know those descriptors. He was running from the different process. He didn't know what the descriptor 11 and 14 is or he could know and you would leak some private Casper data. And that's not all. He also could change the routing table per process which means that you want to say that this dcp-dump should use this routing table. And Casper, of course, would not use that because he was running from the different process. He didn't know that. And if you, for example, would send Casper, you would ask Casper to resolve DNS for you or doing other stuff, he would not respect this routing table. Because we had a different process which wasn't connected, the only connection was the unix domain socket, it was very hard to audit or key trace such communication between such process. And of course, there was one point of failure. If Casper d would fail in your operating system, then you would most likely not use sandbox. If you maybe will not even notice that Casper is not working and, for example, for months you would not use Casper on sandboxing at all. So one of the solutions which was proposed to do that is to make some special system call or make some special flags to unix domain sockets which allow you to copy all of those credentials, all of the settings from one process to another process. Maybe it should be all the way only by route, but this also didn't solve our problem, we would need to send also the descriptor tables and so on. So this was one of the solutions which was proposed, we didn't go that way. We did go in other direction and before I describe the new solution, I also would like to tell you a little bit about process descriptors. So process descriptors were also created around the capsicum. The main idea behind process descriptors is that when you fork, you not only get the feed to the process, but you also get the descriptors to this process. So you can, for example, KQ pull or select on this process and wait when this process will fail or other stuff. And there is also plan to implement a pedawate which will just wait on this, in this particular descriptor. But what is the most interesting in this for us is that if you end this process descriptor, of course, capsicum friendly because you are using descriptor, you are not using the global pit table, so you can watch the process, what he's doing. What is very interesting is that if wait was called in your program with the minus one argument, which means I don't care which child of mine will fail or give some other signal, I don't care, I just want to fetch the first child that will fail. The PD fork will not, the process with process descriptor will not be in this group. If the process with the process descriptor would fail, it will not be noticed by wait process. Of course, if you're using wait with the pit which was given while forking, you can still do that. So the new architecture was to, we changed the architecture and we decided to fork from the actual process, not like before connecting to the demo. We also reduced from a few of the libraries. We now have just libCasper, which is the EPC between Casper and services, and we have just services. Now, if you want to use some, sorry, if you want to use some Casper services, you need to link them to the library. And what is very interesting also, API didn't change at all. And we managed to solve all of the problems which I described with the previous approach. Now if you fork from the same process, you have the same credentials, you have the same MAC labels and so on and so on and so on. One of the things is that if you call the cap init with forks which create the Casper, it will, if you do that, you cannot change your settings because it will not be propagated to the other process. But this is the limit which we can accept for now. And before you could disable Casper globally. If you didn't want Casper, you just go to the services and disable it and then you would use the process without the cap-sic-comand Casper. Now you don't have that choice. You can change that by recompiling your binary and disable Casper. So now we start from the process. So if you need, if process need Casper, it just call cap init, then Casper is forked and also still use Zygote like before. If process needs some service, it's asking the Casper for that. He clones the Zygote, he creates the service, he pass the service to the process and if Casper is no more needed, it just dies. In this approach, we still have all the flexibility which we had before in previous approach. We still can go and delegate Casper at all to another service. So we can send Casper over a unique domain socket to the other process. So those are actual Ali services in our operating system, for example, which I mentioned before, DNS services which allows you to resolve DNS. You can, or system random which provides you some random numbers or random buffers to your process which is also very interesting. You can limit Casper even further. That means that, for example, if you want to resolve DNS only in IPv4, you can tell Casper to do that. If your program will try to resolve in IPv6, Casper will not allow that. If you want, for example, resolve DNS only in FreeBSD.org and FreeBSD.U or whatever, then you also can tell Casper that those are the domains that you want to resolve now other. So if you have, for example, your name application, you can define that only this E-MAP server can be resolved. So here is how the Casper is used. We need to, like I mentioned before, we need to create first the Casper instance by calling CappInit. Then we open the system DNS service which is done by CappServiceOpen. Then we can limit the service by using CappDNSTypeLimit and CappDNSFamilyLimit. In this example, we are limiting, for example, only to use IPv4 and IPv6. And after that, we also need to change the call from getHosbyName to getHosbyName. As you can see, the interface is very similar to the original. The difference is that only the Casper connection. As you can see here, all the time you need to do the special check. If I'm using Casper, am I compiled with Casper or am I not? If not, use the standard library. If you are using Casper, then use this special call. So which I'm working now, and unfortunately I wasn't able to commit that to 11, is LeapCasperMock which hides all that into the library. So when you will call Capp getHosbyName or getHosbyAdr, it will just know if you are compiling with Casper or not. Inside the library, it will tell you connect to the Casper or do the standard function. So we will reduce the amount of work which is needed to be done to capsicumize the application. That said, we have still some ongoing work. We would like to lower the bar which is needed to use Cappsicum and Casper. As you can see, you need to know a lot of things right now. You need to know also some hacks, for example, which I presented before with local time, which isn't very nicely. We also are working still on system file system which allows you to access the file system namespace to open the files, to create files and so on. I believe I implemented like two or three services like that already. I believe Pavel would have done also at least one. But we have still performance issue which comes from the libNV which we are using right now. But we have our Google Summer of Code student who is working on improving that. But we also would like to improve auditing for Casper because right now if you don't run the code, you will not know if your function will fail or not. And maybe we could do something more to provide you more information if this code will work or not. Okay. So thank you very much. Maybe there are some questions. Please. Yes. If I'm not sure if old B is supporting now the multiprocess debugging or not. So basically if the debugger is supporting the multiprocess debugging, it's fine. You just need to check which process you want to debug. Yes. Is there any new model for Casper which 3DSP is to set it to? It's in 11. Is there any new actual program in 11. Everyone. Everyone which are. Okay. Maybe not everyone. I've been reported to the zoo. Right. So, I'm going to show you some programs which are using Capsicum. So TCP dump and KD dump and pink are using Casper and Capsicum. Yes. So, I'm going to show you some programs which are using Capsicum. I'm going to show you some programs which are using Capsicum. I would also say that I'm not sure we would need to check that to be 100% sure. Are there any other questions? Yes? So basically, it will depend So basically, it will depend on which library did you link. If you would link to the libCasper standard library, then the libraries will know that you are linking to this library, so please use Casper. If you will link to the libCasper mock, then this means you don't want to reall casper and use just the normal instructions. Okay, so thank you very much for your attention and see you guys.
and my presentation will be about Capsicum and frameworks. We will be discussing the problems security and as you can see, working security is them is called streak module which allow you for pledge is to use it in over 400 programs. So it's one which I would like you to remember for a remember them for a moment. So this is how the argument but it's still not implemented so you the programs around the operating system. For solutions which allows us to escape from the access to any global namespaces. You cannot read on and so on. You don't have access to any other capabilities. One of them is to do this in the the sandbox we just open the files, we open the rights in sandboxed process is by using entering the capability mode. So Capsicum is be sure that this part is quite secure. This is the different sandbox we don't have that. We just Okay so Casper was my recent work which I was to do that for you. So first implementation was a lot of different issues. For example Casper was started in the beginning of the system and it was because he was in the beginning of the operating could be running a through or he could run a git functions to change those permissions. This resource limit or working directory. When Casper whatever, it will try to open the files in the delegate such path to the Casper, he doesn't know also created around the capsicum. The main idea behind process descriptors is that when you fork, fork will not, the process with process So the new architecture was to, we changed the propagated to the other process. But this is the system, for example, which I mentioned before, from getHosbyName to getHosbyName. As you can all that into the library. So when you will call show you some programs which are using Capsicum.