EDR is Coming; Hide Yo Sh!t
Leibowitz, Michael
Timzen, Topher
There’s a new, largely unaddressed threat in the security industry today, Endpoint Detection and Response (EDR), which aims to stop threat actors in their tracks. The scenario plays out like this... At first your campaign is going well and your attacker objectives are being met. Then, your lovingly crafted payloads become analyst samples, you’re evicted from the environment and you lose your persistence. You and the analyst are now having a bad time. You may feel this is just fear mongering, but we assure you, the risk is real.Fortunately, we have a few new tricks up our sleeves to keep this nightmare scenario at bay. While many would have you believe that we live in a measured and signed boot Utopia on modern systems, we will show you the seedy underbelly of this Brave New World. By abusing early boot mechanisms and UEFI platform firmware, we are able to evade common detection. By showing up early to the fight, we sucker punch EDR, leaving it in a daze unable to see our malicious activities. We put a new twist on old code injection techniques and maintain persistence in UEFI firmware, making an effective invisibility cloak. By leveraging these two techniques, you and the analyst can have a happy and relaxing evening. From that point on - the good ol’ days are back again! Plunder away! Michael Leibowitz Michael has done hard-time in real-time. An old-school computer engineer by education, he spends his days hacking the mothership for a fortune 100 company. Previously, he developed and tested embedded hardware and software, fooled around with strap-on boot roms, mobile apps, office suites, and written some secure software. On nights and weekends he hacks on electronics, writes CFPs, and contributes to the NSA Playset. Topher Timzen Topher Timzen is currently a Principal Vulnerability Enthusiast and enjoys causing constructive mischief. Topher has spoken at conferences such as DEF CON, SecTor and BSidesPDX on offensive security research. Enjoying teaching, particularly about exploitation, he has been running the CTF at BSidesPDX for the past few years. Topher is located in the woods hiking or mountain biking when not computing. Collectively they have pretended to be bears, slayed a dragon or two, and have managed to not bring down a production server (for long). In reality, they just want to write malware.
 We're going to get started this morning with what looks to be a very exciting talk with a couple recorded demos because these guys are smart and they don't do live demos at DEF CON. That is, that's, well you're allowed but it's just a really, really terrible idea. So if you, if this is your first time in track four which we are calling fancy track, here in fancy track you cannot vape, you cannot smoke, anything of any kind. You are not supposed to be having any kind of outside beverages other than water. There you go. Like I said, if you want to kind of move towards the center so that people can get in and out, that will help because we're going to have a lot of people coming to a lot of really good talks today. With that said, let's get TOEFL and Michael up here. How many people use antivirus at work? How many people believe it does anything? There we go. How many people use EDR at work? Yeah? How many people believe it does something? Ah ha! Suckers! Let's give Michael a dough for a big round of applause. Thank you for coming on an early Saturday morning. This is EDR's coming. Hi, Joe Shit. I'm really happy to be here this year. This sort of came about as a hallway conversation at DefCon last year. We had some ideas, we talked it over, it turned into some research and here we are and that's pretty exciting. So go out there and talk to all the people and have all the ideas and submit something next year. All right, so who are we? Well, first of all, we don't speak for our employer. These are speaking all on behalf of ourselves and nothing that we're saying is to be construed as, you know, from our employer. I'm Michael Liebowitz. I like to in my free time make hardware implants, re-implementing NSA hardware implants and I'm a principal troublemaker. Ann? And I'm Joe Fritimzen. I like doing like C-sharp mower stuff so hilariously enough some of the things you're going to see in the future. I'm Joe Fritimzen. I like doing like C-sharp mower stuff so hilariously enough some of the things you're going to see in this talk. I've talked about previously at DefCon 23 so it's kind of like the old is still new. I'm a principal vulnerability enthusiast. We both work on red teams and as you can see by our matching attire we just want to drink coffee and write mower. All right, so here's what we're going to go through and we have a lot to cover so we're going to go through it pretty fast but basically what EDR is, why we care. UEFI and the thing to note about UEFI is UEFI is cross platform which is why we're doing a Windows and Linux demo and why we have a Windows and Linux payload. Of course, you know, everyone's wondering what does this all mean and then some mitigation or whatever and then future work and then conclusions. So we're going to kind of start off with talking about EDR so a lot of you raised your hands that you use this and think it works so we're about to, you know, kind of ruin that for you. So kind of, so it's 10 o'clock, the slides are a little bit hung over so EDR is end point detection in response not enterprise. Thanks slides for being up early with us. The biggest thing about EDR is that it's really just defensive tooling that focuses on like detecting, investigating and mitigating suspicious activities going on within an environment. The big thing that it really provides blue teams is a hunt capability so this is how and a lot of organizations they're making like large scale like correlations for hunt stages so like, oh this machine over here is doing these sorts of things that's not really typical. This alert fired on our scene, let's go investigate. Typically it really just means that like for us on red teams that blue team is going to find you and we don't want to be found. So we're going to sort of look at how we avoid that. And then like the one big thing with EDR is that typically everything's mapped to like MITRE attack and if you're not familiar with MITRE attack that's essentially just like this huge knowledge base of things that attackers tend to do based off of real world observation. So like you probably hear the term like TTP thrown around everywhere. In essence it's really just this huge table that lists things that attackers like to do so you kind of like think back to previous life when you were in kindergarten and you get like a gold star for like turning in your homework on time and like being polite. It's essentially like that but for like us as bad guys so we get gold stars and when we do like persistence we get a gold star for privilege escalation. So like we want to fill out all the things but not have anybody know so we don't actually get the gold stars. We just want to do it. So like I'm saying like EDR is really just tuned like in actuality for like processes, commands and API calls. So if you're like running say like CMD.exe or PowerShell or doing like some registry stuff or trying to set up persistence because those are like TTPs in the MITRE attack framework those tend to be flagged and mapped and then alerted on for the blue team and we want to make sure that none of that actually happens. So a lot of people talk about you know the risk curve and you know this is the other side of the risk curve basically you know no attack, no breach lasts forever right. You can see from the right side of the graph that eventually you're going to get busted and you land your shell you know that's kind of the highest risk time you move around a little bit and eventually you sort of settle into persistence and like the longer you hold on the more chance it is that someone's going to roll you up and really what we want to do is you know make this curve flatten a little bit and you know what does it mean when you know the breach gets detected like no one's sleeping well tonight this is terrible. You know you're lovingly crafted, payload becomes the analyst sample. You're like very upset because all these months of work and crafting that super awesome payload are just down the drain and the analyst is like oh shit there goes my Friday night. Nobody's happy. So what we want to do is we want to modify this risk curve. We want to make it such that you know you're not going to flatten that initial shell pop kind of part like that's kind of the same but we just want to hang on to the good stuff for longer. Eventually you're going to get rolled up but we just hang out and chill out for a little bit longer. So as we were investigating ways that we can hide from EDR Mike and I had some pre-existing platform experience, particularly UEFI platform experience, platform firmware. So in sort of this research it's like we were thinking that we can utilize this sort of functionality to evade all of these detections and make that risk curve and the dwell time for us last a little bit longer. So if you're not familiar with UEFI I have to include this awesome diagram of it because John Luke Hades told everybody ever talking about UEFI that they have to. Essentially if you're not familiar with UEFI it's essentially what modern BIOS is now. So it does all the things that you don't really care about like CPU in it, change your memory, loads of option ROMs from like your PCI devices. There's other talks that go over what this actually means but what we're concerned about is if you look at the bottom there's this notion of runtime services and after the OS boots those are exposed at the operating system level. Some of the things that get exposed within the runtime services stage of UEFI are UEFI firmware variables. So these are persistent variables that actually live within your NV RAM on your platform that are accessible both to UEFI applications like if you're familiar with secure boot all of your secure boot like variables and stuff live there. So like boot order, like the keys that secure boot utilizes things of that nature. So we're going to take advantage of the fact that we can persist within NV RAM within the UEFI platform that we can then access at operating system runtime. So sort of like you're probably thinking at this point well why UEFI firmware variables? Well like I was saying it's a way that you can hide your payloads from all of these detective capabilities because it's a blind spot for all of them. Nobody looks here. Like really at all especially within AV and EDR platforms. If you're not familiar with what UEFI firmware variables are either it essentially consists of like a name and a grid so it's like this tuple and if you are able to set or get that tuple you can pull the contents of what that variable is out of NV RAM and we're going to kind of showcase that we can execute those live on the system to both stash our stuff and to sort of have like this persistence mechanism. So really quickly like UEFI firmware variables have a couple of types. There's authenticated and unauthenticated. This isn't so much important but we kind of just wanted to briefly touch on it just in case you're concerned at all with the specification or what we're doing. Like if you've heard of like authenticated variables these are signed like X509 certs that perform like a certificate check when writing. We're not going to worry about those. There are unauthenticated variables that are also present at that runtime stage. These have no verification on right. The majority of variables on a platform as we'll show you in a demo are unauthenticated. So it's not really abnormal for these to be there and it's not atypical for things to necessarily be writing or reading from there. If you're like a platform researcher or something you know about this. There's a couple of attributes as well to UEFI firmware variables within the specification. We're going to really just focus on three out of the six because as I'll showcase in the Windows 10 API you have to have nonvolatile boot service access and runtime access in order to have UEFI variables that persist within the Windows runtime after boot on your NVRAM. So just note that those three are going to be utilized and that will be shown in the demo as well. Sort of the hilarious little thing here too with why we sort of started thinking about UEFI as a way to hide from EDR. In an old, old life we're walking with some blue team folks and we're talking about ways that we've been being tricky on engagements and sharing some techniques. And we're kind of talking about like IoT devices and how it would be cool to hide like an IoT firmware. And they're like yeah that'd be cool but like please don't ever hide like in platform firmware and Mike and I kind of stopped and were like oh shit. So we're going to do Windows and Linux like Mike said. UEFI is platform agnostic so it doesn't matter what it's running on. It's part of your platform. It helps boot Intel processors. It also works like on AMD. It's kind of different there. It's a specification whatever. So UEFI and Windows. Basically I was re-looking at the MSDN articles for Windows 10 and I recognized so they had taken this off and then they reintroduced the ability to do UEFI platform stuff within 1803. So I was kind of like reading the documents. They listed all of these requirements for actually being able to use this API functionality within Windows now. So it was kind of concerning because there's a lot there that they say you need this otherwise it won't work. Such as you need to declare firmware read and write in your application manifest. You need to have it be a protected app. So like a signed app that the Microsoft store signs needs to be signed. You need to be an admin that has access to the special privilege SE system environment name like privilege token in your process space. So looking at it, it was kind of daunting because it's such a long list of requirements but you know we're hackers. That doesn't mean anything. So we started looking at ways to bypass this like SpecterOps puts out a lot of like WDAC bypasses which is a way to execute signed Windows binaries with that will unsigned Windows binaries so like unsigned Windows binaries you can still execute. Obviously on red teams we sometimes jump to conclusions or we make some leaps forward to speed up engagement time with like assume breach type scenarios or sort of the methodology and thinking that we're going to wind up being admin. Why don't we just become admin now? So like that sort of stuff for our purposes of doing this sort of thing on red team engagements wasn't necessarily impactful. So we just kind of went with it with the assumption that we're going to be, we can be an admin on a box and we're not going to need it to be assigned Windows application. So like just to showcase what the read and write firmware variable API looks like from the MSDN articles you can do set and get firmware variables from NVRAM. Really the key thing here is you just have like the name and GWID tuple that I was mentioning earlier. And for set all you do is you point the buffer you want to write into the variable. You give it the size and the attributes that you want to have it be declared as and it just sets it in NVRAM for you. And then forget it's the same sort of idea. You give it a name and a GWID tuple and then you give it the buffer you want to read into and then it reads the NVRAM out into some memory buffer that you control as the attacker. And of course you'll wind up executing that once you get the variable out of NVRAM. These are the attributes not really important. It's on the slide more for reference but this is from the MSDN article. Note that for variable attribute run time services it says if you want this to be accessible during RT it needs to also be accessible to boot services so that's kind of why we're going to have to set all three in windows. So NVBS and RT variables. So when I was initially implementing this it was sort of the decision between if I wanted it to be in C++ or in C sharp. So I initially implemented all of this in C++ just because it was easy because the MSDN article is basically just give you the code you need. But as I was kind of doing the research it occurred to me that C++ wasn't a viable option because AV flags it very easily. Like one thing that you have to do obviously if we're getting a firmware variable is you need RWX memory. So doing a lot of calls to like virtual alloc, virtual protect. It's kind of a red flag right now especially for EDR products as they start querying all these APIs. Like most applications aren't like making an RWX memory buffer and then executing it like it was shell code. So we're not going to do that. C sharp can basically do everything C++ kind of either with P invoke or reflection and having C sharp malware experience in the past was like yeah let's just do it in C sharp. Furthermore most of the C sharp bypasses or some of the most of the WDAC bypasses are in C sharp anyway so that kind of like checked that flag off for us. And then in order to make things kind of easier for all of our red team friends to use particularly on Windows environments we wanted to make sure that they could use it in C sharp as like kind of the direction that malware authors in Windows are kind of going for red team engagements these days or go-ling. But there's reference code for both on the repo which we'll showcase later after the talk. So essentially the steps for writing a UEFI variable in Windows is really easy once you have that admin privilege. You essentially need to obtain the SE system environment name with set priv. This is the only case of like P invoke that we're going to be using. Furthermore like I was saying like in the manifest where you needed read and write capabilities. The MSDian article is weird in that it lists all of those things for C++ applications. It makes no notion of ever doing this stuff in C sharp. So I've never had to declare those things and I don't really know what Microsoft is stating in that. So just ignore that completely. You don't need it for C sharp. You can then get the address of your pin buffer so that's our payload and then we just write the UEFI variable to NV RAM and now it's persistent storage. So here's some code really quickly to set the privilege. It's just P invoke so you get process. You say that you want the new token privilege. You set it. Boom. We're good. Then you can get the address of your pin buffer in C sharp. Like I said this was your payload. So you initialize an end pointer. You call interop services to get a pin to ray of your buffer that you want to write. You pin it so the garbage collector and nothing can touch it as you're working with it. And then you just simply write that UEFI variable with the set firmware variable call with the tuple and in this case it's going to be C sharp UEFI and then I have a super secret, super secret, super secret quid. Say that five times fast. That you can Google and figure out what it is. So the steps for executing UEFI variable are pretty much similar. You still need that token and the first thing I did in C sharp was I did P invoke with virtual alloc to obtain an RWX memory pointer that I can execute and then I was just obtaining that UEFI variable back into that buffer so I can execute it. So the first step, same idea, you need that privilege. Second step is I start P invoking some memory so I have RWX. But you can't actually really do that in C sharp because it's abnormal to bring things into your import address table that aren't actually C sharp specific. So like all of the virtual calls are more suspicious than getting a new process token because within like C sharp there's no real way to do like process token stuff. You have to pretty much P invoke so it's not suspicious. It is suspicious for EDR products that you're doing virtual alloc, virtual free and virtual protect within C sharp. It's like whoa, stop right there. We're going to tell the blue team about this and they're going to hunt you down. So we can't do that. Hilariously enough as we were going through this research, OJ is working on like a C sharp C alarm interpreter and he was dealing with some stuff and he also says the same thing like don't P invoke your dot net apps. Like EDR is going to find you. Like as he says it's the proverbial solution for them hunting you down. So we're not going to have to, we're going to lose the ability to P invoke to get RWX memory. Which is kind of a problem. So we can't do step two anymore but fear not. The CLR and C sharp is fantastic for malware so we're going to actually just now instead of doing any virtual calls we're going to use reflection within C sharp to obtain RWX memory which just in time compilation leaves RWX memory pages if you're not familiar with it. To read the UEFI variable into that then we're going to write the UEFI variable into a method table pointer and then we're going to execute the method as if nothing actually ever happened. So those are the steps. I'm going to actually go through that in detail because that was probably a little bit jarring. Basically in C sharp if you're not familiar with it because it's an intermediate level language representation of code it has to get just in time compiled to assembly code before it gets executed by the processor. So within C sharp there's this huge method table that contains all of the methods that the C sharp application knows about and all of those contain a JIT stub for those classes methods. So essentially what that means is at the time of just in time compilation the method table gets referenced you then get a function pointer to the executable assembly code that the processor will run which is RWX due to the notion of JIT. You can grab that method pointer, dereference the function pointer that the assembly code lives to which is just the location of the method that you're clobbering and overwrite it. So this essentially means we can declare a method that we don't care about, force it to just in time compile, get the pointer to it and then overwrite it. So it's basically like ret to lib C but in C sharp and it's like more fucky. So the steps for that look like this. We're essentially going to now obtain an RWX JIT memory page to read the variable into. That's gonna consist of defining a method to overwrite, jitting the method, obtaining the pointer to the method and then overwriting it and calling it. So we'll define a method to overwrite. This is in the code that I'm going to be releasing. It's just called overwrite me. It does nothing. We'll jit the method. So here you can see in reflection I'm doing a type of the program I'm in. Get method overwrite me. I call compile service runtime helpers prepare method which is essentially just gonna jit that with the method handle. So I have my method dot method handle that's dereferencing one of the pointers. And then I obtain the pointer to the method which is just get function pointer once I've jitted it. So now I have the location of the raw assembly code after jit and that RWX memory location. So now I write the UEFI variable payload that's stored in nvram into the pointer to method. So I just call get firmware variable ex. You can see the third argument there after the tuple is pointer to method with then the fourth argument being buffer length. That's gonna take the nv ram out, plop it in and then I can just execute the method called overwrite me as if it was actual C sharp code and I hadn't done anything malice. So we're gonna do a quick demo of what that looks like to kinda tie it all together in Windows. Um step one you obtain your shell on target. We've already done that so step one's kinda skipped. We're then gonna run write UEFI C sharp. You'll see this with the writer binary that I've written. Uh in an actual like red team engagement or in a campaign you'd probably do this with like whatever C2 framework you were using. So you can use the C sharp code say like in cobalt strike with some of the functionality there and do it on Windows boxes. Um you'll then do some sort of persistence mechanism for the reader binary which is going to go through and do the steps I just demonstrated with reflection. Um it's like a 4 kilobyte binary you'll use for persistence. You can you know we're not giving your persistence mechanism. I'm sure all of you have lots in your bag. Uh you just need to throw this binary somewhere and and run it. And then we'll uh we'll run it to showcase what it looks like. So the Windows demo. This one. Computers are hard. Computers are hard. So here I am on Windows. Um I'm gonna first go through and run a really quick chip sec module. Uh if you're not from it with chip sec it's a UEFI platform security tool that helps security researchers analyze platform firmware. Uh it does a lot of cool things for UEFI particularly variables. So I did it here as I just ran a module to dump and list what all the UEFI variables currently on my system are. You can see that there's a lot of them. Do note that most of these are NVBS plus RT. Uh so most of them are accessible uh at runtime services to the operating system and they're of course because they're persistent they're persistent and NV RAM. So there they are you didn't see mine. Here I'm gonna dump really quickly the variable list to show you that there's contents of all of these variables. Like this one is kind of funny like test zero this is a test. Um so there's lots of variables here. Nobody really ever audits them. Like I said AV and EDR doesn't look here. So now what I'm gonna do is I'm gonna run write UEFI or UEFI write C sharp that's gonna write a UEFI variable to NV RAM. I ran chip sec again to show you that it's now there. There it is uh C sharp dash UEFI. So now that that's there on box I can execute what the payload is. Um but first I'm gonna show you what that uh there's actual like uh shell code there. So I'll go into the UEFI variables directory with chip sec. I'll dump it out and there you can see that I have some shell code there that I'm gonna execute out of NV RAM with uh with uh the the reader binary. Uh that payload for demo purposes is gonna be our our favorite demo uh Metasploit. So it's just a meterpreter shell that I'm gonna spin up. I'm gonna go through run UEFI read C sharp. And then as you can see from that uh I successfully just executed a payload out of NV RAM with like a 4 kilobyte binary using reflection. Thank you. So the fun doesn't actually end there. So because this is a persistence mechanism and it's persistent uh in NV RAM this means it's gonna survive reboots. It's gonna survive reinstalling your operating system. The only way to clear this out is to like clobber over that variable or uh pull NV RAM with like a deadie prog and re uh like rewrite your UEFI um variable space. So I'm gonna shut down the box reboot it go back to my Metasploit shell uh rerun the console and then it's a cooking show. It takes a long time for Windows to boot so speed it up uh you know I just put the payload in the oven. It's gonna be done pretty quickly. The machine's booting. Still booting. It's a cooking show. Wait a minute. There it is. Let's see. And there we go. I just executed my payload out of NV RAM again uh with a persistence mechanism out of a UEFI variable. Yay cookies. And shells. It baked from shells. Awesome. Um so we kind of like have hand waived the persistence thing. We're gonna leave that as an exercise up to the reader. Like I said WDAC bypasses are a great way to do this. Uh in actuality uh your payload's a UEFI variable like good luck have fun analysts. Uh we love you still though like we're gonna help you but this is fun. Um so like what about Windows EDR products? We haven't necessarily touched on that like obviously this is a way to mitigate detection. Um so we looked at a couple of uh EDR vendors and we found no relevant information pertaining to the usage of either these API calls executing out of UEFI variable or anything of that nature. The only thing they're really going to see is that you're executing this binary. Uh but like there's binaries executed on systems all the time that's not really something too relevant that's gonna trigger hunt. Um furthermore uh there's a lot of ways currently to sync whole or to tamper with EDR products. So here's like a five line PowerShell script that you can use to like sync whole EDR products. This works on a lot of them. Uh like EDR products are things of software running on a box. Software have configs. Configs can be tampered with. So just tampered with configs a lot of the times and you can get away with anything on a box on Windows. Um there's a lot of other ways to go about it. We can chat like after the talk about it. Uh this isn't really a talk about this so it's a talk about hiding your shit and that's how you hide your shit in Windows. Um so WDAC bypass is just for references. Uh now that I've talked about hiding your shit in Windows, uh Mike's gonna talk about some Linux stuff. Boy Windows is silly. Let's talk about Linux. Linux is you know everyone knows that's where the real loot is. So let's talk about the problem space. Uh basically let's introduce our players here. We have you know the kernel. We have the EDR and we have on the right we have your sample. And you know EDR is looking at your sample and that's bad. That's what makes it your sample and not your payload. Um and you know the EDR and your sample are actually kind of peers right. We're both running as privileged processes and the EDR has some hooks into kernel space to help it do it's job. And so that's what that sort of rectangle just above the eyeballs is. Eyeballs are obviously EDR. And so like what does our solution space look like? Well you know what we really want is just to make you know just a sucker punch the EDR a little bit you know while it's not looking and make sure that it just doesn't look at us at all and then it's back to being our payload. So you know how are we gonna do that? We need to like we need to show up early to the fight right so that it never ceases coming. So we need to infect something. So you know how does your computer how does your computer boot? And what can we infect? Well the first thing the boots is a platform firmware and that's signed by the OEM. You can't really infect that easily. Boo. The next thing that's signed by micros the shim that's signed by Microsoft and it pivots the key over to the distro. That's a little bit harder to infect. Uh grub you know signed by the distro. No good. The kernel signed by the distro. No good. But the RAM disk is generated on system and not signed. This sounds like a good time. And then sometime later some shit happens and the EDR is started. So obviously what we need to infect is the RAM disk. So how are we gonna what capabilities do we have? What tools do we have at our disposal in the Linux environment to make things happen and make the EDR not look at us. So the first sort of wonderful sys call to introduce is ptrace. And this is you know why we say the 90s are back again. Like ptrace exploitation of processes has been like as old as time itself. But you know and it's tapered off in the modern era because we have policies that prevent you from doing it. We have like Yama and S.E. Linux and App Armor and silly stuff like smack and Timo you know whatever. But the best part about all this stuff is the policy is implied in user space. Alrighty. So let's go through this. Let's go through this in flowchart sort of land. So we have the RAM disk is actually the original PID 1. That's actually where a knit starts from. And then it finds your root file system, you know, draws some pretty stuff on screen like make sure you have the refunds whatever. And then it does it actually deletes everything out of the root file system except for the target directory and then it moves the mount from the target to root and then it execs system D. And that will come up again this sort of deleting everything. And then like system D starts and like you know the thumbs down is the policy being loaded that prevents you from attacking the EDR and then of course our eyeballs here are the EDR. So let's talk about some other things we have FA Notify. FA Notify is kind of a obscure API but like it's designed for AV. I don't think any AV actually uses it but you know who cares. Exploiting security or using security APIs for unintended things is like one of my favorite things. So basically what this lets you do is this lets you you know do the AV thing right. Like a file is accessed you get to stop that process from accessing that file, decide whether it's okay and then you can say if it is to go ahead which effectively allows us to inhibit start up of other processes. Another fantastic utility is MemFD Create. This has been talked about a lot in the hacker scene but essentially like you can create an anonymous file and this works like a file, get a file descriptor and then you can actually access it through you know ProcPid FD even from other processes. This is fantastic. And you know the best part is like everyone says never touch desk kids. And then another API that we can use is and this is also somewhat obscure and not really security relevant is a PRCTL, PRCET timer select. So we need some marker for our process to say to the EDR don't look at this. And so we need something that's inheritable, right? So you know you can have your militia shell, you can catch shadow and when cat does, cat also inherits the marker. So we do the set timer slack that basically controls how often you wake up the CPU. It's designed to save power but I don't care about that. And then lastly like config EFI virus. This is the kernel config to make the EFI virus file system. You saw what a pain in the ass it was to do stuff with EFI on Windows. Windows is dumb. It's just a file system. You just read and write files. It's super easy. You can do it from a shell script. And then I talked previously about MS move. Like basically this if you look in the code this is labeled as black magic fuckery. I can go through these steps but it's really convoluted. But essentially if you want to have a malicious process that survives pivoting the root file system out from under you, there's a whole lot of really weird stuff involving containers and charoots and namespaces and weird stuff to do to so that your malicious process sees the real root file system as opposed to seeing the init root file system which has nothing in it. Funny story, even though you can never have two root file systems in Linux, if you don't do this you have two root file systems in that process. And the real one and the init one and nothing is there. It's like really messed up. So anyway, let's go through how this works in practice. So our little devil emoji here, I like emojis, is our malicious demon. This is effectively stage one. We in the init script in the ramfs, forks and execs that, we open the EFI vars, we actually mount the EFI vars file system and mount proc and all that. And then we fetch it out of the, we fetch stage two and three out of UEFI land. And then we just kind of stay there and we cross that boundary between init ramfs land and the real system land. And that execs our friend system D which then spawns all kinds of other garbage. And when it spawns the policy load which we detect through EFI notify we give a stop signal to CIS CTL. CIS CTL is going to apply the policy that says you cannot Ptrace. And there's our EDR over there. I think you can figure out the next step. We're going to Ptrace the EDR and then like have our way with it. So what Ptrace allows us to do is basically we stop the process. You can see we probably end up stopping it right after or before a CIS call. And we can just back up to the CIS call, we can control the IP, back it to the CIS call and then we can just set EAX and set what CIS calls we'd like to make. So we're effectively coercing CIS calls into the process. So we can call memfd create. Then in our other process because we can access procfd, procpaid fd we can shove stage three in there which is embedded in stage two which by the way never touched disk. And then we can do an M-map. Fortunately unlike in Windows, M-mapping rewired execute pages is like totally normal, libc does it all the time. And then we can just put our shell code in there. And then we set, oops I went too fast, then we set our EIP to the sled there and we actually just jump over. And then we effectively return to, we return to DL open as we learned yesterday and as I kind of already knew like, I'm sorry I forgot the speaker's name, we talked about it yesterday. It's on my no card. Oh no, I'm out of sync. Anyway. So libc has an internal DL open. We can do the old school LD preload trick. It's separate without LD preloading. We can call the internal DL open and then we can have our malicious SO. And that malicious SO can clobber whatever we need to clobber. And then we return. All right. So now we can send the continue to our policy load and load the actual policy that prevents us from doing this. And our EDR is actually now looking the other way. So basically if you look in the code and you see our payload, and this is sort of a point that also tofer touched on, that you don't want to, there's two options here about clobbering the EDR, either the input stage or the output stage. And the input stage is complicated. You have to understand how it processes information from the kernel. The output stage is super simple. You've already looked at the logs. You know what they say. You just want to compromise its ability to write things to the output log or things you don't want to the output log. And then there's our malicious process and everybody's happy. The EDR is looking the way and we can plunder away. So let's do a little demo. What I'm going to do is we're going to tune up AuditD. AuditD is our example EDR. You know, I know that AuditD is not a commercial EDR vendor and you're wondering does this work on commercial EDR vendor? Yep, probably. And we'll install our implant, we'll reboot, we'll set the marker, we'll do the exploit again and we'll show that we're invisible. All right, let's do the demo. Okay. Oh god, how do you do this? Windows is hard. Oh god. Do it. Okay. Oh god, what do I do? Oh god. I know how to use Windows. This Windows shit is complicated. All right, here we go. We got the analyst on the right, we got the hacker on the left. And what we're going to do is the analyst is going to turn on the audit rules, he's going to tune up Audit so that it just has every exec. Then we're going to tailor the audit log, we're going to exploit the enterprise tool, you can see we're root, we're making all this noise, it's terrible. You know, they're going to roll this up. You can see it on the right, all that noise. Then we're going to run our infector binary. Our infector binary is going to make a whole lot of noise. But this noise is actually really normal because systems generate init ram fs all the time, so it's fine. So it's going to make basically all the noise that it makes on a, on a UAFI or on a init ram fs update. This is kind of a lot of reused harness from my horse pill talk from a few years ago. But you know, it's as true today as it was there. And like, you know, everything's infected, have a nice day. And then we're going to reboot. Let's do some quick show time. Let's see if I edited this video well enough. Here we are, waiting. Okay, waiting. I'll edit it tighter next time. Okay, and again we've tuned up audit and you can see we're displaying the audit log there. Let's, let's see, make a little space there. Okay. And then we're going to do the same thing. We're going to, actually we're going to set our marker first and that's going to make a little bit of noise. But once you set the timer slack, that's what that PRCTL call is. You can see the marker is set and you can also see that there's no noise in the audit log. We're, and then I, I game root again and you can see again, no noise. We're, we're invisible. We can, we can do all those nasty things we did before. Invisible. It's awesome. Ta-da. And then, uh, we can show the, we can show the policy is applied. You can see like, MMO3 means Ptrace is, is completely disabled in the system. And that is true. Like Ptrace is now completely disabled in the system. But we inhibited the policy load that prevented us from doing that. And then, uh, like I said, everything's a file system or everything's a file in Linux. Like there's an e5.rf file system. If you look like, uh, somewhere in there, there should be a lull key. Yeah, there it is. Yeah, right around there. Cause hacking is funny. And then ta-da, we did it. How do we get back to the slides? Okay. Thank you. And, you know, everyone on a Saturday morning at Def Con is always thinking themselves, what, what does this all mean? You know, we just want to bring happiness to everyone. Everyone's going to sleep well tonight. This is the net happiness increase. You're happy. The analyst is happy. That, that payload that you spent months working on is still your payload and not their sample. Everything is good. That's what we're all about. Bringing happiness to the world. All right. I don't really care about mitigation so I'm going to have tofer talk about that. I mean, I don't really care either but we felt it necessary. Um, there's a couple of things that you can do to mitigate this. Like the one biggest thing is cause we're utilizing UEFI variables is to actually monitor and audit those against your organization's fleet. That would, that would be like the first step to sort of mitigating these risks that we've presented. Um, furthermore, EDR vendors, if any of you are out there, you should be detecting UEFI APIs and this functionality in Windows and in Linux bases if you happen to be doing like Linux EDR. Um, it's not really common for applications to set and get firmware variables. Um, and furthermore, like after the installation of a platform, uh, NV, BS and RT variables being set is pretty weird. Uh, I've never actually seen that in practice. If you have seen that in practice, come talk to me about it cause I'd like to know where cause I want to abuse it. Um, furthermore, as we kind of showcase EDR tamper resistance is not at all effective. Uh, it's very easy to like sync all, uh, the sensor, kill the sensor as Mike showed. It's very easy to P trace the sensor. Um, so vendors really just need to work on securing their, uh, agents and their processes a little bit better. Um, furthermore, Mike kind of said this and his horse pulled talk at Black Hat a few years ago, but assembling RANDISCs on systems is just silly. Stop doing that if you're a Linux distro. Um, so like as far as closing the rest goes, uh, we have some future work. So, you know, the system firmware is, uh, a great, a great place to hide and there's all kinds of goodies in there and we are just touching the surface of it. And it's interesting like as we were doing this research, a lot of companies started announcing that they're going to start looking at the firmware space as a place to hunt. But you know, this is a cat mouse game and uh, as far as I can tell the, uh, are we the mouse or the cat? Anyway, one of us is already ahead. And I think it's us. I'm not sure if we're the cat or the mouse. Alright. So like in closing, we're bringing that happiness to everybody. We're going to have ourselves a UEFI dot party. We're plundering away our loot. We're sucker punching that pesky EDR. Um, and all of our code is located on this GitHub link, uh, perturbed platypus or you know, as we like to call ourselves, APTPP. Uh, we, we just pushed the code. We just confirmed it. We had a, we had a timer on a box that pushed it exactly 1045. Uh, it's live. So go, go have at it, plunder away. Uh, here's some references that you can look at. Uh, that, that's all we got for you. Just wanted to flavor yourself. Hey, here's a map. It says URTPCC again. My grin is just on the
 We're going to get started this morning with what looks to be a very exciting talk with a  couple recorded demos because these guys are smart and they don't do live demos at DEF CON.  That is, that's, well you're allowed but it's just a really, really terrible idea. So if you,  if this is your first time in track four which we are calling fancy track, here in fancy track  you cannot vape, you cannot smoke, anything of any kind. You are not supposed to be having any  kind of outside beverages other than water. There you go. Like I said, if you want to kind of  move towards the center so that people can get in and out, that will help because we're going to  have a lot of people coming to a lot of really good talks today. With that said, let's get  TOEFL and Michael up here. How many people use antivirus at work? How many people believe it  does anything? There we go. How many people use EDR at work? Yeah? How many people believe it  does something? Ah ha! Suckers! Let's give Michael a dough for a big round of applause.  Thank you for coming on an early Saturday morning. This is EDR's coming. Hi, Joe Shit. I'm really happy  to be here this year. This sort of came about as a hallway conversation at DefCon last year. We  had some ideas, we talked it over, it turned into some research and here we are and that's  pretty exciting. So go out there and talk to all the people and have all the ideas and submit  something next year. All right, so who are we? Well, first of all, we don't speak for our  employer. These are speaking all on behalf of ourselves and nothing that we're saying is to  be construed as, you know, from our employer. I'm Michael Liebowitz. I like to in my free time  make hardware implants, re-implementing NSA hardware implants and I'm a principal troublemaker.  Ann? And I'm Joe Fritimzen. I like doing like C-sharp mower stuff so hilariously enough some of  the things you're going to see in the future. I'm Joe Fritimzen. I like doing like C-sharp mower  stuff so hilariously enough some of the things you're going to see in this talk. I've talked about  previously at DefCon 23 so it's kind of like the old is still new. I'm a principal vulnerability  enthusiast. We both work on red teams and as you can see by our matching attire we just want to  drink coffee and write mower. All right, so here's what we're going to go through and we have a  lot to cover so we're going to go through it pretty fast but basically what EDR is, why we care.  UEFI and the thing to note about UEFI is UEFI is cross platform which is why we're doing a  Windows and Linux demo and why we have a Windows and Linux payload. Of course, you know,  everyone's wondering what does this all mean and then some mitigation or whatever and then  future work and then conclusions. So we're going to kind of start off with talking about EDR so a  lot of you raised your hands that you use this and think it works so we're about to, you know,  kind of ruin that for you. So kind of, so it's 10 o'clock, the slides are a little bit hung  over so EDR is end point detection in response not enterprise. Thanks slides for being up early  with us. The biggest thing about EDR is that it's really just defensive tooling that focuses on  like detecting, investigating and mitigating suspicious activities going on within an  environment. The big thing that it really provides blue teams is a hunt capability so this is how  and a lot of organizations they're making like large scale like correlations for hunt stages so  like, oh this machine over here is doing these sorts of things that's not really typical. This  alert fired on our scene, let's go investigate. Typically it really just means that like for us on  red teams that blue team is going to find you and we don't want to be found. So we're going to sort of  look at how we avoid that. And then like the one big thing with EDR is that typically everything's  mapped to like MITRE attack and if you're not familiar with MITRE attack that's essentially just  like this huge knowledge base of things that attackers tend to do based off of real world  observation. So like you probably hear the term like TTP thrown around everywhere. In essence it's  really just this huge table that lists things that attackers like to do so you kind of like think  back to previous life when you were in kindergarten and you get like a gold star for like turning in  your homework on time and like being polite. It's essentially like that but for like us as bad guys  so we get gold stars and when we do like persistence we get a gold star for privilege  escalation. So like we want to fill out all the things but not have anybody know so we don't  actually get the gold stars. We just want to do it. So like I'm saying like EDR is really just  tuned like in actuality for like processes, commands and API calls. So if you're like running say  like CMD.exe or PowerShell or doing like some registry stuff or trying to set up persistence  because those are like TTPs in the MITRE attack framework those tend to be flagged and mapped and  then alerted on for the blue team and we want to make sure that none of that actually happens.  So a lot of people talk about you know the risk curve and you know this is the other side of the  risk curve basically you know no attack, no breach lasts forever right. You can see from the right  side of the graph that eventually you're going to get busted and you land your shell you know  that's kind of the highest risk time you move around a little bit and eventually you sort of settle  into persistence and like the longer you hold on the more chance it is that someone's going to roll  you up and really what we want to do is you know make this curve flatten a little bit and you  know what does it mean when you know the breach gets detected like no one's sleeping well tonight  this is terrible. You know you're lovingly crafted, payload becomes the analyst sample. You're  like very upset because all these months of work and crafting that super awesome payload are just  down the drain and the analyst is like oh shit there goes my Friday night. Nobody's happy. So  what we want to do is we want to modify this risk curve. We want to make it such that you know  you're not going to flatten that initial shell pop kind of part like that's kind of the same but  we just want to hang on to the good stuff for longer. Eventually you're going to get rolled up  but we just hang out and chill out for a little bit longer. So as we were investigating ways  that we can hide from EDR Mike and I had some pre-existing platform experience, particularly  UEFI platform experience, platform firmware. So in sort of this research it's like we were thinking  that we can utilize this sort of functionality to evade all of these detections and make that risk  curve and the dwell time for us last a little bit longer. So if you're not familiar with UEFI I  have to include this awesome diagram of it because John Luke Hades told everybody ever talking  about UEFI that they have to. Essentially if you're not familiar with UEFI it's essentially what  modern BIOS is now. So it does all the things that you don't really care about like CPU in it,  change your memory, loads of option ROMs from like your PCI devices. There's other talks that go  over what this actually means but what we're concerned about is if you look at the bottom there's  this notion of runtime services and after the OS boots those are exposed at the operating  system level. Some of the things that get exposed within the runtime services stage of UEFI are  UEFI firmware variables. So these are persistent variables that actually live within your NV RAM on  your platform that are accessible both to UEFI applications like if you're familiar with secure  boot all of your secure boot like variables and stuff live there. So like boot order, like the  keys that secure boot utilizes things of that nature. So we're going to take advantage of the  fact that we can persist within NV RAM within the UEFI platform that we can then access at  operating system runtime. So sort of like you're probably thinking at this point well why UEFI  firmware variables? Well like I was saying it's a way that you can hide your payloads from all of  these detective capabilities because it's a blind spot for all of them. Nobody looks here. Like  really at all especially within AV and EDR platforms. If you're not familiar with what UEFI  firmware variables are either it essentially consists of like a name and a grid so it's like  this tuple and if you are able to set or get that tuple you can pull the contents of what that  variable is out of NV RAM and we're going to kind of showcase that we can execute those live on the  system to both stash our stuff and to sort of have like this persistence mechanism. So really  quickly like UEFI firmware variables have a couple of types. There's authenticated and  unauthenticated. This isn't so much important but we kind of just wanted to briefly touch on it just  in case you're concerned at all with the specification or what we're doing. Like if you've  heard of like authenticated variables these are signed like X509 certs that perform like a  certificate check when writing. We're not going to worry about those. There are unauthenticated  variables that are also present at that runtime stage. These have no verification on right. The  majority of variables on a platform as we'll show you in a demo are unauthenticated. So it's not  really abnormal for these to be there and it's not atypical for things to necessarily be writing or  reading from there. If you're like a platform researcher or something you know about this.  There's a couple of attributes as well to UEFI firmware variables within the specification.  We're going to really just focus on three out of the six because as I'll showcase in the Windows 10  API you have to have nonvolatile boot service access and runtime access in order to have UEFI  variables that persist within the Windows runtime after boot on your NVRAM. So just note that those  three are going to be utilized and that will be shown in the demo as well. Sort of the hilarious  little thing here too with why we sort of started thinking about UEFI as a way to hide from EDR.  In an old, old life we're walking with some blue team folks and we're talking about ways that we've been  being tricky on engagements and sharing some techniques. And we're kind of talking about like  IoT devices and how it would be cool to hide like an IoT firmware. And they're like yeah that'd be  cool but like please don't ever hide like in platform firmware and Mike and I kind of stopped and  were like oh shit. So we're going to do Windows and Linux like Mike said. UEFI is platform  agnostic so it doesn't matter what it's running on. It's part of your platform. It helps boot  Intel processors. It also works like on AMD. It's kind of different there. It's a specification  whatever. So UEFI and Windows. Basically I was re-looking at the MSDN articles for Windows 10 and I  recognized so they had taken this off and then they reintroduced the ability to do UEFI platform  stuff within 1803. So I was kind of like reading the documents. They listed all of these  requirements for actually being able to use this API functionality within Windows now. So it was  kind of concerning because there's a lot there that they say you need this otherwise it won't  work. Such as you need to declare firmware read and write in your application manifest. You need to  have it be a protected app. So like a signed app that the Microsoft store signs needs to be signed. You  need to be an admin that has access to the special privilege SE system environment name like  privilege token in your process space. So looking at it, it was kind of daunting because it's such a  long list of requirements but you know we're hackers. That doesn't mean anything. So we started  looking at ways to bypass this like SpecterOps puts out a lot of like WDAC bypasses which is a way  to execute signed Windows binaries with that will unsigned Windows binaries so like unsigned  Windows binaries you can still execute. Obviously on red teams we sometimes jump to conclusions or  we make some leaps forward to speed up engagement time with like assume breach type  scenarios or sort of the methodology and thinking that we're going to wind up being admin. Why don't  we just become admin now? So like that sort of stuff for our purposes of doing this sort of  thing on red team engagements wasn't necessarily impactful. So we just kind of went with it with  the assumption that we're going to be, we can be an admin on a box and we're not going to need it to  be assigned Windows application. So like just to showcase what the read and write firmware  variable API looks like from the MSDN articles you can do set and get firmware variables from  NVRAM. Really the key thing here is you just have like the name and GWID tuple that I was  mentioning earlier. And for set all you do is you point the buffer you want to write into the  variable. You give it the size and the attributes that you want to have it be declared as and it  just sets it in NVRAM for you. And then forget it's the same sort of idea. You give it a name and a  GWID tuple and then you give it the buffer you want to read into and then it reads the NVRAM out  into some memory buffer that you control as the attacker. And of course you'll wind up executing  that once you get the variable out of NVRAM. These are the attributes not really important. It's  on the slide more for reference but this is from the MSDN article. Note that for variable  attribute run time services it says if you want this to be accessible during RT it needs to also be  accessible to boot services so that's kind of why we're going to have to set all three in windows. So  NVBS and RT variables. So when I was initially implementing this it was sort of the decision  between if I wanted it to be in C++ or in C sharp. So I initially implemented all of this in C++  just because it was easy because the MSDN article is basically just give you the code you need. But  as I was kind of doing the research it occurred to me that C++ wasn't a viable option because AV  flags it very easily. Like one thing that you have to do obviously if we're getting a firmware  variable is you need RWX memory. So doing a lot of calls to like virtual alloc, virtual protect. It's  kind of a red flag right now especially for EDR products as they start querying all these APIs. Like  most applications aren't like making an RWX memory buffer and then executing it like it was shell  code. So we're not going to do that. C sharp can basically do everything C++ kind of either with  P invoke or reflection and having C sharp malware experience in the past was like yeah let's just do  it in C sharp. Furthermore most of the C sharp bypasses or some of the most of the WDAC bypasses are  in C sharp anyway so that kind of like checked that flag off for us. And then in order to make things  kind of easier for all of our red team friends to use particularly on Windows environments we wanted to  make sure that they could use it in C sharp as like kind of the direction that malware authors in  Windows are kind of going for red team engagements these days or go-ling. But there's reference  code for both on the repo which we'll showcase later after the talk. So essentially the steps for  writing a UEFI variable in Windows is really easy once you have that admin privilege. You essentially  need to obtain the SE system environment name with set priv. This is the only case of like P invoke  that we're going to be using. Furthermore like I was saying like in the manifest where you needed  read and write capabilities. The MSDian article is weird in that it lists all of those things for C++  applications. It makes no notion of ever doing this stuff in C sharp. So I've never had to declare  those things and I don't really know what Microsoft is stating in that. So just ignore that completely.  You don't need it for C sharp. You can then get the address of your pin buffer so that's our payload  and then we just write the UEFI variable to NV RAM and now it's persistent storage. So here's some  code really quickly to set the privilege. It's just P invoke so you get process. You say that you  want the new token privilege. You set it. Boom. We're good. Then you can get the address of your  pin buffer in C sharp. Like I said this was your payload. So you initialize an end pointer. You  call interop services to get a pin to ray of your buffer that you want to write. You pin it so the  garbage collector and nothing can touch it as you're working with it. And then you just simply  write that UEFI variable with the set firmware variable call with the tuple and in this case it's  going to be C sharp UEFI and then I have a super secret, super secret, super secret quid. Say  that five times fast. That you can Google and figure out what it is. So the steps for  executing UEFI variable are pretty much similar. You still need that token and the first thing I  did in C sharp was I did P invoke with virtual alloc to obtain an RWX memory pointer that I can  execute and then I was just obtaining that UEFI variable back into that buffer so I can execute  it. So the first step, same idea, you need that privilege. Second step is I start P invoking  some memory so I have RWX. But you can't actually really do that in C sharp because it's  abnormal to bring things into your import address table that aren't actually C sharp specific. So  like all of the virtual calls are more suspicious than getting a new process token because  within like C sharp there's no real way to do like process token stuff. You have to pretty much  P invoke so it's not suspicious. It is suspicious for EDR products that you're doing virtual  alloc, virtual free and virtual protect within C sharp. It's like whoa, stop right there. We're  going to tell the blue team about this and they're going to hunt you down. So we can't do  that. Hilariously enough as we were going through this research, OJ is working on like a C  sharp C alarm interpreter and he was dealing with some stuff and he also says the same thing  like don't P invoke your dot net apps. Like EDR is going to find you. Like as he says it's the  proverbial solution for them hunting you down. So we're not going to have to, we're going to  lose the ability to P invoke to get RWX memory. Which is kind of a problem. So we can't do step  two anymore but fear not. The CLR and C sharp is fantastic for malware so we're going to actually  just now instead of doing any virtual calls we're going to use reflection within C sharp to  obtain RWX memory which just in time compilation leaves RWX memory pages if you're not  familiar with it. To read the UEFI variable into that then we're going to write the UEFI  variable into a method table pointer and then we're going to execute the method as if nothing  actually ever happened. So those are the steps. I'm going to actually go through that in  detail because that was probably a little bit jarring. Basically in C sharp if you're not  familiar with it because it's an intermediate level language representation of code it has to  get just in time compiled to assembly code before it gets executed by the processor. So  within C sharp there's this huge method table that contains all of the methods that the C sharp  application knows about and all of those contain a JIT stub for those classes methods. So  essentially what that means is at the time of just in time compilation the method table gets  referenced you then get a function pointer to the executable assembly code that the processor  will run which is RWX due to the notion of JIT. You can grab that method pointer, dereference  the function pointer that the assembly code lives to which is just the location of the method  that you're clobbering and overwrite it. So this essentially means we can declare a method that  we don't care about, force it to just in time compile, get the pointer to it and then  overwrite it. So it's basically like ret to lib C but in C sharp and it's like more fucky. So  the steps for that look like this. We're essentially going to now obtain an RWX JIT memory  page to read the variable into. That's gonna consist of defining a method to overwrite, jitting  the method, obtaining the pointer to the method and then overwriting it and calling it. So  we'll define a method to overwrite. This is in the code that I'm going to be releasing. It's  just called overwrite me. It does nothing. We'll jit the method. So here you can see in  reflection I'm doing a type of the program I'm in. Get method overwrite me. I call compile  service runtime helpers prepare method which is essentially just gonna jit that with the method  handle. So I have my method dot method handle that's dereferencing one of the pointers. And  then I obtain the pointer to the method which is just get function pointer once I've jitted it. So  now I have the location of the raw assembly code after jit and that RWX memory location. So  now I write the UEFI variable payload that's stored in nvram into the pointer to method. So  I just call get firmware variable ex. You can see the third argument there after the tuple is  pointer to method with then the fourth argument being buffer length. That's gonna take the nv  ram out, plop it in and then I can just execute the method called overwrite me as if it was  actual C sharp code and I hadn't done anything malice. So we're gonna do a quick demo of what  that looks like to kinda tie it all together in Windows. Um step one you obtain your shell on  target. We've already done that so step one's kinda skipped. We're then gonna run write UEFI C  sharp. You'll see this with the writer binary that I've written. Uh in an actual like red team  engagement or in a campaign you'd probably do this with like whatever C2 framework you were  using. So you can use the C sharp code say like in cobalt strike with some of the functionality  there and do it on Windows boxes. Um you'll then do some sort of persistence mechanism for the  reader binary which is going to go through and do the steps I just demonstrated with reflection.  Um it's like a 4 kilobyte binary you'll use for persistence. You can you know we're not giving  your persistence mechanism. I'm sure all of you have lots in your bag. Uh you just need to throw  this binary somewhere and and run it. And then we'll uh we'll run it to showcase what it looks  like. So the Windows demo. This one. Computers are hard. Computers are hard. So here I am on  Windows. Um I'm gonna first go through and run a really quick chip sec module. Uh if you're not  from it with chip sec it's a UEFI platform security tool that helps security researchers  analyze platform firmware. Uh it does a lot of cool things for UEFI particularly variables. So  I did it here as I just ran a module to dump and list what all the UEFI variables currently on my  system are. You can see that there's a lot of them. Do note that most of these are NVBS plus RT.  Uh so most of them are accessible uh at runtime services to the operating system and they're of  course because they're persistent they're persistent and NV RAM. So there they are you  didn't see mine. Here I'm gonna dump really quickly the variable list to show you that there's  contents of all of these variables. Like this one is kind of funny like test zero this is a test.  Um so there's lots of variables here. Nobody really ever audits them. Like I said AV and EDR  doesn't look here. So now what I'm gonna do is I'm gonna run write UEFI or UEFI write C sharp  that's gonna write a UEFI variable to NV RAM. I ran chip sec again to show you that it's now  there. There it is uh C sharp dash UEFI. So now that that's there on box I can execute what the  payload is. Um but first I'm gonna show you what that uh there's actual like uh shell code there.  So I'll go into the UEFI variables directory with chip sec. I'll dump it out and there you can see  that I have some shell code there that I'm gonna execute out of NV RAM with uh with uh the the  reader binary. Uh that payload for demo purposes is gonna be our our favorite demo uh Metasploit. So  it's just a meterpreter shell that I'm gonna spin up. I'm gonna go through run UEFI read C sharp.  And then as you can see from that uh I successfully just executed a payload out of NV RAM with  like a 4 kilobyte binary using reflection. Thank you. So the fun doesn't actually end there. So  because this is a persistence mechanism and it's persistent uh in NV RAM this means it's gonna  survive reboots. It's gonna survive reinstalling your operating system. The only way to clear this  out is to like clobber over that variable or uh pull NV RAM with like a deadie prog and re uh  like rewrite your UEFI um variable space. So I'm gonna shut down the box reboot it go back to my  Metasploit shell uh rerun the console and then it's a cooking show. It takes a long time for  Windows to boot so speed it up uh you know I just put the payload in the oven. It's gonna be  done pretty quickly. The machine's booting. Still booting. It's a cooking show. Wait a  minute. There it is. Let's see. And there we go. I just executed my payload out of NV RAM again  uh with a persistence mechanism out of a UEFI variable.  Yay cookies. And shells. It baked from shells. Awesome. Um so we kind of like have hand waived the  persistence thing. We're gonna leave that as an exercise up to the reader. Like I said WDAC  bypasses are a great way to do this. Uh in actuality uh your payload's a UEFI variable like  good luck have fun analysts. Uh we love you still though like we're gonna help you but this is  fun. Um so like what about Windows EDR products? We haven't necessarily touched on that like  obviously this is a way to mitigate detection. Um so we looked at a couple of uh EDR vendors and  we found no relevant information pertaining to the usage of either these API calls executing  out of UEFI variable or anything of that nature. The only thing they're really going to see is  that you're executing this binary. Uh but like there's binaries executed on systems all the  time that's not really something too relevant that's gonna trigger hunt. Um furthermore uh  there's a lot of ways currently to sync whole or to tamper with EDR products. So here's like a  five line PowerShell script that you can use to like sync whole EDR products. This works on a  lot of them. Uh like EDR products are things of software running on a box. Software have  configs. Configs can be tampered with. So just tampered with configs a lot of the times and  you can get away with anything on a box on Windows. Um there's a lot of other ways to go  about it. We can chat like after the talk about it. Uh this isn't really a talk about this so  it's a talk about hiding your shit and that's how you hide your shit in Windows. Um so WDAC  bypass is just for references. Uh now that I've talked about hiding your shit in Windows, uh  Mike's gonna talk about some Linux stuff. Boy Windows is silly. Let's talk about Linux. Linux is  you know everyone knows that's where the real loot is. So let's talk about the problem space. Uh  basically let's introduce our players here. We have you know the kernel. We have the EDR and we  have on the right we have your sample. And you know EDR is looking at your sample and that's  bad. That's what makes it your sample and not your payload. Um and you know the EDR and your  sample are actually kind of peers right. We're both running as privileged processes and the EDR  has some hooks into kernel space to help it do it's job. And so that's what that sort of  rectangle just above the eyeballs is. Eyeballs are obviously EDR. And so like what does our  solution space look like? Well you know what we really want is just to make you know just a  sucker punch the EDR a little bit you know while it's not looking and make sure that it just  doesn't look at us at all and then it's back to being our payload. So you know how are we  gonna do that? We need to like we need to show up early to the fight right so that it never  ceases coming. So we need to infect something. So you know how does your computer how does your  computer boot? And what can we infect? Well the first thing the boots is a platform  firmware and that's signed by the OEM. You can't really infect that easily. Boo. The next  thing that's signed by micros the shim that's signed by Microsoft and it pivots the key over  to the distro. That's a little bit harder to infect. Uh grub you know signed by the distro. No  good. The kernel signed by the distro. No good. But the RAM disk is generated on system and not  signed. This sounds like a good time. And then sometime later some shit happens and the EDR is  started. So obviously what we need to infect is the RAM disk. So how are we gonna what  capabilities do we have? What tools do we have at our disposal in the Linux environment to make  things happen and make the EDR not look at us. So the first sort of wonderful sys call to  introduce is ptrace. And this is you know why we say the 90s are back again. Like ptrace  exploitation of processes has been like as old as time itself. But you know and it's tapered off  in the modern era because we have policies that prevent you from doing it. We have like Yama and  S.E. Linux and App Armor and silly stuff like smack and Timo you know whatever. But the best part  about all this stuff is the policy is implied in user space. Alrighty. So let's go through this.  Let's go through this in flowchart sort of land. So we have the RAM disk is actually the  original PID 1. That's actually where a knit starts from. And then it finds your root file  system, you know, draws some pretty stuff on screen like make sure you have the refunds  whatever. And then it does it actually deletes everything out of the root file system except  for the target directory and then it moves the mount from the target to root and then it execs  system D. And that will come up again this sort of deleting everything. And then like system D  starts and like you know the thumbs down is the policy being loaded that prevents you from  attacking the EDR and then of course our eyeballs here are the EDR. So let's talk about some  other things we have FA Notify. FA Notify is kind of a obscure API but like it's designed for AV. I  don't think any AV actually uses it but you know who cares. Exploiting security or using  security APIs for unintended things is like one of my favorite things. So basically what this  lets you do is this lets you you know do the AV thing right. Like a file is accessed you get to  stop that process from accessing that file, decide whether it's okay and then you can say if it is  to go ahead which effectively allows us to inhibit start up of other processes. Another  fantastic utility is MemFD Create. This has been talked about a lot in the hacker scene but  essentially like you can create an anonymous file and this works like a file, get a file  descriptor and then you can actually access it through you know ProcPid FD even from other  processes. This is fantastic. And you know the best part is like everyone says never touch  desk kids. And then another API that we can use is and this is also somewhat obscure and not  really security relevant is a PRCTL, PRCET timer select. So we need some marker for our  process to say to the EDR don't look at this. And so we need something that's inheritable, right?  So you know you can have your militia shell, you can catch shadow and when cat does, cat also  inherits the marker. So we do the set timer slack that basically controls how often you wake up  the CPU. It's designed to save power but I don't care about that. And then lastly like  config EFI virus. This is the kernel config to make the EFI virus file system. You saw what a  pain in the ass it was to do stuff with EFI on Windows. Windows is dumb. It's just a file  system. You just read and write files. It's super easy. You can do it from a shell script. And  then I talked previously about MS move. Like basically this if you look in the code this is  labeled as black magic fuckery. I can go through these steps but it's really convoluted. But  essentially if you want to have a malicious process that survives pivoting the root file system  out from under you, there's a whole lot of really weird stuff involving containers and  charoots and namespaces and weird stuff to do to so that your malicious process sees the real  root file system as opposed to seeing the init root file system which has nothing in it. Funny  story, even though you can never have two root file systems in Linux, if you don't do this you  have two root file systems in that process. And the real one and the init one and nothing is  there. It's like really messed up. So anyway, let's go through how this works in practice. So  our little devil emoji here, I like emojis, is our malicious demon. This is effectively  stage one. We in the init script in the ramfs, forks and execs that, we open the EFI vars, we  actually mount the EFI vars file system and mount proc and all that. And then we fetch it  out of the, we fetch stage two and three out of UEFI land. And then we just kind of stay  there and we cross that boundary between init ramfs land and the real system land. And that  execs our friend system D which then spawns all kinds of other garbage. And when it spawns  the policy load which we detect through EFI notify we give a stop signal to CIS CTL. CIS CTL  is going to apply the policy that says you cannot Ptrace. And there's our EDR over there. I think  you can figure out the next step. We're going to Ptrace the EDR and then like have our way  with it. So what Ptrace allows us to do is basically we stop the process. You can see we  probably end up stopping it right after or before a CIS call. And we can just back up to the CIS  call, we can control the IP, back it to the CIS call and then we can just set EAX and set what  CIS calls we'd like to make. So we're effectively coercing CIS calls into the process. So we can  call memfd create. Then in our other process because we can access procfd, procpaid fd we can  shove stage three in there which is embedded in stage two which by the way never touched disk. And  then we can do an M-map. Fortunately unlike in Windows, M-mapping rewired execute pages is  like totally normal, libc does it all the time. And then we can just put our shell code in  there. And then we set, oops I went too fast, then we set our EIP to the sled there and we  actually just jump over. And then we effectively return to, we return to DL open as we learned  yesterday and as I kind of already knew like, I'm sorry I forgot the speaker's name, we talked  about it yesterday. It's on my no card. Oh no, I'm out of sync. Anyway. So libc has an internal  DL open. We can do the old school LD preload trick. It's separate without LD preloading. We can  call the internal DL open and then we can have our malicious SO. And that malicious SO can  clobber whatever we need to clobber. And then we return. All right. So now we can send the  continue to our policy load and load the actual policy that prevents us from doing this. And our  EDR is actually now looking the other way. So basically if you look in the code and you see  our payload, and this is sort of a point that also tofer touched on, that you don't want to,  there's two options here about clobbering the EDR, either the input stage or the output stage.  And the input stage is complicated. You have to understand how it processes information from  the kernel. The output stage is super simple. You've already looked at the logs. You know what  they say. You just want to compromise its ability to write things to the output log or things you  don't want to the output log. And then there's our malicious process and everybody's happy. The  EDR is looking the way and we can plunder away. So let's do a little demo. What I'm going to do is  we're going to tune up AuditD. AuditD is our example EDR. You know, I know that AuditD is not a  commercial EDR vendor and you're wondering does this work on commercial EDR vendor? Yep,  probably. And we'll install our implant, we'll reboot, we'll set the marker, we'll do the exploit  again and we'll show that we're invisible. All right, let's do the demo. Okay. Oh god, how do  you do this? Windows is hard. Oh god. Do it. Okay. Oh god, what do I do? Oh god. I know how to  use Windows. This Windows shit is complicated. All right, here we go. We got the analyst on the  right, we got the hacker on the left. And what we're going to do is the analyst is going to turn  on the audit rules, he's going to tune up Audit so that it just has every exec. Then we're going to  tailor the audit log, we're going to exploit the enterprise tool, you can see we're root, we're  making all this noise, it's terrible. You know, they're going to roll this up. You can see it on  the right, all that noise. Then we're going to run our infector binary. Our infector binary is  going to make a whole lot of noise. But this noise is actually really normal because systems  generate init ram fs all the time, so it's fine. So it's going to make basically all the noise  that it makes on a, on a UAFI or on a init ram fs update. This is kind of a lot of reused  harness from my horse pill talk from a few years ago. But you know, it's as true today as it  was there. And like, you know, everything's infected, have a nice day. And then we're going to  reboot. Let's do some quick show time. Let's see if I edited this video well enough. Here we  are, waiting. Okay, waiting. I'll edit it tighter next time. Okay, and again we've tuned up  audit and you can see we're displaying the audit log there. Let's, let's see, make a little  space there. Okay. And then we're going to do the same thing. We're going to, actually we're  going to set our marker first and that's going to make a little bit of noise. But once you  set the timer slack, that's what that PRCTL call is. You can see the marker is set and you can  also see that there's no noise in the audit log. We're, and then I, I game root again and you  can see again, no noise. We're, we're invisible. We can, we can do all those nasty things we did  before. Invisible. It's awesome. Ta-da. And then, uh, we can show the, we can show the policy  is applied. You can see like, MMO3 means Ptrace is, is completely disabled in the system. And  that is true. Like Ptrace is now completely disabled in the system. But we inhibited the  policy load that prevented us from doing that. And then, uh, like I said, everything's a file  system or everything's a file in Linux. Like there's an e5.rf file system. If you look like,  uh, somewhere in there, there should be a lull key. Yeah, there it is. Yeah, right around  there. Cause hacking is funny. And then ta-da, we did it. How do we get back to the  slides? Okay. Thank you. And, you know, everyone on a Saturday morning at Def Con is always  thinking themselves, what, what does this all mean? You know, we just want to bring happiness  to everyone. Everyone's going to sleep well tonight. This is the net happiness increase.  You're happy. The analyst is happy. That, that payload that you spent months working on is  still your payload and not their sample. Everything is good. That's what we're all about.  Bringing happiness to the world. All right. I don't really care about mitigation so I'm  going to have tofer talk about that. I mean, I don't really care either but we felt it  necessary. Um, there's a couple of things that you can do to mitigate this. Like the one  biggest thing is cause we're utilizing UEFI variables is to actually monitor and audit  those against your organization's fleet. That would, that would be like the first step to  sort of mitigating these risks that we've presented. Um, furthermore, EDR vendors, if  any of you are out there, you should be detecting UEFI APIs and this functionality in Windows  and in Linux bases if you happen to be doing like Linux EDR. Um, it's not really common for  applications to set and get firmware variables. Um, and furthermore, like after the installation  of a platform, uh, NV, BS and RT variables being set is pretty weird. Uh, I've never actually  seen that in practice. If you have seen that in practice, come talk to me about it cause I'd  like to know where cause I want to abuse it. Um, furthermore, as we kind of showcase EDR  tamper resistance is not at all effective. Uh, it's very easy to like sync all, uh, the  sensor, kill the sensor as Mike showed. It's very easy to P trace the sensor. Um, so vendors  really just need to work on securing their, uh, agents and their processes a little bit  better. Um, furthermore, Mike kind of said this and his horse pulled talk at Black Hat a few years  ago, but assembling RANDISCs on systems is just silly. Stop doing that if you're a Linux  distro. Um, so like as far as closing the rest goes, uh, we have some future work. So, you  know, the system firmware is, uh, a great, a great place to hide and there's all kinds of  goodies in there and we are just touching the surface of it. And it's interesting like as we  were doing this research, a lot of companies started announcing that they're going to start  looking at the firmware space as a place to hunt. But you know, this is a cat mouse game and  uh, as far as I can tell the, uh, are we the mouse or the cat? Anyway, one of us is already  ahead. And I think it's us. I'm not sure if we're the cat or the mouse. Alright. So like in  closing, we're bringing that happiness to everybody. We're going to have ourselves a UEFI dot  party. We're plundering away our loot. We're sucker punching that pesky EDR. Um, and all of our  code is located on this GitHub link, uh, perturbed platypus or you know, as we like to call  ourselves, APTPP. Uh, we, we just pushed the code. We just confirmed it. We had a, we had a  timer on a box that pushed it exactly 1045. Uh, it's live. So go, go have at it, plunder away. Uh,  here's some references that you can look at. Uh, that, that's all we got for you.  Just wanted to flavor yourself. Hey, here's a map. It says URTPCC again. My grin is just on the
Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_0_4307.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_4308_7775.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_7776_16007.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_16008_16247.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_16248_17471.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_17472_19715.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_19716_20807.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_20808_21323.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_21324_24515.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_24516_25235.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_25236_25715.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_25716_27251.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_27252_27755.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_27756_29315.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_29316_30851.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_30852_32351.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_32352_33839.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_33840_34043.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_34044_34439.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_34440_35027.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_35028_35387.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_35388_36119.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_36120_36311.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_36312_36443.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_36444_36767.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_36768_36887.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_36888_37607.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_37608_37703.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_37704_38171.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_38172_38891.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_38892_42563.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_42564_44879.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_44880_45347.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_45348_45479.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_45480_45647.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_45648_45995.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_45996_46175.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_46176_47531.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_47532_50927.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_50928_55643.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_55644_57179.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_57180_57383.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_57384_58259.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_58260_58427.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_58428_58835.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_58836_59531.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_59532_61139.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_61140_62495.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_62496_63527.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_63528_64967.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_64968_65495.png Michael_Leibowitz_-_EDR_is_Coming_Hide_Yo_Sh_t_-_D_q2KUufrjoRo_65496_67637.png
We're going to get started this morning with what looks to be a very exciting talk with a couple recorded demos because these guys are smart and they don't do live demos at DEF CON. That is, that's, well you're allowed but it's just a really, really terrible idea. So if you, if this is your first time in track four which we are calling fancy track, here in fancy track you cannot vape, you cannot smoke, anything of any kind. You are not supposed to be having any kind of outside beverages other than water. There you go. Like I said, if you want to kind of move towards the center so that people can get in and out, that will help because we're going to have a lot of people coming to a lot of really good talks today. With that said, let's get TOEFL and Michael up here. How many people use antivirus at work? How many people believe it does anything? There we go. How many people use EDR at work? Yeah? How many people believe it does something? Ah ha! Suckers! Let's give Michael a dough for a big round of applause. Thank you for coming on an early Saturday morning. This is EDR's coming. Hi, Joe Shit. I'm really happy to be here this year. This sort of came about as a hallway conversation at DefCon last year. We had some ideas, we talked it over, it turned into some research and here we are and that's pretty exciting. So go out there and talk to all the people and have all the ideas and submit something next year. All right, so who are we? Well, first of all, we don't speak for our employer. These are speaking all on behalf of ourselves and nothing that we're saying is to be construed as, you know, from our employer. I'm Michael Liebowitz. I like to in my free time make hardware implants, re-implementing NSA hardware implants and I'm a principal troublemaker. Ann? And I'm Joe Fritimzen. I like doing like C-sharp mower stuff so hilariously enough some of the things you're going to see in the future. I'm Joe Fritimzen. I like doing like C-sharp mower stuff so hilariously enough some of the things you're going to see in this talk. I've talked about previously at DefCon 23 so it's kind of like the old is still new. I'm a principal vulnerability enthusiast. We both work on red teams and as you can see by our matching attire we just want to drink coffee and write mower. All right, so here's what we're going to go through and we have a lot to cover so we're going to go through it pretty fast but basically what EDR is, why we care. UEFI and the thing to note about UEFI is UEFI is cross platform which is why we're doing a Windows and Linux demo and why we have a Windows and Linux payload. Of course, you know, everyone's wondering what does this all mean and then some mitigation or whatever and then future work and then conclusions. So we're going to kind of start off with talking about EDR so a lot of you raised your hands that you use this and think it works so we're about to, you know, kind of ruin that for you. So kind of, so it's 10 o'clock, the slides are a little bit hung over so EDR is end point detection in response not enterprise. Thanks slides for being up early with us. The biggest thing about EDR is that it's really just defensive tooling that focuses on like detecting, investigating and mitigating suspicious activities going on within an environment. The big thing that it really provides blue teams is a hunt capability so this is how and a lot of organizations they're making like large scale like correlations for hunt stages so like, oh this machine over here is doing these sorts of things that's not really typical. This alert fired on our scene, let's go investigate. Typically it really just means that like for us on red teams that blue team is going to find you and we don't want to be found. So we're going to sort of look at how we avoid that. And then like the one big thing with EDR is that typically everything's mapped to like MITRE attack and if you're not familiar with MITRE attack that's essentially just like this huge knowledge base of things that attackers tend to do based off of real world observation. So like you probably hear the term like TTP thrown around everywhere. In essence it's really just this huge table that lists things that attackers like to do so you kind of like think back to previous life when you were in kindergarten and you get like a gold star for like turning in your homework on time and like being polite. It's essentially like that but for like us as bad guys so we get gold stars and when we do like persistence we get a gold star for privilege escalation. So like we want to fill out all the things but not have anybody know so we don't actually get the gold stars. We just want to do it. So like I'm saying like EDR is really just tuned like in actuality for like processes, commands and API calls. So if you're like running say like CMD.exe or PowerShell or doing like some registry stuff or trying to set up persistence because those are like TTPs in the MITRE attack framework those tend to be flagged and mapped and then alerted on for the blue team and we want to make sure that none of that actually happens. So a lot of people talk about you know the risk curve and you know this is the other side of the risk curve basically you know no attack, no breach lasts forever right. You can see from the right side of the graph that eventually you're going to get busted and you land your shell you know that's kind of the highest risk time you move around a little bit and eventually you sort of settle into persistence and like the longer you hold on the more chance it is that someone's going to roll you up and really what we want to do is you know make this curve flatten a little bit and you know what does it mean when you know the breach gets detected like no one's sleeping well tonight this is terrible. You know you're lovingly crafted, payload becomes the analyst sample. You're like very upset because all these months of work and crafting that super awesome payload are just down the drain and the analyst is like oh shit there goes my Friday night. Nobody's happy. So what we want to do is we want to modify this risk curve. We want to make it such that you know you're not going to flatten that initial shell pop kind of part like that's kind of the same but we just want to hang on to the good stuff for longer. Eventually you're going to get rolled up but we just hang out and chill out for a little bit longer. So as we were investigating ways that we can hide from EDR Mike and I had some pre-existing platform experience, particularly UEFI platform experience, platform firmware. So in sort of this research it's like we were thinking that we can utilize this sort of functionality to evade all of these detections and make that risk curve and the dwell time for us last a little bit longer. So if you're not familiar with UEFI I have to include this awesome diagram of it because John Luke Hades told everybody ever talking about UEFI that they have to. Essentially if you're not familiar with UEFI it's essentially what modern BIOS is now. So it does all the things that you don't really care about like CPU in it, change your memory, loads of option ROMs from like your PCI devices. There's other talks that go over what this actually means but what we're concerned about is if you look at the bottom there's this notion of runtime services and after the OS boots those are exposed at the operating system level. Some of the things that get exposed within the runtime services stage of UEFI are UEFI firmware variables. So these are persistent variables that actually live within your NV RAM on your platform that are accessible both to UEFI applications like if you're familiar with secure boot all of your secure boot like variables and stuff live there. So like boot order, like the keys that secure boot utilizes things of that nature. So we're going to take advantage of the fact that we can persist within NV RAM within the UEFI platform that we can then access at operating system runtime. So sort of like you're probably thinking at this point well why UEFI firmware variables? Well like I was saying it's a way that you can hide your payloads from all of these detective capabilities because it's a blind spot for all of them. Nobody looks here. Like really at all especially within AV and EDR platforms. If you're not familiar with what UEFI firmware variables are either it essentially consists of like a name and a grid so it's like this tuple and if you are able to set or get that tuple you can pull the contents of what that variable is out of NV RAM and we're going to kind of showcase that we can execute those live on the system to both stash our stuff and to sort of have like this persistence mechanism. So really quickly like UEFI firmware variables have a couple of types. There's authenticated and unauthenticated. This isn't so much important but we kind of just wanted to briefly touch on it just in case you're concerned at all with the specification or what we're doing. Like if you've heard of like authenticated variables these are signed like X509 certs that perform like a certificate check when writing. We're not going to worry about those. There are unauthenticated variables that are also present at that runtime stage. These have no verification on right. The majority of variables on a platform as we'll show you in a demo are unauthenticated. So it's not really abnormal for these to be there and it's not atypical for things to necessarily be writing or reading from there. If you're like a platform researcher or something you know about this. There's a couple of attributes as well to UEFI firmware variables within the specification. We're going to really just focus on three out of the six because as I'll showcase in the Windows 10 API you have to have nonvolatile boot service access and runtime access in order to have UEFI variables that persist within the Windows runtime after boot on your NVRAM. So just note that those three are going to be utilized and that will be shown in the demo as well. Sort of the hilarious little thing here too with why we sort of started thinking about UEFI as a way to hide from EDR. In an old, old life we're walking with some blue team folks and we're talking about ways that we've been being tricky on engagements and sharing some techniques. And we're kind of talking about like IoT devices and how it would be cool to hide like an IoT firmware. And they're like yeah that'd be cool but like please don't ever hide like in platform firmware and Mike and I kind of stopped and were like oh shit. So we're going to do Windows and Linux like Mike said. UEFI is platform agnostic so it doesn't matter what it's running on. It's part of your platform. It helps boot Intel processors. It also works like on AMD. It's kind of different there. It's a specification whatever. So UEFI and Windows. Basically I was re-looking at the MSDN articles for Windows 10 and I recognized so they had taken this off and then they reintroduced the ability to do UEFI platform stuff within 1803. So I was kind of like reading the documents. They listed all of these requirements for actually being able to use this API functionality within Windows now. So it was kind of concerning because there's a lot there that they say you need this otherwise it won't work. Such as you need to declare firmware read and write in your application manifest. You need to have it be a protected app. So like a signed app that the Microsoft store signs needs to be signed. You need to be an admin that has access to the special privilege SE system environment name like privilege token in your process space. So looking at it, it was kind of daunting because it's such a long list of requirements but you know we're hackers. That doesn't mean anything. So we started looking at ways to bypass this like SpecterOps puts out a lot of like WDAC bypasses which is a way to execute signed Windows binaries with that will unsigned Windows binaries so like unsigned Windows binaries you can still execute. Obviously on red teams we sometimes jump to conclusions or we make some leaps forward to speed up engagement time with like assume breach type scenarios or sort of the methodology and thinking that we're going to wind up being admin. Why don't we just become admin now? So like that sort of stuff for our purposes of doing this sort of thing on red team engagements wasn't necessarily impactful. So we just kind of went with it with the assumption that we're going to be, we can be an admin on a box and we're not going to need it to be assigned Windows application. So like just to showcase what the read and write firmware variable API looks like from the MSDN articles you can do set and get firmware variables from NVRAM. Really the key thing here is you just have like the name and GWID tuple that I was mentioning earlier. And for set all you do is you point the buffer you want to write into the variable. You give it the size and the attributes that you want to have it be declared as and it just sets it in NVRAM for you. And then forget it's the same sort of idea. You give it a name and a GWID tuple and then you give it the buffer you want to read into and then it reads the NVRAM out into some memory buffer that you control as the attacker. And of course you'll wind up executing that once you get the variable out of NVRAM. These are the attributes not really important. It's on the slide more for reference but this is from the MSDN article. Note that for variable attribute run time services it says if you want this to be accessible during RT it needs to also be accessible to boot services so that's kind of why we're going to have to set all three in windows. So NVBS and RT variables. So when I was initially implementing this it was sort of the decision between if I wanted it to be in C++ or in C sharp. So I initially implemented all of this in C++ just because it was easy because the MSDN article is basically just give you the code you need. But as I was kind of doing the research it occurred to me that C++ wasn't a viable option because AV flags it very easily. Like one thing that you have to do obviously if we're getting a firmware variable is you need RWX memory. So doing a lot of calls to like virtual alloc, virtual protect. It's kind of a red flag right now especially for EDR products as they start querying all these APIs. Like most applications aren't like making an RWX memory buffer and then executing it like it was shell code. So we're not going to do that. C sharp can basically do everything C++ kind of either with P invoke or reflection and having C sharp malware experience in the past was like yeah let's just do it in C sharp. Furthermore most of the C sharp bypasses or some of the most of the WDAC bypasses are in C sharp anyway so that kind of like checked that flag off for us. And then in order to make things kind of easier for all of our red team friends to use particularly on Windows environments we wanted to make sure that they could use it in C sharp as like kind of the direction that malware authors in Windows are kind of going for red team engagements these days or go-ling. But there's reference code for both on the repo which we'll showcase later after the talk. So essentially the steps for writing a UEFI variable in Windows is really easy once you have that admin privilege. You essentially need to obtain the SE system environment name with set priv. This is the only case of like P invoke that we're going to be using. Furthermore like I was saying like in the manifest where you needed read and write capabilities. The MSDian article is weird in that it lists all of those things for C++ applications. It makes no notion of ever doing this stuff in C sharp. So I've never had to declare those things and I don't really know what Microsoft is stating in that. So just ignore that completely. You don't need it for C sharp. You can then get the address of your pin buffer so that's our payload and then we just write the UEFI variable to NV RAM and now it's persistent storage. So here's some code really quickly to set the privilege. It's just P invoke so you get process. You say that you want the new token privilege. You set it. Boom. We're good. Then you can get the address of your pin buffer in C sharp. Like I said this was your payload. So you initialize an end pointer. You call interop services to get a pin to ray of your buffer that you want to write. You pin it so the garbage collector and nothing can touch it as you're working with it. And then you just simply write that UEFI variable with the set firmware variable call with the tuple and in this case it's going to be C sharp UEFI and then I have a super secret, super secret, super secret quid. Say that five times fast. That you can Google and figure out what it is. So the steps for executing UEFI variable are pretty much similar. You still need that token and the first thing I did in C sharp was I did P invoke with virtual alloc to obtain an RWX memory pointer that I can execute and then I was just obtaining that UEFI variable back into that buffer so I can execute it. So the first step, same idea, you need that privilege. Second step is I start P invoking some memory so I have RWX. But you can't actually really do that in C sharp because it's abnormal to bring things into your import address table that aren't actually C sharp specific. So like all of the virtual calls are more suspicious than getting a new process token because within like C sharp there's no real way to do like process token stuff. You have to pretty much P invoke so it's not suspicious. It is suspicious for EDR products that you're doing virtual alloc, virtual free and virtual protect within C sharp. It's like whoa, stop right there. We're going to tell the blue team about this and they're going to hunt you down. So we can't do that. Hilariously enough as we were going through this research, OJ is working on like a C sharp C alarm interpreter and he was dealing with some stuff and he also says the same thing like don't P invoke your dot net apps. Like EDR is going to find you. Like as he says it's the proverbial solution for them hunting you down. So we're not going to have to, we're going to lose the ability to P invoke to get RWX memory. Which is kind of a problem. So we can't do step two anymore but fear not. The CLR and C sharp is fantastic for malware so we're going to actually just now instead of doing any virtual calls we're going to use reflection within C sharp to obtain RWX memory which just in time compilation leaves RWX memory pages if you're not familiar with it. To read the UEFI variable into that then we're going to write the UEFI variable into a method table pointer and then we're going to execute the method as if nothing actually ever happened. So those are the steps. I'm going to actually go through that in detail because that was probably a little bit jarring. Basically in C sharp if you're not familiar with it because it's an intermediate level language representation of code it has to get just in time compiled to assembly code before it gets executed by the processor. So within C sharp there's this huge method table that contains all of the methods that the C sharp application knows about and all of those contain a JIT stub for those classes methods. So essentially what that means is at the time of just in time compilation the method table gets referenced you then get a function pointer to the executable assembly code that the processor will run which is RWX due to the notion of JIT. You can grab that method pointer, dereference the function pointer that the assembly code lives to which is just the location of the method that you're clobbering and overwrite it. So this essentially means we can declare a method that we don't care about, force it to just in time compile, get the pointer to it and then overwrite it. So it's basically like ret to lib C but in C sharp and it's like more fucky. So the steps for that look like this. We're essentially going to now obtain an RWX JIT memory page to read the variable into. That's gonna consist of defining a method to overwrite, jitting the method, obtaining the pointer to the method and then overwriting it and calling it. So we'll define a method to overwrite. This is in the code that I'm going to be releasing. It's just called overwrite me. It does nothing. We'll jit the method. So here you can see in reflection I'm doing a type of the program I'm in. Get method overwrite me. I call compile service runtime helpers prepare method which is essentially just gonna jit that with the method handle. So I have my method dot method handle that's dereferencing one of the pointers. And then I obtain the pointer to the method which is just get function pointer once I've jitted it. So now I have the location of the raw assembly code after jit and that RWX memory location. So now I write the UEFI variable payload that's stored in nvram into the pointer to method. So I just call get firmware variable ex. You can see the third argument there after the tuple is pointer to method with then the fourth argument being buffer length. That's gonna take the nv ram out, plop it in and then I can just execute the method called overwrite me as if it was actual C sharp code and I hadn't done anything malice. So we're gonna do a quick demo of what that looks like to kinda tie it all together in Windows. Um step one you obtain your shell on target. We've already done that so step one's kinda skipped. We're then gonna run write UEFI C sharp. You'll see this with the writer binary that I've written. Uh in an actual like red team engagement or in a campaign you'd probably do this with like whatever C2 framework you were using. So you can use the C sharp code say like in cobalt strike with some of the functionality there and do it on Windows boxes. Um you'll then do some sort of persistence mechanism for the reader binary which is going to go through and do the steps I just demonstrated with reflection. Um it's like a 4 kilobyte binary you'll use for persistence. You can you know we're not giving your persistence mechanism. I'm sure all of you have lots in your bag. Uh you just need to throw this binary somewhere and and run it. And then we'll uh we'll run it to showcase what it looks like. So the Windows demo. This one. Computers are hard. Computers are hard. So here I am on Windows. Um I'm gonna first go through and run a really quick chip sec module. Uh if you're not from it with chip sec it's a UEFI platform security tool that helps security researchers analyze platform firmware. Uh it does a lot of cool things for UEFI particularly variables. So I did it here as I just ran a module to dump and list what all the UEFI variables currently on my system are. You can see that there's a lot of them. Do note that most of these are NVBS plus RT. Uh so most of them are accessible uh at runtime services to the operating system and they're of course because they're persistent they're persistent and NV RAM. So there they are you didn't see mine. Here I'm gonna dump really quickly the variable list to show you that there's contents of all of these variables. Like this one is kind of funny like test zero this is a test. Um so there's lots of variables here. Nobody really ever audits them. Like I said AV and EDR doesn't look here. So now what I'm gonna do is I'm gonna run write UEFI or UEFI write C sharp that's gonna write a UEFI variable to NV RAM. I ran chip sec again to show you that it's now there. There it is uh C sharp dash UEFI. So now that that's there on box I can execute what the payload is. Um but first I'm gonna show you what that uh there's actual like uh shell code there. So I'll go into the UEFI variables directory with chip sec. I'll dump it out and there you can see that I have some shell code there that I'm gonna execute out of NV RAM with uh with uh the the reader binary. Uh that payload for demo purposes is gonna be our our favorite demo uh Metasploit. So it's just a meterpreter shell that I'm gonna spin up. I'm gonna go through run UEFI read C sharp. And then as you can see from that uh I successfully just executed a payload out of NV RAM with like a 4 kilobyte binary using reflection. Thank you. So the fun doesn't actually end there. So because this is a persistence mechanism and it's persistent uh in NV RAM this means it's gonna survive reboots. It's gonna survive reinstalling your operating system. The only way to clear this out is to like clobber over that variable or uh pull NV RAM with like a deadie prog and re uh like rewrite your UEFI um variable space. So I'm gonna shut down the box reboot it go back to my Metasploit shell uh rerun the console and then it's a cooking show. It takes a long time for Windows to boot so speed it up uh you know I just put the payload in the oven. It's gonna be done pretty quickly. The machine's booting. Still booting. It's a cooking show. Wait a minute. There it is. Let's see. And there we go. I just executed my payload out of NV RAM again uh with a persistence mechanism out of a UEFI variable. Yay cookies. And shells. It baked from shells. Awesome. Um so we kind of like have hand waived the persistence thing. We're gonna leave that as an exercise up to the reader. Like I said WDAC bypasses are a great way to do this. Uh in actuality uh your payload's a UEFI variable like good luck have fun analysts. Uh we love you still though like we're gonna help you but this is fun. Um so like what about Windows EDR products? We haven't necessarily touched on that like obviously this is a way to mitigate detection. Um so we looked at a couple of uh EDR vendors and we found no relevant information pertaining to the usage of either these API calls executing out of UEFI variable or anything of that nature. The only thing they're really going to see is that you're executing this binary. Uh but like there's binaries executed on systems all the time that's not really something too relevant that's gonna trigger hunt. Um furthermore uh there's a lot of ways currently to sync whole or to tamper with EDR products. So here's like a five line PowerShell script that you can use to like sync whole EDR products. This works on a lot of them. Uh like EDR products are things of software running on a box. Software have configs. Configs can be tampered with. So just tampered with configs a lot of the times and you can get away with anything on a box on Windows. Um there's a lot of other ways to go about it. We can chat like after the talk about it. Uh this isn't really a talk about this so it's a talk about hiding your shit and that's how you hide your shit in Windows. Um so WDAC bypass is just for references. Uh now that I've talked about hiding your shit in Windows, uh Mike's gonna talk about some Linux stuff. Boy Windows is silly. Let's talk about Linux. Linux is you know everyone knows that's where the real loot is. So let's talk about the problem space. Uh basically let's introduce our players here. We have you know the kernel. We have the EDR and we have on the right we have your sample. And you know EDR is looking at your sample and that's bad. That's what makes it your sample and not your payload. Um and you know the EDR and your sample are actually kind of peers right. We're both running as privileged processes and the EDR has some hooks into kernel space to help it do it's job. And so that's what that sort of rectangle just above the eyeballs is. Eyeballs are obviously EDR. And so like what does our solution space look like? Well you know what we really want is just to make you know just a sucker punch the EDR a little bit you know while it's not looking and make sure that it just doesn't look at us at all and then it's back to being our payload. So you know how are we gonna do that? We need to like we need to show up early to the fight right so that it never ceases coming. So we need to infect something. So you know how does your computer how does your computer boot? And what can we infect? Well the first thing the boots is a platform firmware and that's signed by the OEM. You can't really infect that easily. Boo. The next thing that's signed by micros the shim that's signed by Microsoft and it pivots the key over to the distro. That's a little bit harder to infect. Uh grub you know signed by the distro. No good. The kernel signed by the distro. No good. But the RAM disk is generated on system and not signed. This sounds like a good time. And then sometime later some shit happens and the EDR is started. So obviously what we need to infect is the RAM disk. So how are we gonna what capabilities do we have? What tools do we have at our disposal in the Linux environment to make things happen and make the EDR not look at us. So the first sort of wonderful sys call to introduce is ptrace. And this is you know why we say the 90s are back again. Like ptrace exploitation of processes has been like as old as time itself. But you know and it's tapered off in the modern era because we have policies that prevent you from doing it. We have like Yama and S.E. Linux and App Armor and silly stuff like smack and Timo you know whatever. But the best part about all this stuff is the policy is implied in user space. Alrighty. So let's go through this. Let's go through this in flowchart sort of land. So we have the RAM disk is actually the original PID 1. That's actually where a knit starts from. And then it finds your root file system, you know, draws some pretty stuff on screen like make sure you have the refunds whatever. And then it does it actually deletes everything out of the root file system except for the target directory and then it moves the mount from the target to root and then it execs system D. And that will come up again this sort of deleting everything. And then like system D starts and like you know the thumbs down is the policy being loaded that prevents you from attacking the EDR and then of course our eyeballs here are the EDR. So let's talk about some other things we have FA Notify. FA Notify is kind of a obscure API but like it's designed for AV. I don't think any AV actually uses it but you know who cares. Exploiting security or using security APIs for unintended things is like one of my favorite things. So basically what this lets you do is this lets you you know do the AV thing right. Like a file is accessed you get to stop that process from accessing that file, decide whether it's okay and then you can say if it is to go ahead which effectively allows us to inhibit start up of other processes. Another fantastic utility is MemFD Create. This has been talked about a lot in the hacker scene but essentially like you can create an anonymous file and this works like a file, get a file descriptor and then you can actually access it through you know ProcPid FD even from other processes. This is fantastic. And you know the best part is like everyone says never touch desk kids. And then another API that we can use is and this is also somewhat obscure and not really security relevant is a PRCTL, PRCET timer select. So we need some marker for our process to say to the EDR don't look at this. And so we need something that's inheritable, right? So you know you can have your militia shell, you can catch shadow and when cat does, cat also inherits the marker. So we do the set timer slack that basically controls how often you wake up the CPU. It's designed to save power but I don't care about that. And then lastly like config EFI virus. This is the kernel config to make the EFI virus file system. You saw what a pain in the ass it was to do stuff with EFI on Windows. Windows is dumb. It's just a file system. You just read and write files. It's super easy. You can do it from a shell script. And then I talked previously about MS move. Like basically this if you look in the code this is labeled as black magic fuckery. I can go through these steps but it's really convoluted. But essentially if you want to have a malicious process that survives pivoting the root file system out from under you, there's a whole lot of really weird stuff involving containers and charoots and namespaces and weird stuff to do to so that your malicious process sees the real root file system as opposed to seeing the init root file system which has nothing in it. Funny story, even though you can never have two root file systems in Linux, if you don't do this you have two root file systems in that process. And the real one and the init one and nothing is there. It's like really messed up. So anyway, let's go through how this works in practice. So our little devil emoji here, I like emojis, is our malicious demon. This is effectively stage one. We in the init script in the ramfs, forks and execs that, we open the EFI vars, we actually mount the EFI vars file system and mount proc and all that. And then we fetch it out of the, we fetch stage two and three out of UEFI land. And then we just kind of stay there and we cross that boundary between init ramfs land and the real system land. And that execs our friend system D which then spawns all kinds of other garbage. And when it spawns the policy load which we detect through EFI notify we give a stop signal to CIS CTL. CIS CTL is going to apply the policy that says you cannot Ptrace. And there's our EDR over there. I think you can figure out the next step. We're going to Ptrace the EDR and then like have our way with it. So what Ptrace allows us to do is basically we stop the process. You can see we probably end up stopping it right after or before a CIS call. And we can just back up to the CIS call, we can control the IP, back it to the CIS call and then we can just set EAX and set what CIS calls we'd like to make. So we're effectively coercing CIS calls into the process. So we can call memfd create. Then in our other process because we can access procfd, procpaid fd we can shove stage three in there which is embedded in stage two which by the way never touched disk. And then we can do an M-map. Fortunately unlike in Windows, M-mapping rewired execute pages is like totally normal, libc does it all the time. And then we can just put our shell code in there. And then we set, oops I went too fast, then we set our EIP to the sled there and we actually just jump over. And then we effectively return to, we return to DL open as we learned yesterday and as I kind of already knew like, I'm sorry I forgot the speaker's name, we talked about it yesterday. It's on my no card. Oh no, I'm out of sync. Anyway. So libc has an internal DL open. We can do the old school LD preload trick. It's separate without LD preloading. We can call the internal DL open and then we can have our malicious SO. And that malicious SO can clobber whatever we need to clobber. And then we return. All right. So now we can send the continue to our policy load and load the actual policy that prevents us from doing this. And our EDR is actually now looking the other way. So basically if you look in the code and you see our payload, and this is sort of a point that also tofer touched on, that you don't want to, there's two options here about clobbering the EDR, either the input stage or the output stage. And the input stage is complicated. You have to understand how it processes information from the kernel. The output stage is super simple. You've already looked at the logs. You know what they say. You just want to compromise its ability to write things to the output log or things you don't want to the output log. And then there's our malicious process and everybody's happy. The EDR is looking the way and we can plunder away. So let's do a little demo. What I'm going to do is we're going to tune up AuditD. AuditD is our example EDR. You know, I know that AuditD is not a commercial EDR vendor and you're wondering does this work on commercial EDR vendor? Yep, probably. And we'll install our implant, we'll reboot, we'll set the marker, we'll do the exploit again and we'll show that we're invisible. All right, let's do the demo. Okay. Oh god, how do you do this? Windows is hard. Oh god. Do it. Okay. Oh god, what do I do? Oh god. I know how to use Windows. This Windows shit is complicated. All right, here we go. We got the analyst on the right, we got the hacker on the left. And what we're going to do is the analyst is going to turn on the audit rules, he's going to tune up Audit so that it just has every exec. Then we're going to tailor the audit log, we're going to exploit the enterprise tool, you can see we're root, we're making all this noise, it's terrible. You know, they're going to roll this up. You can see it on the right, all that noise. Then we're going to run our infector binary. Our infector binary is going to make a whole lot of noise. But this noise is actually really normal because systems generate init ram fs all the time, so it's fine. So it's going to make basically all the noise that it makes on a, on a UAFI or on a init ram fs update. This is kind of a lot of reused harness from my horse pill talk from a few years ago. But you know, it's as true today as it was there. And like, you know, everything's infected, have a nice day. And then we're going to reboot. Let's do some quick show time. Let's see if I edited this video well enough. Here we are, waiting. Okay, waiting. I'll edit it tighter next time. Okay, and again we've tuned up audit and you can see we're displaying the audit log there. Let's, let's see, make a little space there. Okay. And then we're going to do the same thing. We're going to, actually we're going to set our marker first and that's going to make a little bit of noise. But once you set the timer slack, that's what that PRCTL call is. You can see the marker is set and you can also see that there's no noise in the audit log. We're, and then I, I game root again and you can see again, no noise. We're, we're invisible. We can, we can do all those nasty things we did before. Invisible. It's awesome. Ta-da. And then, uh, we can show the, we can show the policy is applied. You can see like, MMO3 means Ptrace is, is completely disabled in the system. And that is true. Like Ptrace is now completely disabled in the system. But we inhibited the policy load that prevented us from doing that. And then, uh, like I said, everything's a file system or everything's a file in Linux. Like there's an e5.rf file system. If you look like, uh, somewhere in there, there should be a lull key. Yeah, there it is. Yeah, right around there. Cause hacking is funny. And then ta-da, we did it. How do we get back to the slides? Okay. Thank you. And, you know, everyone on a Saturday morning at Def Con is always thinking themselves, what, what does this all mean? You know, we just want to bring happiness to everyone. Everyone's going to sleep well tonight. This is the net happiness increase. You're happy. The analyst is happy. That, that payload that you spent months working on is still your payload and not their sample. Everything is good. That's what we're all about. Bringing happiness to the world. All right. I don't really care about mitigation so I'm going to have tofer talk about that. I mean, I don't really care either but we felt it necessary. Um, there's a couple of things that you can do to mitigate this. Like the one biggest thing is cause we're utilizing UEFI variables is to actually monitor and audit those against your organization's fleet. That would, that would be like the first step to sort of mitigating these risks that we've presented. Um, furthermore, EDR vendors, if any of you are out there, you should be detecting UEFI APIs and this functionality in Windows and in Linux bases if you happen to be doing like Linux EDR. Um, it's not really common for applications to set and get firmware variables. Um, and furthermore, like after the installation of a platform, uh, NV, BS and RT variables being set is pretty weird. Uh, I've never actually seen that in practice. If you have seen that in practice, come talk to me about it cause I'd like to know where cause I want to abuse it. Um, furthermore, as we kind of showcase EDR tamper resistance is not at all effective. Uh, it's very easy to like sync all, uh, the sensor, kill the sensor as Mike showed. It's very easy to P trace the sensor. Um, so vendors really just need to work on securing their, uh, agents and their processes a little bit better. Um, furthermore, Mike kind of said this and his horse pulled talk at Black Hat a few years ago, but assembling RANDISCs on systems is just silly. Stop doing that if you're a Linux distro. Um, so like as far as closing the rest goes, uh, we have some future work. So, you know, the system firmware is, uh, a great, a great place to hide and there's all kinds of goodies in there and we are just touching the surface of it. And it's interesting like as we were doing this research, a lot of companies started announcing that they're going to start looking at the firmware space as a place to hunt. But you know, this is a cat mouse game and uh, as far as I can tell the, uh, are we the mouse or the cat? Anyway, one of us is already ahead. And I think it's us. I'm not sure if we're the cat or the mouse. Alright. So like in closing, we're bringing that happiness to everybody. We're going to have ourselves a UEFI dot party. We're plundering away our loot. We're sucker punching that pesky EDR. Um, and all of our code is located on this GitHub link, uh, perturbed platypus or you know, as we like to call ourselves, APTPP. Uh, we, we just pushed the code. We just confirmed it. We had a, we had a timer on a box that pushed it exactly 1045. Uh, it's live. So go, go have at it, plunder away. Uh, here's some references that you can look at. Uh, that, that's all we got for you. Just wanted to flavor yourself. Hey, here's a map. It says URTPCC again. My grin is just on the
they don't do live demos at DEF CON. That is, is your first time in track four which we are Yeah? How many people believe it does something? hardware implants, re-implementing NSA hardware EDR is end point detection in response not enterprise. Thanks slides for being up early with stars and when we do like persistence we get a you're like running say like CMD.exe or talk about you know the risk curve and you know is terrible. You know you're lovingly crafted, We want to make it such that you know you're not Eventually you're going to get rolled up but we pre-existing platform experience, particularly UEFI platform experience, platform firmware. So in sort of this research it's like we were functionality to evade all of these detections your secure boot like variables and stuff live you can hide your payloads from all of these and if you are able to set or get that tuple you like UEFI firmware variables have a couple of variables on a platform as we'll show you in a There's a couple of attributes as well to UEFI three are going to be utilized and that will be become admin now? So like that sort of stuff for that we're going to be, we can be an admin on a aren't like making an RWX memory buffer and then reflection and having C sharp malware experience in the past was like yeah let's just do it in C going to have to, we're going to lose the ability UEFI variable into that then we're going to write mechanism for the reader binary which is going to put the payload in the oven. It's gonna be done kernel. We have the EDR and we have on the right processes and the EDR has some hooks into kernel a sucker punch the EDR a little bit you know to the fight right so that it never ceases know how does your computer how does your signed by the distro. No good. The kernel signed this is you know why we say the 90s are back again. Like ptrace exploitation of processes has been like as old as time itself. But you know and fetch it out of the, we fetch stage two and three three in there which is embedded in stage two DL open and then we can have our malicious SO. in the code and you see our payload, and this is You know what they say. You just want to got the analyst on the right, we got the hacker pill talk from a few years ago. But you know, Yeah, there it is. Yeah, right around there. assembling RANDISCs on systems is just silly. our code is located on this GitHub link, uh,