 Okay, guys, welcome to the security Devroom talk about application whitelisting in Linux environment by Radvan Sroka. Please welcome. Hello, Fosden. My name is Radvan Sroka, and I'm working as a software engineer in Red Hat in Bernou. And I'm very excited to be here as a speaker and as a developer. So let's talk about application whitelisting. What is an application whitelisting? Well, it is a security practice where the application or the software itself is able to run according to its presence on the list. And usually administrator is responsible for maintaining such a list. So it is his choice what will be on this list. Why is that so important? Well, it adds another level of security to the system. And application whitelisting capability is a part of the many certification schemes such as common criteria and many others. This basically pushes software vendors to implement some sort of application whitelisting solution. So where is Red Hat? Well, we introduced FA policy framework in role 8.1 and Fedora 29. And it's available to use for everyone. FA policy framework is a very simple and lightweight solution. And it benefits from RPM and DNF integration. It has also audit support and it is built upon FA Notify API. FA Notify API is a kernel API which is very similar to iNotify. Who knows iNotify can watch file system events based on system calls like open, read, write and close. But FA Notify can also watch exact system calls and moreover, it's blockable on system call side. That means that system call will be paused until decision has been made on the other side. So this is very simple scenario how FA Notify can work. So we have two processes here. The first on the left is Vesh which is being watched. And it would like to run PS command, standard Linux utility. And this system call will be on hold. Execution of the system call will be on hold. And kernel will notify the email which is the watcher in this case. FA policy the email and it sends an event to this email. And the email can see that something is happening on the system and we can see from the event that Vesh is going to execute PS command with such as ID. And this demo has to decide what to do with it. Well, it can send a lot, decision a lot. That means that exec VE will be eventually success on the other side. It can send the night. And that means that exec VE will fail. And Vesh will be not able to exec PS command. This is how FA policy the framework architecture looks like. Well, it has multiple backends. And the most significant part of the project is the demo itself. When the demo starts, it loads all data from backends and it saves them into database. And then it can create some query to verify trust, let's say. So how can we configure it? FA policy D can be configured in three ways. The first one is a rules file. We can find there the default set of rules like set from distribution. The second way is configuration file for the demo. We can tweak some performance options there, usually. And the last way how to set it is FA policy D trust file. And there we can put a list of applications with trust, with trust, actually. So as I said before, there are multiple optional backends. Right now, there are two possibilities implemented. The first one is RPMDB, which is the backend which loads all data from RPM database. And the second one is FA policy D trust file, which, as I said, contains the list of trusted applications. And when the application is trusted with the default set of rules, it will be allowed. So FA policy D has its own rule language implemented and it has subject object notation, very similar to SOE nukes or audit. And it can be divided into four parts. Where the first is the decision. Decision is the action what will be taken when the rule matches. And it can be allowed or denied. We can combine it with audit. So it also, the decision will be audited. And we can find the decision in audit logs. The second part of the rule is permission. Permission can be open or execute that comes from FA notify API because there are two types of events there. And it is based on system calls. And there is also any keyboard that can match any of them. The third part of the rule is subject. It's started before colon. And it is a process that is running and it wants to call exact or open system call. And the object, the part after the colon is usually file that is going to be executed or opened. We can install FFPOLCD framework very easily on Federa or REL. It's as simple as that. So let's try to run it. And we want to, let's imagine that we have some applications in HomeDeer and we would like to run them even if they are not installed from RPM. So for example, I have in my bin two applications. First is my binary, which is a normal, usual compiled binary. It is actually copied from OS command. And the second is some Python script. So if you run this, binary, it works. So let's start the demo. When we run it in debug mode, as a root, of course, and we save the output, we can try to run it again and it is not possible. Because this particular application is not trusted. So what can we do about it? Well, we can investigate the output, of the FFPOLCD, if we start looking for my bin, we should find something like that, which says that rule nine from rules file has matched. It is some default rule that denies everything, let's say. And it's denied, this event which had a type execute and some metadata. And we can see that the subject is shell, it is SH, and the object is my binary. So my shell would like to execute my binary with this file type as an executable. So let's try to construct a rule from that. So we want to allow this event that has permission execute with this subject, which is shell, and we would like to force that shell has to be trusted. Okay, that means it has to be installed from the standard repository, let's say. And there is my binary, which is in the path, and it has this file type, and we know that it is not trusted, but this is optional, it doesn't have to be there. So if we put this rule at the beginning of the rule file, then we can try to run our binary again, and we can see that it works. What about that Python script? Well, we are able to run it right now with FFOCD disabled. So it's some whole world script. If we run again the demon as before, we can see that it is not possible to run it, this Python script. So we will investigate again the same approach. We will grab from my app, and we can see that there was an event that says, actually it is very similar event as before. It has the same subject, the shell, but the object is different. Now it's my app, and it has a different file type, which is application Python right now, or text Python. So if we construct the rule, it is also very similar rule as before. We can set trust one for subject, and we should be able to run this Python application from ZSH as we were able to do before. But we are not able to. So let's start the second round of investigation. If we grab again the output of FFOCD, we will grab two lines now. The first is allowed, permission execute. So the rule we put at the beginning of the rules file, it actually matched. But there is second event that says it needs to open this file actually from shell. So it looks like shell is first, or part of the execution or exact system call is also called open system call, right? So this is the reason why it's that self. So if we can see that these two lines are very similar, we can use any keyboard for permission, and we can allow these two events with one rule. If we again update our rules file and run the Python script, now we can see that we are able to. What's the difference between these two ways of running Python scripts? So on the left side, we can see that shell is opening this Python script. But on the right side, it looks like Python 3 interpreter is running this script, right? So if we grab for my app again, we can see that subject is different. But we can fix this with all keyword instead of exact. So we have rule that will allow any permission and with any or all subjects that are trusted. And again, the object is the same as before. The second way how to enable this application is to enable whole directory. But this is not very secure, right? And the third way is the best from my point of view is to add these applications to the FAPOCD trust file, as we can see on the image. And we are able to run them. So if we are okay with our configuration, we can just simply enable FAPOCD with SystemD. That's all. Thanks. Any question? How do you prevent race conditions in the policy handling system? Especially during boot, it might take some time for the demo that you use in order to set up the policy. It's available. It depends how the unit file is based on. So we can start this demo very early, or even in the early boot. Alright, so I've got two questions. Hopefully one of them will be pretty short. So are you aware of any efforts to enable FAPOCD in other distributions than Red Hat based? I mean, it seems that apart from RPMDB integration, there's nothing under it that should not work. Well, I made a page last week that made Leap RPM optional, and there is an API that can be easily extended to some other trust source. Now, it is not possible. You can use it just only with this trust file, but you have to maintain it, but it's not easy. But you can implement some other source of the trust very easily. There are, I think, three functions you have to implement in C. Second question. If I understand correctly right now, it's very much limited to identifying files to allow or deny by their location, which obviously means that if you have got permissions to copy and execute files from some directory, like you give from the home directory, all the users have to do is just copy the file to a different place. I suspect it might be a limitation of the Feign Notify API, but are there any plans to extend this to some sort of integrity-based or hash-based policies? Let me think. So, yes, we are not checking the integrity. We have all the hashes. We can do that. We have hashes from our RPM database. So theoretically, it can work. It can be implemented with a few lines of code, but we are not doing this right now because it has some performance impact right now, and we would like to put it down. But if you want some real solution for that, that will compute all hashes and all files, so there is an IMA, but that has a big overhead, really. So adding the trust just confirms that the package is installed, and that's it. That's the only check that's happening. Adding trust one, all that does is check if the package is installed and it's running from that location. It doesn't do any Shah-based checks, nothing else. I just said that. Any other question? Which system calls are you preventing? Are you also preventing like P open stuff like that? We are looking for whole family of system calls, right? So all exact system calls or open system calls. They are watched by this API. So any other questions? Have you considered on implementing this with SE Linux or app armor style of settings instead of doing it in new? What I want to say is, would it be possible to do exactly this with SE Linux in a special setting like you do not have to disallow everything with SE Linux just like a small portion and then allow stuff again? Or was it Oscar ready because he's laughing? Because it's like common question. Well, some limited scope can be implemented by SE Linux, but there is a problem with these labels because you have to check them all the time and you have to realize that these labels are okay. So you would technically need to loop RestorCon or something like that all the time. So we would like to enhance this application to really check hashes and content of the file. And this is not possible with SE Linux because SE Linux has the label, but it doesn't really care about the content of the file or hash or something. So one last question, anyone? So if no, thank you for your presentation.