 So I hope you guys really appreciate it. They're gonna be going pretty pretty quickly So give them a round of applause and we'll get started All right. Well, this is EDR is coming hide your shit and This used to be a 90 minute talk then we cut it down to 45 minute now We cut it down to 25 minutes. So yeah, it's gonna go pretty fast So I'm Michael Liebowitz Rukula in the twitters. I'm a principal troublemaker at Oracle cloud infrastructure and you know what we say is not endorsed by our employer or the opinion of our employer in any way and and I'm Taufer Timson. I'll do a lot of a C sharp mower stuff I'm a principal vulnerability enthusiast also on the Oracle cloud infrastructure red team And if it's not obvious from our matching attire, we just really want to write malware and drink coffee But in the other order All right, so let's go through the agenda real quick remember we're going fast What is EDR? We're gonna talk about Firmware and then some windows bullshit and then some Linux bullshit and then we're gonna figure out what life means There's gonna be some recommendations what we might do in the future and then Conclusions which I guess is also what does it all mean? Okay, so what is EDR? so EDR stands for endpoint detective response and basically you can read that but What it means is the blue team is going to roll you up and throw you out and it's just gonna make your life hard Some prominent vendors are mentioned at the bottom of the slide Not going to mention any particular vendors, but if you're wondering does this work on vendor it does If you're not already familiar, this is the mitar attack framework. So This is a set of techniques and basically I Think what we need to think about it is this is bikes basically a behavior chart for bad guys It's just like kindergarten every time you do one of these things you get a little you get a little gold star every time you You know credential dump, etc. And this is how EDR maps what you do to What you do And then you know I think in infosec we talk a lot about risk and we talk about the risk curve and I and we're gonna talk about the other risk curve So basically no nothing good lasts forever You know at this part of the graph and just my pointer show oh it kind of does So, you know, you know that feeling like your initial shell pop But this is like where you're pretty likely to get popped And then and then, you know, basically they haven't caught you by now. They're not gonna catch you and You know you start your persistence phase and it goes and goes but no breach lasts forever and eventually eventually eventually they're gonna catch you and that's you know That's we want to that we want to live for longer and the end result of that is Everyone's having a bad day You you're you're lovingly crafted payload becomes their sample and Months of work are down the drain. Everyone's Friday is ruined that this sucks. What can we do about this? So we need to we need to make the we need to flatten the risk curve You've heard that before right? We want you know, we can't make the initial shell popped being less likely to get detected But maybe we can flatten out that their net persistence phase give you a little bit longer to enjoy your good time And you know as I said nothing lasts forever. You will somewhere somewhere over there get popped So how are we gonna make that risk curve flattens such that we're no longer being detected after our initial shells popped Well, we're gonna utilize a little thing called UEFI If you're not familiar with UEFI, this is essentially what people refer to as modern-day BIOS. It's a Platform firmware that does all of these things and this chart is included because once upon a time John Luke ades during a black hat talk said if any research was talking about UEFI you have to include this slide So here's the slide Basically, it's if you're not familiar with it. It's platform firmware. It's what essentially Sits it helps boot the processor. So it does all of like your memory training your CPU and it all of those things Is UEFI does all of it. It also boots option ROMs from PCI devices and whatnot. You've likely seen like the low jacks finding that came out earlier last year where it was a Thing called a bootkit. So this is malicious firmware malicious code running in platform firmware. That's where this all happens The interesting thing to take out of this I store of a diagram is this notion of runtime So once the operating system boots and you've been handed off to the operating system bootloader from UEFI You expose runtime services So these are runtime services that are exposed by the platform firmware that are available to the operating system during the runtime of the platform Things that are in this category are like UEFI applications. Nobody really uses those who cares and then UEFI Platform firmware variables. So these are persistent storage variables that are in NV RAM on your platform Aka if you restart your operating system through always there They're persistent in firmware where nothing can see you EDR has no idea what it is No, no AV vendors even know this exists and let's be honest if you didn't know anything about UEFI this chart wouldn't help you So why UEFI variables and why are we gonna focus on platform level? Well Nothing is actually looking at UEFI platform firmware right now from a security vendor perspective like EDR and AV products are kind of starting to They've talked about doing it, but nobody really does it well and we can essentially just stash payloads in Platform firmware in these UEFI variables and evade basically everything. Nope. Nobody nobody looks here So basically what happened is you can take a name So in this case like a test name and then a thing called a GWID and it becomes essentially Tupel that can be looked up by the platform firmware in order to pull that that variable out of NV RAM Which contains a bunch of data and then there is variable attributes in this case a non-volatile Boot service accessible and runtime accessible and you need that in the windows environment in order to have persistent storage and pull it You can read the UEFI spec if you want to know more. I wouldn't recommend it So there's a couple of types of UEFI variables You've probably heard of authenticated variables before these are variables that are backed up with x509 aka secure boot Secure boot everything lives in an authenticated variable. That's where your PK your KEK and your DB keys and whatnot are so the things That actually sign like the boot loader. That's where that's where they're stored But what we care about is unauthenticated variables because there's no verification on right. There's no there's no verification They're not they're not signed And the majority of variables on your platform are actually unauthenticated. So to anybody looking it's benign. Whatever there's things there We nobody knows they exist So we're gonna talk about UEFI stuff on Windows and on Linux because it's platform firmware. It's also platform agnostic So every single operating system is using it and there's other forms of UEFI like we're gonna talk about the UEFI that's Published by Intel, but there's also like core boot which is Google's version of it that runs on like Chromebooks and whatnot But we're focusing on x86 platforms. So it's UEFI So UEFI and Windows is somewhat peculiar So they actually took it away in like early versions of Windows 10 and my background before Leading and doing red teaming stuff was a platform firmware research So when I was reading through some MSDN articles and I saw release notes on Windows 10 1803 They reintroduced the get-and-set firmware variable API And it had this long list of requirements. So it had to be you have to have this special token It has to be an admin app It has to be signed by the Microsoft Store in order to actually execute on a box All these requirements. There's a little URL. You can go and see all the things that are required Turns out as hackers, you don't actually have to worry about any of that shit. It all works So here's a really quick example, and we're flying through this. It's a lot of gotta talk fast There's get-and-set firmware variable Apis that once you bypass all of that bullshit that Microsoft says you need that you don't need you can do these things So I said that UEFI variable has a name and a grid people So those are the first two arguments basically when you're setting you just say I want to have this name in the squid And then you give it the the payload. We're gonna call it a payload because it's not data It's it's our malicious payload and you just say write that to a firmware variable with the squid and this this name And then when you pull it, it's similar You just give it a memory address over here in the ether that you're going to have like a Zara WX memory page You'll pull that firmware variable out Which is your payload and then you're gonna run it as like a raw memory pointer So you can do that in C++ Hilariously enough the MSDN article is a little bit right when you're talking about C++ and you need some of those Requirements in that long list So that kind of sucks and C++ do if you're at all familiar with how EDR and AV works Obviously if you're doing things like virtual protect virtual alloc and any of those calls to make RWX memory AV typically at this point in time is like whoa, you can't actually do that. That's malicious. Nobody does that. I You know blue team hunch you down and it's already over so in C sharp because of the notion of Like just in time compilation everything's RWX. So sweet free RWX memory for execution Nothing really ever looks at C sharp apps from an AV perspective like they'll look at strings and signatures of P invoke Which I'll get to but you can basically not worry about any of that either Furthermore, there's a bunch more stuff that makes C sharp great like bypassing W DAC is really easy Like sign code and C sharp whatever there's tons of tools that you just compile and run Specter ops guys have a lot of stuff on their blog about that and furthermore like we're red teamers We want to make things easy for a red team friend. So C sharp is like the language of choice right now since nobody uses PowerShell anymore And there's reference code for both in the repo which will show after the talk So basically if you want to write a UEFI variable to stash your payload and hide your shit You still need this SE system environment name token So this is a case where you do have to P invoke. You just have to get a privileged token That's pretty benign a lot of apps do that. So EDR doesn't really care about that You then get the address of your pin buffer in C sharp, which is your payload and it has to be pinned because Basically in order to do this you have to go from unmanaged to managed code or from managed code to unmanaged code and C sharp So if it's not pinned the garbage collector treats it differently So a little little C sharp fun for you I'm then you can just write the UEFI variable with with a grid and a name tuple and then it's in your platform firmware for forever So here's code to set it. It's it's all in the repo. Basically you you P invoke set privilege You obtain that SE privileged token and now you're privileged app You then get the address of the pin buffer in C sharp. So that's really easy to it's basically a couple of Reflective calls to like interop services. So in this case, I'm just pinning a Payload which I'll show you in the demo. It's basically for examples here. It's just going to be like a meterpreter super exciting and Then you write the UEFI variable. So here I have the variable name and the grid So there's my tuple. I give it the payload and then it just writes it into my UEFI platform So because I was saying UEFI platform NVRAM is persistent across everything so you can erase the operating system and that's still going to be there So you might not actually have the persistence mechanism to execute that payload, but it's still going to be there So that's that's pretty cool. It's nice artifact of this attack So to execute it, it's pretty similar You still need that token and you need a couple of other I'm going to hand wave things to get around So like for example persistence, we're not giving you a new persistence mechanism here. It's arbitrary It's whatever you want it to be Pick your favorite. I know all of you red teamers out there have have fun tools to do this So basically you still need the token in this case We're going to P invoke that RWX memory stuff and then obtain the UEFI variable with get firmware environment variable ex and then execute it But actually I was lying because we can't P invoke. I already told you that you don't do that Hilariously enough. I've done a lot of P invoke stuff and C sharp malware Writing in the past. I actually spoke at devcon 23 on a on a C sharp like malware framework thing that I built So I already knew this but when this came out OJ's tweet He was working on some C alarm interpreter stuff So I had to include it basically if you're writing C sharp malware, don't use P invoke It's the proverbial sin and EDR is going to find you and obviously we're trying to hide our shit and not get found So instead of P invoking what you're going to do now is you're going to reflectively obtain RWX JIT memory because everything in C sharp after it gets just in time compiled is RWX So that's that's a total freebie. I love it We'll still write in the same way But we're going to now write reflectively and then we're going to execute the method So I'll show you what that looks like in code because I know that's a lot So basically if you're not familiar with what C sharp and reflection is C sharp is great in that because it's an intermediate level language It has to get just in time compiled and all of that becomes RWX memory because they don't clean anything up once it's been jitted and If you look at the implementation of how C sharp does this you basically wind up with this huge mesh method table That has these JIT stubs for all of the classes methods So basically with reflection you can you can reflectively obtain and look at the the program Grab all of those methods that you want dereference the JIT stub Force the just in time compilation process to happen on that JIT stub despite the fact it's not going to be executed Grab that as a memory pointer Overwrite that memory pointer and then call it like it's a real method Follow me Okay, I'm going to show you some code So this is now instead of P invoke. This is step two. We're going to reflectively attain RWX chip memory We're going to define a method. We're going to jit it and then we're going to overwrite that pointer So this is real easy. I'm just going to define a method to overwrite. It does nothing overwrite me There's also a blog post on this if you're not following along so take a picture the slides are public Then you're going to jit the method so here I just reflectively get the overwrite me method and then I get the the method handle to it and once I have the method handle I can do runtime helpers prepare method and that forces the just in time compilation process And then I can dereference that method handle to the raw function pointer and that raw function pointer is the assembly code That's going to get executed on by the processor. So that's pointer to method now So then when I write the when I read the UEFI variable that's already been stashed by my writer binary I can now give the variable name and GWID tuple. I can use the pointer to method which is reflective RWX memory that's been jitted and then I can execute the method and I don't have to like use any weird like assembly voodoo here Like you'd have to do in C++ because overwrite me now points because I overwrote it in that reflective stub It up take it actually has the shellcode now from the UEFI variable So EDR and AV doesn't see shit So here's the demo I'm going to obtain a quick shell on the target. This is all hand wavy It's going to go real fast because Mike still has to talk and we have like eight minutes left So here's the demo. I'm going to speed it up So what I just did is I'm on a Windows box. I just ran a thing called chip sec It's a platform security tool that allows you to basically audit firmware variables and audit your UEFI platforms Check it out. It's awesome. So I just ran a module. That's essentially dump all of the UEFI variables You can see them all you can see which ones are authenticated which ones aren't what the attributes of them are I can go through and dump them all you can see that there's you know a variety of different variables and they all have data So like this is a test for example And so what I'm going to do is I'm going to use that right UEFI C sharp executable I'm going to write a new variable. So this is how I'm stashing my payload So I just wrote it. I'm stashing my payload. You can see now. I have a new variable. That's in the platform C sharp UEFI I can go through and actually list what the data is. So like I said, it's just going to be like a meterpreter payload There's the payload. It's just data within UEFI And at this point you might with that writer binary AV and EDR is going to catch you there probably Because like we said, we're just trying to flatten the wrist curve the initial shell pop. That's when they're going to catch you But once that pat payload and persistence is all in UEFI firmware variable space Yeah, they don't they don't see you anymore and that's what we want So here I'm going to come over and you write read C sharp So this is going through all the reflective magic and that's going to execute the UEFI variable with the reflective properties that I just described and then I can come over here and you can see that my shell opened So it gets better. So because this is a platform firmware It's persisting across reboots that variables always going to be living there I'm rebooting the VM just to showcase that that payload still going to be executed once the machine pops back up It's a cooking show. It's baking the VMs booting and there we go. It just reran. It's in platform firmware come at me EDR So that's the demo. What about EDR products? Well, like I said, they don't see any of this They might see the initial write binary, but that's about it No EDR is looking at UEFI variables. No, where's AV the persistence mechanism. Like I said is hand wavy Y'all know how to bypass persistence mechanisms and not get caught Furthermore, like EDR is pretty garbage. You can just think whole all of it anyway So I sink whole EDR within my UEFI payload So like even if they're turning it back on it gets disabled once the platform boots and it's being disabled from UEFI platform payloads Then some references and that's that's the window stuff Mike has like five minutes to talk about Linux bullshit All right, so that was awesome windows bullshit I don't understand any of it and anyone anyway everyone knows that all the real loot is on Linux anyway Instead of a interpreter. We got a full weaponized payload. So this is gonna go pretty fast Okay, so if we think about the problem space basically we have EDR EDR is looking at your you know looking at your payload which just became their sample the important thing to notice here is that the EDR and your payload because you're running as root, right? Are basically peers. There's a little bit of a kernel interface that the EDR uses to To look at what your sample is doing but basically, you know, this is an even playing field. So what can we do about this? Well, we can show up early and sucker punch the EDR and it becomes our payload and it's looking the other way So how are we gonna show up early? Well, let's let's talk about how your computer boots We know that it boots at the firmware and that's signed by the OEM and we can't infect that. That's a bummer and Then the shim boots which is signed by Microsoft. That's a bummer and Then grub boots and it's signed by the distro. That's a bummer And then the kernel boots which is also signed by the distro bummer The RAM disk though is unsigned and generated on the system So it looks normal to generate a RAM disk on a system and there's no verification. I like it And sometime later EDR shows up. So obviously we want to land where the happy face is so what what techniques do we have to To to control execution of the EDR. Well, we have ptrace and ptrace is great It lets you, you know, read them write memory and control the registers But the problem is that ptrace is usually prohibited by policy. The good news is policy is applied by user space That's great Okay, so let's think about how how this works in context. So first thing is system boots. You have PID 1. It's in the RAM disk space It execs into the root FS land that system D. It's also PID 1 it loads the policy and the EDR The thumbs down is the policy and the eyeballs of the EDR and then you know, you get rolled up and that's no good So what other APIs do we have to use we have FA notify FA notify is like an AV API. So we're just going to use that for evil lets you Intercept file opens and then hold them to decide if it's okay or no And then we have memfd create. We don't want to leave anything running on, you know leave any payload on disk So we'll just make a file descriptor in memory that looks That that looks like a file, but it's not one and then this is like some black magic fuckery That's in the code that you can you can just look in the code for black magic fuckery and you'll find this part Okay, so What we're going to do is we're going to make a demon you can see the little the little demon face in The boot flow and we're going to do that and it's going to span ramdisk land and And root FS land and it's going to open the UEFI firmware It's going to grab out stage two of the payload. So stage one is the demon Then system D is going to exact and it is going to stop the policy load from applying the prevents our malicious action Then we're going to inject into the EDR platform. That's stage three and How are we going to do that we're while we're going to p trace which is going to stop us right on the edge of a system call Then we're going to control eax and we can coerce by single-stepping system calls So we'll make a page That looks like a file. We'll put our we'll put our malicious library in there We'll map another will coerce another page and we'll put our shellcode in there And then we'll return to DL or we'll return to libc with the deal open with libc's internal deal open And then we'll return back to wherever the EDR was great so now The EDR is infected. It can't see us and we load the policy. So everything looks fine But it can't see our payload see the eyeballs are looking the other way This is the Linux demo We have like a minute 30 remaining. So I'm just going to let it rip and you're going to figure out what happened Oh god, how do you computer? See go go go. It's running. Oh god Computers are hard. Okay. I need to do this. I need to do this stuff contour He still doesn't know how to use okay, so we have the analyst on the right the hacker on the left We're going to tune up audit D as our example EDR Whoa So we tuned it up. You can see a bunch of noise there the analyst sees you We're going to exploit to get an enterprise tool to get root. You can see where root You can see like we're making noise. Oh, no, then we're gonna have a bad day now we're gonna overwrite the The RAM disk and infect the UEFI you can see it makes noise you saw that initial part You might get caught everything's infected. Have a nice day Then we reboot cooking show cooking show cooking show go go go go go go go Okay, we tune up audit here and you can see we're back at the analyst on the On the right and the hacker on the left then we set our marker there We set our marker so that our payload knows not to Not to look at us and Then you can see that That we have our marker. It's time or slack namespace and We can exploit things and you can see it's not making any noise in the in the EDR And we are totally silent And we're doing all of our our bad stuff and then ta-da. This is where you clap. It's hard because there's no shell pop It's just nothing happens Okay, so what does this all mean? Oh god. Oh god computers are hard This is this yields a net increase in overall happiness. You're happy the analyst is happy Everyone is going to have a pleasant a pleasant Friday evening All right, we're out of time so mitigations and recommendations like basically you're fucked All right, so there's some future work you talk to us outside about what it is Basically, we now have a net increase in happiness. We've flattened the wrist curve We're not going to get detected once our shells pop We're going to have a UEFI dot party and we're going to plunder aware loot like it's the 90s again There's a lot of code on our github repo. We're perturbed platypus or as every Awesome malware duo needs an apt name and in this case we're apt pp We can talk about that outside So that's all we got. There's some references. Thank you. Thank you very much. All right If anyone has any questions for them, let's let's move it outside and thanks for your time everyone