 We're going to start today's threat detection session on MITRE ATT&CK and FALCO. So what we're going to achieve today is we're going to use FALCO as our IDS or threat detection tool to detect the tactics, techniques, and procedures associated with the MITRE ATT&CK framework. And we'll use Atomic Red Team 2 to actually generate those test scenarios. So to start, what is FALCO? A lot of people showing today already know what FALCO is. So it's an open standard for cloud-native threat detection. Again, it's widely used, especially in the cloud-native compute foundation ecosystem. It has over 100 contributing companies, over 50 million downloads. These companies range from some of the largest fintech organizations to software developers and other industries. So with that, we'll look at what is MITRE ATT&CK? MITRE ATT&CK framework, or the matrix, is a way of seeing the, as I say earlier, the tactics and techniques across the kill chain within your environment, so things like reconnaissance through initial access, all the way to impact data exaltation, that kind of stuff. So it's a way of categorizing what stage is an attack happening in your environment? Is it early access, or is it something that's data destruction? Is it happening later on once they've gained persistence with your environment? Now in order to understand, we won't go through every single tactic and technique in this session. What we'll do is we'll cover a few test scenarios that we can generate through ATT&CK RED. And again, we'll give context around those tests as we're performing them. Now why are we using ATT&CK RED? Just like Falco, ATT&CK RED is an open source solution. Security teams can quickly use it for free. It's portable. It's a way to consistently reproduce the same test scenarios irrespective of who's performing the test. They are already preconfigured. And what they do is they are mapped to the MITRE ATT&CK matrix. So when you look at these T numbers, think of the tactics and techniques that we see in MITRE ATT&CK. And you can quickly map the different tactics that are being performed and see if Falco is able to detect those in real time. Now why is Falco a good tool for this kind of exercise? Well, the first point is it uses a system called architecture. So what that allows us to see is anything from an application, anything happening from Kubernetes, the operating system. Essentially, it's kernel activity. So we can look at process activity, network, read write activity, file IO, a bunch of different scenarios. The other way of looking at it is it's real time. So as the system call is executed, we can then process that and trigger the event in real time. And we'll go through all this further in context throughout the session. The important thing we're going to start with is the rule structure. So Falco already has some rules that are pre-configured, but we will have to create our own in the case of where we don't have MITRE ATT&CK alignment. So the first thing to note is it has this arbitrary name or rule name that you give, and the description is just some additional context around that. Now the most important part that we can look at within this rule structure is the condition. So with Falco rules, you can define a list. And a list could be just items that are listed. You can also create a macro, and a macro is some kind of other arbitrary context. So you could say, look for these items and these other items, or these items without some other context. You can put that into a macro, and that way we can add deeper context rather than just looking for a specific system call that's being performed. We can actually correlate a bunch of different contexts within those macros, and those macros build up our condition set within the rule. The output is essentially what you see in the alert. So it's usually some kind of string, like in this case, a shell was spawned in a container, but then the system call fields that we're handling, we inject those fields. You can see they've got the little percentage sign at the end. So what we're doing here is we're populating the fields. So username or process name or container ID or command line argument, we put those into the populated fields so that when those contexts from the condition set is triggered and it's matching, it has to be a spawn process and it's a container and it's a shell process to know it's a terminal shell, then we'll tell you exactly what command was performed from which container ID, that kind of context for the alert. Then you could set priorities. So is the alert informational? Is it something lower priority? Is it warning? Is it something like a critical activity that's most certainly considered something we should be worried about? And then tags are part of that kind of automation context. So we could say, in this case, is it aligned with minor execution or specifically shell activity? Now I mentioned earlier about those things in the conditional set. Those are your lists and macros. So a list, as I say, could be a list of IP addresses. It could be fully qualified domains. Macros are also a way of just looking for additional context. You can have macros embedded within macros. So you can be as deep within contexts as you want. So in this case, we have shell processes, which is looking for anything that's a process that's listed under shell binaries. And then you see that shell binaries, again, has the additional context of what defines a shell binary exactly. So with all that context known, what we're going to do is create some custom rules eventually and tag those. The perfect example here is where we see it's tagged with minor command and control. So it might be in the case of a disallowed SSH connection. It definitely, it's a potential command and control example. So a user is trying to speak to a C2 server or from a C2 server to perform that SSH connection to your remote environment, but also could be an example of lateral movement. So it's someone's trying to move laterally into your cloud environment and again, performing an SSH attempt on that. So you may need to tag with different context. And again, you might want to also tag it with just the T number itself with the tactic and sub-technique associated with that. Now, in case you're thinking we're building all these arbitrary rules ourselves, actually a lot of them are already baked in by default. In the case of system calls or system rules, again, this number is probably changing regularly, but at the time of writing this, I guess there were 65 system calls rules. And then similarly for things like Kubernetes, it has its own audit log rules and there's about 40 out of the box rules for that. So in the case of the most common scenarios, there's already a default rule, but of course, when we're trying to extend our MITRE coverage, we can build our own custom rules to extend our coverage across the scope. As I say, it's not limited to just Kubernetes container system call activity. We also can handle event sources from different audit logging sources. So things like AWS CloudTrail as a source, we could stream those events to Falco and of course perform the alerting on it. It's not limited to just CloudTrail, of course, whatever application you have that generates real-time events. So it's an audit logging source. Of course, we should be able to handle those, process those and trigger alerts based on it. So it's an exciting tool for extending coverage, not just on hosts and containers, but into other third-party applications that you use every day in your environment. The thing I'm just gonna close off, because I don't want this to be a slide deck, I'd prefer this to be an interactive session, is being able to view the rules. So what we're gonna do is, as you can see in this example, we go into a web UI, search for MITRE-related context, and then we'll pick the rules that are most relevant to the TIDs that we're trying to perform execution tests on. If we can't find a relevant example, then we know where our coverage is lacking and where we can generate new scenarios. So with that, I'm gonna go into this test environment. It's the instructor environment. I'm just gonna start by clicking on the Start button, but one thing that's also we're pointing out is these instruct labs are a great way for people to just interactively go in the browser and test the scenario I built myself. So if you wanna know, like watch a video about how we do the whole test scenarios locally, or even just when you want to start deploying Falco, performing some arbitrary tests yourself, this is a great place to get started. So with that, I'm going to create a network namespace called Falco. In the Falco network namespace, I want to deploy Falco itself. So we're using Helm for the deployment process here. Now you might be wondering when you see it that there's a lot of feature flags. One is setting TTY set to true. So essentially for real-time detection, we need that setting to happen. We also have some kind of run K3S examples. So for our collector, we actually set specific source relevant socket context. So if I set cube CTL, get nodes. So the host itself and dash a wide, you can actually see that the version of the node we're running has this version 1.21, but also it's the K3S example. So it's just a single node cluster. It's basically any normal Ubuntu image, but we are using it as K3S. Now if we go down further through the test scenarios, you can watch to check for status changes. So Falco is nearly ready. It's one out of two ready and it's running. We wait for it to be two out of two ready and then we should be able to check for this conditional set. So actually I can just run wait pods, check for condition. If it tells us it's ready, then it's yeah, now we have conditional met. So it should be two out of two ready now. Knowing this context, knowing that Falco was deployed successfully via help, we can perform our first test. So the first thing I want to do is it's just a simple find command. So we're finding in the root directory some context of some credentials. Going back to Falco, we just need run a single line command, which is Falco logs. And you can see that we already triggered our first event. So the alert is this warning rep private keys or private activities that were found. As I mentioned earlier, we can go to this web UI and you can look up something like rep and you can look at what is the context that builds up these list of rep activities. Or we can actually just look for the rule itself that was triggered. Again, you can go in, you can look in further about how the rule is built. So if you want to extend on it, of course we can extend our coverage even in on the existing rules. So with that, we've triggered a very simple test scenario. We've shown how we're using Kube CTL logs and checking for the actual Falco container for any events that are triggered and then gripping for, again, that specific rule that we're triggering. Now, if you weren't used the rep, of course you can look at all events that are triggered off Falco. But for the purpose of this lab, we want to focus on isolated cases associated with those specific tactics we want to perform. So the next thing we want to do is install Atomic Red. So we like with Falco, we create a namespace called Atomic Red. We've made the process a little easier here. So we've made the image external. So now you can just create a Kubernetes deployment unlike using the Helm process. With this, we just specify the hosted image, which is the Atomic Red latest. And other than that, everything else is pretty much standard. We know there's one single pod is going to be created. We understand that the security context in order to perform a lot of the actions within the miter attack table, it needs privilege permission. So we set a security context with privilege set to true. So with that, we've done our deployment. It should be relatively straightforward. So if we say Kube CTL get pods, you can see that it's container creating. Now it's running. So it's very quick, that whole deployment process, 29 seconds in total to execute. Now with that, once Atomic Red's deployed, there's nothing else left to do on this section. We can move to the next part of the lab. Now, once we have Atomic Red and we have Falco, the best way to execute or show this real time detection is to perform a kind of a split screen. So on one side, we'll execute into the container, which is the Atomic Red pod. And then on the right side view, we're gonna do that command we saw earlier, which is the Kube CTL logs. It's taking just a few moments to load up here. In the meantime, like I say, on the top of the bar here, you have this Atomic Red reference. In each of the tabs, you can click on the reference doc. And that's a great way to just check, what is the relevant T number that we're looking at right now and how can we interact with that, trigger those test scenarios. So the first test scenario we're looking at here is we have T1070. Now, we can do two things. You can either go to the Atomic Red reference doc, which will take us externally to the GitHub repo for Red Canary, who managed the Atomic Red project. And this will give us the context about what's happening here. So it's an indicator of removal. So it's file deletion, as you can see here. Now, there's a bunch of tests. So they'll tell us there's deleting a single file or an entire folder, in the case for Linux or Mac OS, you like Unix type system. In a case of Windows systems, you can do the same executed tasks. But again, it'll understand the environment it's running in and perform the relevant associated tests. Now, the nice thing is we don't have to keep jumping back to Atomic Red tests. The first thing we want to do is just PowerShell in. So we mentioned we execute or exec into the Atomic Red deployment. So in that case, if I run this PowerShell within the session, you can see now I'm running as root PowerShell. If I run this import module, what I'm doing is importing the test scenario for the Atomic Red tests. Now, there's a bunch of things we can do. There's a bunch of different feature flags. So if you want to show the details associated with it, you can use the feature flag, show details. And that gives us some context about what is happening here. So we mentioned it's all to do with file dilation. So as we say, they're all Linux specific tests we're performing here because we're running it in a, you know, an Ubuntu image, as we mentioned in the first part of the session. So you can see that kind of the actual command is being executed. So it doesn't need elevated permissions in this case. The attack command can be performed as a standard user and it just echoes out this, you can see RM for remove and some other arbitrary context. We don't need to look into all the specific context here, but what we need to know is what exactly is the test doing? First of all, which is file deletion. So what I've done is I'm looking for anything related to this bulk data has been removed from disk because I know that out of the box, there should be this bulk file deletion. See the way we by default, we have a rule for bulk data deletion. And importantly, when we look at the context associated with it, we can see that again, does have the relevant tagging. So for the relevant minor attack tactics and the T number associated with it and what it does it apply to this process activity, container and file system on the host. So going back into our environment, we want to execute those tests. So the next thing might be checking for prerequisites. Do you have prerequisite checks done that allow for you to perform this executed test? You can see here, there's no specific prerequisites defined or required for this case. So it can actually do the deletion activity without you needing to do some additional custom configuration. So the last thing I'll do is I'll actually execute the test. And it's as simple as running invoke atomic tests against the T number, which was T1070 against the sub number. So I paste the test in and you see that on the right side view, we're looking for QCTL logs. I'm using the dash F against the file, we're using the tail command at zero. So it's looking for anything that's quite literally happening right now in the network namespace Falco against the container Falco. And again, we're doing it by label. We're looking for that specific matching label. So that again, there's only one pod in that network namespace that matches the label of name equals Falco. So yeah, there we go. Perform my first test. Every time it's performed on the left side, the second it's executed on the right side, I get the real-time detection. So perfect. We've proven first of all that Falco detects all the lesion out of the box because we have the preconfigured rule. There's no kind of, you know, there's not a black box in this case. It's all very transparent about the rules that we provide. And there is visibility again through this UI about what rules we've already created out of the box. So there's nothing else we need to do here. The rule already exists added by the default rule feed and by invoking tests we see on the right side view in real-time the detections occur. So we're gonna move on to the next test scenario in our session. So the next one should be related to, I believe, it's gonna be like an escape from container scenario. So we'll go back to start. And again, looking at this introduction, it tells us, yeah, breaking out of a container. So adversaries might wanna break out of a container as a way of gaining access to host. So this test scenario is going to be a breakout from container and we want to be able to detect some unusual network execution. So in this case, detecting like a network tool that was launched within a container is a perfect example of how an adversary might want to move laterally out of that environment. So we start in the same place. We start on the left side from the atomic red test and the right side is Falco. So knowing how we do all of these, we always have to PowerShell in and then we need to import the specific tests so you'll see every time we import the relevant test scenarios. I don't know why it's not importing if I was to copy, go back here, paste. Maybe I'd try quitting and pasting again. Okay, that works fine. So we import a test scenario. It's best practice to perform a cleanup. So you always use the dash clean at the end. Again, if you were doing this in your own environment to make sure you're not importing through other junk tests between each test scenario. So with that, we can show our details again. As we mentioned, we want to detect specific network tools that are being used. Now by checking the details view, we get again the context of the commands that are being used. So if config, if it was a netcat, we know what tools are being used here. So in our case, we could create some very simple arbitrary rule that says if I see netcat trigger that detection. And again, by checking details, we know exactly what it is that we're trying to scope into our rule. Now same thing again, for network tool, we should already have this rule in our rules feed. So if I just type in network tool, we should have a bunch of different scenarios. Actually, there's launching remote file copy tools, ingress remote tools, suspicious network tools on a host or in the container. So we're focused on the container scenario. We can see what are the macros. As I mentioned earlier, if you wanted to see what the network tool processes are, we can copy that macro. We can filter again for it in our search view. And by clicking into that specific macro, we can see it's type macro and that will tell us how it's built. So you can see it's a process name and then the process name is looking for listed network tool binaries. So we're going further down this rabbit hole of looking for the additional context, but by looking for network tool binaries, then we can see it's listed here for netcat, NC, nmap, dig, tcp, dump, tshark. There are a bunch of different networking tools, telnet. So if we executed any of those arbitrary tests, this should actually trigger our detection rule because again, it was looking for a listed process and the process has to match one of these process names. And again, we know this is a type list. So going back into our environment, we could check prerequisites, but I don't think there's any prerequisite requirements here. It'll perform a test. You can see it's the running escape to host technique simulation. And again, it already has Docker installed. So there's not a whole lot of checks that we need to go for. So by just running the test scenario, we can actually see, again, the same thing. One of the test scenarios that is going to run is we saw them here. There's like netcat, ifconfig, bunch of different tests are executed. The best thing you can do is just have rules or a list with deeper context. So by having more and more examples of network tools that could be run by an attacker as they're moving laterally. Now, one thing I haven't talked about much other than in slide deck was around the conditions that we're showing, not the conditional set, sorry, but the output. So as I mentioned, we can see that this test is definitely happening from atomic red because we can see it's coming from the container atomic red and with the relevant image that we deployed earlier. But also you can see, for instance, what command was executed. So in this case, it was command was set to NECA. So in case there was any confusion about exactly what command was triggered that actually gave this detection, well, here was the command that was executed. And in the case of more complex commands, of course, we see the full output from the shell. So with that, I'm happy with what we've learned from this test scenario and we should get this detection network tool launched. So every time I run the test scenario, I should get the same thing again. So if I was to, yeah, actually, that one's kind of frozen up, but we'll move on to the next test scenario, that's okay. So with that known, the next one we're picking a test scenario where we don't have a Falka rule. This is a great way to better understand the complexities or the individual requirements for creating your new custom rule and again, deploying the changes. So I'll start by, again, nothing's changed here, it's going into the terminal shell. We just want to then import the relevant test scenarios. Now from here, I want to test it straight away. And you'll notice on the right side, I'm looking for anything that's potentially malicious Python script. The reason I'm looking for that is because it's running these Python commands. So yeah, nothing's coming up for Python. Even if I remove the grep, I can get everything that's happening from Falka, you know, as in maybe it's detecting something else. So we can perform the test one more time. You do get other detections but they're not relevant to the context here. Like for instance, remember we mentioned how we're power shelling into there, we're running under root. So we get things like file below Etsy or in some specific environment where it's running. So we can see the RC local test that is being performed which is the, you know, we said there's two scenarios here, there's the RC local and there's RC common or the two SNES tests that are gonna be performed. So let's go see that with the details view. So if I say show details, you can see, yeah, here we go. So you can see in under Etsy RC local, that's fine. So we did get that context. We do see it's under Etsy RC local. However, this rule doesn't specifically align with what is the MITRE attack activity that's being performed which is the malicious Python script. So although we do get detections of other anomalous things happening in environments and maybe if you read through all of the commands that are being run like the T Etsy RC local, you could probably understand that something's happening but we want specific rules aligned with specific tactics and techniques. So with that known, if we go back and add the grep for potentially malicious Python script, we wanna create our custom rule scenario. So we've added some extra views here. One way of looking at it here is if I open VIM and go in terminal two, so I just run VI, MITRE rules to YAML, the file is written but if I go I and we insert, I can paste this rule that was already pre-written, paste it. Now you can see this is a little bit more complex. It's looking for things like the Python. So if there's a process command line executed and it contains Python with the dash C, we're also looking for if there's Python three run as opposed to the older version of Python or Python two, there might be, yeah, again, the attacker adversary might use specific versions of Python. So it's good to have those examples so it contains those strings and it also has other contexts like it contains echo or base 64 is included in there somewhere or decode and import. So we're putting a bunch of different conditional set and we're saying if these commands are executed, then we're pretty sure it's something to do with Python but under description, we're adding far more context around what are these individual operations. So things like we wanna detect base 64 encoded Python scripts that are executed on command line. So notice how it's a Python script and, you can say and or operator, so there's Boolean logic, but if it's and it contains the base 64 command line, then we know it's a base 64 encoded specifically Python script. And then again, why are we doing this? Well, as we found out when we read the MITRE attack documentation, base 64 can be used to encode binary data for transfer for ASCII only command lines and the attackers can leverage this technique in various exploits to load shell code. And of course the outcome is to evade detection. So this would be a good example of data exfiltration or sorry, data evasion. So in this case, we aligned the tag for TA005 for defensive asian, but keep in mind the specific test we're doing was the T1037. So again, there can be overlap between obfuscation of files and information as well as defensive asian with specific tests that you might be executing. So all of this, as we mentioned earlier is from the same data source, which the system calls. So with all that in mind, what I'm going to do is I'll save the file. Now we know the file saved because if we go to file directory and you go under root and you see MITRE rules you can see the file is now being saved. So what we want to do is we want to deploy the new change. So I'm using Helm again, but unlike the previous time we used Helm we're saying Helm upgrade. So we're making a change, ignore the formatting stuff that shouldn't be a problem. We're making the change again in the network namespace falco and make sure they're on the same version that I was using earlier, which is 3.3.0. I'm reusing values ahead earlier, so there's no unusual change, but all we're doing is we're pointing in that we're taking context from the new file, which is MITRE rules.yaml, which was this file. So we say custom rules in the custom rules context where we have this file called MITRE rules.yaml. And again, I've only added one single rule here. Now, one thing that's worth pointing out as well is that we've added a lot of output context here. So for potentially malicious Python script, we wanna know process IDs, we wanna know event types, we wanna know the image that was executing it, container, if that is running from as much context as possible. So we've added all of those arbitrary points into our output so that when we trigger detection in a while, we'll get that. Now, I don't want to break this view because we'll be coming back to this in a second. So what we wanna do is delete the pod. By deleting the pod, it will essentially forcefully remove anything that was potentially cashed to do with the previous Falco deployment. And then when we get pods and check for any changes on Falco, we'll get the cleanest version. That's just to avoid any possible mistake. So you can see the status change is gonna go through as first has to terminate the pod that we just ran the QCTL delete pod command. But because Kubernetes and containers or other ephemeral, they're designed to die and recreate, we don't need to do anything else. It should go through the terminating process and then start going through container creating, running one out of one or one out of two and then two out of two. So you can see the process of pending, initializing, then pod initializing, running and give it one more second and then we see two out of two running. So actual upgrades of Falco are pretty pain-free. We just, we point to a fall or make the changes. We run the Helm upgrade command and just for make sure there's no potential issues, we do the delete pod to make sure there was nothing cashed associated with that. So I'm pretty confident Falco is running at this point. So we can go back to atomic red. If we notice that the command disappears, it's simple just to up and then run the command again. So we're looking for potential malicious Python script. And with that, if I run my test one more time, it didn't run that time. And I'm wondering is it because Falco is not okay, it is two out of two ready now. So if we look for that command one last time and then I run my test, which, oh, that was the show details. So if I execute the test this time, and there we go. Now, another thing to point out here is you might be wondering, well, we got two detections. Why did that happen? The reason why is we looked for remember anything that was base 64 and we also looked for if it was a Python script. Now, from the outputs, we know clearly that the first test was looking for the test against RC common. And then the other one was RC local. Yeah, there's two test scenarios, RC common, RC local. So when we look at the output, we can see that the file name in this case was the first test was against RC common. And then the second file name output test was against RC local. So in that case, the context matched in two different scenarios. So two rules were triggered. And again, just to make sure there's no mistake here, you run it one more time and you see that there's two more alerts that were triggered. So hopefully this session was a great way to understand how Falco's deployed, how to use Falco, how to use Atomic Red in a real world test scenario, better understanding MITRE attack, what the framework exists for and why and just being able to upgrade Falco, creating your own custom rules and extending coverage of the MITRE attack framework. And with that, if there's any questions that anyone has after seeing the session, check out Falco.org for more information.