1 00:00:00,580 --> 00:00:02,400 All right, welcome back, everybody. 2 00:00:02,400 --> 00:00:08,740 And thank you so much for supporting the DEF CON community and especially the Red Team Village. 3 00:00:08,760 --> 00:00:12,080 And without any further ado, I pass it back to Gabriel. 4 00:00:12,460 --> 00:00:13,480 Take it away. 5 00:00:14,080 --> 00:00:15,180 Hi again, everyone. 6 00:00:15,580 --> 00:00:20,240 This is a little different, but yeah, this is... 7 00:00:20,240 --> 00:00:22,660 I'm introducing a new tool called DropEngine. 8 00:00:22,660 --> 00:00:25,460 It's a Malibu payload creation framework. 9 00:00:25,480 --> 00:00:30,420 A bit about me, won't go on about this for too long, but my name is Gabe Ryan. 10 00:00:30,420 --> 00:00:32,580 I'm a Red Team Operator at Specter Ops. 11 00:00:32,700 --> 00:00:36,820 I used to work in a place called Gotham Digital Science doing security consulting. 12 00:00:37,240 --> 00:00:42,480 Got my Twitter handle and my LinkedIn username is actually pretty interesting. 13 00:00:42,480 --> 00:00:45,640 It's ms08016. 14 00:00:46,620 --> 00:00:49,740 So without further ado, let's just dive right into this. 15 00:00:50,060 --> 00:00:52,540 Let's talk about initial access payloads. 16 00:00:52,580 --> 00:00:55,760 So what are initial access payloads as opposed to normal payloads? 17 00:00:55,760 --> 00:01:00,060 Initial access payloads are typically used to gain access to a system environment. 18 00:01:00,060 --> 00:01:07,020 So at the very start of your engagement, it's what you're using to essentially gain your initial foothold. 19 00:01:07,880 --> 00:01:09,260 They're pretty simple in design. 20 00:01:09,260 --> 00:01:13,540 I mean, it really has like one job, which is to execute an implant or second stage payload. 21 00:01:13,820 --> 00:01:20,160 And then from there, you pretty much do everything, you know, all your secondary endpoint operations happen from that point onwards. 22 00:01:20,520 --> 00:01:25,560 Colloquially, they're also known as droppers or shellcode runners because they run shellcode. 23 00:01:27,320 --> 00:01:36,100 But yeah, you know, while initial access payloads do have a pretty simple role, there are some obstacles that you have to face when designing them. 24 00:01:36,100 --> 00:01:40,780 So I mean, despite the fact that it's like, you know, they perform a seemingly mundane task, right? 25 00:01:40,780 --> 00:01:43,120 That they just load code in memory and execute it. 26 00:01:43,740 --> 00:01:45,840 You know, there are some challenges to contend with. 27 00:01:45,840 --> 00:01:53,460 The first of which is that, you know, during the delivery phase, so what you're actually trying to get this payload onto the target machine. 28 00:01:53,900 --> 00:01:56,560 Usually, that's going to be done via spear phishing. 29 00:01:56,600 --> 00:02:08,860 And if that's the direction you're going, you know, this payload is going to be exposed to signature-based detections, you know, in the form of mail filters, you know, and stuff that's scanning through the email that you're sending out. 30 00:02:09,080 --> 00:02:12,020 It also may be exposed to automated behavioral analysis. 31 00:02:12,020 --> 00:02:21,020 So automated sandboxes, essentially what they do is they take your payload, and they actually execute it in a controlled environment. 32 00:02:21,220 --> 00:02:31,840 The reason why they do this is that you know, whereas if you're just looking for signatures, you're going to get these like brittle signatures, but that are kind of easy to evade. 33 00:02:31,840 --> 00:02:42,580 But in this instance, if you're looking at that, you know, what the program is doing, while it's executing, you're actually looking at behavior, which is a little more difficult to hide. 34 00:02:43,860 --> 00:02:47,680 And finally, during the delivery phase, your payload is going to be downloaded and saved to disk. 35 00:02:47,680 --> 00:02:51,220 And you have to do this without triggering AV or, you know, getting caught by EDR or whatever. 36 00:02:52,580 --> 00:02:55,300 So that's the final challenge. 37 00:02:55,380 --> 00:02:57,720 And then once you've done that, you have to execute your payload. 38 00:02:57,720 --> 00:03:00,260 So the payload is going to be executed from disk. 39 00:03:00,280 --> 00:03:05,280 Usually if it's like a phishing payload or something like that. 40 00:03:05,820 --> 00:03:10,060 Although typically in-memory operations are a little better. 41 00:03:10,520 --> 00:03:11,680 You know, when you're just... 42 00:03:12,440 --> 00:03:15,920 One of the challenges of your initial access payload is that you can't really start that way. 43 00:03:15,920 --> 00:03:18,140 So you have to start from disk a lot of time. 44 00:03:19,280 --> 00:03:24,320 And you have to do this without triggering Antivirus or Endpoint Detection and Response, aka EDR. 45 00:03:24,520 --> 00:03:34,760 In Windows environments, you know, that you're also going to, you know, application whitelisting is pretty much ubiquitous if you're operating within like an Active Director environment or dealing with Windows. 46 00:03:35,800 --> 00:03:38,860 What this means is that you're going to have to find a way to bypass that. 47 00:03:38,860 --> 00:03:41,380 And that usually means relying on something called... 48 00:03:41,380 --> 00:03:46,620 the concept known as live-off-the-land binaries and scripts or LOBOS. 49 00:03:46,680 --> 00:03:54,000 Essentially what these are, I mean, they're just like utilities, they're binaries that become packaged with the operating system. 50 00:03:54,380 --> 00:04:00,160 And, you know, they're usually designed to like fulfill some benign role. 51 00:04:00,220 --> 00:04:01,880 But you can actually... 52 00:04:01,880 --> 00:04:10,740 What makes them special is that they have some functionality that you can essentially leverage to do something that is useful for you as an adversary. 53 00:04:10,740 --> 00:04:21,520 So in this case, there are several live-off-the-land binaries and scripts that can be used to execute payloads in various interesting ways. 54 00:04:22,140 --> 00:04:23,920 So that's fortunate that you can rely on that. 55 00:04:23,920 --> 00:04:27,680 You can use that to bypass application whitelisting. 56 00:04:27,680 --> 00:04:40,540 The problem is that most of these pretty much restrict you to programming languages and execution methods that get filtered through the Windows Common Language Runtime or CLR. 57 00:04:40,540 --> 00:04:49,520 And CLR, if you're going through the CLR, you have to contend with Microsoft's anti-malware scan interface for AMP-C, which just kind of like examines all this stuff that's going through. 58 00:04:49,880 --> 00:04:53,640 So, you know, that's another obstacle you have to do. 59 00:04:53,640 --> 00:05:03,500 So in a lot of ways, getting this initial payload working and running can be very challenging, despite the fact that you're trying to do something that's seemingly simple. 60 00:05:04,360 --> 00:05:06,320 It's almost paradoxical in that way. 61 00:05:08,660 --> 00:05:13,380 And finally, I mean, you should assume that your initial access payload is going to be discovered. 62 00:05:13,500 --> 00:05:15,740 That's just a safe assumption to make. 63 00:05:16,060 --> 00:05:21,680 So your payload really should be able to withstand manual analysis in the form of threat hunters, reverse engineers, and the like. 64 00:05:23,660 --> 00:05:28,620 So with that in mind, all these are obstacles that are insurmountable. 65 00:05:28,660 --> 00:05:31,240 There are ways to contend with all of this. 66 00:05:31,620 --> 00:05:37,300 It is a bit of a cat and mouse game, but it's something that you can get around. 67 00:05:37,360 --> 00:05:41,240 The problem is that successful evasion techniques do not last very long. 68 00:05:41,260 --> 00:05:43,600 They have a tendency to get stale. 69 00:05:43,600 --> 00:05:46,360 They have relatively short shelf life. 70 00:05:46,380 --> 00:05:58,020 And this is because if you're doing your job right, defenders will eventually learn from what you're doing as a red teamer and write detections against whatever TTPs you're using. 71 00:05:58,020 --> 00:06:06,080 So those really cool new TTPs that you drop, if you're doing your job right, this will actually improve their security. 72 00:06:06,080 --> 00:06:11,240 And they won't work forever if you're using the same TTPs for years and years. 73 00:06:11,260 --> 00:06:15,880 Well, you know, you could argue that you're not really improving the security. 74 00:06:15,880 --> 00:06:17,360 But yeah, that's a whole other thing. 75 00:06:17,360 --> 00:06:20,340 But so defenders will eventually catch up to you. 76 00:06:20,340 --> 00:06:23,980 And what this means is that your payloads are finite. 77 00:06:23,980 --> 00:06:26,360 They have a shelf life. 78 00:06:26,820 --> 00:06:28,220 And that's good. 79 00:06:28,300 --> 00:06:30,020 And specific payloads, right? 80 00:06:30,020 --> 00:06:31,720 So we were talking about TTPs there, right? 81 00:06:31,720 --> 00:06:35,500 But specific payloads that you write have an even shorter shelf life. 82 00:06:35,500 --> 00:06:46,420 Because at some point, you know, someone's going to write a signature-based detection for that particular, you know, assembly that you drop on an op or something like that. 83 00:06:46,640 --> 00:06:50,120 And , you know, that's relatively easy to do. 84 00:06:50,120 --> 00:06:51,820 I mean, relatively, right? 85 00:06:51,820 --> 00:06:57,300 I mean, from an adversaries perspective, what this means is that reusing payloads is likely to get you burned. 86 00:06:57,300 --> 00:06:59,440 So, you know, this is where... 87 00:06:59,440 --> 00:07:05,840 what this means is that initial access payloads are typically, you know, kind of a pain point for offensive teams. 88 00:07:06,700 --> 00:07:10,980 And that's because, you know, you have all these challenges that you have to overcome. 89 00:07:11,280 --> 00:07:22,040 And the ways that you overcome these obstacles, you know, the methods that you use, essentially, are not going to last. 90 00:07:22,040 --> 00:07:28,660 And you typically have to write them by hand, or at least modify them by hand on a per-engagement basis. 91 00:07:29,080 --> 00:07:31,860 And, you know, code reuse can be problematic. 92 00:07:32,340 --> 00:07:33,700 And there's a lot of moving parts. 93 00:07:33,700 --> 00:07:35,280 There's a lot of... 94 00:07:35,280 --> 00:07:43,880 I mean, despite the relatively simple purpose, if you've ever looked at, like, the source code for, you know, doing a process hollowing in C-sharp, you'll see there's a lot of code involved. 95 00:07:43,880 --> 00:07:46,620 And there's a lot of things that can go wrong. 96 00:07:47,300 --> 00:07:50,280 So there's, you know, code reuse is a problem. 97 00:07:50,460 --> 00:07:52,600 You have to do a lot of stuff by hand. 98 00:07:52,600 --> 00:07:57,240 And there's a lot of moving parts, despite the fact that you're trying to do something relatively simple, which is kind of paradoxical. 99 00:07:59,080 --> 00:08:04,440 So to kind of contend with this problem, you know, I was actually just kind of, like, researching payloads independently. 100 00:08:04,440 --> 00:08:09,300 But at some point, you know, I just had the idea to work on this new tool called DropEngine. 101 00:08:09,300 --> 00:08:17,660 Essentially, the goal of DropEngine is to address this problem by providing a malleable framework for creating shellcode runners. 102 00:08:17,880 --> 00:08:21,660 So if you've ever used, like, Coblestrike, for example, one of the cool... 103 00:08:21,660 --> 00:08:29,220 one of the things that makes, like, Coblestrike great is the fact that, you know, just about every aspect of your agent that you're placing on... 104 00:08:29,220 --> 00:08:35,380 that you're using on the target machines that you're operating on, can be modified. 105 00:08:35,380 --> 00:08:43,980 You know, you can modify traffic profiles, you can modify, you know, essentially how it's dealing with, like, you know, using name pipes and whatnot. 106 00:08:44,100 --> 00:08:49,420 Like, just about every aspect of its use, you can customize it in some way. 107 00:08:49,420 --> 00:08:54,240 And by doing that, you know, really get a lot of use out of this one tool. 108 00:08:54,540 --> 00:08:59,320 So I guess the core idea was to try to do something similar with initial access payloads. 109 00:08:59,320 --> 00:09:15,720 And, you know, the core idea is to identify discrete payload components so basically, like, examine, you know, like, your typical payload and say, what are all the parts that you see in this payload that kind of repeat themselves across every payload that you ever write? 110 00:09:15,760 --> 00:09:19,280 And, you know, identify those and turn them into modules. 111 00:09:20,360 --> 00:09:27,520 And as a bonus, provide built-in obfuscation encryption and symbolic substitution capabilities, which makes it easier to evade signature-based detections. 112 00:09:27,520 --> 00:09:33,040 And in the case of encryption, makes it easier to, you know, evade human analysts. 113 00:09:33,060 --> 00:09:39,920 And, you know, by doing that, we greatly extend the shelf life of, you know, those individual payload components that we're writing. 114 00:09:42,220 --> 00:09:44,160 So how would something like this work? 115 00:09:45,060 --> 00:09:48,340 To kind of think about this, right, we have to talk about how payloads are built. 116 00:09:48,760 --> 00:09:54,700 This is actually, you know, the interesting thing about this project, this is less of a Red Team project than it is like a software development project. 117 00:09:54,700 --> 00:09:59,380 Because, like, we're actually not really trying to do a whole lot of crazy stuff here with the actual... 118 00:10:01,800 --> 00:10:03,020 ...the payload itself. 119 00:10:03,020 --> 00:10:06,340 We're just looking at kind of the abstract design pattern here. 120 00:10:07,000 --> 00:10:12,380 You know, if we think about the anatomy of a payload, at their core, initial access payloads are relatively simple. 121 00:10:12,380 --> 00:10:14,720 They involve two major steps, which we talked about. 122 00:10:14,840 --> 00:10:16,960 You load the shellcode into memory and you execute it. 123 00:10:17,260 --> 00:10:19,300 A little bit of terminology I'm going to throw out here. 124 00:10:19,300 --> 00:10:26,880 From this point onward in this presentation, we're going to refer to the routine that performs these two actions as the executor function, just to kind of make things simple. 125 00:10:28,360 --> 00:10:31,220 So, there are many ways of achieving shellcode execution. 126 00:10:31,220 --> 00:10:37,780 You know, you've got the allele injection, spawn a local thread, you use process hollowing, thread execution, hijacking, all kinds of stuff. 127 00:10:37,780 --> 00:10:41,660 But we actually want to abstract away specific details like this. 128 00:10:41,660 --> 00:10:43,600 We don't really want to focus on them quite yet. 129 00:10:43,960 --> 00:10:47,620 Because what we're looking at is actually for more of a bigger picture. 130 00:10:49,060 --> 00:10:51,830 You know, also something else we need to consider, we mentioned that we need to... 131 00:10:54,400 --> 00:10:56,380 ...contend with application whitelisting. 132 00:10:56,380 --> 00:11:05,440 And that really means that we're limited to formats that can be executed by LullBoss, you know, LullBoss for land buyers and scripts. 133 00:11:06,040 --> 00:11:10,740 So, what this means is that our initial access payload is really going to require three basic components. 134 00:11:10,740 --> 00:11:13,020 And you can kind of see my diagram here on the left here. 135 00:11:13,120 --> 00:11:14,740 We're going to have the shellcode runner. 136 00:11:14,740 --> 00:11:17,320 Technically, the whole entire thing is a shellcode runner. 137 00:11:17,320 --> 00:11:23,840 But we'll, just for the sake of labeling things, you know, we'll refer to this outer wrapper as a shellcode runner. 138 00:11:23,840 --> 00:11:26,220 That's going to be LullBoss specific, right? 139 00:11:26,680 --> 00:11:30,340 You know, if it's MSBuild payload, that's going to be like an XML file, basically. 140 00:11:30,340 --> 00:11:35,540 If it's an installutil payload, that's going to be a C sharp file that's compiled into an assembly. 141 00:11:35,840 --> 00:11:37,820 But you have your outer shellcode runner. 142 00:11:38,080 --> 00:11:39,860 And then you have your payload name. 143 00:11:39,880 --> 00:11:41,260 That's your application entry point. 144 00:11:41,260 --> 00:11:45,180 That's going to call your executor function and really everything else that gets called within your payload. 145 00:11:45,180 --> 00:11:47,000 But we're not going to worry about everything else yet. 146 00:11:47,480 --> 00:11:49,020 It's just these three components. 147 00:11:49,620 --> 00:11:51,860 And then finally, you have your executor function. 148 00:11:51,860 --> 00:11:59,940 And this is going to load your software to memory, execute it, and, you know, essentially, yeah, that's the meat of this payload so far. 149 00:12:00,820 --> 00:12:04,040 So DropEngine implements these basic components as base classes. 150 00:12:04,560 --> 00:12:12,280 Essentially, what I've done is I've taken these three components and made it so you can inherit from them and derive modules from them. 151 00:12:12,280 --> 00:12:18,680 And what this means is that you can just write a module, and you can use any executor type you want, wrap it in any shellcode runner you want. 152 00:12:18,680 --> 00:12:24,720 And the overall structure of the payload remains the same, despite that you have a lot of different options as to how to actually implement all this stuff. 153 00:12:26,120 --> 00:12:29,060 To kind of give you an example, you know, we're talking about the structure. 154 00:12:29,340 --> 00:12:31,720 You know, this is a... I ripped this direct... 155 00:12:32,720 --> 00:12:39,860 Well, there's supposed to be a link to this GitHub, but I guess, like, it's getting cropped on the bottom because it's PowerPoint and Zoom. 156 00:12:39,860 --> 00:12:44,480 But yeah, this is from 0x13steveflores' GitHub. 157 00:12:44,480 --> 00:12:46,000 It's from a project called MoveKit. 158 00:12:46,000 --> 00:12:49,300 This is just an MSBuild runner, right? 159 00:12:49,300 --> 00:12:55,240 You have your outer wrapper, which is what we talked about here, right? 160 00:12:55,240 --> 00:12:56,780 And this is just your XML file. 161 00:12:56,780 --> 00:13:01,240 You have your payload main, which is just importing stuff and calling this executor here. 162 00:13:01,240 --> 00:13:06,260 And then you have your actual executor function there, your shellcode inject. 163 00:13:09,040 --> 00:13:10,580 So... and this is going to be interesting. 164 00:13:10,580 --> 00:13:12,300 I have to switch back and forth here a little bit. 165 00:13:12,300 --> 00:13:18,220 I'm actually going to stop sharing for a second and then reshare from Hyper. 166 00:13:19,300 --> 00:13:19,820 Cool. 167 00:13:19,940 --> 00:13:27,920 So, yeah, you're going to see a lot of other stuff here, but if you look at the overall structure of how things are done, we have our 168 00:13:32,740 --> 00:13:39,940 payload main components, have our runners. 169 00:13:39,940 --> 00:13:43,180 We can break them into individual discrete components like that. 170 00:13:43,300 --> 00:13:46,260 And we'll kind of go into more depth in this in a little bit. 171 00:13:46,400 --> 00:13:52,500 And then, of course, we have our executor functions, which I don't have a whole lot of them in there quite yet, but that's okay. 172 00:13:53,220 --> 00:13:58,360 So I'm going to stop this in an attempt to share this again. 173 00:13:58,360 --> 00:13:59,940 Okay, there we go. 174 00:14:00,360 --> 00:14:03,040 And then hit from current slide. 175 00:14:03,040 --> 00:14:03,840 Okay. 176 00:14:04,360 --> 00:14:09,280 So we've identified our discrete components here, right? 177 00:14:09,280 --> 00:14:11,380 These items here. 178 00:14:13,080 --> 00:14:18,080 We also want to throw in encryption capabilities. 179 00:14:18,080 --> 00:14:26,280 It's typically a good idea to leverage encryption when creating initial access payloads for multiple reasons. 180 00:14:26,460 --> 00:14:30,300 Basically, you have your shellcode that is going to be executed by your shellcode runner. 181 00:14:33,020 --> 00:14:36,380 A lot of these are going to be like binary payloads or something like that. 182 00:14:36,580 --> 00:14:43,400 You don't necessarily want to have to throw that whole entire thing out just because that particular signature is detected by antivirus. 183 00:14:43,400 --> 00:14:50,320 What we do is, one way of hiding that from signature-based checks is by encrypting it. 184 00:14:50,560 --> 00:14:57,380 But the other advantage of encrypting your shellcode is that it makes it more difficult for human analysts to reverse engineer our payload. 185 00:14:57,640 --> 00:15:00,500 Remember, we need to assume that the payload is eventually going to get caught. 186 00:15:01,000 --> 00:15:07,720 And when it does, we want to make it as difficult for the reverse engineer to pick this apart as humanly possible. 187 00:15:09,600 --> 00:15:19,100 What this means is that our updated payload execution process is actually going to involve a few more steps. 188 00:15:19,100 --> 00:15:23,090 We are going to load the encrypted payload into memory. 189 00:15:23,600 --> 00:15:29,420 We're going to decrypt that payload using an encryption key to obtain plaintext shellcode. 190 00:15:29,780 --> 00:15:33,680 And then finally, we're going to load that plaintext shellcode into memory and execute it. 191 00:15:33,880 --> 00:15:37,700 So the extra step here that we've added is this encryption function. 192 00:15:40,500 --> 00:15:48,160 If we're going to use encryption, this introduces yet another thing that we have to account for, and that's key storage, derivation, and retrieval. 193 00:15:48,660 --> 00:15:55,800 When we leverage encryption to protect our shellcode, essentially this is going to require us to provide our payload with one of the following. 194 00:15:55,920 --> 00:16:00,700 It's either going to need to be able to derive the encryption key somehow without actually storing it. 195 00:16:00,700 --> 00:16:03,880 So it's not going to store it, but we need to be able to obtain the encryption key somehow. 196 00:16:03,880 --> 00:16:11,860 It needs to go... if we can't do that, it could possibly just retrieve the encryption key from some other location. 197 00:16:11,860 --> 00:16:13,620 So we could provide it with that capability. 198 00:16:14,060 --> 00:16:17,880 Or we could just store the encryption key itself in the payload. 199 00:16:17,880 --> 00:16:31,080 Now, obviously, this last option is not ideal because, you know, if you're storing the encryption key in the shellcode, if someone compromised in the payload, then someone compromises the payload, then they can decrypt the shellcode and you're kind of... 200 00:16:31,640 --> 00:16:38,600 you're just adding an extra step, but you're not really making it terribly difficult to pick apart. 201 00:16:40,320 --> 00:16:42,820 So let's talk about this first option a bit. 202 00:16:42,980 --> 00:16:47,440 We mentioned the use of... 203 00:16:48,360 --> 00:16:51,060 the first option is to derive the encryption key. 204 00:16:51,900 --> 00:16:56,400 One really great way of doing this is the use of environmental keying. 205 00:16:56,420 --> 00:16:57,800 This is like a really... 206 00:16:58,260 --> 00:17:02,000 I mean, so environmental keying has been around for a pretty long time. 207 00:17:02,000 --> 00:17:10,200 I mean, there's a lot, if you just look up like Mauer, you know, environmental keying and just Google it, there's just tons of papers written about the subject. 208 00:17:10,320 --> 00:17:20,220 I think that the three most relevant projects to check out though, in terms of like prior work, that's like really relevant to red teaming, would definitely be... 209 00:17:22,080 --> 00:17:27,700 well, Ebola is the classic one, you know, that, yeah, that's... 210 00:17:28,480 --> 00:17:36,000 so if you look up Ebola GitHub, like that one is going to come up really, and environmental keying, that one will come up. 211 00:17:36,000 --> 00:17:42,240 The other one is Spotter, that one was released fairly recently, I think like in 2018 or something like that. 212 00:17:42,280 --> 00:17:45,100 And, you know, it pretty much, you know, does something pretty similar. 213 00:17:46,400 --> 00:17:47,460 And then also there's... 214 00:17:48,560 --> 00:17:55,880 I think like Leo Lupik has some blog posts where he talks about this and also expands off of those. 215 00:17:56,440 --> 00:18:04,920 But yeah, so the idea with environmental keying is that you actually derive the encryption key either entirely or in part from values in the environment. 216 00:18:05,000 --> 00:18:06,520 So what do we mean by this? 217 00:18:06,520 --> 00:18:12,680 Well, I mean, let's say that, you know, by attributes in the environment, you know, we're talking about usernames. 218 00:18:13,040 --> 00:18:22,860 So for example, you could use the currently logged in user that your payload is running as, as part of the encryption key. 219 00:18:22,860 --> 00:18:33,280 You could, you know, try to obtain the external IP address from where your payload is executing and use that as part of the encryption key. 220 00:18:33,280 --> 00:18:34,700 You could, you know, use your... 221 00:18:34,700 --> 00:18:43,080 make sure that you're actually on the right computer by deriving the encryption key in part by using your internal FQDN. 222 00:18:43,660 --> 00:18:44,840 I actually didn't like... 223 00:18:44,840 --> 00:18:47,060 you could even like use the moon phase or something like that. 224 00:18:47,060 --> 00:18:50,020 I mean, you can, you know, but essentially what this lets you do... 225 00:18:50,560 --> 00:18:52,440 well, there's two things. 226 00:18:53,580 --> 00:19:02,060 One, it makes your payload very, very resistant to analysis because your encryption key is now no longer being stored in the payload. 227 00:19:02,240 --> 00:19:15,800 And essentially they'd have to, you know, essentially like if you're setting encryption key to the value of the hard drive serial number, you know, that means that you'll be able to decrypt and execute your payload on a specific machine that has that particular hard drive plugged in. 228 00:19:16,680 --> 00:19:35,700 But if you're an analyst and you just have a copy of this payload, unless you know what specific machine you're going after and what the serial number is, you're essentially forced to attempt to crack that encryption by guessing the value of that serial number. 229 00:19:35,700 --> 00:19:39,060 So it makes your payload super hard to crack. 230 00:19:39,060 --> 00:19:41,560 And the added advantage is that it's very targeted. 231 00:19:43,280 --> 00:19:50,680 Your shellcode is only going to be decrypted on machines that match the key's specific attributes or if someone says they're brute forcing for a very, very long time. 232 00:19:53,980 --> 00:19:56,940 So I'm now going to set the first live demo of this. 233 00:19:57,460 --> 00:19:59,140 Over Zoom, no less. 234 00:19:59,280 --> 00:20:00,620 All right. 235 00:20:00,620 --> 00:20:03,380 So I'm going to do a couple of things. 236 00:20:03,380 --> 00:20:09,940 First, I'm going to show you my setup that I'm using for this, because I think that's important, just so you all know kind of what's going on here. 237 00:20:09,940 --> 00:20:14,020 So I'm going to stop sharing for one second and I'm literally going to share. 238 00:20:15,200 --> 00:20:16,380 Well, can I do that? 239 00:20:18,000 --> 00:20:19,180 Okay, actually, yeah. 240 00:20:19,180 --> 00:20:27,570 So the first thing I have to show you, security settings on this machine that I'm using, because that's actually very relevant. 241 00:20:33,760 --> 00:20:36,240 And you should see it. 242 00:20:36,260 --> 00:20:39,520 Okay, let me try sharing this again. 243 00:20:45,500 --> 00:20:46,720 Oh, you know what I can do? 244 00:20:46,980 --> 00:20:47,860 Yeah, here it is. 245 00:20:47,860 --> 00:20:49,280 Okay, I got it. 246 00:20:49,280 --> 00:20:58,680 So as you can see, I don't have cloud delivery protection because I don't want the stuff I'm working on at the moment to get shipped off to antivirus analysis land, essentially. 247 00:20:58,680 --> 00:21:02,560 So that's turned off, as well as automatic sample submission. 248 00:21:02,560 --> 00:21:06,020 But this is a brand new Windows 10 install. 249 00:21:06,620 --> 00:21:09,200 I have real-time protection turned on. 250 00:21:09,880 --> 00:21:13,240 Tamper protection is turned on, so you can't disable it. 251 00:21:13,940 --> 00:21:21,400 But I do have an exclusion setup, and I want to explain this really fast in case you're wondering why certain things aren't working. 252 00:21:21,580 --> 00:21:26,400 So I have one exclusion here, and this is this directory, demo AB include. 253 00:21:26,400 --> 00:21:31,980 So essentially, what I'm going to be doing during these demos is I have four, and I'm going to have to now 254 00:21:35,860 --> 00:21:38,000 switch windows that I'm sharing again. 255 00:21:38,040 --> 00:21:40,020 So you should see hyper right now. 256 00:21:40,020 --> 00:21:40,920 There's four terminals. 257 00:21:40,920 --> 00:21:43,400 I'm going to try to make this a little cleaner. 258 00:21:46,910 --> 00:21:50,050 So in the top left, this is just for my benefit. 259 00:21:50,050 --> 00:21:52,710 That's essentially, I'm trying not to anger the demo gods. 260 00:21:53,130 --> 00:22:00,230 So I am keeping as much of this stuff in the text file, and I'm going to run the commands that are in there rather than trying to just guess. 261 00:22:00,730 --> 00:22:02,150 This will be relevant later. 262 00:22:02,150 --> 00:22:06,590 This is going to be a remote key server, and you can kind of... we'll talk about that in a second. 263 00:22:06,590 --> 00:22:07,830 This is a Metasploit instance. 264 00:22:07,830 --> 00:22:10,630 So this is... yeah, so we're actually going to use Meterpreter for this. 265 00:22:10,630 --> 00:22:16,810 So every AV engine under the sun should be able to detect what we're doing, essentially, is what I'm trying to say. 266 00:22:16,810 --> 00:22:23,670 We're just using... the payload we're going to be using is going to be just a plain Meterpreter reverse HTTPS. 267 00:22:23,970 --> 00:22:29,350 We have to use HTTPS because the actual unencrypted traffic will be picked up immediately. 268 00:22:30,810 --> 00:22:32,760 So that exclusion that we're seeing... 269 00:22:35,030 --> 00:22:36,610 I'm just being difficult. 270 00:22:36,610 --> 00:22:37,140 I'm going to have to... 271 00:22:38,610 --> 00:22:43,050 It's going to be in this directory here. 272 00:22:43,750 --> 00:22:45,150 I'm going to AV exclude. 273 00:22:45,150 --> 00:23:00,930 And this is because we're going to be building this payload, and although the payload was generated here, the second I SCP that payload over onto my main machine, which is what you're seeing in this top right terminal here, Defender would just nuke that. 274 00:23:00,930 --> 00:23:07,210 And I really don't want to just keep turning Defender on and off every time I have to do a demo, which is because that's just going to... 275 00:23:07,210 --> 00:23:09,390 I'm trying to make this go as smoothly as possible. 276 00:23:10,870 --> 00:23:16,990 So the compromise here is that we're going to be pulling our actual shellcode out of demo AV exclude. 277 00:23:16,990 --> 00:23:19,130 But when we execute it, that's not where we're executing from. 278 00:23:19,130 --> 00:23:21,470 We're going to be executing outside of that exclusion folder. 279 00:23:22,310 --> 00:23:28,110 Okay, with that out of the way, let's show you how to go over... 280 00:23:38,800 --> 00:23:45,180 Let's go over how we'd make a payload using environmental keying. 281 00:23:45,400 --> 00:23:52,540 So essentially, the first thing we're going to do is get a list of available models, right? 282 00:23:52,540 --> 00:23:53,640 And just run this. 283 00:23:53,640 --> 00:23:57,420 And these are all the different payload components we can choose from. 284 00:23:57,420 --> 00:23:59,940 So let's say that we want to use environmental keying. 285 00:23:59,940 --> 00:24:01,340 We want to essentially grab... 286 00:24:04,420 --> 00:24:10,380 Let's do the FQDN, because I have that written down, and my current username. 287 00:24:10,380 --> 00:24:12,460 So we're going to derive the key from that. 288 00:24:12,700 --> 00:24:14,840 In that case, we could just do this. 289 00:24:14,840 --> 00:24:25,740 We could do Python, prop engine, break onto a new line here, specify that our shellcode should be... 290 00:24:27,620 --> 00:24:33,980 You know, in that demo, maybe exclude to shell. 291 00:24:35,180 --> 00:24:37,760 We're going to use an interface... 292 00:24:37,760 --> 00:24:39,960 So the interface, I'm specifying this command interface. 293 00:24:39,960 --> 00:24:42,080 That's like literally the glue that holds everything together. 294 00:24:42,080 --> 00:24:44,920 You know, if you're working in C-sharp, you're going to use a C-sharp interface. 295 00:24:45,140 --> 00:24:46,900 Don't worry about that too much. 296 00:24:47,120 --> 00:24:51,980 But we're going to say, C-sharp runner interface, right? 297 00:24:52,500 --> 00:24:54,480 And then we're going to also look at... 298 00:24:54,480 --> 00:24:55,840 Just like this encryption key. 299 00:24:55,840 --> 00:24:58,280 We need an encryption key and a decryption key. 300 00:24:58,880 --> 00:25:06,140 So the EQ keys we're going to use are going to be this external FQDN that we talked about. 301 00:25:06,760 --> 00:25:08,400 And notice I'm using more than one. 302 00:25:08,440 --> 00:25:12,340 We'll kind of go into how that works in a second, right? 303 00:25:14,890 --> 00:25:18,850 I'm just going to use the decryption keys, which is essentially these things, but written in C-sharp. 304 00:25:22,080 --> 00:25:24,900 I'm just going to copy these, put them in there. 305 00:25:26,540 --> 00:25:28,120 We're then going to need to select a encryptor. 306 00:25:28,120 --> 00:25:29,540 It's doing encryptor shellcode. 307 00:25:30,240 --> 00:25:33,300 So we're going to say, encryptor AES. 308 00:25:33,300 --> 00:25:35,360 We're just going to use AES-256. 309 00:25:36,180 --> 00:25:38,780 That should really be named AES-256, not just AES. 310 00:25:38,780 --> 00:25:39,960 I should change that. 311 00:25:40,280 --> 00:25:41,820 And we're going to use a decryptor. 312 00:25:42,520 --> 00:25:51,020 So decryptor C-sharp, origin doll AES, which is the corresponding decryption function that we need. 313 00:25:52,000 --> 00:25:59,320 Finally, for our shellcode, we'll go ahead and use msbuild, because that will save you from having to compile something, which will take extra time. 314 00:26:02,940 --> 00:26:04,520 And then we're going to need a mutator. 315 00:26:04,520 --> 00:26:07,560 We haven't really talked about mutators yet, but we will. 316 00:26:09,380 --> 00:26:13,000 But for now, I'm going to say mutator string. 317 00:26:13,220 --> 00:26:18,840 And essentially, what that's going to do, it's going to take all the variable names in our finished output and change them to a random string. 318 00:26:18,840 --> 00:26:21,720 So it just makes it a little harder to signature around. 319 00:26:22,320 --> 00:26:23,560 And that really is... 320 00:26:23,560 --> 00:26:30,120 Oh, we also need to specify the actual username and external FQDN that we're trying to use for our key. 321 00:26:30,120 --> 00:26:36,240 So I'll put my username as FQDN. 322 00:26:36,400 --> 00:26:38,460 And I'm just going to copy it from here. 323 00:26:38,460 --> 00:26:41,520 And hopefully, this is an update in the last time, like in the past hour or so. 324 00:26:41,520 --> 00:26:42,800 I don't think it would have. 325 00:26:43,360 --> 00:26:46,560 And finally, oops, I forgot something. 326 00:26:48,840 --> 00:26:50,340 We need an executor function. 327 00:26:50,340 --> 00:26:53,440 Yeah, so we need that executor function that actually executes our shellcode. 328 00:26:53,440 --> 00:26:56,780 And we're just going to use C-sharp virtual alloc thread. 329 00:26:57,700 --> 00:27:01,420 And so you may call it virtual alloc, virtual protect, and all that. 330 00:27:02,940 --> 00:27:06,600 And we're going to make our output file example.csproj. 331 00:27:06,600 --> 00:27:09,200 And that's going to be our MSBuild file. 332 00:27:09,280 --> 00:27:09,620 Cool. 333 00:27:09,620 --> 00:27:10,340 Looks like it ran. 334 00:27:10,340 --> 00:27:11,240 Didn't get any errors. 335 00:27:11,240 --> 00:27:17,360 If you look at our example.csproj, here is an obfuscated MSBuild file. 336 00:27:18,280 --> 00:27:23,140 Actually, I should probably show you what this is actually doing. 337 00:27:24,640 --> 00:27:27,760 I'm going to do mutate or null, which basically means don't mutate anything. 338 00:27:30,260 --> 00:27:35,160 But yeah, so basically, here are all the different components that are stacked together. 339 00:27:35,160 --> 00:27:40,320 Here are your decryption keys, and your decryptor, and your executor, and everything else. 340 00:27:40,360 --> 00:27:43,540 And then here's your actual payload itself and payload name. 341 00:27:43,540 --> 00:27:47,340 Essentially, all this is just being rendered into the payload by DropEngine. 342 00:27:47,840 --> 00:27:48,640 Automagically. 343 00:27:49,440 --> 00:27:51,080 And finally, I run everything down there. 344 00:27:51,740 --> 00:27:54,080 But I want this to be random, because I don't know. 345 00:27:54,080 --> 00:27:55,200 Demo gots, I guess. 346 00:27:55,620 --> 00:27:57,360 So I made that a random one. 347 00:27:58,120 --> 00:27:59,820 So now we're going to set up our handler. 348 00:28:00,580 --> 00:28:04,380 Use exploit multihandler payload for CTP. 349 00:28:06,160 --> 00:28:11,220 Lhost set Lport 443, which should be correct. 350 00:28:11,220 --> 00:28:15,180 And I'm going to set exploit-j to start our handler in the background. 351 00:28:15,800 --> 00:28:19,220 And then we're going to actually run this using AliceBuild. 352 00:28:19,580 --> 00:28:21,660 And there we go. 353 00:28:21,960 --> 00:28:28,260 Now, just to kind of, in case you don't believe me, that this is actually doing something. 354 00:28:30,900 --> 00:28:33,180 I'm going to kill everything here. 355 00:28:38,990 --> 00:28:41,050 That was a bad sign. 356 00:28:41,050 --> 00:28:45,530 But I copy of 357 00:28:49,870 --> 00:28:50,930 the enter nano. 358 00:28:52,050 --> 00:28:52,610 All right. 359 00:28:52,610 --> 00:28:53,050 You know what? 360 00:28:53,050 --> 00:28:55,430 I'm actually deviating from the demo right now. 361 00:28:55,430 --> 00:28:57,570 And I think that's a bad idea. 362 00:28:57,570 --> 00:28:59,630 We'll get back to this if we have time. 363 00:29:01,950 --> 00:29:03,030 No, actually, you know what? 364 00:29:03,030 --> 00:29:03,890 I'm stubborn. 365 00:29:03,890 --> 00:29:04,690 Let's do the... 366 00:29:08,740 --> 00:29:14,980 Yeah, I copy demo AV exclude empty shell. 367 00:29:14,980 --> 00:29:17,560 And let's just copy it up on level. 368 00:29:18,720 --> 00:29:24,090 We should get alert. 369 00:29:25,950 --> 00:29:27,110 Or perhaps not. 370 00:29:27,110 --> 00:29:29,370 Maybe we might have to run it to get the alert. 371 00:29:30,270 --> 00:29:32,750 But yeah, I'm not going to say you're tinkering with this. 372 00:29:36,050 --> 00:29:37,610 Let's get back to PowerPoint. 373 00:29:38,930 --> 00:29:39,810 OK. 374 00:29:39,910 --> 00:29:40,970 From current slide. 375 00:29:42,650 --> 00:29:44,710 So that's our payload. 376 00:29:44,710 --> 00:29:51,310 Basically, custom build payload with environmental keying that we literally just created in a second. 377 00:29:54,230 --> 00:29:56,490 So mutator modules, right? 378 00:29:58,210 --> 00:30:00,070 We mentioned also that we're using... 379 00:30:10,280 --> 00:30:11,000 Ignore me. 380 00:30:11,000 --> 00:30:13,100 I could have sworn there was something else that I was supposed to talk about there. 381 00:30:13,100 --> 00:30:13,620 OK. 382 00:30:13,820 --> 00:30:14,200 Yeah. 383 00:30:14,200 --> 00:30:16,420 So the other thing, essentially what we've just done. 384 00:30:17,020 --> 00:30:21,580 We've said, here's the executor function we want to use. 385 00:30:21,700 --> 00:30:24,000 Here's the shellcode runner we want to use. 386 00:30:24,000 --> 00:30:26,700 Here's the encryption decryption routines we want to use. 387 00:30:26,900 --> 00:30:30,000 And by the way, we want to derive our keys from these two specific functions. 388 00:30:30,000 --> 00:30:32,280 And we're going to pull this stuff together and make it into a payload. 389 00:30:32,280 --> 00:30:37,500 And by the way, randomize all the variables in variable names in that payload. 390 00:30:37,800 --> 00:30:40,460 And just write a command, and then it just does it. 391 00:30:40,460 --> 00:30:42,520 And then voila, you have a payload. 392 00:30:43,080 --> 00:30:44,620 The way that we did the actual... 393 00:30:44,620 --> 00:30:50,940 The changing of the variable names was using basically modular symbolic mutation. 394 00:30:50,940 --> 00:30:54,420 So DropEngine supports the use of mutator modules that... 395 00:30:54,420 --> 00:30:55,640 I mean, essentially what they do is that they... 396 00:30:56,700 --> 00:31:09,100 Every module that corresponds to something that has variable names or function names has a mutator method that gets called in the back end by whatever mutator module that you select. 397 00:31:09,100 --> 00:31:18,700 And the mutator module then systematically goes through and takes a list of variable names and maps them using some algorithm. 398 00:31:18,700 --> 00:31:20,080 The algorithm is irrelevant. 399 00:31:20,180 --> 00:31:21,720 It's module specific. 400 00:31:22,460 --> 00:31:23,980 And then when the actual... 401 00:31:23,980 --> 00:31:29,380 And returns back to that module, the original module, that mapping. 402 00:31:29,380 --> 00:31:33,320 So like a dictionary of like, here's all your variable names, and here's the stuff that we've mapped them to. 403 00:31:33,320 --> 00:31:35,300 And then what happens is that when you render... 404 00:31:35,300 --> 00:31:40,300 When that module gets rendered into a rendered template, and that's how we're building everything. 405 00:31:40,300 --> 00:31:41,720 It's using Jinja templates. 406 00:31:43,680 --> 00:31:44,640 We are... 407 00:31:44,640 --> 00:31:51,480 Essentially what's going on is that it looks at that mapping in order to figure out what's in the variable. 408 00:31:51,480 --> 00:31:58,140 So this is pretty cool because it allows us to create payloads that, you know, circumvent signature-based detections pretty easily. 409 00:31:58,300 --> 00:32:02,160 I only have like three supported methods in there right now. 410 00:32:02,300 --> 00:32:05,840 Rot13, the random string, and also symbol substitution using a word list. 411 00:32:05,840 --> 00:32:08,180 Null mutator doesn't really count because that's just... 412 00:32:08,180 --> 00:32:09,220 It just doesn't do anything. 413 00:32:09,220 --> 00:32:10,280 It's a null mutator. 414 00:32:10,280 --> 00:32:12,660 It's primarily there for debugging purposes. 415 00:32:13,840 --> 00:32:17,690 And I've kind of already demonstrated that, but if you want to just go over... 416 00:32:18,680 --> 00:32:21,980 Just once again, what that looks like. 417 00:32:22,180 --> 00:32:30,340 You know, take this one that we just did, just print to the screen instead of out the file. 418 00:32:30,520 --> 00:32:32,010 So for example, here's your... 419 00:32:33,200 --> 00:32:34,320 Actually, let me use... 420 00:32:34,320 --> 00:32:38,720 I've got another piece of shellcode that isn't so long that we can use for demos. 421 00:32:41,080 --> 00:32:45,360 Yeah, so, you know, here's your random strings. 422 00:32:45,740 --> 00:32:46,960 You know, if you wanted to use... 423 00:32:49,880 --> 00:32:50,760 Rot13. 424 00:32:53,200 --> 00:32:57,200 These look an awful lot like the variable names. 425 00:32:57,540 --> 00:32:59,080 Let's use a word list. 426 00:33:02,050 --> 00:33:04,730 You actually have to specify a word list when you do this. 427 00:33:04,730 --> 00:33:06,230 Let's use US cities. 428 00:33:06,230 --> 00:33:07,130 And that will... 429 00:33:07,130 --> 00:33:09,170 Now all your variable names are corresponding to US cities. 430 00:33:09,170 --> 00:33:13,710 A better use of this would just be to make a word list that actually are believable variable names. 431 00:33:13,710 --> 00:33:18,470 But I don't know, this is better for doing a demo. 432 00:33:19,090 --> 00:33:20,490 Let me go back to PowerPoint. 433 00:33:20,870 --> 00:33:22,370 Let's move on from here. 434 00:33:28,370 --> 00:33:30,010 And let me just make sure... 435 00:33:30,010 --> 00:33:30,950 Okay, cool. 436 00:33:32,810 --> 00:33:36,270 So let's talk about some more keying techniques that we support. 437 00:33:36,830 --> 00:33:38,490 We talked about environmental keying. 438 00:33:38,490 --> 00:33:39,730 Remote keying is also pretty neat. 439 00:33:39,730 --> 00:33:52,570 Essentially, instead of deriving the key from some place in your environment, you're actually going to retrieve the encryption key from some remote location, you know, either for HTTP or HTTPS, DNS, or some other communication protocol. 440 00:33:53,410 --> 00:33:54,750 This is actually... 441 00:33:54,750 --> 00:33:59,810 You know, if you have well-designed non-attributable attack infrastructure, it actually makes this method pretty effective. 442 00:33:59,810 --> 00:34:05,570 You know, you can place the key server behind a redirector and only accept requests for that key on very specific... 443 00:34:06,270 --> 00:34:09,710 for very specific profile traffic that's being sent to the redirector. 444 00:34:09,730 --> 00:34:18,130 If you want to make it even better, you can use a one-time remote key, which is a variant in which your key server, which is the server that's hosting these remote keys... 445 00:34:19,230 --> 00:34:23,270 By the way, you want to have one key per payload, and DropEngine does support that. 446 00:34:25,030 --> 00:34:27,690 So keys should be unique to the payload that you generate. 447 00:34:28,270 --> 00:34:39,910 But essentially, the one-time remote key variant, once that key is successfully retrieved from the key server, it actually is deleted from the key server. 448 00:34:39,910 --> 00:34:43,570 So the key server goes back into its database and just nukes the key. 449 00:34:43,590 --> 00:34:54,890 And what this means is that any future requests for that key are either going to be ignored by the key server, or return some kind of junk data, or you could even, at that point, respond to that kind of request by returning a redirect. 450 00:34:54,890 --> 00:35:01,970 So you could do what a redirect would do and redirect that request to something innocuous, like, you know, remotely hosted jQuery or something. 451 00:35:01,970 --> 00:35:04,810 Like , look, it's not... it's just jQuery, right? 452 00:35:04,810 --> 00:35:09,250 But so, I mean, there are obviously some obvious advantages to doing keying this way. 453 00:35:09,290 --> 00:35:11,230 It's very resistant to analysis. 454 00:35:11,430 --> 00:35:13,790 The encryption key is not stored on the payload file. 455 00:35:14,090 --> 00:35:18,230 And it's hopefully being protected in transit using TLS. 456 00:35:18,710 --> 00:35:22,270 It's also less targeted, right? 457 00:35:22,270 --> 00:35:26,810 You know, while highly targeted payloads are good in a lot of cases, sometimes they're not. 458 00:35:26,810 --> 00:35:32,350 Sometimes you don't just want to attack the computer of that one person that has that particular hard drive or username. 459 00:35:32,350 --> 00:35:34,590 Sometimes you want a little more breadth. 460 00:35:34,590 --> 00:35:37,890 In this case, you don't have to limit your scope. 461 00:35:38,810 --> 00:35:40,710 I mean, you should limit your scope regardless. 462 00:35:40,710 --> 00:35:48,330 But I guess what I'm saying is the scope isn't, you know, implicitly limited by your keying mechanism at this point. 463 00:35:51,530 --> 00:35:55,810 So I'll show you how this works in Dropbox really fast. 464 00:35:57,310 --> 00:36:00,330 And I'm going to go back to my screen here, go back to Hyper. 465 00:36:04,400 --> 00:36:08,420 And so in the bottom left, we have this, what looks like a Flask app. 466 00:36:08,860 --> 00:36:10,480 It's really, really basic. 467 00:36:11,700 --> 00:36:15,780 I honestly didn't put a whole lot of time into this because, you know, I was just trying to get the proof of concept out the door. 468 00:36:15,780 --> 00:36:19,440 But this is our remote one-time key server. 469 00:36:19,460 --> 00:36:29,440 And what we're going to do here is do a very similar payload to what we just did, right? 470 00:36:33,920 --> 00:36:34,800 Hang on, let me... 471 00:36:48,190 --> 00:36:49,670 So we're going to grab this. 472 00:36:51,590 --> 00:36:57,050 And this is, you know, as you can see here, well, it's just RAM. 473 00:36:57,050 --> 00:37:06,030 But what we just did, we created a shellcode using our empty shell, like our interpreter shell that's in that empty shell.bin file. 474 00:37:06,550 --> 00:37:08,730 It's pretty much the same attributes we used last time. 475 00:37:08,730 --> 00:37:11,830 The difference here is we actually added some keying components. 476 00:37:12,290 --> 00:37:16,550 We added a new key here, which you can see right here. 477 00:37:16,550 --> 00:37:24,090 It's the D-key one-time remote HTTP and the corresponding decryption key, which is their D-key remote C-sharp OTK HTTP. 478 00:37:24,490 --> 00:37:33,250 And essentially what this is doing is it's just providing functions that will attempt to reach out to this server right here that is running at the bottom left to retrieve this encryption key. 479 00:37:33,250 --> 00:37:37,690 And it's going to use that by using a specific identifier that you need to your implant. 480 00:37:38,090 --> 00:37:43,590 So that, you know, essentially what this guy down here is going to do is look in the database to see if that identifier exists. 481 00:37:43,590 --> 00:37:50,270 And if it does, it's going to respond with the decryption key and send it back to our payload. 482 00:37:50,270 --> 00:37:53,450 And then, you know, it'll be deleted from the database. 483 00:37:53,450 --> 00:37:56,070 So subsequent requests just won't be honored. 484 00:37:57,710 --> 00:37:59,990 So let's run that really fast. 485 00:38:00,430 --> 00:38:03,310 We just kind of prep the bottom left here. 486 00:38:03,610 --> 00:38:07,030 Make sure we don't have any stragglers either in our sessions or... 487 00:38:08,430 --> 00:38:09,750 Oh, okay, cool. 488 00:38:09,750 --> 00:38:11,610 So we're going to run our handler. 489 00:38:14,270 --> 00:38:18,710 And we're going to rebuild this really fast just to make sure everything looks selfless enough. 490 00:38:18,710 --> 00:38:19,650 It does. 491 00:38:21,670 --> 00:38:24,210 And we're going to call it MSBuild once again. 492 00:38:25,630 --> 00:38:27,270 And there we go. 493 00:38:27,810 --> 00:38:30,970 And you'll notice here, this traffic showed up in the Flask app. 494 00:38:30,970 --> 00:38:35,930 And that is our server going back. 495 00:38:35,930 --> 00:38:38,170 That's our payload retrieving the key, right? 496 00:38:38,170 --> 00:38:44,450 Now, let's go ahead and kill this session right here, 497 00:38:51,870 --> 00:38:54,230 right? 498 00:38:56,670 --> 00:38:59,130 And the reason why I'm doing that is I want to show you what happens when we... 499 00:39:00,150 --> 00:39:03,450 So we've already retrieved that remote key. 500 00:39:03,450 --> 00:39:05,810 So what we're going to do now is we're going to just kind of demonstrate. 501 00:39:06,590 --> 00:39:09,870 If we happen to curl for that same value, right? 502 00:39:10,290 --> 00:39:14,550 Let's say we do a curl request to 127. 503 00:39:14,550 --> 00:39:18,030 This is running on mobile, so we can just do this. 504 00:39:22,570 --> 00:39:25,130 HTTP//, we're not using SSL at the moment. 505 00:39:30,150 --> 00:39:30,910 Oh, you know what? 506 00:39:30,910 --> 00:39:33,130 We'd actually need the implant ID, wouldn't we? 507 00:39:33,470 --> 00:39:34,490 Oh, no, here it is. 508 00:39:34,490 --> 00:39:36,970 Yeah, let's grab this implant ID right from here. 509 00:39:37,390 --> 00:39:37,890 Cool. 510 00:39:37,890 --> 00:39:39,990 So we have everything we need to make this work. 511 00:39:41,250 --> 00:39:48,530 And you'll see that we don't actually get a response at this time because it's been cleared. 512 00:39:49,830 --> 00:39:53,530 All right, so back to our PowerPoint. 513 00:39:54,610 --> 00:39:56,590 We've got about 20 minutes left. 514 00:39:56,590 --> 00:39:58,910 Open this up for chat for about 10. 515 00:40:00,090 --> 00:40:02,330 Let's go back here. 516 00:40:04,590 --> 00:40:06,130 Press slide. 517 00:40:06,130 --> 00:40:06,570 All right . 518 00:40:10,500 --> 00:40:19,880 So one thing you'll notice is that we're actually using multiple encryption keys here. 519 00:40:19,880 --> 00:40:20,880 Or it seems like it, right? 520 00:40:20,880 --> 00:40:26,040 Because we're specifying these different key types and combining them to create a final encryption key. 521 00:40:26,200 --> 00:40:30,140 We're doing this using something that I like to call key stacking. 522 00:40:32,280 --> 00:40:33,860 Key stacking is just like a label. 523 00:40:33,860 --> 00:40:38,620 I'm sure this has been done before a million times because it's really not that complicated. 524 00:40:39,260 --> 00:40:40,780 It's pretty simple in practice. 525 00:40:40,780 --> 00:40:42,060 And we'll see that in a minute. 526 00:40:42,060 --> 00:40:48,620 But essentially key stacking is the practice of combining the results of multiple keying methods to create a single combined keys. 527 00:40:48,800 --> 00:40:55,100 So for example, let's say we want a key that's combined of four parts. 528 00:40:55,100 --> 00:41:03,720 The hard drive serial number, external IP address, a non-stored in the payload file, so it's a stored component, and also a one-time key that is retrieved over HTTPS. 529 00:41:03,940 --> 00:41:07,580 Well, in that point, we essentially would just make four method calls within our payload. 530 00:41:09,040 --> 00:41:13,380 To four different key derivation functions, concatenate the results together. 531 00:41:13,540 --> 00:41:20,220 And by doing that, we'd have one encryption key that was derived from all these different sources. 532 00:41:20,440 --> 00:41:23,100 So one advantage of doing this is it gives us a little more security. 533 00:41:23,100 --> 00:41:25,080 It's difficult to compromise. 534 00:41:25,600 --> 00:41:27,700 Disadvantage is kind of complicated. 535 00:41:27,700 --> 00:41:32,420 If you do this by hand, it's just adding more moving parts to the equation. 536 00:41:32,420 --> 00:41:37,100 But once again, since we're using a framework, it makes it a little less complicated. 537 00:41:40,140 --> 00:41:47,820 Essentially, what makes this possible is that the actual architecture that we saw at the very beginning, it has been updated a little bit. 538 00:41:47,820 --> 00:41:54,780 So remember, originally, we just had that shellcode runner and a payload main in there and an executor function. 539 00:41:54,780 --> 00:41:56,600 In this case, we still have our shellcode runner. 540 00:41:56,600 --> 00:41:57,720 It's our outermost wrapper. 541 00:41:57,720 --> 00:42:02,320 That's our LulzBot-specific script that encapsulates everything. 542 00:42:02,420 --> 00:42:04,120 But we also have our payload main. 543 00:42:05,760 --> 00:42:09,860 And within that, we now have, you see here, we all have all these D-key functions. 544 00:42:11,080 --> 00:42:14,160 So we have a D-key 1, D-key 2, all the way through D-key N. 545 00:42:14,160 --> 00:42:15,960 It's an arbitrary number of D-key functions. 546 00:42:16,640 --> 00:42:36,860 And essentially, the way that this works is that each key part is extracted from each of these key derivation functions and passed to the decryptor function along with the shellcode that combined or stacks keys is then used to get the plaintext shellcode and is passed to the executor. 547 00:42:36,960 --> 00:42:41,280 So really, it's not too bad. 548 00:42:43,860 --> 00:42:45,920 We already went over key stacking. 549 00:42:46,820 --> 00:42:48,580 So let's talk about pre-modules and post-modules. 550 00:42:48,580 --> 00:42:51,980 And I included the cookie monster here, because who doesn't like the cookie monster? 551 00:42:56,500 --> 00:42:58,440 So what are pre-modules and post-modules? 552 00:43:00,280 --> 00:43:01,740 Essentially, this is a concept. 553 00:43:01,740 --> 00:43:16,240 I mean, there's often when you're executing that initial access payload, right, that shellcode within your shellcode runner, there are things that you want to do first before you actually start trying to execute your shellcode. 554 00:43:16,620 --> 00:43:33,500 For one thing, you might want to perform sandbox checks, like if you're trying to see if you're in one of those automated sandboxes, you might want to check for some node attributes of the sandboxes, such as certain file paths or number of CPUs or what have you, 555 00:43:33,500 --> 00:43:39,840 to actually see if you're in a quote-unquote real environment or in a sandbox. 556 00:43:41,120 --> 00:43:44,380 Also, we mentioned that this is likely going to be going through the CLR. 557 00:43:44,420 --> 00:43:53,060 So you might want to try to bypass AMSI, and that's something that you might want to try to do before you execute your shellcode. 558 00:43:54,380 --> 00:44:02,160 So what pre-modules do, essentially, they are just subroutines that are pre-pended to everything else in your payload. 559 00:44:02,160 --> 00:44:09,500 So what DropEngine lets you do is you can specify any number of pre-modules that you want, and these will just get run before everything else does. 560 00:44:10,440 --> 00:44:25,880 So, for example, if you want to run a sandbox check and an AMSI bypass, you pass those both to DropEngine as pre-modules, they then get executed, and then once they finish executing, and they are executed in the order that you specify them, by the way, 561 00:44:25,880 --> 00:44:29,080 which is pretty cool because you actually control which order they execute in. 562 00:44:29,080 --> 00:44:33,020 But once they finish executing, then we execute the rest of your shellcode here. 563 00:44:35,180 --> 00:44:37,400 So post-modules, they're pretty much the opposite thing. 564 00:44:37,400 --> 00:44:42,820 Instead of being pre-pended to the beginning of the payload, we append them to the end of the payload. 565 00:44:42,820 --> 00:44:49,420 So that's useful for if there's something that you want to do after your shellcode terminates. 566 00:44:49,420 --> 00:45:00,480 So cleanup routines, log file deletion, modification, and both pre-modules and post-modules should be completely modular and mutable, just like the rest of the payload's components. 567 00:45:00,480 --> 00:45:07,060 So you can mangle all the string names and variable names, however you want. 568 00:45:09,790 --> 00:45:16,930 And so if we're going to demo the process of adding pre-modules, here's how you do it. 569 00:45:18,490 --> 00:45:20,610 I'll make this a super fast one. 570 00:45:30,060 --> 00:45:46,040 So for example, here, you can see if we want to create a payload that, let's say we want to run an empty sandbox check, say like check to see if we're in a sandbox by checking the minimum number of USBs that have ever been installed. 571 00:45:48,580 --> 00:45:54,520 Let's say we look for also file paths that can deliver us to the event that we're in a sandbox. 572 00:45:54,520 --> 00:45:57,140 A file path is a sandbox check. 573 00:45:57,140 --> 00:46:01,960 Then finally, we want to execute an empty scan buffer bypass. 574 00:46:02,560 --> 00:46:05,780 We can just append these here as pre-modules. 575 00:46:17,880 --> 00:46:34,490 And actually, if you're curious what this looks like, I'm not actually going to save this. 576 00:46:34,490 --> 00:46:36,090 I'm just going to send it to the screen. 577 00:46:38,130 --> 00:46:39,430 Yeah, that's what I want to do. 578 00:46:39,430 --> 00:46:43,830 And then I'm going to use that really, really small shellcode that I showed you earlier. 579 00:46:43,910 --> 00:46:45,230 It's easier to read. 580 00:46:48,360 --> 00:46:53,140 It should not be from the exclusion folder, because that small shellcode is not in the exclusion folder. 581 00:46:57,340 --> 00:47:08,040 And you'll see here that, you know, here are your sandbox checks and your empty bypass, and that's all getting executed up here, essentially. 582 00:47:08,040 --> 00:47:11,780 So that all gets done right before you run everything else. 583 00:47:12,360 --> 00:47:16,640 So once again, let's get up on our MSVL payload. 584 00:47:16,640 --> 00:47:22,120 We're going to start up our handler, and we created it in the last step, so I'm not going to recreate it. 585 00:47:23,580 --> 00:47:28,400 And you see that it runs, so everything just kind of goes swimmingly, because we're out of the sandbox. 586 00:47:31,440 --> 00:47:32,700 We go ahead and fill this... 587 00:47:39,470 --> 00:47:41,330 PowerPoint, just wrap this up. 588 00:47:50,750 --> 00:47:53,530 We kind of did both demos at once, and that's all right. 589 00:47:53,770 --> 00:47:57,450 The last thing we're going to talk about is, essentially, how do you create DropEngine modules? 590 00:47:57,450 --> 00:48:02,510 So the goal of the project isn't really to provide pre-baked methods for bypassing APADDR. 591 00:48:04,650 --> 00:48:05,810 It's really more... 592 00:48:06,770 --> 00:48:12,890 We did provide some example modules, but really, they're not really doing anything new or novel. 593 00:48:12,950 --> 00:48:21,950 And this is by design, because the goal of this framework is to enable red teams to maximize the value that they get from their individual payloads by converting them into reusable modules. 594 00:48:22,010 --> 00:48:29,850 And if you're a defender, this is useful, too, because you can use this tool to quickly create large sets of sample payloads from which to build a learning strategy. 595 00:48:32,010 --> 00:48:35,630 So there are two types of modules that you can build, input modules and output modules. 596 00:48:35,750 --> 00:48:38,910 Essentially, input modules are anything that's going in before it hits your payload. 597 00:48:38,910 --> 00:48:46,570 So your encryption function is an input module, whereas, for example, your executor function is going to be an output module. 598 00:48:46,890 --> 00:48:48,430 This is super important. 599 00:48:48,570 --> 00:48:59,510 Shout out to Marcelo, my leader, because basically the loader that he's using to build these is heavily based off of some of the stuff he's done. 600 00:49:01,630 --> 00:49:06,230 When I think about input modules, they always have to correspond to one or more matching output modules. 601 00:49:06,490 --> 00:49:08,750 But they're relatively simple to implement. 602 00:49:08,750 --> 00:49:14,430 As you can see here, what we're doing is we're building an encryption key module. 603 00:49:14,430 --> 00:49:22,490 And we're just inheriting from this base class and then creating a constructor, which is just kind of setting the various attributes associated with this. 604 00:49:24,130 --> 00:49:26,350 All the argument handling is up on the back end. 605 00:49:26,350 --> 00:49:30,590 If you want to pass command line arguments to your module, you just add an add arguments function. 606 00:49:30,590 --> 00:49:35,370 If you've ever used parse in Python before, you can just add all these here. 607 00:49:35,370 --> 00:49:39,790 The parser is already initialized by one of the parent classes of your module. 608 00:49:40,030 --> 00:49:44,130 So you can just make calls to self.parse.addArgument and add all the arguments you want. 609 00:49:44,130 --> 00:49:48,690 And that will get parsed automatically, essentially, once your payload is generated. 610 00:49:49,050 --> 00:49:50,230 And then you have your generate routine. 611 00:49:50,230 --> 00:49:50,830 And this is essentially... 612 00:49:51,970 --> 00:49:57,890 Well, for encryption keys, it's generate, but depending on the module type you're using, you're going to have your function that actually does stuff. 613 00:49:58,590 --> 00:50:02,490 Output modules, very similar, but even simpler. 614 00:50:02,650 --> 00:50:05,830 So the way the output modules work, this is the actual... 615 00:50:06,990 --> 00:50:09,250 These actually get rendered into your payload. 616 00:50:09,710 --> 00:50:12,410 They may potentially correspond to an input module. 617 00:50:12,410 --> 00:50:15,870 They may not, as in the case of an executor, for example. 618 00:50:15,990 --> 00:50:18,530 But it's really just a simple two-component design. 619 00:50:18,530 --> 00:50:24,810 You have a Jinja template and a Python file that stores metadata that is passed to the Jinja template. 620 00:50:25,430 --> 00:50:28,910 So, for example, here I've got a list of all my variables and imports and whatnot. 621 00:50:29,450 --> 00:50:36,570 And that gets passed to the interface, then passed back, and then loaded into the template in however format you need it. 622 00:50:36,770 --> 00:50:40,030 And then here you just have the Jinja template that you're using. 623 00:50:41,170 --> 00:50:45,910 As far as actually creating these things go, how much time do we actually have? 624 00:50:46,870 --> 00:50:48,510 I won't spend too much time on this. 625 00:50:52,310 --> 00:50:55,550 And it's just that if you want to create one of these modules, aside from the stuff... 626 00:50:55,550 --> 00:50:57,530 I guess what we haven't really shown you is the template. 627 00:50:57,650 --> 00:51:00,990 But here's just an example module. 628 00:51:01,170 --> 00:51:02,450 It doesn't really do anything. 629 00:51:04,550 --> 00:51:13,010 But see, all that you have to do is just set these attributes, and then you give it a list of interfaces it's compatible with, and then any input modules it's compatible with. 630 00:51:13,170 --> 00:51:18,530 Give it a list of all the variables in your C-sharp file, or whatever kind of file you're using. 631 00:51:18,530 --> 00:51:20,530 Really, it's not limited to C-sharp. 632 00:51:20,570 --> 00:51:24,490 And then also give it the name of a template, and give it a function and class name. 633 00:51:25,270 --> 00:51:27,510 In this particular instance, you have to do that. 634 00:51:28,950 --> 00:51:30,090 It's not very long. 635 00:51:30,770 --> 00:51:32,410 Then you have to create a template. 636 00:51:33,350 --> 00:51:35,550 And so, literally, this is the process of creating a template. 637 00:51:35,550 --> 00:51:37,890 And I'm actually working on automating this. 638 00:51:38,530 --> 00:51:41,710 But that requires, essentially, you need to write something that can parse C-sharp. 639 00:51:41,710 --> 00:51:44,390 And that's coming along, but it's not quite done yet. 640 00:51:44,390 --> 00:51:57,550 But for now, what you do, if you want to actually turn just a normal C-sharp file into a template that can be understood by DropEngine, you just find all your variables in here, and just wrap them in this Jinja parameter. 641 00:51:57,550 --> 00:52:01,430 So you just say d, and then you use a syntax here. 642 00:52:01,430 --> 00:52:03,690 So we've got variable nick. 643 00:52:05,650 --> 00:52:07,470 We just kind of edit it like that. 644 00:52:08,450 --> 00:52:12,210 And then we can do the same thing here with variable n. 645 00:52:13,030 --> 00:52:14,810 It should be our only two variables there. 646 00:52:15,790 --> 00:52:17,630 And I just do that once again over here. 647 00:52:20,790 --> 00:52:25,690 This is going to be painful for longer ones, but, you know, you only have to do it once in that case. 648 00:52:26,030 --> 00:52:31,250 And I'm working on some ways to kind of automate a lot of that. 649 00:52:33,810 --> 00:52:34,530 Share screen... 650 00:52:34,530 --> 00:52:35,530 Back to PowerPoint... 651 00:52:40,140 --> 00:52:41,680 And that's pretty much it. 652 00:52:41,760 --> 00:52:42,380 I'm going to... 653 00:52:43,520 --> 00:52:46,700 Actually, this is a Zoom thing, so I don't really know. 654 00:52:46,940 --> 00:52:50,240 That's the location of the project on GitHub, if you want to check it out. 655 00:52:51,000 --> 00:52:51,700 I'm going to... 656 00:52:52,600 --> 00:52:56,560 I think it's supposed to be like a Q&A thing right now, and I need to figure out how that works. 657 00:52:56,620 --> 00:52:57,200 So I'm going to... 658 00:52:57,800 --> 00:53:03,540 Yeah, basically, once again, thank you so much for your time and for the presentation here. 659 00:53:03,540 --> 00:53:04,480 Excellent presentation. 660 00:53:04,480 --> 00:53:07,580 So for the Q&A, you can jump into Discord. 661 00:53:07,580 --> 00:53:09,160 It's going to be offline, of course. 662 00:53:09,160 --> 00:53:13,620 There's a little bit of delay between the stream and when they can answer. 663 00:53:13,840 --> 00:53:17,420 And there's a lot of people actually already talking about the presentation. 664 00:53:17,520 --> 00:53:18,740 So kudos. 665 00:53:19,500 --> 00:53:27,660 And for those of you also that probably just joined, please take a look at all the talks and all the activities that we have in our website. 666 00:53:27,660 --> 00:53:31,040 The description should be in the bottom of the screen, right? 667 00:53:31,040 --> 00:53:34,960 So in the description of the screen, all the links and related material. 668 00:53:34,960 --> 00:53:38,260 And also, please join the conversation, as we said, in Discord. 669 00:53:38,520 --> 00:53:43,560 So we're going to go in a little break, and the next presentation will start in just a few minutes. 670 00:53:43,560 --> 00:53:44,960 Thank you again, Gabriel.