WEBVTT

00:00.580 --> 00:02.400
All right, welcome back, everybody.

00:02.400 --> 00:08.740
And thank you so much for supporting the DEF CON community and especially the Red Team Village.

00:08.760 --> 00:12.080
And without any further ado, I pass it back to Gabriel.

00:12.460 --> 00:13.480
Take it away.

00:14.080 --> 00:15.180
Hi again, everyone.

00:15.580 --> 00:20.240
This is a little different, but yeah, this is...

00:20.240 --> 00:22.660
I'm introducing a new tool called DropEngine.

00:22.660 --> 00:25.460
It's a Malibu payload creation framework.

00:25.480 --> 00:30.420
A bit about me, won't go on about this for too long, but my name is Gabe Ryan.

00:30.420 --> 00:32.580
I'm a Red Team Operator at Specter Ops.

00:32.700 --> 00:36.820
I used to work in a place called Gotham Digital Science doing security consulting.

00:37.240 --> 00:42.480
Got my Twitter handle and my LinkedIn username is actually pretty interesting.

00:42.480 --> 00:45.640
It's ms08016.

00:46.620 --> 00:49.740
So without further ado, let's just dive right into this.

00:50.060 --> 00:52.540
Let's talk about initial access payloads.

00:52.580 --> 00:55.760
So what are initial access payloads as opposed to normal payloads?

00:55.760 --> 01:00.060
Initial access payloads are typically used to gain access to a system environment.

01:00.060 --> 01:07.020
So at the very start of your engagement, it's what you're using to essentially gain your initial foothold.

01:07.880 --> 01:09.260
They're pretty simple in design.

01:09.260 --> 01:13.540
I mean, it really has like one job, which is to execute an implant or second stage payload.

01:13.820 --> 01:20.160
And then from there, you pretty much do everything, you know, all your secondary endpoint operations happen from that point onwards.

01:20.520 --> 01:25.560
Colloquially, they're also known as droppers or shellcode runners because they run shellcode.

01:27.320 --> 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.

01:36.100 --> 01:40.780
So I mean, despite the fact that it's like, you know, they perform a seemingly mundane task, right?

01:40.780 --> 01:43.120
That they just load code in memory and execute it.

01:43.740 --> 01:45.840
You know, there are some challenges to contend with.

01:45.840 --> 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.

01:53.900 --> 01:56.560
Usually, that's going to be done via spear phishing.

01:56.600 --> 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.

02:09.080 --> 02:12.020
It also may be exposed to automated behavioral analysis.

02:12.020 --> 02:21.020
So automated sandboxes, essentially what they do is they take your payload, and they actually execute it in a controlled environment.

02:21.220 --> 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.

02:31.840 --> 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.

02:43.860 --> 02:47.680
And finally, during the delivery phase, your payload is going to be downloaded and saved to disk.

02:47.680 --> 02:51.220
And you have to do this without triggering AV or, you know, getting caught by EDR or whatever.

02:52.580 --> 02:55.300
So that's the final challenge.

02:55.380 --> 02:57.720
And then once you've done that, you have to execute your payload.

02:57.720 --> 03:00.260
So the payload is going to be executed from disk.

03:00.280 --> 03:05.280
Usually if it's like a phishing payload or something like that.

03:05.820 --> 03:10.060
Although typically in-memory operations are a little better.

03:10.520 --> 03:11.680
You know, when you're just...

03:12.440 --> 03:15.920
One of the challenges of your initial access payload is that you can't really start that way.

03:15.920 --> 03:18.140
So you have to start from disk a lot of time.

03:19.280 --> 03:24.320
And you have to do this without triggering Antivirus or Endpoint Detection and Response, aka EDR.

03:24.520 --> 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.

03:35.800 --> 03:38.860
What this means is that you're going to have to find a way to bypass that.

03:38.860 --> 03:41.380
And that usually means relying on something called...

03:41.380 --> 03:46.620
the concept known as live-off-the-land binaries and scripts or LOBOS.

03:46.680 --> 03:54.000
Essentially what these are, I mean, they're just like utilities, they're binaries that become packaged with the operating system.

03:54.380 --> 04:00.160
And, you know, they're usually designed to like fulfill some benign role.

04:00.220 --> 04:01.880
But you can actually...

04:01.880 --> 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.

04:10.740 --> 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.

04:22.140 --> 04:23.920
So that's fortunate that you can rely on that.

04:23.920 --> 04:27.680
You can use that to bypass application whitelisting.

04:27.680 --> 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.

04:40.540 --> 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.

04:49.880 --> 04:53.640
So, you know, that's another obstacle you have to do.

04:53.640 --> 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.

05:04.360 --> 05:06.320
It's almost paradoxical in that way.

05:08.660 --> 05:13.380
And finally, I mean, you should assume that your initial access payload is going to be discovered.

05:13.500 --> 05:15.740
That's just a safe assumption to make.

05:16.060 --> 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.

05:23.660 --> 05:28.620
So with that in mind, all these are obstacles that are insurmountable.

05:28.660 --> 05:31.240
There are ways to contend with all of this.

05:31.620 --> 05:37.300
It is a bit of a cat and mouse game, but it's something that you can get around.

05:37.360 --> 05:41.240
The problem is that successful evasion techniques do not last very long.

05:41.260 --> 05:43.600
They have a tendency to get stale.

05:43.600 --> 05:46.360
They have relatively short shelf life.

05:46.380 --> 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.

05:58.020 --> 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.

06:06.080 --> 06:11.240
And they won't work forever if you're using the same TTPs for years and years.

06:11.260 --> 06:15.880
Well, you know, you could argue that you're not really improving the security.

06:15.880 --> 06:17.360
But yeah, that's a whole other thing.

06:17.360 --> 06:20.340
But so defenders will eventually catch up to you.

06:20.340 --> 06:23.980
And what this means is that your payloads are finite.

06:23.980 --> 06:26.360
They have a shelf life.

06:26.820 --> 06:28.220
And that's good.

06:28.300 --> 06:30.020
And specific payloads, right?

06:30.020 --> 06:31.720
So we were talking about TTPs there, right?

06:31.720 --> 06:35.500
But specific payloads that you write have an even shorter shelf life.

06:35.500 --> 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.

06:46.640 --> 06:50.120
And , you know, that's relatively easy to do.

06:50.120 --> 06:51.820
I mean, relatively, right?

06:51.820 --> 06:57.300
I mean, from an adversaries perspective, what this means is that reusing payloads is likely to get you burned.

06:57.300 --> 06:59.440
So, you know, this is where...

06:59.440 --> 07:05.840
what this means is that initial access payloads are typically, you know, kind of a pain point for offensive teams.

07:06.700 --> 07:10.980
And that's because, you know, you have all these challenges that you have to overcome.

07:11.280 --> 07:22.040
And the ways that you overcome these obstacles, you know, the methods that you use, essentially, are not going to last.

07:22.040 --> 07:28.660
And you typically have to write them by hand, or at least modify them by hand on a per-engagement basis.

07:29.080 --> 07:31.860
And, you know, code reuse can be problematic.

07:32.340 --> 07:33.700
And there's a lot of moving parts.

07:33.700 --> 07:35.280
There's a lot of...

07:35.280 --> 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.

07:43.880 --> 07:46.620
And there's a lot of things that can go wrong.

07:47.300 --> 07:50.280
So there's, you know, code reuse is a problem.

07:50.460 --> 07:52.600
You have to do a lot of stuff by hand.

07:52.600 --> 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.

07:59.080 --> 08:04.440
So to kind of contend with this problem, you know, I was actually just kind of, like, researching payloads independently.

08:04.440 --> 08:09.300
But at some point, you know, I just had the idea to work on this new tool called DropEngine.

08:09.300 --> 08:17.660
Essentially, the goal of DropEngine is to address this problem by providing a malleable framework for creating shellcode runners.

08:17.880 --> 08:21.660
So if you've ever used, like, Coblestrike, for example, one of the cool...

08:21.660 --> 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...

08:29.220 --> 08:35.380
that you're using on the target machines that you're operating on, can be modified.

08:35.380 --> 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.

08:44.100 --> 08:49.420
Like, just about every aspect of its use, you can customize it in some way.

08:49.420 --> 08:54.240
And by doing that, you know, really get a lot of use out of this one tool.

08:54.540 --> 08:59.320
So I guess the core idea was to try to do something similar with initial access payloads.

08:59.320 --> 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?

09:15.760 --> 09:19.280
And, you know, identify those and turn them into modules.

09:20.360 --> 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.

09:27.520 --> 09:33.040
And in the case of encryption, makes it easier to, you know, evade human analysts.

09:33.060 --> 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.

09:42.220 --> 09:44.160
So how would something like this work?

09:45.060 --> 09:48.340
To kind of think about this, right, we have to talk about how payloads are built.

09:48.760 --> 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.

09:54.700 --> 09:59.380
Because, like, we're actually not really trying to do a whole lot of crazy stuff here with the actual...

10:01.800 --> 10:03.020
...the payload itself.

10:03.020 --> 10:06.340
We're just looking at kind of the abstract design pattern here.

10:07.000 --> 10:12.380
You know, if we think about the anatomy of a payload, at their core, initial access payloads are relatively simple.

10:12.380 --> 10:14.720
They involve two major steps, which we talked about.

10:14.840 --> 10:16.960
You load the shellcode into memory and you execute it.

10:17.260 --> 10:19.300
A little bit of terminology I'm going to throw out here.

10:19.300 --> 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.

10:28.360 --> 10:31.220
So, there are many ways of achieving shellcode execution.

10:31.220 --> 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.

10:37.780 --> 10:41.660
But we actually want to abstract away specific details like this.

10:41.660 --> 10:43.600
We don't really want to focus on them quite yet.

10:43.960 --> 10:47.620
Because what we're looking at is actually for more of a bigger picture.

10:49.060 --> 10:51.830
You know, also something else we need to consider, we mentioned that we need to...

10:54.400 --> 10:56.380
...contend with application whitelisting.

10:56.380 --> 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.

11:06.040 --> 11:10.740
So, what this means is that our initial access payload is really going to require three basic components.

11:10.740 --> 11:13.020
And you can kind of see my diagram here on the left here.

11:13.120 --> 11:14.740
We're going to have the shellcode runner.

11:14.740 --> 11:17.320
Technically, the whole entire thing is a shellcode runner.

11:17.320 --> 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.

11:23.840 --> 11:26.220
That's going to be LullBoss specific, right?

11:26.680 --> 11:30.340
You know, if it's MSBuild payload, that's going to be like an XML file, basically.

11:30.340 --> 11:35.540
If it's an installutil payload, that's going to be a C sharp file that's compiled into an assembly.

11:35.840 --> 11:37.820
But you have your outer shellcode runner.

11:38.080 --> 11:39.860
And then you have your payload name.

11:39.880 --> 11:41.260
That's your application entry point.

11:41.260 --> 11:45.180
That's going to call your executor function and really everything else that gets called within your payload.

11:45.180 --> 11:47.000
But we're not going to worry about everything else yet.

11:47.480 --> 11:49.020
It's just these three components.

11:49.620 --> 11:51.860
And then finally, you have your executor function.

11:51.860 --> 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.

12:00.820 --> 12:04.040
So DropEngine implements these basic components as base classes.

12:04.560 --> 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.

12:12.280 --> 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.

12:18.680 --> 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.

12:26.120 --> 12:29.060
To kind of give you an example, you know, we're talking about the structure.

12:29.340 --> 12:31.720
You know, this is a... I ripped this direct...

12:32.720 --> 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.

12:39.860 --> 12:44.480
But yeah, this is from 0x13steveflores' GitHub.

12:44.480 --> 12:46.000
It's from a project called MoveKit.

12:46.000 --> 12:49.300
This is just an MSBuild runner, right?

12:49.300 --> 12:55.240
You have your outer wrapper, which is what we talked about here, right?

12:55.240 --> 12:56.780
And this is just your XML file.

12:56.780 --> 13:01.240
You have your payload main, which is just importing stuff and calling this executor here.

13:01.240 --> 13:06.260
And then you have your actual executor function there, your shellcode inject.

13:09.040 --> 13:10.580
So... and this is going to be interesting.

13:10.580 --> 13:12.300
I have to switch back and forth here a little bit.

13:12.300 --> 13:18.220
I'm actually going to stop sharing for a second and then reshare from Hyper.

13:19.300 --> 13:19.820
Cool.

13:19.940 --> 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

13:32.740 --> 13:39.940
payload main components, have our runners.

13:39.940 --> 13:43.180
We can break them into individual discrete components like that.

13:43.300 --> 13:46.260
And we'll kind of go into more depth in this in a little bit.

13:46.400 --> 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.

13:53.220 --> 13:58.360
So I'm going to stop this in an attempt to share this again.

13:58.360 --> 13:59.940
Okay, there we go.

14:00.360 --> 14:03.040
And then hit from current slide.

14:03.040 --> 14:03.840
Okay.

14:04.360 --> 14:09.280
So we've identified our discrete components here, right?

14:09.280 --> 14:11.380
These items here.

14:13.080 --> 14:18.080
We also want to throw in encryption capabilities.

14:18.080 --> 14:26.280
It's typically a good idea to leverage encryption when creating initial access payloads for multiple reasons.

14:26.460 --> 14:30.300
Basically, you have your shellcode that is going to be executed by your shellcode runner.

14:33.020 --> 14:36.380
A lot of these are going to be like binary payloads or something like that.

14:36.580 --> 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.

14:43.400 --> 14:50.320
What we do is, one way of hiding that from signature-based checks is by encrypting it.

14:50.560 --> 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.

14:57.640 --> 15:00.500
Remember, we need to assume that the payload is eventually going to get caught.

15:01.000 --> 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.

15:09.600 --> 15:19.100
What this means is that our updated payload execution process is actually going to involve a few more steps.

15:19.100 --> 15:23.090
We are going to load the encrypted payload into memory.

15:23.600 --> 15:29.420
We're going to decrypt that payload using an encryption key to obtain plaintext shellcode.

15:29.780 --> 15:33.680
And then finally, we're going to load that plaintext shellcode into memory and execute it.

15:33.880 --> 15:37.700
So the extra step here that we've added is this encryption function.

15:40.500 --> 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.

15:48.660 --> 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.

15:55.920 --> 16:00.700
It's either going to need to be able to derive the encryption key somehow without actually storing it.

16:00.700 --> 16:03.880
So it's not going to store it, but we need to be able to obtain the encryption key somehow.

16:03.880 --> 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.

16:11.860 --> 16:13.620
So we could provide it with that capability.

16:14.060 --> 16:17.880
Or we could just store the encryption key itself in the payload.

16:17.880 --> 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...

16:31.640 --> 16:38.600
you're just adding an extra step, but you're not really making it terribly difficult to pick apart.

16:40.320 --> 16:42.820
So let's talk about this first option a bit.

16:42.980 --> 16:47.440
We mentioned the use of...

16:48.360 --> 16:51.060
the first option is to derive the encryption key.

16:51.900 --> 16:56.400
One really great way of doing this is the use of environmental keying.

16:56.420 --> 16:57.800
This is like a really...

16:58.260 --> 17:02.000
I mean, so environmental keying has been around for a pretty long time.

17:02.000 --> 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.

17:10.320 --> 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...

17:22.080 --> 17:27.700
well, Ebola is the classic one, you know, that, yeah, that's...

17:28.480 --> 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.

17:36.000 --> 17:42.240
The other one is Spotter, that one was released fairly recently, I think like in 2018 or something like that.

17:42.280 --> 17:45.100
And, you know, it pretty much, you know, does something pretty similar.

17:46.400 --> 17:47.460
And then also there's...

17:48.560 --> 17:55.880
I think like Leo Lupik has some blog posts where he talks about this and also expands off of those.

17:56.440 --> 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.

18:05.000 --> 18:06.520
So what do we mean by this?

18:06.520 --> 18:12.680
Well, I mean, let's say that, you know, by attributes in the environment, you know, we're talking about usernames.

18:13.040 --> 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.

18:22.860 --> 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.

18:33.280 --> 18:34.700
You could, you know, use your...

18:34.700 --> 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.

18:43.660 --> 18:44.840
I actually didn't like...

18:44.840 --> 18:47.060
you could even like use the moon phase or something like that.

18:47.060 --> 18:50.020
I mean, you can, you know, but essentially what this lets you do...

18:50.560 --> 18:52.440
well, there's two things.

18:53.580 --> 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.

19:02.240 --> 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.

19:16.680 --> 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.

19:35.700 --> 19:39.060
So it makes your payload super hard to crack.

19:39.060 --> 19:41.560
And the added advantage is that it's very targeted.

19:43.280 --> 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.

19:53.980 --> 19:56.940
So I'm now going to set the first live demo of this.

19:57.460 --> 19:59.140
Over Zoom, no less.

19:59.280 --> 20:00.620
All right.

20:00.620 --> 20:03.380
So I'm going to do a couple of things.

20:03.380 --> 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.

20:09.940 --> 20:14.020
So I'm going to stop sharing for one second and I'm literally going to share.

20:15.200 --> 20:16.380
Well, can I do that?

20:18.000 --> 20:19.180
Okay, actually, yeah.

20:19.180 --> 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.

20:33.760 --> 20:36.240
And you should see it.

20:36.260 --> 20:39.520
Okay, let me try sharing this again.

20:45.500 --> 20:46.720
Oh, you know what I can do?

20:46.980 --> 20:47.860
Yeah, here it is.

20:47.860 --> 20:49.280
Okay, I got it.

20:49.280 --> 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.

20:58.680 --> 21:02.560
So that's turned off, as well as automatic sample submission.

21:02.560 --> 21:06.020
But this is a brand new Windows 10 install.

21:06.620 --> 21:09.200
I have real-time protection turned on.

21:09.880 --> 21:13.240
Tamper protection is turned on, so you can't disable it.

21:13.940 --> 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.

21:21.580 --> 21:26.400
So I have one exclusion here, and this is this directory, demo AB include.

21:26.400 --> 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

21:35.860 --> 21:38.000
switch windows that I'm sharing again.

21:38.040 --> 21:40.020
So you should see hyper right now.

21:40.020 --> 21:40.920
There's four terminals.

21:40.920 --> 21:43.400
I'm going to try to make this a little cleaner.

21:46.910 --> 21:50.050
So in the top left, this is just for my benefit.

21:50.050 --> 21:52.710
That's essentially, I'm trying not to anger the demo gods.

21:53.130 --> 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.

22:00.730 --> 22:02.150
This will be relevant later.

22:02.150 --> 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.

22:06.590 --> 22:07.830
This is a Metasploit instance.

22:07.830 --> 22:10.630
So this is... yeah, so we're actually going to use Meterpreter for this.

22:10.630 --> 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.

22:16.810 --> 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.

22:23.970 --> 22:29.350
We have to use HTTPS because the actual unencrypted traffic will be picked up immediately.

22:30.810 --> 22:32.760
So that exclusion that we're seeing...

22:35.030 --> 22:36.610
I'm just being difficult.

22:36.610 --> 22:37.140
I'm going to have to...

22:38.610 --> 22:43.050
It's going to be in this directory here.

22:43.750 --> 22:45.150
I'm going to AV exclude.

22:45.150 --> 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.

23:00.930 --> 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...

23:07.210 --> 23:09.390
I'm trying to make this go as smoothly as possible.

23:10.870 --> 23:16.990
So the compromise here is that we're going to be pulling our actual shellcode out of demo AV exclude.

23:16.990 --> 23:19.130
But when we execute it, that's not where we're executing from.

23:19.130 --> 23:21.470
We're going to be executing outside of that exclusion folder.

23:22.310 --> 23:28.110
Okay, with that out of the way, let's show you how to go over...

23:38.800 --> 23:45.180
Let's go over how we'd make a payload using environmental keying.

23:45.400 --> 23:52.540
So essentially, the first thing we're going to do is get a list of available models, right?

23:52.540 --> 23:53.640
And just run this.

23:53.640 --> 23:57.420
And these are all the different payload components we can choose from.

23:57.420 --> 23:59.940
So let's say that we want to use environmental keying.

23:59.940 --> 24:01.340
We want to essentially grab...

24:04.420 --> 24:10.380
Let's do the FQDN, because I have that written down, and my current username.

24:10.380 --> 24:12.460
So we're going to derive the key from that.

24:12.700 --> 24:14.840
In that case, we could just do this.

24:14.840 --> 24:25.740
We could do Python, prop engine, break onto a new line here, specify that our shellcode should be...

24:27.620 --> 24:33.980
You know, in that demo, maybe exclude to shell.

24:35.180 --> 24:37.760
We're going to use an interface...

24:37.760 --> 24:39.960
So the interface, I'm specifying this command interface.

24:39.960 --> 24:42.080
That's like literally the glue that holds everything together.

24:42.080 --> 24:44.920
You know, if you're working in C-sharp, you're going to use a C-sharp interface.

24:45.140 --> 24:46.900
Don't worry about that too much.

24:47.120 --> 24:51.980
But we're going to say, C-sharp runner interface, right?

24:52.500 --> 24:54.480
And then we're going to also look at...

24:54.480 --> 24:55.840
Just like this encryption key.

24:55.840 --> 24:58.280
We need an encryption key and a decryption key.

24:58.880 --> 25:06.140
So the EQ keys we're going to use are going to be this external FQDN that we talked about.

25:06.760 --> 25:08.400
And notice I'm using more than one.

25:08.440 --> 25:12.340
We'll kind of go into how that works in a second, right?

25:14.890 --> 25:18.850
I'm just going to use the decryption keys, which is essentially these things, but written in C-sharp.

25:22.080 --> 25:24.900
I'm just going to copy these, put them in there.

25:26.540 --> 25:28.120
We're then going to need to select a encryptor.

25:28.120 --> 25:29.540
It's doing encryptor shellcode.

25:30.240 --> 25:33.300
So we're going to say, encryptor AES.

25:33.300 --> 25:35.360
We're just going to use AES-256.

25:36.180 --> 25:38.780
That should really be named AES-256, not just AES.

25:38.780 --> 25:39.960
I should change that.

25:40.280 --> 25:41.820
And we're going to use a decryptor.

25:42.520 --> 25:51.020
So decryptor C-sharp, origin doll AES, which is the corresponding decryption function that we need.

25:52.000 --> 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.

26:02.940 --> 26:04.520
And then we're going to need a mutator.

26:04.520 --> 26:07.560
We haven't really talked about mutators yet, but we will.

26:09.380 --> 26:13.000
But for now, I'm going to say mutator string.

26:13.220 --> 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.

26:18.840 --> 26:21.720
So it just makes it a little harder to signature around.

26:22.320 --> 26:23.560
And that really is...

26:23.560 --> 26:30.120
Oh, we also need to specify the actual username and external FQDN that we're trying to use for our key.

26:30.120 --> 26:36.240
So I'll put my username as FQDN.

26:36.400 --> 26:38.460
And I'm just going to copy it from here.

26:38.460 --> 26:41.520
And hopefully, this is an update in the last time, like in the past hour or so.

26:41.520 --> 26:42.800
I don't think it would have.

26:43.360 --> 26:46.560
And finally, oops, I forgot something.

26:48.840 --> 26:50.340
We need an executor function.

26:50.340 --> 26:53.440
Yeah, so we need that executor function that actually executes our shellcode.

26:53.440 --> 26:56.780
And we're just going to use C-sharp virtual alloc thread.

26:57.700 --> 27:01.420
And so you may call it virtual alloc, virtual protect, and all that.

27:02.940 --> 27:06.600
And we're going to make our output file example.csproj.

27:06.600 --> 27:09.200
And that's going to be our MSBuild file.

27:09.280 --> 27:09.620
Cool.

27:09.620 --> 27:10.340
Looks like it ran.

27:10.340 --> 27:11.240
Didn't get any errors.

27:11.240 --> 27:17.360
If you look at our example.csproj, here is an obfuscated MSBuild file.

27:18.280 --> 27:23.140
Actually, I should probably show you what this is actually doing.

27:24.640 --> 27:27.760
I'm going to do mutate or null, which basically means don't mutate anything.

27:30.260 --> 27:35.160
But yeah, so basically, here are all the different components that are stacked together.

27:35.160 --> 27:40.320
Here are your decryption keys, and your decryptor, and your executor, and everything else.

27:40.360 --> 27:43.540
And then here's your actual payload itself and payload name.

27:43.540 --> 27:47.340
Essentially, all this is just being rendered into the payload by DropEngine.

27:47.840 --> 27:48.640
Automagically.

27:49.440 --> 27:51.080
And finally, I run everything down there.

27:51.740 --> 27:54.080
But I want this to be random, because I don't know.

27:54.080 --> 27:55.200
Demo gots, I guess.

27:55.620 --> 27:57.360
So I made that a random one.

27:58.120 --> 27:59.820
So now we're going to set up our handler.

28:00.580 --> 28:04.380
Use exploit multihandler payload for CTP.

28:06.160 --> 28:11.220
Lhost set Lport 443, which should be correct.

28:11.220 --> 28:15.180
And I'm going to set exploit-j to start our handler in the background.

28:15.800 --> 28:19.220
And then we're going to actually run this using AliceBuild.

28:19.580 --> 28:21.660
And there we go.

28:21.960 --> 28:28.260
Now, just to kind of, in case you don't believe me, that this is actually doing something.

28:30.900 --> 28:33.180
I'm going to kill everything here.

28:38.990 --> 28:41.050
That was a bad sign.

28:41.050 --> 28:45.530
But I copy of

28:49.870 --> 28:50.930
the enter nano.

28:52.050 --> 28:52.610
All right.

28:52.610 --> 28:53.050
You know what?

28:53.050 --> 28:55.430
I'm actually deviating from the demo right now.

28:55.430 --> 28:57.570
And I think that's a bad idea.

28:57.570 --> 28:59.630
We'll get back to this if we have time.

29:01.950 --> 29:03.030
No, actually, you know what?

29:03.030 --> 29:03.890
I'm stubborn.

29:03.890 --> 29:04.690
Let's do the...

29:08.740 --> 29:14.980
Yeah, I copy demo AV exclude empty shell.

29:14.980 --> 29:17.560
And let's just copy it up on level.

29:18.720 --> 29:24.090
We should get alert.

29:25.950 --> 29:27.110
Or perhaps not.

29:27.110 --> 29:29.370
Maybe we might have to run it to get the alert.

29:30.270 --> 29:32.750
But yeah, I'm not going to say you're tinkering with this.

29:36.050 --> 29:37.610
Let's get back to PowerPoint.

29:38.930 --> 29:39.810
OK.

29:39.910 --> 29:40.970
From current slide.

29:42.650 --> 29:44.710
So that's our payload.

29:44.710 --> 29:51.310
Basically, custom build payload with environmental keying that we literally just created in a second.

29:54.230 --> 29:56.490
So mutator modules, right?

29:58.210 --> 30:00.070
We mentioned also that we're using...

30:10.280 --> 30:11.000
Ignore me.

30:11.000 --> 30:13.100
I could have sworn there was something else that I was supposed to talk about there.

30:13.100 --> 30:13.620
OK.

30:13.820 --> 30:14.200
Yeah.

30:14.200 --> 30:16.420
So the other thing, essentially what we've just done.

30:17.020 --> 30:21.580
We've said, here's the executor function we want to use.

30:21.700 --> 30:24.000
Here's the shellcode runner we want to use.

30:24.000 --> 30:26.700
Here's the encryption decryption routines we want to use.

30:26.900 --> 30:30.000
And by the way, we want to derive our keys from these two specific functions.

30:30.000 --> 30:32.280
And we're going to pull this stuff together and make it into a payload.

30:32.280 --> 30:37.500
And by the way, randomize all the variables in variable names in that payload.

30:37.800 --> 30:40.460
And just write a command, and then it just does it.

30:40.460 --> 30:42.520
And then voila, you have a payload.

30:43.080 --> 30:44.620
The way that we did the actual...

30:44.620 --> 30:50.940
The changing of the variable names was using basically modular symbolic mutation.

30:50.940 --> 30:54.420
So DropEngine supports the use of mutator modules that...

30:54.420 --> 30:55.640
I mean, essentially what they do is that they...

30:56.700 --> 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.

31:09.100 --> 31:18.700
And the mutator module then systematically goes through and takes a list of variable names and maps them using some algorithm.

31:18.700 --> 31:20.080
The algorithm is irrelevant.

31:20.180 --> 31:21.720
It's module specific.

31:22.460 --> 31:23.980
And then when the actual...

31:23.980 --> 31:29.380
And returns back to that module, the original module, that mapping.

31:29.380 --> 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.

31:33.320 --> 31:35.300
And then what happens is that when you render...

31:35.300 --> 31:40.300
When that module gets rendered into a rendered template, and that's how we're building everything.

31:40.300 --> 31:41.720
It's using Jinja templates.

31:43.680 --> 31:44.640
We are...

31:44.640 --> 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.

31:51.480 --> 31:58.140
So this is pretty cool because it allows us to create payloads that, you know, circumvent signature-based detections pretty easily.

31:58.300 --> 32:02.160
I only have like three supported methods in there right now.

32:02.300 --> 32:05.840
Rot13, the random string, and also symbol substitution using a word list.

32:05.840 --> 32:08.180
Null mutator doesn't really count because that's just...

32:08.180 --> 32:09.220
It just doesn't do anything.

32:09.220 --> 32:10.280
It's a null mutator.

32:10.280 --> 32:12.660
It's primarily there for debugging purposes.

32:13.840 --> 32:17.690
And I've kind of already demonstrated that, but if you want to just go over...

32:18.680 --> 32:21.980
Just once again, what that looks like.

32:22.180 --> 32:30.340
You know, take this one that we just did, just print to the screen instead of out the file.

32:30.520 --> 32:32.010
So for example, here's your...

32:33.200 --> 32:34.320
Actually, let me use...

32:34.320 --> 32:38.720
I've got another piece of shellcode that isn't so long that we can use for demos.

32:41.080 --> 32:45.360
Yeah, so, you know, here's your random strings.

32:45.740 --> 32:46.960
You know, if you wanted to use...

32:49.880 --> 32:50.760
Rot13.

32:53.200 --> 32:57.200
These look an awful lot like the variable names.

32:57.540 --> 32:59.080
Let's use a word list.

33:02.050 --> 33:04.730
You actually have to specify a word list when you do this.

33:04.730 --> 33:06.230
Let's use US cities.

33:06.230 --> 33:07.130
And that will...

33:07.130 --> 33:09.170
Now all your variable names are corresponding to US cities.

33:09.170 --> 33:13.710
A better use of this would just be to make a word list that actually are believable variable names.

33:13.710 --> 33:18.470
But I don't know, this is better for doing a demo.

33:19.090 --> 33:20.490
Let me go back to PowerPoint.

33:20.870 --> 33:22.370
Let's move on from here.

33:28.370 --> 33:30.010
And let me just make sure...

33:30.010 --> 33:30.950
Okay, cool.

33:32.810 --> 33:36.270
So let's talk about some more keying techniques that we support.

33:36.830 --> 33:38.490
We talked about environmental keying.

33:38.490 --> 33:39.730
Remote keying is also pretty neat.

33:39.730 --> 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.

33:53.410 --> 33:54.750
This is actually...

33:54.750 --> 33:59.810
You know, if you have well-designed non-attributable attack infrastructure, it actually makes this method pretty effective.

33:59.810 --> 34:05.570
You know, you can place the key server behind a redirector and only accept requests for that key on very specific...

34:06.270 --> 34:09.710
for very specific profile traffic that's being sent to the redirector.

34:09.730 --> 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...

34:19.230 --> 34:23.270
By the way, you want to have one key per payload, and DropEngine does support that.

34:25.030 --> 34:27.690
So keys should be unique to the payload that you generate.

34:28.270 --> 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.

34:39.910 --> 34:43.570
So the key server goes back into its database and just nukes the key.

34:43.590 --> 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.

34:54.890 --> 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.

35:01.970 --> 35:04.810
Like , look, it's not... it's just jQuery, right?

35:04.810 --> 35:09.250
But so, I mean, there are obviously some obvious advantages to doing keying this way.

35:09.290 --> 35:11.230
It's very resistant to analysis.

35:11.430 --> 35:13.790
The encryption key is not stored on the payload file.

35:14.090 --> 35:18.230
And it's hopefully being protected in transit using TLS.

35:18.710 --> 35:22.270
It's also less targeted, right?

35:22.270 --> 35:26.810
You know, while highly targeted payloads are good in a lot of cases, sometimes they're not.

35:26.810 --> 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.

35:32.350 --> 35:34.590
Sometimes you want a little more breadth.

35:34.590 --> 35:37.890
In this case, you don't have to limit your scope.

35:38.810 --> 35:40.710
I mean, you should limit your scope regardless.

35:40.710 --> 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.

35:51.530 --> 35:55.810
So I'll show you how this works in Dropbox really fast.

35:57.310 --> 36:00.330
And I'm going to go back to my screen here, go back to Hyper.

36:04.400 --> 36:08.420
And so in the bottom left, we have this, what looks like a Flask app.

36:08.860 --> 36:10.480
It's really, really basic.

36:11.700 --> 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.

36:15.780 --> 36:19.440
But this is our remote one-time key server.

36:19.460 --> 36:29.440
And what we're going to do here is do a very similar payload to what we just did, right?

36:33.920 --> 36:34.800
Hang on, let me...

36:48.190 --> 36:49.670
So we're going to grab this.

36:51.590 --> 36:57.050
And this is, you know, as you can see here, well, it's just RAM.

36:57.050 --> 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.

37:06.550 --> 37:08.730
It's pretty much the same attributes we used last time.

37:08.730 --> 37:11.830
The difference here is we actually added some keying components.

37:12.290 --> 37:16.550
We added a new key here, which you can see right here.

37:16.550 --> 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.

37:24.490 --> 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.

37:33.250 --> 37:37.690
And it's going to use that by using a specific identifier that you need to your implant.

37:38.090 --> 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.

37:43.590 --> 37:50.270
And if it does, it's going to respond with the decryption key and send it back to our payload.

37:50.270 --> 37:53.450
And then, you know, it'll be deleted from the database.

37:53.450 --> 37:56.070
So subsequent requests just won't be honored.

37:57.710 --> 37:59.990
So let's run that really fast.

38:00.430 --> 38:03.310
We just kind of prep the bottom left here.

38:03.610 --> 38:07.030
Make sure we don't have any stragglers either in our sessions or...

38:08.430 --> 38:09.750
Oh, okay, cool.

38:09.750 --> 38:11.610
So we're going to run our handler.

38:14.270 --> 38:18.710
And we're going to rebuild this really fast just to make sure everything looks selfless enough.

38:18.710 --> 38:19.650
It does.

38:21.670 --> 38:24.210
And we're going to call it MSBuild once again.

38:25.630 --> 38:27.270
And there we go.

38:27.810 --> 38:30.970
And you'll notice here, this traffic showed up in the Flask app.

38:30.970 --> 38:35.930
And that is our server going back.

38:35.930 --> 38:38.170
That's our payload retrieving the key, right?

38:38.170 --> 38:44.450
Now, let's go ahead and kill this session right here,

38:51.870 --> 38:54.230
right?

38:56.670 --> 38:59.130
And the reason why I'm doing that is I want to show you what happens when we...

39:00.150 --> 39:03.450
So we've already retrieved that remote key.

39:03.450 --> 39:05.810
So what we're going to do now is we're going to just kind of demonstrate.

39:06.590 --> 39:09.870
If we happen to curl for that same value, right?

39:10.290 --> 39:14.550
Let's say we do a curl request to 127.

39:14.550 --> 39:18.030
This is running on mobile, so we can just do this.

39:22.570 --> 39:25.130
HTTP//, we're not using SSL at the moment.

39:30.150 --> 39:30.910
Oh, you know what?

39:30.910 --> 39:33.130
We'd actually need the implant ID, wouldn't we?

39:33.470 --> 39:34.490
Oh, no, here it is.

39:34.490 --> 39:36.970
Yeah, let's grab this implant ID right from here.

39:37.390 --> 39:37.890
Cool.

39:37.890 --> 39:39.990
So we have everything we need to make this work.

39:41.250 --> 39:48.530
And you'll see that we don't actually get a response at this time because it's been cleared.

39:49.830 --> 39:53.530
All right, so back to our PowerPoint.

39:54.610 --> 39:56.590
We've got about 20 minutes left.

39:56.590 --> 39:58.910
Open this up for chat for about 10.

40:00.090 --> 40:02.330
Let's go back here.

40:04.590 --> 40:06.130
Press slide.

40:06.130 --> 40:06.570
All right .

40:10.500 --> 40:19.880
So one thing you'll notice is that we're actually using multiple encryption keys here.

40:19.880 --> 40:20.880
Or it seems like it, right?

40:20.880 --> 40:26.040
Because we're specifying these different key types and combining them to create a final encryption key.

40:26.200 --> 40:30.140
We're doing this using something that I like to call key stacking.

40:32.280 --> 40:33.860
Key stacking is just like a label.

40:33.860 --> 40:38.620
I'm sure this has been done before a million times because it's really not that complicated.

40:39.260 --> 40:40.780
It's pretty simple in practice.

40:40.780 --> 40:42.060
And we'll see that in a minute.

40:42.060 --> 40:48.620
But essentially key stacking is the practice of combining the results of multiple keying methods to create a single combined keys.

40:48.800 --> 40:55.100
So for example, let's say we want a key that's combined of four parts.

40:55.100 --> 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.

41:03.940 --> 41:07.580
Well, in that point, we essentially would just make four method calls within our payload.

41:09.040 --> 41:13.380
To four different key derivation functions, concatenate the results together.

41:13.540 --> 41:20.220
And by doing that, we'd have one encryption key that was derived from all these different sources.

41:20.440 --> 41:23.100
So one advantage of doing this is it gives us a little more security.

41:23.100 --> 41:25.080
It's difficult to compromise.

41:25.600 --> 41:27.700
Disadvantage is kind of complicated.

41:27.700 --> 41:32.420
If you do this by hand, it's just adding more moving parts to the equation.

41:32.420 --> 41:37.100
But once again, since we're using a framework, it makes it a little less complicated.

41:40.140 --> 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.

41:47.820 --> 41:54.780
So remember, originally, we just had that shellcode runner and a payload main in there and an executor function.

41:54.780 --> 41:56.600
In this case, we still have our shellcode runner.

41:56.600 --> 41:57.720
It's our outermost wrapper.

41:57.720 --> 42:02.320
That's our LulzBot-specific script that encapsulates everything.

42:02.420 --> 42:04.120
But we also have our payload main.

42:05.760 --> 42:09.860
And within that, we now have, you see here, we all have all these D-key functions.

42:11.080 --> 42:14.160
So we have a D-key 1, D-key 2, all the way through D-key N.

42:14.160 --> 42:15.960
It's an arbitrary number of D-key functions.

42:16.640 --> 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.

42:36.960 --> 42:41.280
So really, it's not too bad.

42:43.860 --> 42:45.920
We already went over key stacking.

42:46.820 --> 42:48.580
So let's talk about pre-modules and post-modules.

42:48.580 --> 42:51.980
And I included the cookie monster here, because who doesn't like the cookie monster?

42:56.500 --> 42:58.440
So what are pre-modules and post-modules?

43:00.280 --> 43:01.740
Essentially, this is a concept.

43:01.740 --> 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.

43:16.620 --> 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,

43:33.500 --> 43:39.840
to actually see if you're in a quote-unquote real environment or in a sandbox.

43:41.120 --> 43:44.380
Also, we mentioned that this is likely going to be going through the CLR.

43:44.420 --> 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.

43:54.380 --> 44:02.160
So what pre-modules do, essentially, they are just subroutines that are pre-pended to everything else in your payload.

44:02.160 --> 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.

44:10.440 --> 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,

44:25.880 --> 44:29.080
which is pretty cool because you actually control which order they execute in.

44:29.080 --> 44:33.020
But once they finish executing, then we execute the rest of your shellcode here.

44:35.180 --> 44:37.400
So post-modules, they're pretty much the opposite thing.

44:37.400 --> 44:42.820
Instead of being pre-pended to the beginning of the payload, we append them to the end of the payload.

44:42.820 --> 44:49.420
So that's useful for if there's something that you want to do after your shellcode terminates.

44:49.420 --> 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.

45:00.480 --> 45:07.060
So you can mangle all the string names and variable names, however you want.

45:09.790 --> 45:16.930
And so if we're going to demo the process of adding pre-modules, here's how you do it.

45:18.490 --> 45:20.610
I'll make this a super fast one.

45:30.060 --> 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.

45:48.580 --> 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.

45:54.520 --> 45:57.140
A file path is a sandbox check.

45:57.140 --> 46:01.960
Then finally, we want to execute an empty scan buffer bypass.

46:02.560 --> 46:05.780
We can just append these here as pre-modules.

46:17.880 --> 46:34.490
And actually, if you're curious what this looks like, I'm not actually going to save this.

46:34.490 --> 46:36.090
I'm just going to send it to the screen.

46:38.130 --> 46:39.430
Yeah, that's what I want to do.

46:39.430 --> 46:43.830
And then I'm going to use that really, really small shellcode that I showed you earlier.

46:43.910 --> 46:45.230
It's easier to read.

46:48.360 --> 46:53.140
It should not be from the exclusion folder, because that small shellcode is not in the exclusion folder.

46:57.340 --> 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.

47:08.040 --> 47:11.780
So that all gets done right before you run everything else.

47:12.360 --> 47:16.640
So once again, let's get up on our MSVL payload.

47:16.640 --> 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.

47:23.580 --> 47:28.400
And you see that it runs, so everything just kind of goes swimmingly, because we're out of the sandbox.

47:31.440 --> 47:32.700
We go ahead and fill this...

47:39.470 --> 47:41.330
PowerPoint, just wrap this up.

47:50.750 --> 47:53.530
We kind of did both demos at once, and that's all right.

47:53.770 --> 47:57.450
The last thing we're going to talk about is, essentially, how do you create DropEngine modules?

47:57.450 --> 48:02.510
So the goal of the project isn't really to provide pre-baked methods for bypassing APADDR.

48:04.650 --> 48:05.810
It's really more...

48:06.770 --> 48:12.890
We did provide some example modules, but really, they're not really doing anything new or novel.

48:12.950 --> 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.

48:22.010 --> 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.

48:32.010 --> 48:35.630
So there are two types of modules that you can build, input modules and output modules.

48:35.750 --> 48:38.910
Essentially, input modules are anything that's going in before it hits your payload.

48:38.910 --> 48:46.570
So your encryption function is an input module, whereas, for example, your executor function is going to be an output module.

48:46.890 --> 48:48.430
This is super important.

48:48.570 --> 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.

49:01.630 --> 49:06.230
When I think about input modules, they always have to correspond to one or more matching output modules.

49:06.490 --> 49:08.750
But they're relatively simple to implement.

49:08.750 --> 49:14.430
As you can see here, what we're doing is we're building an encryption key module.

49:14.430 --> 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.

49:24.130 --> 49:26.350
All the argument handling is up on the back end.

49:26.350 --> 49:30.590
If you want to pass command line arguments to your module, you just add an add arguments function.

49:30.590 --> 49:35.370
If you've ever used parse in Python before, you can just add all these here.

49:35.370 --> 49:39.790
The parser is already initialized by one of the parent classes of your module.

49:40.030 --> 49:44.130
So you can just make calls to self.parse.addArgument and add all the arguments you want.

49:44.130 --> 49:48.690
And that will get parsed automatically, essentially, once your payload is generated.

49:49.050 --> 49:50.230
And then you have your generate routine.

49:50.230 --> 49:50.830
And this is essentially...

49:51.970 --> 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.

49:58.590 --> 50:02.490
Output modules, very similar, but even simpler.

50:02.650 --> 50:05.830
So the way the output modules work, this is the actual...

50:06.990 --> 50:09.250
These actually get rendered into your payload.

50:09.710 --> 50:12.410
They may potentially correspond to an input module.

50:12.410 --> 50:15.870
They may not, as in the case of an executor, for example.

50:15.990 --> 50:18.530
But it's really just a simple two-component design.

50:18.530 --> 50:24.810
You have a Jinja template and a Python file that stores metadata that is passed to the Jinja template.

50:25.430 --> 50:28.910
So, for example, here I've got a list of all my variables and imports and whatnot.

50:29.450 --> 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.

50:36.770 --> 50:40.030
And then here you just have the Jinja template that you're using.

50:41.170 --> 50:45.910
As far as actually creating these things go, how much time do we actually have?

50:46.870 --> 50:48.510
I won't spend too much time on this.

50:52.310 --> 50:55.550
And it's just that if you want to create one of these modules, aside from the stuff...

50:55.550 --> 50:57.530
I guess what we haven't really shown you is the template.

50:57.650 --> 51:00.990
But here's just an example module.

51:01.170 --> 51:02.450
It doesn't really do anything.

51:04.550 --> 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.

51:13.170 --> 51:18.530
Give it a list of all the variables in your C-sharp file, or whatever kind of file you're using.

51:18.530 --> 51:20.530
Really, it's not limited to C-sharp.

51:20.570 --> 51:24.490
And then also give it the name of a template, and give it a function and class name.

51:25.270 --> 51:27.510
In this particular instance, you have to do that.

51:28.950 --> 51:30.090
It's not very long.

51:30.770 --> 51:32.410
Then you have to create a template.

51:33.350 --> 51:35.550
And so, literally, this is the process of creating a template.

51:35.550 --> 51:37.890
And I'm actually working on automating this.

51:38.530 --> 51:41.710
But that requires, essentially, you need to write something that can parse C-sharp.

51:41.710 --> 51:44.390
And that's coming along, but it's not quite done yet.

51:44.390 --> 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.

51:57.550 --> 52:01.430
So you just say d, and then you use a syntax here.

52:01.430 --> 52:03.690
So we've got variable nick.

52:05.650 --> 52:07.470
We just kind of edit it like that.

52:08.450 --> 52:12.210
And then we can do the same thing here with variable n.

52:13.030 --> 52:14.810
It should be our only two variables there.

52:15.790 --> 52:17.630
And I just do that once again over here.

52:20.790 --> 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.

52:26.030 --> 52:31.250
And I'm working on some ways to kind of automate a lot of that.

52:33.810 --> 52:34.530
Share screen...

52:34.530 --> 52:35.530
Back to PowerPoint...

52:40.140 --> 52:41.680
And that's pretty much it.

52:41.760 --> 52:42.380
I'm going to...

52:43.520 --> 52:46.700
Actually, this is a Zoom thing, so I don't really know.

52:46.940 --> 52:50.240
That's the location of the project on GitHub, if you want to check it out.

52:51.000 --> 52:51.700
I'm going to...

52:52.600 --> 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.

52:56.620 --> 52:57.200
So I'm going to...

52:57.800 --> 53:03.540
Yeah, basically, once again, thank you so much for your time and for the presentation here.

53:03.540 --> 53:04.480
Excellent presentation.

53:04.480 --> 53:07.580
So for the Q&A, you can jump into Discord.

53:07.580 --> 53:09.160
It's going to be offline, of course.

53:09.160 --> 53:13.620
There's a little bit of delay between the stream and when they can answer.

53:13.840 --> 53:17.420
And there's a lot of people actually already talking about the presentation.

53:17.520 --> 53:18.740
So kudos.

53:19.500 --> 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.

53:27.660 --> 53:31.040
The description should be in the bottom of the screen, right?

53:31.040 --> 53:34.960
So in the description of the screen, all the links and related material.

53:34.960 --> 53:38.260
And also, please join the conversation, as we said, in Discord.

53:38.520 --> 53:43.560
So we're going to go in a little break, and the next presentation will start in just a few minutes.

53:43.560 --> 53:44.960
Thank you again, Gabriel.

