[00:00.890 --> 00:02.930] So, a little bit of a forewarning. [00:03.150 --> 00:07.890] This presentation was initially supposed to be conducted by me, myself, and another person. [00:08.530 --> 00:09.510] And that was a joke. [00:10.250 --> 00:10.690] No. [00:11.250 --> 00:15.650] So, this is going to be a heavily technical presentation. [00:15.910 --> 00:17.930] Those in the room, be very warned. [00:18.050 --> 00:19.050] This is not conceptual. [00:19.410 --> 00:24.430] It was initially supposed to be half and half, but because my people are not here today, that's what it's going to be. [00:25.050 --> 00:27.470] Although, some of you in the room might really enjoy this. [00:27.470 --> 00:31.650] So, is it showing up? [00:34.590 --> 00:35.550] It's not showing up. [00:45.410 --> 00:46.210] Ah, there we go. [00:46.350 --> 00:46.550] Okay. [00:46.670 --> 00:46.970] Hold on. [00:47.030 --> 00:47.450] Let me reset. [01:00.760 --> 01:01.100] Cool. [01:01.260 --> 01:01.640] Much better. [01:02.360 --> 01:02.720] All right. [01:02.800 --> 01:03.040] Awesome. [01:03.200 --> 01:05.840] So, my presentation is about EDR evasion. [01:05.960 --> 01:08.200] If you don't know what EDR is, we were going to get there. [01:09.200 --> 01:11.960] How Threat Actors Evade Modern Security Defenses. [01:12.320 --> 01:13.780] So, who actually am I? [01:13.860 --> 01:14.660] My name is Logan Klein. [01:14.800 --> 01:18.960] I have been a penetration tester and red teamer for Proactivist for about a year now. [01:19.160 --> 01:25.760] I have a little over 2,500 hours in offensive security engagements, along with 20 successful collectively engagements. [01:26.380 --> 01:39.400] I have lots of certifications from Security Plus to OSEP to OSWE, which I'm currently getting right now, along with my MALDEV certificate, which has been actually an amazingly fast and nice journey. [01:39.560 --> 01:42.800] I enjoy it all the way through, surprisingly. [01:42.800 --> 01:44.120] Uh, anyways. [01:44.400 --> 01:45.800] So, I specialize. [01:46.060 --> 01:51.280] My niche is in malware development, EDR evasion, and custom team software development. [01:51.460 --> 01:53.640] Basically, just offensive security tooling. [01:53.840 --> 01:57.860] I love making software in an offensive perspective, right? [01:57.860 --> 02:02.160] Uh, I'm a recent graduate of Alfred State College with my BTEC and cyber security. [02:02.480 --> 02:06.000] And I am genuinely passionate about offensive software development. [02:06.220 --> 02:07.400] I do this on my weekends. [02:07.440 --> 02:08.380] I do this on my free time. [02:08.520 --> 02:09.540] This, this is what I like to do. [02:10.280 --> 02:14.200] Uh, and this is why I've progressed so fastly, because I don't want to do anything else. [02:15.200 --> 02:15.600] Really. [02:15.760 --> 02:17.740] I mean, I know that sounds ridiculous, but yeah. [02:18.080 --> 02:19.540] So, what is EDR? [02:20.180 --> 02:20.280] Okay. [02:20.460 --> 02:23.940] EDR, in the most fundamental sense, is an antivirus plus. [02:23.940 --> 02:27.800] It's just, it's just, uh, literally, it's just antivirus and steroids. [02:28.600 --> 02:29.260] That's it. [02:29.540 --> 02:30.340] Very simple. [02:30.520 --> 02:42.300] It protects your endpoints, your actual machines from being targeted by, well, in theory, by being targeted in, by malicious threat actors, executing arbitrary code, whatnot, lateral movement. [02:42.520 --> 02:47.460] Uh, as you'll see later on, that's not always the case, because there are methodologies to bypass that. [02:47.720 --> 02:48.900] There's always a count and masking. [02:49.920 --> 02:52.860] As, as red team gets better, blue team gets better, and vice versa. [02:53.200 --> 02:53.280] Right. [02:53.500 --> 02:57.580] So, it's like this tug of war in the lines in the middle, in a sense, I guess, now that I think about it. [02:57.980 --> 02:58.340] Okay. [02:58.460 --> 03:01.080] So, what is in EDR, and how does it actually work? [03:01.220 --> 03:01.360] Okay. [03:01.580 --> 03:04.380] So, it works on a holistic oriented architecture. [03:04.820 --> 03:05.060] Okay. [03:05.200 --> 03:12.900] All that means, fancy word, interconnected, it simply just means it's using interconnected pieces of telemetry. [03:13.300 --> 03:13.700] Okay. [03:13.700 --> 03:16.400] So, let's just say if there's multiple eyes, right? [03:16.560 --> 03:17.980] So, each one of you guys have eyes, right? [03:18.940 --> 03:21.200] Imagine if you guys had more than one eye. [03:21.460 --> 03:21.780] Okay. [03:21.880 --> 03:22.040] Cool. [03:22.440 --> 03:35.060] So, it's using all of these eyes to actually see, to get information of the operating system to see if what you're doing, or if, what, or if what the user's doing, or if there's malicious code in the system, X, Y, and Z, and so forth. [03:35.320 --> 03:35.540] Okay. [03:35.620 --> 03:49.960] So, the analysis and the various data sources that we're going to be talking about in depth later on are going to be called AMSI, standing for anti- malware scanning interface, ETW, event tracing for windows, DLL patching, and signature-based detection, [03:50.100 --> 03:51.680] which is very linear, but we will get to that. [03:52.040 --> 04:05.720] Now, an important thing to note for the more technical people in the room is that the ETW element, part of it, an actual, a large part of it actually sits at the edge of the kernel space in the user space. [04:05.720 --> 04:19.040] So, basically what that means is that there's certain fundamental operations that cannot be bypassed, that you cannot, if the EDR is correctly configured, you literally will not be able to bypass it without rootkit level access. [04:19.260 --> 04:20.420] So, you need to be system. [04:20.560 --> 04:25.360] And even when you are system, you actually have to go out of your way, so to speak. [04:25.540 --> 04:26.960] It's much harder to do that. [04:27.200 --> 04:29.080] So, machine learning analysis. [04:29.320 --> 04:30.400] So, it uses weighted detection. [04:30.400 --> 04:37.200] So, a good way to describe this would simply be to, whenever you take college, right? [04:37.340 --> 04:39.800] So, everyone's probably been in a college class now or none, right? [04:40.040 --> 04:46.480] So, let's just say you get a B plus, okay, for four credits, and let's just say you get a C minus for two credits. [04:46.880 --> 04:54.880] Now, the four credit class that you get a B minus or B plus, whatever I said before, is actually going to be weighted heavier. [04:54.920 --> 04:55.320] Why? [04:55.320 --> 04:57.840] Because it has a baseline credit of four, okay? [04:58.080 --> 05:01.020] So, think about all those eyes and the telemetry. [05:01.220 --> 05:04.900] So, the data that it's gathering and synthesizing, like, collectively. [05:05.300 --> 05:22.760] And what it's doing is, depending on those types of data, those categories of data, whether it's network connections, threads being created, you name it, what's going to happen is it's going to have a specific weight within a specific context, and that's going to have a specific grade, okay? [05:23.520 --> 05:27.800] So, that's what holistic analysis kind of means. [05:28.020 --> 05:30.480] And that's what makes EDR a massive game changer. [05:31.020 --> 05:45.740] And you can imagine the outcome of an array of these weights and these grades would equal a certain threshold of probability of if a specific code or action is malicious or not, right? [05:45.740 --> 05:52.400] So, you can think, like, let's just say, if it's 30%, we're probably not going to alert and we're probably not going to inform the SOC team, right? [05:52.520 --> 05:59.700] But if it's 70%, what we might do is we might not actually block it because it's not 100% confident that it's actually malicious. [05:59.700 --> 06:04.500] So, we don't want to be creating, I guess, our own internal denial service in a sense. [06:04.500 --> 06:08.320] But we're definitely going to notify the SOC team and then the threat hunters are going to come in. [06:08.460 --> 06:11.300] They're going to say, hmm, this was probably malicious and here's why. [06:12.340 --> 06:18.320] These are trained... actually, yeah, speaking of which, these things could be trained also on a baseline. [06:18.700 --> 06:34.980] So, in other words, if you have an organization run normally for about a year, normal network connections, normal processes at normal times, it will get a heuristic, which is why machine learning is amazing, actually, in terms of the big data element of it, [06:35.060 --> 06:44.460] because it's able to, how do you say, extrapolate attributes and make interconnections that wouldn't be possible with humans in a realistic timeframe. [06:44.900 --> 06:49.100] So, it's going to see patterns that humans will literally just never be able to see realistically. [06:49.540 --> 06:55.300] And that's amazing when comparing the current instance to a previous known good baseline. [06:56.680 --> 07:00.280] Yeah, it's very... it's really actually very something nice. [07:00.860 --> 07:04.240] Yep, outputs, probability, likelihood of malicious behavior, weighted. [07:04.560 --> 07:09.600] Yep, integration within security operations center environments, and slash operational security environments. [07:09.800 --> 07:15.680] Okay, so, a security operation center environment is fundamentally a blue team environment. [07:16.080 --> 07:23.480] All it means is that it's a bunch of defenders, cyber defenders, who utilize blue team cyber defender tools. [07:23.480 --> 07:26.600] Although, sometimes they do use some what we would call red team. [07:26.760 --> 07:30.120] So, red team being offensive tools, blue team being defensive tools. [07:30.740 --> 07:34.320] Keep in mind, just to throw this out there, red team only exists to make the blue team better. [07:34.700 --> 07:36.880] Don't know why I had to say that, but I did, because it's important. [07:37.900 --> 07:40.380] Because we wouldn't exist without them, that's for sure. [07:42.340 --> 07:51.940] So, this allows for interoperability within the systems that they actually use to get telemetry, which is actually very nice. [07:52.580 --> 07:53.060] Cool. [07:53.400 --> 08:06.400] And for more people that are technical, the playbook automation within security orchestration and response automation frameworks and tool sets, you can automate a lot of your problems away. [08:06.820 --> 08:07.060] For sure. [08:08.320 --> 08:08.420] Cool. [08:08.920 --> 08:10.460] So, comparing EDR and antivirus. [08:10.640 --> 08:10.740] All right. [08:10.960 --> 08:13.540] Antivirus is primarily focused on signature-based detection. [08:13.540 --> 08:14.380] What does this mean? [08:14.800 --> 08:14.880] Okay. [08:15.220 --> 08:24.780] Are the zeros and ones inside of this file in this specific sequence, or within this specific context, malicious, known malicious, or not? [08:24.980 --> 08:25.400] Right? [08:25.500 --> 08:30.340] Could be a probability of being malicious, just like the weighted analysis, but it's extraordinarily linear. [08:31.320 --> 08:32.780] AVs are not nearly as holistic. [08:33.140 --> 08:33.260] Okay? [08:33.360 --> 08:35.040] That just makes them subpar overall. [08:35.280 --> 08:35.420] Right? [08:35.600 --> 08:42.000] The moral of the story, the synthesis, if you will, is that antiviruses are not enough to stop modern defenders. [08:42.000 --> 08:44.700] It's not even close, and you're about to see that in a minute or two. [08:45.260 --> 08:49.180] Now, what I will say is that the definitions of AV have changed into marketing. [08:49.520 --> 08:51.460] How many people in this room have heard of AI? [08:53.300 --> 08:53.740] Okay. [08:54.140 --> 08:55.540] It's technically not AI. [08:55.720 --> 08:58.100] And the reason why they do that is because of marketing. [08:58.300 --> 09:00.260] No one knows what a large language model is. [09:00.360 --> 09:03.120] No one knows what a machine learning algorithm is. [09:03.220 --> 09:06.000] But everyone knows what artificial intelligence is. [09:06.080 --> 09:08.800] Because we're intelligent, we understand the artificial part of it. [09:08.800 --> 09:12.300] The same thing goes to antivirus systems and EDRs. [09:13.280 --> 09:14.920] No one knows what an EDR is. [09:15.100 --> 09:17.500] Everyone knows what an antivirus is because people get sick. [09:17.640 --> 09:21.060] They have to go to the doctor and get cured from this virus. [09:21.220 --> 09:22.300] They recover from the virus. [09:22.420 --> 09:22.480] Right? [09:23.000 --> 09:27.520] So, these companies that are making these antivirus products are actually using a lot of... [09:27.520 --> 09:33.140] Not a lot, but a substantial amount of the EDR mechanisms of prevention. [09:33.140 --> 09:35.520] But they're just not saying it's an EDR. [09:35.820 --> 09:36.300] Right? [09:36.440 --> 09:38.360] Because they don't want to have to rebrand and remarket. [09:38.420 --> 09:39.580] They're just going to lose consumers. [09:39.600 --> 09:43.900] And they're just going to confuse their user base, in a sense. [09:44.080 --> 09:49.880] So, this EDR mechanism is definitely being diffused onto other technologies, for sure. [09:52.180 --> 09:54.100] So, what is AMSI? [09:54.540 --> 09:58.480] So, like I said before, AMSI stands for Anti-Malware Scanning Interface. [09:58.480 --> 10:00.540] Now, this is where it gets relatively technical. [10:01.880 --> 10:02.440] Okay. [10:02.580 --> 10:06.160] So, there are compiled languages, and there are interpreted languages. [10:06.500 --> 10:06.880] Okay? [10:07.180 --> 10:14.360] Compiled languages go straight from source code, so high-level code, to low-level code assembly, through what's called a compiler. [10:15.260 --> 10:15.360] Okay? [10:15.980 --> 10:16.480] Inter... [10:16.480 --> 10:20.200] Interpreted code goes through a specific environment. [10:20.200 --> 10:23.920] It gets converted into bytecode, generally speaking, although that can change. [10:24.100 --> 10:25.380] But it's generally bytecode. [10:25.380 --> 10:32.480] And then, from bytecode, it goes into the specific environment that translates that bytecode into machine code. [10:32.620 --> 10:35.680] And the reason why they do this, well, there is actually a good amount of reasons. [10:36.100 --> 10:43.620] But the primary one is for rapid development, because it allows you to operate on a level of abstraction that wouldn't necessarily be possible with other high-level languages. [10:43.960 --> 10:48.160] That's why you see certain languages like Python, they can be interpreted, but they also can be compiled. [10:48.160 --> 10:54.080] While C, you want the most low-level, how do you say, functionality possible. [10:54.340 --> 10:56.920] So, obviously, it's just going to be straight-up compiled, which is amazing. [10:57.020 --> 10:58.080] I like C a lot. [10:58.240 --> 10:58.980] C and C++. [11:00.000 --> 11:00.360] Cool. [11:01.880 --> 11:06.240] So, as you're going to see here on the next slide, this is kind of how the mapping is going to work. [11:06.240 --> 11:18.380] But for right now, just understand that it allows third-party applications to scan, basically, determine if interpreted code is malicious or not. [11:18.680 --> 11:22.040] And how it works, and they can make plug-ins for this. [11:22.180 --> 11:26.780] And it's well-documented on the Windows docs, variable-documented, actually. [11:27.560 --> 11:34.700] Although it's just kind of complicated, because Windows docs, they do a great job documenting, but the issue is that they kind of just don't explain things correctly. [11:35.380 --> 11:36.240] But then again, neither do I. [11:36.420 --> 11:37.100] So, fair enough. [11:37.860 --> 11:39.180] Which you're about to see in a second. [11:39.380 --> 11:39.480] Okay. [11:39.640 --> 11:41.760] So, you have these interpreted... [11:41.760 --> 11:42.700] Is my cursor showing? [11:42.820 --> 11:42.860] No. [11:43.000 --> 11:46.180] But you see on the top, you'll see PowerShell, VBScript, other application. [11:46.400 --> 11:46.460] Cool. [11:46.740 --> 11:48.000] Those are your interpreted languages. [11:48.320 --> 11:48.560] Okay? [11:49.420 --> 11:54.300] Those have certain runtime environments that take in the bytecode and turn it into assembly code. [11:54.420 --> 11:56.240] So, machine code, the raw zeros and ones. [11:56.640 --> 11:56.940] Okay? [11:57.340 --> 12:06.920] And then on top of that, what every time that if they have to, I guess, perform a cycle, that you can say, of these zeros and ones, they are going to call upon a function. [12:07.160 --> 12:07.540] Okay? [12:08.000 --> 12:12.260] And this function is going to be what's called in the Win32 API layer, rather. [12:12.840 --> 12:26.080] All this means is the Win32 API layer, it enables the user space to communicate with the kernel space through a safe mechanism, safe and abstract mechanism. [12:26.580 --> 12:29.520] That's kind of complicated, but I think you'll see what I mean later on. [12:30.120 --> 12:34.340] Now that layer is going to call another layer, and then that layer is going to call another layer. [12:34.540 --> 12:38.700] All this is, is a function calling a function, calling a function and passing multiple parameters. [12:39.500 --> 12:40.400] That's kind of it. [12:40.820 --> 12:41.840] Multiple segments of code. [12:42.140 --> 12:44.660] Now it's delineated, well, for multiple reasons. [12:44.860 --> 12:48.080] One security and one simplicity, because it allows for rapid development. [12:48.080 --> 12:53.560] Because the more abstract something is, the quicker that you can get something done generally, but the less you can do. [12:54.280 --> 12:54.540] Okay? [12:55.160 --> 12:56.440] So that's going to now... [12:56.440 --> 13:01.760] So the last, I guess, layer, you can see where the third-party AV provider class would be. [13:01.880 --> 13:05.580] This would be the plugin from the EDR virus software, whatever it may be. [13:05.580 --> 13:08.420] It's going to communicate via a protocol. [13:08.900 --> 13:09.820] RPC bind. [13:10.020 --> 13:10.780] Arbitrary name. [13:11.040 --> 13:13.260] Arbitrary protocol, relatively speaking, for the layman. [13:13.440 --> 13:13.880] Doesn't matter. [13:14.360 --> 13:16.640] They communicate on that local host. [13:17.060 --> 13:20.840] Send it up to, well, in this case, Windows Defender. [13:21.460 --> 13:25.120] But it would be the endpoint detection and response system at that point. [13:25.620 --> 13:27.180] Or the driver, rather. [13:28.080 --> 13:28.380] Cool. [13:29.540 --> 13:32.340] So there are two primary bypasses to this. [13:32.560 --> 13:38.360] So there's patching AMSI scan buffer, which if we go back to the slide really quick, you can see here, it's actually the... [13:39.400 --> 13:42.900] It's actually the first call, technically, in the sequence. [13:44.640 --> 13:51.060] Or, we can do what's called hardware breakpoint hooking. [13:51.700 --> 13:52.180] Okay? [13:52.380 --> 13:55.940] And that's exponentially more complicated, but I'm going to go over it because I do have time. [13:55.940 --> 13:59.980] Because I was supposed to have two more people here with me, so I had to change my presentation. [14:00.200 --> 14:01.120] Now I get to be more technical. [14:01.280 --> 14:02.520] Because I was the more technical guy. [14:02.640 --> 14:05.280] I know some of you guys in the room are like, I'm not supposed to be talking about this. [14:05.400 --> 14:07.000] I'm like, yeah, I'm not supposed to be. [14:07.480 --> 14:07.800] Anyways. [14:08.220 --> 14:08.540] Cool. [14:09.780 --> 14:10.100] Yeah. [14:10.400 --> 14:10.760] Thank you. [14:11.300 --> 14:16.160] So this is the segment of code that represents the AMSI scan buffer. [14:16.420 --> 14:16.700] Okay? [14:16.840 --> 14:21.220] So what this means is we're going to do what's called inline hooking. [14:21.640 --> 14:21.880] Okay. [14:22.300 --> 14:23.580] We're going to take the... [14:23.580 --> 14:25.040] I wish my cursor was there, but that's fine. [14:25.040 --> 14:31.140] We're going to take the line that says the virtual address location of AMSI scan buffer. [14:31.480 --> 14:35.200] This is the address of that function in memory, in runtime. [14:35.460 --> 14:39.260] And we identify that through various systems, which I will explain later on. [14:39.640 --> 14:43.340] We're going to overwrite it with the XOR buffer that you see above. [14:43.480 --> 14:45.300] So basically a bunch of zeros and ones. [14:45.300 --> 14:47.560] It's just four... [14:47.560 --> 14:48.320] So four... [14:48.320 --> 14:49.900] Four segments of hex. [14:50.160 --> 14:50.220] Right? [14:50.840 --> 14:53.440] So you're 4831, C0, C3. [14:53.660 --> 14:55.280] All this is, is simple XOR. [14:55.460 --> 14:55.660] Okay? [14:56.100 --> 14:57.480] So we're going to take a same... [14:57.940 --> 14:58.980] I think it's a RAX. [14:59.320 --> 15:02.940] We're going to XOR a register, basically a storage container. [15:03.220 --> 15:05.760] We'll run it through a specific bitwise operation. [15:05.760 --> 15:17.880] I guess I can describe a bitwise operation as simply performing certain low-level binary mathematical sequences, although that's probably not exactly correct. [15:18.080 --> 15:20.140] But that's one way to conceptualize it. [15:20.620 --> 15:22.960] And then that's going to return a zero. [15:22.960 --> 15:23.840] Okay? [15:24.160 --> 15:31.020] And because it's going to return a zero from this, now we can call the zero XC3. [15:31.220 --> 15:32.940] And that's going to be a return. [15:33.220 --> 15:38.160] That says, hey, this AMSI scan buffer that we're in, now we can exit it. [15:38.260 --> 15:42.820] And because the last operation had a return of zero, it's going to return zero. [15:43.100 --> 15:48.500] Meaning that the calling function now sees it as not malicious because the return was zero. [15:48.680 --> 15:49.760] Otherwise it would be one. [15:49.880 --> 15:51.360] Because in this instance it's one. [15:51.360 --> 15:52.500] Okay. [15:53.200 --> 16:00.880] And as you can see here actually on the second one, you'll see for later on, this same methodology works for ETW event rate location as well. [16:01.420 --> 16:01.660] Cool. [16:02.040 --> 16:04.360] Now time for the relatively complex part. [16:05.220 --> 16:05.820] Okay. [16:06.040 --> 16:09.540] So there's something associated... [16:09.540 --> 16:13.400] There's a component of the CPU called the address generation unit. [16:13.600 --> 16:13.880] Okay. [16:14.120 --> 16:23.300] All it means is that it's determining your effective current address and the address that you could be going to in that operation of your current effective address. [16:23.460 --> 16:23.540] Okay. [16:24.020 --> 16:28.060] So I live on a specific road and I go for walks a lot. [16:28.900 --> 16:29.160] Okay. [16:29.360 --> 16:30.640] I step out of my house. [16:30.820 --> 16:32.000] My house is number 73. [16:32.460 --> 16:32.760] Okay. [16:32.840 --> 16:34.280] That's my current effective address. [16:34.520 --> 16:39.180] The AGU understands that and it defines that for me because it handles that part for the CPU. [16:39.180 --> 16:41.940] When I walk down the street, it's 72. [16:42.420 --> 16:43.200] Then it's 71. [16:43.480 --> 16:45.120] So my effective address changes. [16:45.660 --> 16:45.940] Cool. [16:46.800 --> 16:47.080] Okay. [16:47.380 --> 16:50.740] Now you have your storage containers or your CPU registers. [16:51.160 --> 16:53.380] DRO, DR1, DR2, DR3. [16:53.860 --> 16:59.220] These are storage containers that enable hardware break point. [16:59.740 --> 16:59.820] Okay. [17:00.040 --> 17:02.020] Well, basically a hardware break point. [17:02.020 --> 17:11.780] And for the last, I guess for the more technical people in the room, if anyone's heard of a software break point, like in three, I think is the, is the mathematical operation with an assembly. [17:12.240 --> 17:14.020] That allows for logical debugging. [17:14.780 --> 17:24.660] So logical hooking, but that's easily detectable by just reading binaries because that, that piece of assembly that the zeros and zeros and ones should not be there because it's debugging, right? [17:24.760 --> 17:27.700] That's just an IOC and what we would call an indicator compromise. [17:28.340 --> 17:30.900] Someone's trying to do something legitly or someone's trying to do something bad. [17:30.900 --> 17:32.760] But either way, you, anyways. [17:33.140 --> 17:33.360] Okay. [17:33.780 --> 17:43.720] Uh, so what it's going to do is we can store a effective address within these CPU registers that we want to trigger our break point on. [17:44.160 --> 17:47.380] So the AGU says, hey, this is my effective address. [17:47.580 --> 17:47.860] Cool. [17:48.160 --> 17:49.400] I'm going to check these registers. [17:49.860 --> 17:53.560] It does my effective registers match any of these addresses. [17:54.140 --> 17:54.620] Okay. [17:54.720 --> 17:54.940] No. [17:55.200 --> 17:55.380] Cool. [17:55.520 --> 17:56.160] Onto the next one. [17:56.380 --> 17:56.760] Okay. [17:56.880 --> 17:57.440] Oh, it does. [17:57.740 --> 17:58.220] Okay. [18:00.900 --> 18:00.940] Okay. [18:01.160 --> 18:01.220] Cool. [18:01.580 --> 18:03.940] Now we're going to go to the CPU register storage container. [18:04.560 --> 18:05.000] DR7. [18:05.200 --> 18:09.880] Are we going to say, okay, were we told that we should trigger the break point upon an execution? [18:10.360 --> 18:11.180] Reading or writing? [18:12.080 --> 18:12.260] Okay. [18:12.360 --> 18:12.940] Let's just say writing. [18:13.540 --> 18:14.200] Oh, well, we're writing. [18:14.440 --> 18:14.640] Okay. [18:14.900 --> 18:16.280] Now this break point gets triggered. [18:16.700 --> 18:18.160] In this instance, probably be execution. [18:18.500 --> 18:20.340] But break point gets triggered. [18:20.860 --> 18:27.120] And now we set the break point through a bunch of what we would call low level native APIs and win 32 APIs. [18:27.640 --> 18:41.240] Told the system, the kernel of the system through syscalls to define the break point, like not logically, hardware-wise, that, hey, at this function in memory, you're going to trigger my break point. [18:41.320 --> 18:49.540] And the beautiful thing is, is that now I can cause an exception intentionally, and I can return the value of, no, this is legit. [18:49.860 --> 18:50.380] Right? [18:50.740 --> 18:55.420] My, whatever, whatever binaries, whatever zero ones got past you is, is legit. [18:55.720 --> 18:58.420] But logically, that, that didn't happen. [18:58.620 --> 18:58.800] Right? [18:58.900 --> 19:00.000] But it thinks it does logically. [19:00.740 --> 19:01.260] Okay. [19:04.140 --> 19:05.380] What is ETW? [19:05.600 --> 19:05.720] Okay. [19:05.820 --> 19:07.540] So this is event tracing for Windows. [19:08.200 --> 19:14.020] Fundamentally, this is actually, definitely more conceptually easier to understand for everyone. [19:14.540 --> 19:15.600] It's just logging. [19:15.600 --> 19:17.640] Like, it's just logging what happens on the systems. [19:18.760 --> 19:20.400] What processes were executed. [19:20.680 --> 19:21.880] What files were touched. [19:22.420 --> 19:23.080] Things like that. [19:23.580 --> 19:26.740] What registry keys, if you guys know registry keys. [19:27.160 --> 19:31.980] And actually, in theory, it could track everything if you configure it to do so. [19:32.580 --> 19:33.780] It could, in theory. [19:34.400 --> 19:43.260] It takes a lot of configuration, but I believe there are schemas of XML online that you could, I guess, download to configure and implement it. [19:43.360 --> 19:43.880] Anyways, cool. [19:45.680 --> 19:46.920] So, understanding ETW. [19:47.140 --> 19:48.140] So, real-time event logging. [19:48.680 --> 19:50.520] This is critical for incident responders. [19:50.680 --> 19:51.800] Yes, I have it at the bottom as well. [19:52.400 --> 19:55.920] So, again, all system events, in theory, can be logged. [19:56.180 --> 19:57.580] Very important, because that's a theoretical. [19:57.800 --> 20:08.980] Now, for my technical people in the room, when I was trying to perform this bypass a couple months ago, I ran into a big roadblock, if you say. [20:09.580 --> 20:13.300] So, there's kernel-level abstraction within ETW. [20:13.520 --> 20:13.680] Okay. [20:13.760 --> 20:14.400] What does that mean? [20:14.900 --> 20:15.060] Okay. [20:15.300 --> 20:23.800] So, ETW, technically speaking, monitors only in the, sorry, operates only in the kernel, but it monitors in both. [20:23.800 --> 20:24.500] Okay. [20:24.840 --> 20:37.640] So, what that means on a fundamental scale is that it's basically, technically speaking, it's impossible with its entirety to actually disable ETW without having rootkit or kernel-level access. [20:38.180 --> 20:39.500] It's literally impossible. [20:41.620 --> 20:55.000] So, basically, the ETW driver, okay, sits at the edge of the kernel space, okay, and it intercepts all of the system calls, because there's no way to get around a system call. [20:55.100 --> 20:57.880] I'm going to show you guys something in a couple slides here. [20:58.900 --> 21:04.040] And it's going to be fancy, I'm going to bypass certain stuff, but this is the edge, right? [21:04.160 --> 21:07.420] There's no bypassing these certain things, and you'll see that in the next slide. [21:07.940 --> 21:25.880] But it sits in between the user space and the kernel space, and it monitors for, well, it monitors for, if I can recall on the top of my head, process creation, thread creation, file creation, all that fun stuff. [21:26.020 --> 21:30.140] Even if you patch the user space, it will always do that, because there's always a syscall. [21:30.520 --> 21:30.980] Cool. [21:31.780 --> 21:36.480] Oh, and it has to be configured correctly, because keep in mind, ETW is independent of EDR. [21:36.480 --> 21:37.280] I should have said that. [21:37.640 --> 21:47.280] Because if your EDR system is not... and the reason why I'm saying EDR is because I can't imagine even right now an antivirus hooking into this, although maybe they are, because like I said, the marketing's changed. [21:48.520 --> 21:55.520] But the EDR has to be configured to actually read the system-level syscalls in the kernel, which is not that hard. [21:55.640 --> 21:57.540] They should be doing that, but some don't, right? [21:57.540 --> 21:57.940] Because... [21:58.380 --> 22:03.200] But you have like a distribution of good EDRs and bad EDRs and all that. [22:03.700 --> 22:07.500] Are all these things applicable to Microsoft Windows? [22:07.920 --> 22:09.940] Or are any of these EDR stuff going to be applicable? [22:10.140 --> 22:10.220] Oh. [22:10.860 --> 22:11.500] Yeah, yeah, yeah. [22:11.580 --> 22:11.920] Okay, okay. [22:12.200 --> 22:16.820] So the concept of the EDR is going to be applicable basically everywhere. [22:17.040 --> 22:17.440] Right? [22:17.660 --> 22:21.340] Now the tool or technology is going to change and its implementation is going to change. [22:21.340 --> 22:24.980] But the concept of these bypasses generally won't. [22:25.200 --> 22:31.540] Because believe it or not, and I don't want to go too in-depth in this, especially because now I'm definitely exiting out of my domain of competency. [22:32.200 --> 22:38.480] But generally speaking, if you look at the Windows architecture and the Linux architecture, they're actually relatively similar now. [22:38.620 --> 22:39.540] They're practical implementation. [22:40.300 --> 22:43.260] They use completely different functions, but they use something called share objects. [22:43.760 --> 22:46.000] That's just a dynamic link library for those who know. [22:46.180 --> 22:47.340] That's basically what it does. [22:47.420 --> 22:50.900] It's just a completely different methodology of practical implementation. [22:50.900 --> 22:52.340] It's the same concept. [22:52.660 --> 22:55.280] So a lot of the things that I'm talking about, because yes, you're right. [22:55.400 --> 22:57.600] I am talking about primarily Windows stuff. [22:58.360 --> 23:00.520] But it just, it does translate. [23:00.680 --> 23:08.400] And the exploit chain rather, or the malware chain, whatever you want to call it, is directly applicable to Windows only. [23:08.660 --> 23:10.560] But yeah, great question for sure. [23:11.820 --> 23:12.260] Cool. [23:12.600 --> 23:17.120] Although the EDRs and antivirus for Linux systems are notoriously bad. [23:18.100 --> 23:20.020] Worse, worse rather, relative to Windows. [23:20.200 --> 23:22.100] And I think it's because of this open-source stuff. [23:22.300 --> 23:23.000] And I don't know. [23:23.100 --> 23:24.900] I don't want to get into that because I kind of don't know. [23:25.380 --> 23:26.340] But generally. [23:27.420 --> 23:27.540] Okay. [23:28.000 --> 23:28.660] I skipped a slide. [23:28.840 --> 23:29.000] Cool. [23:29.440 --> 23:29.600] All right. [23:29.760 --> 23:30.040] Patching. [23:30.160 --> 23:34.220] So there's three primary bypasses for patching, for bypassing ETW. [23:35.000 --> 23:37.400] So there's the same patching, inline hooking, and memory. [23:37.740 --> 23:38.280] Okay, cool. [23:38.360 --> 23:39.820] You have the hardware breakpoint again. [23:39.820 --> 23:44.840] And then you have something because ETW is easy to understand at a high level. [23:44.980 --> 23:47.660] But it's actually far more complex, in my opinion, at least. [23:47.900 --> 23:50.280] Because all you're doing with AMSI is a bunch of function calls. [23:50.860 --> 23:53.160] Which technically this is too, but not really. [23:53.820 --> 23:54.160] Okay. [23:54.620 --> 23:59.260] If you guys are anything like me, when you looked at this diagram, you're like, what is going on? [23:59.360 --> 24:01.560] So I have another diagram to show. [24:01.720 --> 24:03.220] And I'm going to try and walk you guys through this. [24:03.360 --> 24:05.320] So we have the controller. [24:05.720 --> 24:08.380] Okay, controller initiates the ETW session. [24:08.380 --> 24:09.180] Cool. [24:09.480 --> 24:09.900] Hey, kernel. [24:10.140 --> 24:10.760] I want a session. [24:11.160 --> 24:11.360] Awesome. [24:11.480 --> 24:12.080] Here's your session. [24:12.680 --> 24:12.760] Okay. [24:13.160 --> 24:16.120] Now, kernel says, hey, your session's located in XYZ. [24:16.320 --> 24:17.560] This could be a physical file. [24:17.740 --> 24:20.940] This could be a file in memory, or what we would call a buffer. [24:21.240 --> 24:21.440] Okay? [24:22.140 --> 24:22.620] Cool. [24:23.100 --> 24:24.280] Here are your providers. [24:24.580 --> 24:24.860] Right? [24:24.940 --> 24:27.800] Your providers could be within a dynamic link library. [24:28.100 --> 24:34.860] All a dynamic link library is, in the most fundamental sense, is a resource for an executable to use. [24:35.480 --> 24:37.320] In its most fundamental sense. [24:37.320 --> 24:43.840] So there's a bunch of functions that executables can call upon from these shared resources. [24:44.860 --> 24:51.960] And one of those is called ETW EventWrite, located within a specific DLL called kernel.32. [24:52.640 --> 24:52.940] Cool. [24:54.380 --> 24:55.540] And then you have the consumer. [24:56.020 --> 24:58.160] In this instance, it's going to be the EDR. [24:58.940 --> 24:59.300] Okay? [24:59.520 --> 25:04.260] So the EDR is going to be able to consume all of this data, which is super nice for the EDR. [25:05.320 --> 25:08.960] Except there's one vulnerability that we can possibly do with this. [25:09.400 --> 25:14.940] Besides bypassing the provider, what we can do is we can actually hijack it. [25:15.640 --> 25:28.620] Because if the EDR is not getting system logs when it knows it should be, if it's configured correctly and it's a great EDR or even a good EDR, it's going to say, okay, why am I not getting event logs for this? [25:28.620 --> 25:29.900] It's not like it's not doing anything. [25:30.560 --> 25:35.240] Like, even if there's a thread going, if the thread dies, it should have told me a thread died. [25:35.440 --> 25:37.580] So what we can do is called provider hijacking. [25:37.940 --> 25:43.580] We can say, hey, Windows, Windows operating system, Windows kernel, I'm now your provider. [25:43.580 --> 25:45.900] And now I can send it arbitrary logs. [25:46.320 --> 25:47.100] So random logs. [25:47.380 --> 25:51.220] Right now, obviously, as an attacker, I wouldn't send it random logs, although you could. [25:51.480 --> 26:00.300] I would send it logs that are more emblematic of what legitimate software would be doing. [26:01.200 --> 26:08.240] But yeah, so like I said before, and this is actually one of the toughest things to bypass in these systems, is sessions are managed by the kernel. [26:08.740 --> 26:18.700] There's, there's no messing with the, if you don't have rootkit level access, generally speaking, there's really no messing with the session or consumer or controller for that matter, generally. [26:19.880 --> 26:28.120] So you, you can't prevent yourself from hiding process creation, images, file, network, registry, memory, like allocating memory. [26:28.300 --> 26:28.660] It's a big one. [26:28.760 --> 26:30.280] I didn't, I don't know why I didn't think about that before. [26:30.500 --> 26:30.680] But yeah. [26:31.980 --> 26:34.080] So DLL unhooking and hell escape. [26:34.280 --> 26:35.780] So now we get to the actual fun stuff. [26:35.780 --> 26:40.080] Because believe it or not, I actually implemented some of these stuff that I want to show you guys. [26:40.260 --> 26:43.040] And this is, this is why I was actually called upon here in the first place. [26:43.140 --> 26:45.320] Because I made, I made something relatively cool. [26:45.460 --> 26:45.960] I think it's cool. [26:46.060 --> 26:47.000] Half the people in this room don't. [26:47.100 --> 26:47.800] Which is fair enough. [26:47.980 --> 26:48.440] Because I'm a nerd. [26:48.580 --> 26:49.000] All right, whatever. [26:49.400 --> 26:49.900] Okay, continuing. [26:50.500 --> 26:50.700] Cool. [26:52.940 --> 26:53.300] Okay. [26:53.560 --> 26:57.100] The concept of DLL unhooking, or hooking and unhooking. [26:57.420 --> 26:57.520] Okay. [26:57.900 --> 27:04.580] EDRs hook or patch either in memory at runtime or statically on disk redirecting execution of the monoring code. [27:04.580 --> 27:04.980] Okay. [27:05.300 --> 27:07.360] All this means DLL, right? [27:07.480 --> 27:10.900] Shared resources that a executable utilizes. [27:11.220 --> 27:11.300] Okay. [27:11.620 --> 27:16.160] It's going to call upon those functions for when it needs something done within the Windows operating system. [27:16.300 --> 27:17.940] Or perhaps something a little bit more niche. [27:18.440 --> 27:19.020] Okay, cool. [27:19.220 --> 27:33.580] So what these EDR systems do is they say, hey, I know, hey, executable, malicious executable, I know you're going to call upon, let's just say, if you're going to do something malicious, you're going to call this specific function called, called virtual alloc. [27:33.580 --> 27:34.820] Because you want to allocate memory. [27:34.980 --> 27:36.080] And then you're going to call create thread. [27:36.260 --> 27:50.080] And so what I'm going to do is for the exact same thing that we did for the AMSI buffer, like the AMSI patching and the ETW patching, they're going to overwrite that function in memory to jump to their own malicious code. [27:50.080 --> 27:54.220] Just kind of like we did with the hardware breakpoint hooking. [27:55.060 --> 28:01.300] And the, it's like a combination of the hardware breakpoint hooking and the patching. [28:01.500 --> 28:15.000] Because they want to jump to their code so that way they can, and you'll see in a second, so that way they can actually look and get an exponentially better insight of what parameters are being passed to these potentially dangerous functions if implemented, [28:15.100 --> 28:16.480] well, maliciously. [28:17.680 --> 28:19.260] There are several ways to do this. [28:20.060 --> 28:22.800] And I actually am solid on time. [28:23.020 --> 28:26.840] But I will simplify the IAT, EAT, and inline hooking. [28:26.960 --> 28:28.180] Inline hooking is just what we did. [28:28.280 --> 28:29.000] We find it in memory. [28:29.240 --> 28:30.300] We overwrite bytes. [28:30.600 --> 28:33.600] Hey, jump to my code or return to exit this function. [28:33.800 --> 28:33.920] Cool. [28:34.760 --> 28:55.000] IAT and EAT hooking, at a fundamental level, there's a data, there's a sub data structure within the dynamic link library that has a export table that basically says, hey, executable, you can call upon all of these functions and I'm broadcasting to you through my own data structures what functions you can call. [28:56.560 --> 28:57.200] Cool. [28:58.640 --> 28:59.000] All right. [28:59.180 --> 29:00.080] I'm going to move on from that. [29:00.900 --> 29:04.300] Because then we're going to get in the weeds of this and I want to show you guys something really cool. [29:05.160 --> 29:05.340] Okay. [29:06.000 --> 29:06.360] Yes. [29:06.540 --> 29:12.340] So, again, it will redirect code because it hooked and patched the memory. [29:12.620 --> 29:12.700] Right? [29:12.920 --> 29:15.140] And so what this allows us to do, gathers parameters. [29:15.140 --> 29:25.400] So let's just say if you have a massive buffer and that buffer is like, for the more technical people in the room, I guess a typical meterpreter, basically typical malware. [29:25.760 --> 29:34.060] It's going to be able to scan that malware because even though that it's in memory, because again, and I guess I should have specified this further with the antivirus. [29:34.220 --> 29:36.920] The antivirus specializes on disk. [29:36.920 --> 29:37.580] Okay. [29:37.760 --> 29:38.760] So an on-disk scan. [29:39.200 --> 29:42.700] Originally, if you go back a decade ago, antivirus did not scan in memory. [29:42.960 --> 29:45.160] Now they do because it's more of an EDR thing. [29:45.720 --> 29:46.140] Kind of. [29:46.460 --> 29:46.520] Right? [29:46.720 --> 29:47.640] So generally speaking. [29:49.080 --> 29:58.660] And this allows to scan basically segments of memory appropriately without just scanning all the memory at once. [29:58.760 --> 30:01.080] And that would take up too much of the processing power on the CPU. [30:01.520 --> 30:03.080] Anyways, collect function order. [30:03.360 --> 30:07.300] So there's a order, a function called order, a heuristic, if you will. [30:08.120 --> 30:11.520] I should say malware is typically going to call, I want to allocate memory. [30:11.700 --> 30:12.240] Okay, cool. [30:12.380 --> 30:13.680] I'm going to write to the memory. [30:14.000 --> 30:14.580] Okay, cool. [30:14.800 --> 30:16.820] And then I'm going to create a thread at the memory. [30:16.980 --> 30:17.340] Right? [30:17.460 --> 30:20.640] And I'm doing those in sequential order without anything else in between. [30:21.460 --> 30:24.540] That in and of itself, and again, this is where the weighted detection comes in. [30:24.660 --> 30:27.280] That in and of itself is not a, hey, this is malicious. [30:27.280 --> 30:32.920] But all of these accumulative factors definitely will make it what we call an indicator of compromise. [30:33.100 --> 30:34.720] And then it would just be malware. [30:34.940 --> 30:35.000] Right? [30:35.540 --> 30:36.460] Inspect return values. [30:36.620 --> 30:39.520] So it can just see what is the, what is the output? [30:39.700 --> 30:41.500] What is the net output of this function? [30:41.640 --> 30:42.340] What is it returning? [30:42.660 --> 30:42.740] Right? [30:43.560 --> 30:45.020] Block or short circuit connection. [30:45.200 --> 30:45.260] Right? [30:45.360 --> 30:51.040] So again, if it's, if it's a weight of 70%, you might not want to block or short execution. [30:51.040 --> 30:53.160] But if it's 90 or above, you probably do. [30:53.500 --> 30:55.220] No matter what, you went over at the SOC team. [30:55.400 --> 30:55.860] So the blue team. [30:56.300 --> 30:57.580] But, yeah. [30:57.840 --> 30:59.280] And that's, again, configurable. [30:59.540 --> 31:01.600] Well, it should be if they did that correctly. [31:02.200 --> 31:03.020] Which they should have. [31:04.200 --> 31:04.600] Cool. [31:05.720 --> 31:08.160] High level overview of module stomping. [31:08.900 --> 31:09.240] Okay. [31:09.720 --> 31:11.120] This is where it gets kind of cool. [31:21.040 --> 31:25.620] So we can fundamentally resolve all of the functions ourselves without relying on the operating system. [31:26.080 --> 31:26.160] Okay? [31:26.800 --> 31:35.320] So, and, and the primary reason for that is because if we take from the operating system, again, high level concept, it knows that we're taking from it because it's, or sorry, sorry. [31:35.480 --> 31:40.720] If, if it gives us resources, rather, we, it knows it's giving us resources because it's giving us resources. [31:41.180 --> 31:41.400] Right? [31:41.600 --> 31:44.940] But if we take from it, we, they might not know that we're taking from it. [31:45.020 --> 31:45.180] Right? [31:45.180 --> 31:45.200] Right? [31:45.440 --> 32:03.500] So if we do everything ourselves and don't rely upon the Windows operating system and work on lower levels of abstraction possible and especially don't use other people's tools, you can get away with a lot of, I guess, typical indicators of compromise that other threat actors might not be able to [32:03.500 --> 32:15.160] just because there's more of a, how do you say, a net heuristic, malicious heuristic to what they're doing in general because they're using other things. [32:15.180 --> 32:15.700] They're using other people's tools. [32:15.880 --> 32:18.100] So if you want to be a good threat actor, make your own tools. [32:18.360 --> 32:21.620] That's what I always say because they're just really good. [32:21.740 --> 32:23.760] Anyways, okay, before I go on a rant because I do that. [32:24.280 --> 32:24.680] Cool. [32:25.100 --> 32:32.040] So what we're going to do is we're going to download a new one from the Microsoft repository, right? [32:32.160 --> 32:38.920] Because the DLL in memory is infested or infected with the patching of the EDR. [32:39.200 --> 32:40.320] So we want to remove that. [32:40.400 --> 32:41.180] How do we remove that? [32:41.340 --> 32:54.600] Well, we could do it methodically and all of that and in the code, but that'd be so, how do you say, so repetitive and there's no way that you can turn that into position, what we call position independent shellcode, which I will get to. [32:54.900 --> 32:57.960] It just wouldn't, it wouldn't be the correct size to do that. [32:58.180 --> 33:04.400] So what we do is we parse the DLLs, we get the timestamp, and we get the size. [33:04.840 --> 33:15.000] We cut those values in half, concatenate them together, and that's actually the unique identifier of that exact DLL represented within the Windows repository. [33:15.840 --> 33:23.560] So then we can go and say, hey, I know exactly what DLL this Windows system is using, and I don't even have to know when I send this malicious payload out. [33:23.760 --> 33:36.960] I don't have to know what operating system of Windows that you're using specifically because I'm resolving it dynamically in a way that's efficient enough to where I don't have to have a huge code base, right? [33:36.960 --> 33:38.540] I don't have to have a lot of shellcode to do it. [33:38.700 --> 33:40.640] So I'm able to, yeah. [33:41.060 --> 33:45.880] Anyway, so again, so parsing, parsing, lots of parsing, just lots of manual work. [33:46.320 --> 33:53.820] And what we do, and I will demonstrate this, but basically we find the DLL in memory, we download those DLLs, cool. [33:54.300 --> 34:01.940] We store them into what's called a heap, which is basically a growing, a dynamic memory space, okay? [34:01.940 --> 34:11.840] I don't know how to explain that without technical terms, but it's like a room that grows and shrinks, kind of, for more space in runtime when needed. [34:12.260 --> 34:12.700] Cool. [34:12.960 --> 34:13.820] We store those. [34:13.940 --> 34:23.360] We parse the one in memory that we just got, that we just downloaded, and get the elements that we need of it, which in this instance is going to be called the .text element. [34:23.640 --> 34:25.480] We're going to take that .text element. [34:25.480 --> 34:37.280] We're going to identify our current .text element of the DLL in memory, and we're going to superimpose it onto it, to remove all of those, well, from the threat actor's perspective, malicious buffers. [34:37.500 --> 34:42.740] But from the blue team's perspective, not, yeah, yeah, not malicious stuff. [34:42.920 --> 34:44.180] So, yes, cool. [34:44.560 --> 34:45.440] Very cool stuff. [34:45.600 --> 34:45.680] Okay. [34:46.120 --> 34:47.380] This is kind of complicated. [34:47.660 --> 34:52.740] But this is a high overview of the attack sequence that you're about to see. [34:54.480 --> 34:55.080] Okay. [34:55.660 --> 35:07.600] So, there's a executable, made in C++, using a certain environment that allows me to utilize certain frameworks and certain libraries I wouldn't normally be able to, okay? [35:08.140 --> 35:10.160] Because that's typically done in C sharp. [35:10.460 --> 35:12.340] That library is called the .NET framework. [35:12.720 --> 35:19.200] Through that .NET framework, I'm going to create a, what we would call a PowerShell run space. [35:19.200 --> 35:30.740] All that means is, for the more technical people in the room, is when you open up a PowerShell terminal, okay, what happens on the back end as you send commands, it's really sending it. [35:30.820 --> 35:33.820] All PowerShell.exe is, it's just a front for the back end. [35:34.280 --> 35:36.640] And that back end is a PowerShell run space. [35:36.900 --> 35:43.860] You send the command invocations there, and then you execute the script, and it gives you the command output to the console. [35:44.140 --> 35:44.520] Cool. [35:44.600 --> 35:48.280] What we're doing is we're just skipping the PowerShell part, and we're just opening the run space ourselves. [35:49.540 --> 35:49.900] Cool. [35:49.900 --> 35:54.520] That run space could live in, I guess, a very simplistic method for right now. [35:54.680 --> 35:59.800] It would be, like, for persistence would be an auto run binary, or something of that sort. [35:59.940 --> 36:07.780] Basically, whenever the computer restarts, it will execute the payload, download my malicious payload, so I can get a reverse shell again. [36:07.920 --> 36:09.540] There's other ways to do it, but yes. [36:11.980 --> 36:12.340] Cool. [36:12.340 --> 36:17.180] And so what that binary is going to do, it's going to download my malicious PowerShell script. [36:17.180 --> 36:17.720] Okay. [36:17.860 --> 36:21.100] What is my malicious PowerShell script comprised of? [36:22.440 --> 36:22.920] Okay. [36:23.260 --> 36:28.400] So it is comprised of two pieces of position-independent shellcode. [36:28.540 --> 36:28.700] Okay. [36:29.000 --> 36:30.880] What is position-independent shellcode? [36:31.120 --> 36:34.160] Position-independent shellcode is not context-dependent. [36:34.260 --> 36:34.480] Okay. [36:34.660 --> 36:35.260] What does that mean? [36:35.260 --> 36:46.980] That means I can put it anywhere in memory and create a thread or jump to it technically with a current thread, and then execute it, and it doesn't have to have context. [36:47.280 --> 36:57.100] It will all run on its own without a loader, without any type of assistance, if you will, because it's taking from the operating system, and it doesn't require anything of it. [36:57.680 --> 36:57.980] Okay? [36:59.100 --> 37:08.540] What this position-independent shellcode does, because there's two elements, the first element bypasses the AMSI by patching, because we're already doing that with the DLL unhooking. [37:08.960 --> 37:09.620] Two minutes? [37:10.560 --> 37:11.420] Oh, two minutes? [37:11.960 --> 37:12.400] 20. [37:12.640 --> 37:13.020] Oh, okay. [37:13.180 --> 37:13.640] No, 20. [37:13.800 --> 37:14.040] Okay. [37:14.280 --> 37:14.640] Sorry, guys. [37:15.100 --> 37:16.000] I thought I said two. [37:16.140 --> 37:16.320] I don't mind. [37:16.440 --> 37:16.660] Okay. [37:16.960 --> 37:17.400] Cool. [37:17.580 --> 37:17.860] All right. [37:17.940 --> 37:18.300] We're good. [37:20.260 --> 37:20.860] Awesome. [37:20.860 --> 37:21.460] Yeah. [37:21.720 --> 37:41.880] So, because we are already modifying the permissions in memory for this example, I figured, because I should have explained this actually earlier, the patching of AMSI and ETW in memory is a relatively high-level indicator of compromise, but as you'll see in the moment, [37:42.100 --> 37:53.220] and I did this somewhat intentionally, one, because the hardware breakpoint stuff was incredibly difficult to implement within what we call independent shellcode, and what I would have to do is I would have to make a custom loader. [37:53.320 --> 38:04.100] Basically, I would have to do what Windows does for my own program, and within the shellcode, I would have to have my shellcode, not to get too crazy anyways, I will go off the rails, so I'm going to stick to this. [38:07.100 --> 38:21.520] So, technically, and so what this is going to do is it's going to override AMSI, and technically it does not bypass AMSI because, as you'll see, it is actually a g-zipped binary, and by the time it executes, it just doesn't have any signatures in it because I made it my own. [38:21.860 --> 38:23.560] So, I technically don't have to do that. [38:23.680 --> 38:39.280] I'm technically, I am bypassing AMSI, but I'm doing that after I already did my malicious actions, which I did that actually intentionally because I could have made two separate dynamic link libraries, but one, this slide would be more, and two, I wanted to illustrate the fact that if you can make [38:39.280 --> 38:47.020] everything yourself and buy, you have a lot more freedom if you make everything yourself because there's just not signatures associated with it. [38:47.040 --> 38:50.240] I can make it do whatever I want, you know, with enough time, of course. [38:50.400 --> 38:51.900] And so, anyways, cool. [38:53.400 --> 38:56.160] That's going to bypass, right? [38:56.240 --> 39:05.400] It's going to unhook the DLLs and ETWs, the event, right, in the binary that actually called it, which is going to be the PowerShell downloader binary. [39:05.900 --> 39:08.000] So, we're going to remove all the bad stuff. [39:08.220 --> 39:10.100] Well, from the threat actor's point, bad stuff. [39:10.360 --> 39:12.300] But from the blue team's perspective, good stuff. [39:12.500 --> 39:14.360] So, it's a lose for them, win for us, awesome. [39:15.620 --> 39:31.360] Then, what our other position independent shellcode is going to do, after it executes that, and this is in the same reflective, and I should probably clarify, this is what we would call a reflective DLL. [39:32.700 --> 39:34.200] Basically, I'm taking a DLL. [39:34.560 --> 39:38.160] I'm taking the binary, I'm putting it into a different format called Base64. [39:38.480 --> 39:38.860] Okay, cool. [39:39.240 --> 39:42.300] Then, I'm zipping that Base64 to give it an appropriate size. [39:42.340 --> 39:46.700] Otherwise, it would be, like, ridiculously long, right? [39:46.780 --> 39:49.820] So, I have to zip it up, and then I have to unzip it, then use it. [39:49.900 --> 39:58.220] And this reflective DLL, which is the same file structure as the executable, by the way, which is very easy to use, actually, because you don't have to do anything else with it. [39:58.220 --> 40:11.660] Anyways, what that allows me to do is, and that's going to be in the PowerShell that we're going to download, and we're going to reflectively invoke these two positions of independent shellcode. [40:11.840 --> 40:17.700] And the second part of that is going to basically do what's called process hollowing. [40:19.440 --> 40:26.980] So, it's going to process hollow a native Windows service called SBChost. [40:27.260 --> 40:28.560] Okay, what does that mean? [40:28.900 --> 40:31.080] We're going to overwrite. [40:31.220 --> 40:32.500] We're going to create the process. [40:32.560 --> 40:35.060] We're going to suspend the process before it's created. [40:35.340 --> 40:39.820] We're going to slip in malicious code before a thread is started. [40:40.480 --> 40:40.920] Okay? [40:41.700 --> 40:49.120] And then what we are going to do is, well, start that code, and then we're going to basically start it. [40:49.520 --> 40:56.320] And this position-independent shellcode is going to bypass ETW, not AMSI, because that's not associated with SBChost. [40:57.440 --> 41:00.200] And it's not there by default, but it's going to bypass ETW. [41:00.420 --> 41:02.680] It's going to do the DLL unhooking bypasses. [41:02.680 --> 41:10.140] And in this case, for the sake of nice graphics, it's going to download a meterpreter stage one payload. [41:10.260 --> 41:12.580] And that stage one payload is just going to download another one. [41:14.020 --> 41:14.500] Cool. [41:15.520 --> 41:15.940] Okay. [41:16.160 --> 41:17.760] So, I'm going to go over this. [41:17.940 --> 41:20.260] And I could not fit the video in here. [41:20.380 --> 41:25.420] So, I'm going to have to show you guys like this, if it wants to load. [41:26.820 --> 41:28.060] You know what's funny, too? [41:28.240 --> 41:31.980] I pre-recorded this, that way the demo gods wouldn't punish me. [41:31.980 --> 41:34.060] But it won't let me open the file. [41:34.480 --> 41:36.980] So, it seems like the demo gods are spiting me. [41:37.800 --> 41:40.680] So, what I'm going to do... [41:42.300 --> 41:42.760] Oh, [41:49.440 --> 41:50.020] that's unfortunate. [41:50.540 --> 41:51.180] No shot. [41:51.340 --> 41:52.000] I'm going to find it. [41:52.580 --> 41:53.040] 100%. [41:54.500 --> 41:54.960] Sick. [41:55.180 --> 41:56.520] I even had it open. [41:56.700 --> 41:58.060] So, I wouldn't have to deal with this. [42:03.400 --> 42:03.860] Cool. [42:04.540 --> 42:05.040] Is that it? [42:06.180 --> 42:07.380] Please tell me that's it. [42:07.540 --> 42:08.260] MP4 file? [42:11.340 --> 42:12.360] That might not be it. [42:12.640 --> 42:13.860] Let's not do that. [42:15.020 --> 42:15.500] Unreal. [42:17.220 --> 42:19.320] I even had it up and prepared, too. [42:19.560 --> 42:20.640] That's so ridiculous. [42:22.140 --> 42:22.620] Okay. [42:25.020 --> 42:26.360] So, what is this file? [42:26.800 --> 42:27.900] This is probably it, right? [42:29.240 --> 42:30.000] Yeah, it is. [42:31.320 --> 42:31.800] Cool. [42:32.740 --> 42:32.980] All right. [42:32.980 --> 42:36.940] Demo gods just slightly agitated that I tried to circumvent them. [42:37.360 --> 42:40.480] Clearly not livid because they let me. [42:41.060 --> 42:41.380] Oh, no. [42:41.580 --> 42:41.780] Maybe not. [42:41.980 --> 42:43.040] Maybe it just has to load now. [42:43.300 --> 42:43.360] Cool. [42:44.840 --> 42:45.820] Has those Yankees. [42:46.360 --> 42:46.440] Yeah? [42:46.800 --> 42:47.820] They just played, right? [42:48.640 --> 42:49.480] Yankees just played? [42:49.920 --> 42:50.020] Yeah? [42:50.320 --> 42:50.460] Okay. [42:50.680 --> 42:50.880] Anyways. [42:51.120 --> 42:51.280] All right. [42:51.440 --> 42:51.560] Cool. [42:53.860 --> 42:54.280] Awesome. [42:54.280 --> 42:54.920] All right. [42:55.440 --> 43:02.180] So, what you guys are about to see here at first, this is the creation of the position independent shellcode. [43:02.680 --> 43:03.080] Okay. [43:08.200 --> 43:09.700] Thank you for letting me know, by the way. [43:09.880 --> 43:12.840] That would have been funny if I went through this entire thing and just everyone sitting there. [43:13.420 --> 43:14.900] That would have been hilarious, actually. [43:14.900 --> 43:16.400] You guys should have pranked me. [43:16.540 --> 43:17.180] That would have been good. [43:17.680 --> 43:17.880] All right. [43:22.460 --> 43:23.620] Oh, I know why. [43:30.730 --> 43:33.630] Because you guys have it set at a specific window, don't you guys? [43:34.890 --> 43:35.730] It's just whatever. [43:36.370 --> 43:37.310] It's whatever is there? [43:37.610 --> 43:37.810] Whatever. [43:38.590 --> 43:38.990] Okay. [43:39.190 --> 43:47.170] So, I'm going to try unplug and re-plug in and hopefully it connects to my actual video window that I have because it was connecting to the PowerPoint presentation. [43:49.130 --> 43:52.690] And because I couldn't put the video in the PowerPoint presentation, I think because of formatting. [43:53.170 --> 43:56.110] But, sorry guys, technical difficulties. [43:56.330 --> 43:56.490] I know. [43:56.590 --> 44:00.290] I'm giving a presentation about technical expertise and I can't do this. [44:00.430 --> 44:01.030] This is... [44:02.150 --> 44:02.510] Yeah. [44:02.790 --> 44:03.010] I know. [44:03.010 --> 44:03.870] I know it does. [44:04.030 --> 44:06.190] But this, you know, this is the lowest of the low right here. [44:06.510 --> 44:07.030] Sorry, guys. [44:08.290 --> 44:09.090] Can you see what I mean? [44:25.200 --> 44:25.560] Ah. [44:25.700 --> 44:26.380] Just duplicate it. [44:26.520 --> 44:26.540] Yeah. [44:31.940 --> 44:32.300] Oh. [44:32.740 --> 44:33.600] Thank you, my man. [44:34.320 --> 44:34.880] All right. [44:34.980 --> 44:35.920] It's the nerves that are getting me. [44:36.100 --> 44:36.260] All right. [44:36.320 --> 44:36.580] Awesome. [44:37.700 --> 44:38.140] Cool. [44:38.700 --> 44:39.060] Okay. [44:39.200 --> 44:47.200] So, what you guys are about to see, if this plays, is the creation and the development of the position independent shellcode. [44:48.840 --> 44:50.900] Come on. [44:51.020 --> 44:51.380] Let me... [44:51.380 --> 44:51.860] There we go. [44:52.480 --> 44:52.920] Cool. [44:53.180 --> 44:55.180] So, what you're seeing here is data structures. [44:55.180 --> 45:16.200] These data structures are going to allow me to store multiple dynamic link libraries, sorry, multiple elements of the dynamic link libraries with which I need to do in order to perform certain resolution... in order to resolve certain functions. [45:16.800 --> 45:17.380] Okay? [45:18.460 --> 45:19.620] And I... [45:19.620 --> 45:26.120] If you guys noticed, then I will go back slightly, is I have a my context data structure here. [45:26.280 --> 45:34.060] And the reason why I had to do that is because I can't initialize my data structures globally. [45:34.240 --> 45:39.200] And that's because the global data structures are located within the R data section. [45:39.200 --> 45:42.400] And those are read-only data, but I have to write to it. [45:42.800 --> 45:43.000] Okay? [45:43.940 --> 45:47.860] And because of that, and I didn't want to make my own custom loader yet just for this. [45:48.000 --> 45:53.340] So, I figured, okay, I will just keep everything within the dot text section, hence the stack and everything in the heap. [45:54.000 --> 45:54.340] Okay? [45:54.920 --> 45:55.700] And, yeah. [45:55.840 --> 46:01.580] So, this allows us basically to write to these data structures while invoking it in the stack and passing that context. [46:01.880 --> 46:04.100] So, what you see here is basically a little bit of assembly. [46:04.380 --> 46:06.340] Hey, you're going to start at the function called entry. [46:06.880 --> 46:07.320] Cool. [46:07.320 --> 46:10.040] These are my read-only variables, right? [46:10.180 --> 46:14.380] But I'm telling, hey, GCC compiler, you're going to store these within dot text. [46:14.960 --> 46:15.480] Cool. [46:16.520 --> 46:16.800] Okay. [46:17.060 --> 46:21.140] These are my type definitions because I'm going to have function pointers. [46:22.200 --> 46:37.780] And so, the compiler, even though that I'm getting pointer functions to functions in memory, the compiler still needs to know what these functions, the schema of these functions, if you will, or the framework of the structure, because it needs to be able to compile it. [46:38.040 --> 46:38.520] Right? [46:39.420 --> 46:41.900] So, I also have a custom hasher here. [46:42.040 --> 46:44.620] It's based off of a very well-known hasher. [46:44.760 --> 46:47.040] I forget the specific name, DJ something. [46:47.040 --> 46:51.520] But basically, I implemented that. [46:51.680 --> 46:56.740] I have two different variations of unique code variation, normal code variation. [46:57.020 --> 46:57.040] Cool. [46:57.480 --> 47:02.720] And this is going to allow me to not have explicit strings within my shell code. [47:02.820 --> 47:06.220] Because if I have a bunch of strings in my shell code, it's going to be relatively... [47:07.000 --> 47:08.860] Well, it's not going to be easy, but it's just another indicator. [47:08.860 --> 47:09.980] It's bad OPSEC, right? [47:10.480 --> 47:10.840] It's just... [47:10.840 --> 47:12.560] It's just a bunch of, oh, I'm... [47:12.560 --> 47:17.520] Why are all of the function strings that I'm calling with... [47:17.880 --> 47:20.820] In the strings, but the binary doesn't see that I'm calling these functions. [47:21.480 --> 47:21.800] Right? [47:21.860 --> 47:22.940] So, why do I have them in string format? [47:23.160 --> 47:27.860] It's just another IOC that we bypass by hashing it and then getting a known hash from that set... [47:28.720 --> 47:29.160] 10 minutes? [47:29.560 --> 47:29.820] Cool. [47:29.960 --> 47:30.880] Sorry, I don't have my glasses on. [47:31.260 --> 47:32.120] I should have... [47:32.120 --> 47:33.680] You know, I don't know what I was thinking, but... [47:34.220 --> 47:34.540] Cool. [47:34.700 --> 47:35.320] Oh, questions? [47:35.720 --> 47:36.320] Yeah, yeah, yeah. [47:36.420 --> 47:37.420] All right, I'm going to fly through this. [47:37.800 --> 47:38.120] Cool. [47:38.860 --> 47:46.280] We're going to identify the process environment block, and then we are going to identify the image base. [47:46.380 --> 47:48.480] From the image base, we're going to do a bunch of data structure stuff. [47:48.880 --> 47:52.880] Those documented data structures allow me to parse and get the function pointers in memory. [47:53.320 --> 47:56.920] I'm going to rush to make sure you guys get some questions in while still showing you this. [47:57.080 --> 48:01.660] This is going to fetch the resource from what I was talking about earlier from Microsoft repository. [48:02.700 --> 48:03.580] And then... [48:04.380 --> 48:06.340] Please pass slogan, scroll down. [48:06.620 --> 48:06.940] Cool. [48:06.940 --> 48:17.360] This is the build URL that's actually going to take the time date stamp and the image size and append it to a string and give us the proper URL string. [48:17.640 --> 48:17.760] Cool. [48:18.020 --> 48:18.280] Awesome. [48:20.820 --> 48:21.340] Yep. [48:22.320 --> 48:22.820] Cool. [48:23.140 --> 48:24.020] That's what it's doing. [48:24.260 --> 48:25.360] Identify the text section. [48:25.360 --> 48:34.160] So this is identifying the text section within both the stored, the downloaded DLL and the one that's already present in memory. [48:34.360 --> 48:37.520] And I'm overwriting the one in memory with the one that I downloaded in the heap. [48:37.600 --> 48:38.780] That's located down in the heap. [48:39.260 --> 48:39.540] Okay. [48:39.700 --> 48:39.960] Cool. [48:40.320 --> 48:40.920] That's what I'm doing. [48:41.140 --> 48:43.220] And then there's the AMSI ETW bypass. [48:44.440 --> 48:44.880] Awesome. [48:45.040 --> 48:46.800] And that's the fetch stage two payload. [48:46.800 --> 48:49.180] This is what we're going to insert into SVC host. [48:49.320 --> 48:54.580] Keep in mind, the position independent shell codes are slightly different for the SVC host and the other one. [48:54.660 --> 48:58.120] But this is 99% of what it is. [48:58.500 --> 48:58.920] Cool. [48:59.100 --> 49:00.320] Now we're going to do all that fun stuff. [49:00.580 --> 49:03.800] We're going to call these function pointers and execute those functions. [49:04.020 --> 49:04.260] Cool. [49:04.420 --> 49:04.780] Awesome. [49:06.100 --> 49:07.140] Oh, no. [49:07.360 --> 49:07.760] My video. [49:08.240 --> 49:08.340] Okay. [49:08.440 --> 49:09.520] Hopefully I full screen this. [49:10.000 --> 49:14.920] This is where I'm storing that position independent shell code. [49:15.380 --> 49:15.900] That's... [49:15.900 --> 49:16.520] Yeah, I know. [49:16.760 --> 49:17.580] You want to know why? [49:17.640 --> 49:20.760] It's because I have a 256 display at home. [49:21.600 --> 49:24.280] And I think I... [49:25.000 --> 49:25.880] There we go. [49:26.620 --> 49:28.220] Basically two sets of shell code. [49:28.420 --> 49:28.740] Cool. [49:29.160 --> 49:34.140] One of them is for the AMSI and ETW bypass for the current PowerShell downloader. [49:34.140 --> 49:41.500] The other one is going to be for SVC host to obviously bypass the DLL hooking and all that fun stuff and still download our malicious payload. [49:42.220 --> 49:46.040] You see here that we're spawning the SVC host process with the suspend flag. [49:46.180 --> 49:48.340] Keep in mind, we are using get proc address, which is... [49:48.340 --> 49:50.160] And I actually do this intentionally because... [49:50.840 --> 49:52.180] Well, one, for the sake of rapid development. [49:52.620 --> 49:57.960] Two, for the sake to illustrate that you don't have to do everything perfect if you make everything custom for EDR bypassing. [49:58.100 --> 49:59.500] Because all I did was... [49:59.500 --> 50:01.880] And this is a very rudimentary methodology to do... [50:01.880 --> 50:04.040] Is get module handle A and get proc address. [50:04.220 --> 50:09.120] Basically what I am doing manually in my shell code, I just did within this net assembly. [50:09.680 --> 50:11.500] Just one, obviously for the sake of development. [50:11.760 --> 50:14.380] Two, you don't have to be perfect. [50:14.520 --> 50:16.360] You just have to meet a specific threshold. [50:16.760 --> 50:17.140] Okay? [50:18.000 --> 50:20.280] So we're resolving those functions dynamically. [50:20.640 --> 50:21.880] We're calling upon those functions. [50:22.140 --> 50:23.200] We're doing all that. [50:24.400 --> 50:27.040] Again, we're getting the process environment block. [50:27.960 --> 50:29.700] We're finding the image base. [50:29.980 --> 50:32.820] We're finding ELF new, which points to the NT header. [50:33.100 --> 50:33.560] Cool. [50:33.660 --> 50:34.180] There's signature. [50:34.500 --> 50:35.260] This is... [50:35.260 --> 50:41.740] Now, this binary that you just saw with the two pieces shellcode and the process hollowing is base64 gzips encoded. [50:42.040 --> 50:44.600] This is placed within here on my attacking machine. [50:44.760 --> 50:48.580] And that's what's going to be downloaded and reflectively loaded as a DLL. [50:49.960 --> 50:50.520] Cool. [50:53.320 --> 50:53.800] So... [50:53.800 --> 50:55.440] And then this is the PowerShell downloader. [50:55.520 --> 50:58.360] Now, of course, me being the hyper-intelligent being that I am. [50:58.520 --> 50:59.020] Definitely not. [50:59.200 --> 51:00.700] I did not full screen this. [51:01.440 --> 51:01.920] So... [51:01.920 --> 51:04.760] But what this does is it's just a simple PowerShell one-liner. [51:04.900 --> 51:09.940] And by the way, yes, this does bypass signatures even on disk, which is... [51:09.940 --> 51:18.560] Because there's not much inherently dangerous about a PowerShell downloader in and of itself, especially because it presumes it relies upon AMSI. [51:19.620 --> 51:20.100] Cool. [51:20.100 --> 51:21.380] How many minutes do I have left? [51:21.860 --> 51:22.420] I'm done. [51:22.740 --> 51:23.560] But, you know... [51:23.560 --> 51:24.200] Six. [51:24.460 --> 51:25.720] Six for questions. [51:25.960 --> 51:26.100] Okay. [51:26.720 --> 51:28.600] And then you'll see SVC host process. [51:28.820 --> 51:29.040] Voila. [51:29.260 --> 51:29.640] It works. [51:30.620 --> 51:31.460] EDRs bypassed. [51:32.000 --> 51:32.360] Fantastic. [51:32.860 --> 51:34.920] I mean, that's pretty much why I have to... [51:34.920 --> 51:37.260] Especially because I went longer than I anticipated. [51:37.960 --> 51:39.460] But, you know, do you guys have any questions? [51:45.840 --> 51:46.160] Yeah. [51:46.320 --> 51:46.700] Go for a minute. [51:47.080 --> 51:47.340] All right. [51:50.100 --> 51:50.420] So... [51:50.420 --> 51:57.800] The DLL and hooking relies on overriding VDR hooked versions of DLs, clean versions in memory. [51:57.920 --> 52:03.380] Are there no protection mechanisms to prevent or attach those types of... [52:03.380 --> 52:03.540] No. [52:03.760 --> 52:03.860] No. [52:04.020 --> 52:04.300] Of course. [52:04.480 --> 52:04.540] Yeah. [52:04.680 --> 52:07.640] So basically, because keep in mind whenever you modify memory... [52:08.280 --> 52:08.640] Yeah. [52:09.100 --> 52:21.400] So the ETW system, because again, this is operating on the kernel level, those virtual protects, so those APIs, to modify those positions in memory, even if you bypass... [52:21.400 --> 52:34.680] First of all, let's just say because there's a system call that's associated with those functions, if the EDR is configured correctly, it's going to be able to say, why are you modifying rewrite execute change to this section, the text section of the DLL? [52:35.120 --> 52:35.980] We don't want that. [52:36.140 --> 52:36.660] Right? [52:36.660 --> 52:51.380] Now, keep in mind, this method will not work for all EDRs, which is why it's very awesome, and this is why I love getting super deep into the custom software development, just for offensive security purposes, because one EDR might detect something that another EDR just completely misses out on. [52:51.420 --> 52:51.500] Sure. [52:51.700 --> 52:54.180] That's because it's so dynamic, that it's actually... [52:54.180 --> 52:55.920] There's blind spots for certain... [52:55.920 --> 52:57.680] It's like they have their own personality, in a sense. [52:57.820 --> 53:06.500] But yes, no, there's definitely mechanisms, because if they're properly monitoring the ETW calls, or the sysc calls via ETW at the kernel level, they should be able to stop that. [53:06.500 --> 53:07.040] Okay. [53:07.100 --> 53:08.420] And say, what are you doing? [53:08.620 --> 53:09.000] No, no, no. [53:09.000 --> 53:09.740] Like, done, right? [53:09.940 --> 53:15.000] Now, you might be able to do what you have to do quick enough, right, to where it can't... [53:15.680 --> 53:20.340] It's detecting and trying to stop, but you've already spawned the other process, like the SBC host process. [53:20.340 --> 53:30.960] And if you're doing what's called PPID spoofing, so parent process ID spoofing, and some other mechanisms, you might be able to trick the EDR into thinking that this spawned from a different process. [53:31.140 --> 53:37.720] That way it doesn't terminate the entire process line of... [53:37.720 --> 53:38.180] Sure. [53:38.180 --> 53:39.600] That's the spawning of the processes, right? [53:40.000 --> 53:40.240] Yeah, yeah, yeah, yeah. [53:40.480 --> 53:40.560] Yep. [53:40.920 --> 53:41.280] That's... [53:41.280 --> 53:41.340] Yeah. [53:41.760 --> 53:41.960] Cool. [53:42.640 --> 53:42.760] Yep. [53:43.460 --> 53:43.740] Absolutely. [53:44.440 --> 53:45.160] Any other questions? [53:49.640 --> 53:51.920] I either did a really good job or a really bad job. [53:52.780 --> 53:53.980] Because no one's got questions. [53:54.120 --> 53:54.500] That's awesome. [53:55.160 --> 53:55.980] Any other questions? [53:56.360 --> 53:56.500] No? [53:56.880 --> 53:57.060] Okay. [53:57.060 --> 53:57.120] Sure. [53:59.300 --> 53:59.660] All right. [53:59.860 --> 53:59.940] Cool. [54:00.680 --> 54:01.080] Yeah. [54:01.660 --> 54:01.800] All right. [54:02.020 --> 54:02.540] Thank you guys. [54:02.860 --> 54:03.940] Thank you guys for having me. [54:04.400 --> 54:05.040] Appreciate it.