start	end	text
580	2400	All right, welcome back, everybody.
2400	6400	And thank you so much for supporting the DEF CON community
6400	8740	and especially the Red Team Village.
8760	12080	And without any further ado, I pass it back to Gabriel.
12460	13480	Take it away.
14080	15180	Hi again, everyone.
15580	20240	This is a little different, but yeah, this is...
20240	22660	I'm introducing a new tool called DropEngine.
22660	25460	It's a Malibu payload creation framework.
25480	29000	A bit about me, won't go on about this for too long,
29000	30420	but my name is Gabe Ryan.
30420	32580	I'm a Red Team Operator at Specter Ops.
32700	34700	I used to work in a place called Gotham Digital Science
34700	36820	doing security consulting.
37240	41520	Got my Twitter handle and my LinkedIn username
41520	42480	is actually pretty interesting.
42480	45640	It's ms08016.
46620	49740	So without further ado, let's just dive right into this.
50060	52540	Let's talk about initial access payloads.
52580	54460	So what are initial access payloads
54460	55760	as opposed to normal payloads?
55760	57720	Initial access payloads are typically used
57720	60060	to gain access to a system environment.
60060	62280	So at the very start of your engagement,
62280	67020	it's what you're using to essentially gain your initial foothold.
67880	69260	They're pretty simple in design.
69260	70760	I mean, it really has like one job,
70760	73540	which is to execute an implant or second stage payload.
73820	76140	And then from there, you pretty much do everything,
76140	78460	you know, all your secondary endpoint operations
78460	80160	happen from that point onwards.
80520	83580	Colloquially, they're also known as droppers or shellcode runners
84200	85560	because they run shellcode.
87320	89800	But yeah, you know, while initial access payloads
89800	91980	do have a pretty simple role,
91980	96100	there are some obstacles that you have to face when designing them.
96100	98720	So I mean, despite the fact that it's like,
98720	100780	you know, they perform a seemingly mundane task, right?
100780	103120	That they just load code in memory and execute it.
103740	105840	You know, there are some challenges to contend with.
105840	109100	The first of which is that, you know, during the delivery phase,
109100	110700	so what you're actually trying to get this payload
111740	113460	onto the target machine.
113900	116560	Usually, that's going to be done via spear phishing.
116600	119000	And if that's the direction you're going,
119000	123040	you know, this payload is going to be exposed to signature-based detections,
123040	124360	you know, in the form of mail filters,
124360	128860	you know, and stuff that's scanning through the email that you're sending out.
129080	132020	It also may be exposed to automated behavioral analysis.
132020	134700	So automated sandboxes, essentially what they do
136080	137580	is they take your payload,
137580	141020	and they actually execute it in a controlled environment.
141220	143140	The reason why they do this is that
144620	147240	you know, whereas if you're just looking for signatures,
148040	149800	you're going to get these like brittle signatures,
149800	151840	but that are kind of easy to evade.
151840	153780	But in this instance, if you're looking at
154500	156860	that, you know, what the program is doing,
156860	158240	while it's executing,
158240	160420	you're actually looking at behavior,
160420	162580	which is a little more difficult to hide.
163860	165520	And finally, during the delivery phase,
165520	167680	your payload is going to be downloaded and saved to disk.
167680	168900	And you have to do this without triggering AV
168900	171220	or, you know, getting caught by EDR or whatever.
172580	175300	So that's the final challenge.
175380	176520	And then once you've done that,
176520	177720	you have to execute your payload.
177720	180260	So the payload is going to be executed from disk.
180280	185280	Usually if it's like a phishing payload or something like that.
185820	190060	Although typically in-memory operations are a little better.
190520	191680	You know, when you're just...
192440	193920	One of the challenges of your initial access payload
193920	195920	is that you can't really start that way.
195920	198140	So you have to start from disk a lot of time.
199280	201220	And you have to do this without triggering Antivirus
201220	204320	or Endpoint Detection and Response, aka EDR.
204520	206920	In Windows environments, you know,
206920	208180	that you're also going to, you know,
208180	210600	application whitelisting is pretty much ubiquitous
211110	213100	if you're operating within like an Active Director environment
213100	214760	or dealing with Windows.
215800	218860	What this means is that you're going to have to find a way to bypass that.
218860	221380	And that usually means relying on something called...
221380	226620	the concept known as live-off-the-land binaries and scripts or LOBOS.
226680	227860	Essentially what these are,
227860	229240	I mean, they're just like utilities,
229240	234000	they're binaries that become packaged with the operating system.
234380	240160	And, you know, they're usually designed to like fulfill some benign role.
240220	241880	But you can actually...
241880	244560	What makes them special is that they have some functionality
244560	247460	that you can essentially leverage
247460	250740	to do something that is useful for you as an adversary.
250740	254560	So in this case, there are several live-off-the-land binaries and scripts
254560	261520	that can be used to execute payloads in various interesting ways.
262140	263920	So that's fortunate that you can rely on that.
263920	267680	You can use that to bypass application whitelisting.
267680	272200	The problem is that most of these pretty much restrict you to
274440	276400	programming languages and execution methods
276400	280540	that get filtered through the Windows Common Language Runtime or CLR.
280540	282340	And CLR, if you're going through the CLR,
282340	287100	you have to contend with Microsoft's anti-malware scan interface for AMP-C,
287100	289520	which just kind of like examines all this stuff that's going through.
289880	293640	So, you know, that's another obstacle you have to do.
293640	297580	So in a lot of ways, getting this initial payload working and running
297580	298760	can be very challenging,
298760	303500	despite the fact that you're trying to do something that's seemingly simple.
304360	306320	It's almost paradoxical in that way.
308660	311260	And finally, I mean, you should assume
311260	313380	that your initial access payload is going to be discovered.
313500	315740	That's just a safe assumption to make.
316060	318800	So your payload really should be able to withstand manual analysis
318800	321680	in the form of threat hunters, reverse engineers, and the like.
323660	328620	So with that in mind, all these are obstacles that are insurmountable.
328660	331240	There are ways to contend with all of this.
331620	337300	It is a bit of a cat and mouse game, but it's something that you can get around.
337360	341240	The problem is that successful evasion techniques do not last very long.
341260	343600	They have a tendency to get stale.
343600	346360	They have relatively short shelf life.
346380	348560	And this is because if you're doing your job right,
348560	352800	defenders will eventually learn from what you're doing as a red teamer
352800	358020	and write detections against whatever TTPs you're using.
358020	363420	So those really cool new TTPs that you drop,
363420	366080	if you're doing your job right, this will actually improve their security.
366080	371240	And they won't work forever if you're using the same TTPs for years and years.
371260	375880	Well, you know, you could argue that you're not really improving the security.
375880	377360	But yeah, that's a whole other thing.
377360	380340	But so defenders will eventually catch up to you.
380340	383980	And what this means is that your payloads are finite.
383980	386360	They have a shelf life.
386820	388220	And that's good.
388300	390020	And specific payloads, right?
390020	391720	So we were talking about TTPs there, right?
391720	395500	But specific payloads that you write have an even shorter shelf life.
395500	398860	Because at some point, you know,
399460	402200	someone's going to write a signature-based detection for that particular,
402700	406420	you know, assembly that you drop on an op or something like that.
406640	410120	And, you know, that's relatively easy to do.
410120	411820	I mean, relatively, right?
411820	414080	I mean, from an adversaries perspective,
414080	417300	what this means is that reusing payloads is likely to get you burned.
417300	419440	So, you know, this is where...
419440	423000	what this means is that initial access payloads are typically,
423000	425840	you know, kind of a pain point for offensive teams.
426700	428780	And that's because, you know,
428780	430980	you have all these challenges that you have to overcome.
431280	435160	And the ways that you overcome these obstacles,
436160	439100	you know, the methods that you use, essentially,
440640	442040	are not going to last.
442040	443540	And you typically have to write them by hand,
443540	448660	or at least modify them by hand on a per-engagement basis.
449080	451860	And, you know, code reuse can be problematic.
452340	453700	And there's a lot of moving parts.
453700	455280	There's a lot of...
455280	457440	I mean, despite the relatively simple purpose,
457440	460260	if you've ever looked at, like, the source code for, you know,
460260	462140	doing a process hollowing in C-sharp,
462140	463880	you'll see there's a lot of code involved.
463880	466620	And there's a lot of things that can go wrong.
467300	470280	So there's, you know, code reuse is a problem.
470460	472600	You have to do a lot of stuff by hand.
472600	473580	And there's a lot of moving parts,
473580	475680	despite the fact that you're trying to do something relatively simple,
475680	477240	which is kind of paradoxical.
479080	480860	So to kind of contend with this problem,
480860	483200	you know, I was actually just kind of, like,
483200	484440	researching payloads independently.
484440	485740	But at some point, you know,
485740	489300	I just had the idea to work on this new tool called DropEngine.
489300	492540	Essentially, the goal of DropEngine is to address this problem
492540	497660	by providing a malleable framework for creating shellcode runners.
497880	500880	So if you've ever used, like, Coblestrike, for example,
500880	501660	one of the cool...
501660	503340	one of the things that makes, like, Coblestrike great
503340	507580	is the fact that, you know, just about every aspect of your agent
507580	509220	that you're placing on...
509220	513100	that you're using on the target machines that you're operating on,
514440	515380	can be modified.
515380	516840	You know, you can modify traffic profiles,
516840	522240	you can modify, you know, essentially how it's dealing with, like,
522240	523980	you know, using name pipes and whatnot.
524100	527140	Like, just about every aspect of its use,
527140	529420	you can customize it in some way.
529420	531660	And by doing that, you know,
531660	534240	really get a lot of use out of this one tool.
534540	536740	So I guess the core idea was to try to do something similar
536740	539320	with initial access payloads.
539320	543060	And, you know, the core idea is to identify discrete payload components
543060	547600	so basically, like, examine, you know, like, your typical payload
547600	551480	and say, what are all the parts that you see in this payload
551480	555720	that kind of repeat themselves across every payload that you ever write?
555760	559280	And, you know, identify those and turn them into modules.
560360	562780	And as a bonus, provide built-in obfuscation encryption
562780	564760	and symbolic substitution capabilities,
564760	567520	which makes it easier to evade signature-based detections.
567520	569160	And in the case of encryption,
569160	573040	makes it easier to, you know, evade human analysts.
573060	576640	And, you know, by doing that, we greatly extend the shelf life
576640	579920	of, you know, those individual payload components that we're writing.
582220	584160	So how would something like this work?
585060	586500	To kind of think about this, right,
586500	588340	we have to talk about how payloads are built.
588760	591200	This is actually, you know, the interesting thing about this project,
591200	593280	this is less of a Red Team project
593280	594700	than it is like a software development project.
594700	597020	Because, like, we're actually not really trying to do
597200	599380	a whole lot of crazy stuff here with the actual...
601800	603020	...the payload itself.
603020	606340	We're just looking at kind of the abstract design pattern here.
607000	609660	You know, if we think about the anatomy of a payload,
609660	612380	at their core, initial access payloads are relatively simple.
612380	614720	They involve two major steps, which we talked about.
614840	616960	You load the shellcode into memory and you execute it.
617260	619300	A little bit of terminology I'm going to throw out here.
619300	621140	From this point onward in this presentation,
621140	623500	we're going to refer to the routine that performs these two actions
623500	626880	as the executor function, just to kind of make things simple.
628360	631220	So, there are many ways of achieving shellcode execution.
631220	632900	You know, you've got the allele injection,
632900	635620	spawn a local thread, you use process hollowing,
635620	637780	thread execution, hijacking, all kinds of stuff.
637780	641660	But we actually want to abstract away specific details like this.
641660	643600	We don't really want to focus on them quite yet.
643960	647620	Because what we're looking at is actually for more of a bigger picture.
649060	650840	You know, also something else we need to consider,
650840	651830	we mentioned that we need to...
654400	656380	...contend with application whitelisting.
656380	658580	And that really means that we're limited to formats
658580	663900	that can be executed by LullBoss, you know,
663900	665440	LullBoss for land buyers and scripts.
666040	668160	So, what this means is that our initial access payload
668160	670740	is really going to require three basic components.
670740	673020	And you can kind of see my diagram here on the left here.
673120	674740	We're going to have the shellcode runner.
674740	677320	Technically, the whole entire thing is a shellcode runner.
677320	680820	But we'll, just for the sake of labeling things,
680820	683840	you know, we'll refer to this outer wrapper as a shellcode runner.
683840	686220	That's going to be LullBoss specific, right?
686680	688500	You know, if it's MSBuild payload,
688500	690340	that's going to be like an XML file, basically.
690340	692300	If it's an installutil payload,
692300	695540	that's going to be a C sharp file that's compiled into an assembly.
695840	697820	But you have your outer shellcode runner.
698080	699860	And then you have your payload name.
699880	701260	That's your application entry point.
701260	702940	That's going to call your executor function
702940	705180	and really everything else that gets called within your payload.
705180	707000	But we're not going to worry about everything else yet.
707480	709020	It's just these three components.
709620	711860	And then finally, you have your executor function.
711860	713760	And this is going to load your software to memory,
713760	717140	execute it, and, you know, essentially,
717140	719940	yeah, that's the meat of this payload so far.
720820	724040	So DropEngine implements these basic components as base classes.
724560	728200	Essentially, what I've done is I've taken these three components
728200	732280	and made it so you can inherit from them and derive modules from them.
732280	735020	And what this means is that you can just write a module,
735020	736800	and you can use any executor type you want,
736800	738680	wrap it in any shellcode runner you want.
738680	740880	And the overall structure of the payload remains the same,
740880	742120	despite that you have a lot of different options
742120	744720	as to how to actually implement all this stuff.
746120	747800	To kind of give you an example, you know,
747800	749060	we're talking about the structure.
749340	751720	You know, this is a... I ripped this direct...
752720	754440	Well, there's supposed to be a link to this GitHub,
754440	756580	but I guess, like, it's getting cropped on the bottom
756580	759860	because it's PowerPoint and Zoom.
759860	764480	But yeah, this is from 0x13steveflores' GitHub.
764480	766000	It's from a project called MoveKit.
766000	769300	This is just an MSBuild runner, right?
769300	773240	You have your outer wrapper,
773240	775240	which is what we talked about here, right?
775240	776780	And this is just your XML file.
776780	779440	You have your payload main, which is just importing stuff
779440	781240	and calling this executor here.
781240	785320	And then you have your actual executor function there,
785320	786260	your shellcode inject.
789040	790580	So... and this is going to be interesting.
790580	792300	I have to switch back and forth here a little bit.
792300	793640	I'm actually going to stop sharing for a second
794440	798220	and then reshare from Hyper.
799300	799820	Cool.
799940	803540	So, yeah, you're going to see a lot of other stuff here,
803540	807160	but if you look at the overall structure of how things are done,
807160	817120	we have our payload main components,
817540	819940	have our runners.
819940	823180	We can break them into individual discrete components like that.
823300	826260	And we'll kind of go into more depth in this in a little bit.
826400	829040	And then, of course, we have our executor functions,
829040	830920	which I don't have a whole lot of them in there quite yet,
830920	832500	but that's okay.
833220	838360	So I'm going to stop this in an attempt to share this again.
838360	839940	Okay, there we go.
840360	843040	And then hit from current slide.
843040	843840	Okay.
844360	849280	So we've identified our discrete components here, right?
849280	851380	These items here.
853080	858080	We also want to throw in encryption capabilities.
858080	863040	It's typically a good idea to leverage encryption when creating initial access payloads
864440	866280	for multiple reasons.
866460	870300	Basically, you have your shellcode that is going to be executed by your shellcode runner.
873020	876380	A lot of these are going to be like binary payloads or something like that.
876580	879000	You don't necessarily want to have to throw that whole entire thing out
879000	883400	just because that particular signature is detected by antivirus.
883400	890320	What we do is, one way of hiding that from signature-based checks is by encrypting it.
890560	895000	But the other advantage of encrypting your shellcode is that it makes it more difficult
895000	897380	for human analysts to reverse engineer our payload.
897640	900500	Remember, we need to assume that the payload is eventually going to get caught.
901000	905680	And when it does, we want to make it as difficult for the reverse engineer
905680	907720	to pick this apart as humanly possible.
909600	916060	What this means is that our updated payload execution process
916600	919100	is actually going to involve a few more steps.
919100	923090	We are going to load the encrypted payload into memory.
923600	929420	We're going to decrypt that payload using an encryption key to obtain plaintext shellcode.
929780	933680	And then finally, we're going to load that plaintext shellcode into memory and execute it.
933880	937700	So the extra step here that we've added is this encryption function.
940500	945820	If we're going to use encryption, this introduces yet another thing that we have to account for,
945820	948160	and that's key storage, derivation, and retrieval.
948660	951960	When we leverage encryption to protect our shellcode,
951960	955800	essentially this is going to require us to provide our payload with one of the following.
955920	958700	It's either going to need to be able to derive the encryption key somehow
958700	960700	without actually storing it.
960700	963880	So it's not going to store it, but we need to be able to obtain the encryption key somehow.
963880	967220	It needs to go... if we can't do that,
967220	971860	it could possibly just retrieve the encryption key from some other location.
971860	973620	So we could provide it with that capability.
974060	977880	Or we could just store the encryption key itself in the payload.
977880	982680	Now, obviously, this last option is not ideal because, you know,
982680	984940	if you're storing the encryption key in the shellcode,
984940	987000	if someone compromised in the payload,
987000	988960	then someone compromises the payload,
988960	991080	then they can decrypt the shellcode and you're kind of...
991640	993220	you're just adding an extra step,
993220	998600	but you're not really making it terribly difficult to pick apart.
1000320	1002820	So let's talk about this first option a bit.
1002980	1007440	We mentioned the use of...
1008360	1011060	the first option is to derive the encryption key.
1011900	1016400	One really great way of doing this is the use of environmental keying.
1016420	1017800	This is like a really...
1018260	1022000	I mean, so environmental keying has been around for a pretty long time.
1022000	1024600	I mean, there's a lot, if you just look up like Mauer,
1024600	1027020	you know, environmental keying and just Google it,
1027640	1030200	there's just tons of papers written about the subject.
1030320	1036160	I think that the three most relevant projects to check out though,
1036160	1037080	in terms of like prior work,
1037080	1039220	that's like really relevant to red teaming,
1039220	1040220	would definitely be...
1042080	1043780	well, Ebola is the classic one, you know,
1044260	1047700	that, yeah, that's...
1048480	1050760	so if you look up Ebola GitHub,
1050760	1054060	like that one is going to come up really,
1054060	1056000	and environmental keying, that one will come up.
1056000	1058280	The other one is Spotter,
1058280	1060140	that one was released fairly recently,
1060140	1062240	I think like in 2018 or something like that.
1062280	1065100	And, you know, it pretty much, you know, does something pretty similar.
1066400	1067460	And then also there's...
1068560	1073160	I think like Leo Lupik has some blog posts where he talks about this
1073160	1075880	and also expands off of those.
1076440	1078960	But yeah, so the idea with environmental keying
1078960	1081140	is that you actually derive the encryption key
1081140	1084920	either entirely or in part from values in the environment.
1085000	1086520	So what do we mean by this?
1086520	1089660	Well, I mean, let's say that, you know,
1089660	1091100	by attributes in the environment,
1091100	1092680	you know, we're talking about usernames.
1093040	1097700	So for example, you could use the currently logged in user
1097700	1100200	that your payload is running as,
1101420	1102860	as part of the encryption key.
1102860	1105440	You could, you know, try to obtain the external IP address
1105440	1109700	from where your payload is executing
1109700	1113280	and use that as part of the encryption key.
1113280	1114700	You could, you know, use your...
1114700	1116460	make sure that you're actually on the right computer
1116460	1120480	by deriving the encryption key in part
1120480	1123080	by using your internal FQDN.
1123660	1124840	I actually didn't like...
1124840	1127060	you could even like use the moon phase or something like that.
1127060	1128220	I mean, you can, you know,
1128220	1130020	but essentially what this lets you do...
1130560	1132440	well, there's two things.
1133580	1138680	One, it makes your payload very, very resistant to analysis
1138680	1140160	because your encryption key is now
1140160	1142060	no longer being stored in the payload.
1142240	1143420	And essentially they'd have to, you know,
1143420	1145480	essentially like if you're setting encryption key
1145480	1148400	to the value of the hard drive serial number,
1148400	1150520	you know, that means that you'll be able to decrypt
1150520	1152900	and execute your payload on a specific machine
1152900	1155800	that has that particular hard drive plugged in.
1156680	1158260	But if you're an analyst
1158260	1161300	and you just have a copy of this payload,
1161300	1168000	unless you know what specific machine you're going after
1168000	1169280	and what the serial number is,
1169280	1172960	you're essentially forced to attempt to crack that encryption
1172960	1175700	by guessing the value of that serial number.
1175700	1179060	So it makes your payload super hard to crack.
1179060	1181560	And the added advantage is that it's very targeted.
1183280	1184960	Your shellcode is only going to be decrypted
1184960	1187520	on machines that match the key's specific attributes
1187520	1188960	or if someone says they're brute forcing
1188960	1190680	for a very, very long time.
1193980	1196940	So I'm now going to set the first live demo of this.
1197460	1199140	Over Zoom, no less.
1199280	1200620	All right.
1200620	1203380	So I'm going to do a couple of things.
1203380	1205480	First, I'm going to show you my setup that I'm using for this,
1205480	1206720	because I think that's important,
1206720	1209940	just so you all know kind of what's going on here.
1209940	1211520	So I'm going to stop sharing for one second
1211520	1214020	and I'm literally going to share.
1215200	1216380	Well, can I do that?
1218000	1219180	Okay, actually, yeah.
1219180	1220800	So the first thing I have to show you,
1223370	1225270	security settings on this machine that I'm using,
1225270	1227570	because that's actually very relevant.
1233760	1236240	And you should see it.
1236260	1239520	Okay, let me try sharing this again.
1245500	1246720	Oh, you know what I can do?
1246980	1247860	Yeah, here it is.
1247860	1249280	Okay, I got it.
1249280	1252340	So as you can see, I don't have cloud delivery protection
1252340	1254680	because I don't want the stuff I'm working on at the moment
1254680	1258680	to get shipped off to antivirus analysis land, essentially.
1258680	1262560	So that's turned off, as well as automatic sample submission.
1262560	1266020	But this is a brand new Windows 10 install.
1266620	1269200	I have real-time protection turned on.
1269880	1273240	Tamper protection is turned on, so you can't disable it.
1273940	1275920	But I do have an exclusion setup,
1275920	1277760	and I want to explain this really fast
1277760	1281400	in case you're wondering why certain things aren't working.
1281580	1284000	So I have one exclusion here,
1284000	1286400	and this is this directory, demo AB include.
1286400	1288240	So essentially, what I'm going to be doing during these demos
1288780	1291980	is I have four, and I'm going to have to now
1295860	1298000	switch windows that I'm sharing again.
1298040	1300020	So you should see hyper right now.
1300020	1300920	There's four terminals.
1300920	1303400	I'm going to try to make this a little cleaner.
1306910	1310050	So in the top left, this is just for my benefit.
1310050	1312710	That's essentially, I'm trying not to anger the demo gods.
1313130	1317410	So I am keeping as much of this stuff in the text file,
1317410	1318610	and I'm going to run the commands that are in there
1318610	1320230	rather than trying to just guess.
1320730	1322150	This will be relevant later.
1322150	1323950	This is going to be a remote key server,
1323950	1326590	and you can kind of... we'll talk about that in a second.
1326590	1327830	This is a Metasploit instance.
1327830	1329770	So this is... yeah, so we're actually going to use
1329770	1330630	Meterpreter for this.
1330630	1334670	So every AV engine under the sun should be able to detect
1334670	1336810	what we're doing, essentially, is what I'm trying to say.
1336810	1338870	We're just using... the payload we're going to be using
1338870	1341630	is going to be just a plain Meterpreter
1341630	1343670	reverse HTTPS.
1343970	1347030	We have to use HTTPS because the actual unencrypted traffic
1347030	1349350	will be picked up immediately.
1350810	1352760	So that exclusion that we're seeing...
1355030	1356610	I'm just being difficult.
1356610	1357140	I'm going to have to...
1358610	1363050	It's going to be in this directory here.
1363750	1365150	I'm going to AV exclude.
1365150	1367570	And this is because we're going to be building this payload,
1367570	1369970	and although the payload was generated here,
1369970	1374830	the second I SCP that payload over onto my main machine,
1374830	1379310	which is what you're seeing in this top right terminal here,
1379310	1380930	Defender would just nuke that.
1380930	1383630	And I really don't want to just keep turning Defender on and off
1383630	1385050	every time I have to do a demo,
1385050	1387210	which is because that's just going to...
1387210	1389390	I'm trying to make this go as smoothly as possible.
1390870	1394230	So the compromise here is that we're going to be pulling
1394230	1396990	our actual shellcode out of demo AV exclude.
1396990	1399130	But when we execute it, that's not where we're executing from.
1399130	1401470	We're going to be executing outside of that exclusion folder.
1402310	1408110	Okay, with that out of the way, let's show you how to go over...
1418800	1425180	Let's go over how we'd make a payload using environmental keying.
1425400	1427380	So essentially, the first thing we're going to do
1428940	1432540	is get a list of available models, right?
1432540	1433640	And just run this.
1433640	1437420	And these are all the different payload components we can choose from.
1437420	1439940	So let's say that we want to use environmental keying.
1439940	1441340	We want to essentially grab...
1444420	1447700	Let's do the FQDN, because I have that written down,
1448840	1450380	and my current username.
1450380	1452460	So we're going to derive the key from that.
1452700	1454840	In that case, we could just do this.
1454840	1461480	We could do Python, prop engine,
1461480	1463740	break onto a new line here,
1463740	1465740	specify that our shellcode should be...
1467620	1473980	You know, in that demo, maybe exclude to shell.
1475180	1477760	We're going to use an interface...
1477760	1479960	So the interface, I'm specifying this command interface.
1479960	1482080	That's like literally the glue that holds everything together.
1482080	1484920	You know, if you're working in C-sharp, you're going to use a C-sharp interface.
1485140	1486900	Don't worry about that too much.
1487120	1491980	But we're going to say, C-sharp runner interface, right?
1492500	1494480	And then we're going to also look at...
1494480	1495840	Just like this encryption key.
1495840	1498280	We need an encryption key and a decryption key.
1498880	1506140	So the EQ keys we're going to use are going to be this external FQDN that we talked about.
1506760	1508400	And notice I'm using more than one.
1508440	1512340	We'll kind of go into how that works in a second, right?
1514890	1516370	I'm just going to use the decryption keys,
1516370	1518850	which is essentially these things, but written in C-sharp.
1522080	1524900	I'm just going to copy these, put them in there.
1526540	1528120	We're then going to need to select a encryptor.
1528120	1529540	It's doing encryptor shellcode.
1530240	1533300	So we're going to say, encryptor AES.
1533300	1535360	We're just going to use AES-256.
1536180	1538780	That should really be named AES-256, not just AES.
1538780	1539960	I should change that.
1540280	1541820	And we're going to use a decryptor.
1542520	1546160	So decryptor C-sharp, origin doll AES,
1546160	1551020	which is the corresponding decryption function that we need.
1552000	1555640	Finally, for our shellcode, we'll go ahead and use msbuild,
1555640	1557700	because that will save you from having to compile something,
1557700	1559320	which will take extra time.
1562940	1564520	And then we're going to need a mutator.
1564520	1567560	We haven't really talked about mutators yet, but we will.
1569380	1573000	But for now, I'm going to say mutator string.
1573220	1574320	And essentially, what that's going to do,
1574320	1577300	it's going to take all the variable names in our finished output
1577300	1578840	and change them to a random string.
1578840	1581720	So it just makes it a little harder to signature around.
1582320	1583560	And that really is...
1583560	1587780	Oh, we also need to specify the actual username and external FQDN
1587780	1590120	that we're trying to use for our key.
1590120	1596240	So I'll put my username as FQDN.
1596400	1598460	And I'm just going to copy it from here.
1598460	1601520	And hopefully, this is an update in the last time, like in the past hour or so.
1601520	1602800	I don't think it would have.
1603360	1606560	And finally, oops, I forgot something.
1608840	1610340	We need an executor function.
1610340	1613440	Yeah, so we need that executor function that actually executes our shellcode.
1613440	1616780	And we're just going to use C-sharp virtual alloc thread.
1617700	1621420	And so you may call it virtual alloc, virtual protect, and all that.
1622940	1626600	And we're going to make our output file example.csproj.
1626600	1629200	And that's going to be our MSBuild file.
1629280	1629620	Cool.
1629620	1630340	Looks like it ran.
1630340	1631240	Didn't get any errors.
1631240	1637360	If you look at our example.csproj, here is an obfuscated MSBuild file.
1638280	1643140	Actually, I should probably show you what this is actually doing.
1644640	1647760	I'm going to do mutate or null, which basically means don't mutate anything.
1650260	1655160	But yeah, so basically, here are all the different components that are stacked together.
1655160	1660320	Here are your decryption keys, and your decryptor, and your executor, and everything else.
1660360	1663540	And then here's your actual payload itself and payload name.
1663540	1667340	Essentially, all this is just being rendered into the payload by DropEngine.
1667840	1668640	Automagically.
1669440	1671080	And finally, I run everything down there.
1671740	1674080	But I want this to be random, because I don't know.
1674080	1675200	Demo gots, I guess.
1675620	1677360	So I made that a random one.
1678120	1679820	So now we're going to set up our handler.
1680580	1684380	Use exploit multihandler payload for CTP.
1686160	1691220	Lhost set Lport 443, which should be correct.
1691220	1695180	And I'm going to set exploit-j to start our handler in the background.
1695800	1699220	And then we're going to actually run this using AliceBuild.
1699580	1701660	And there we go.
1701960	1708260	Now, just to kind of, in case you don't believe me, that this is actually doing something.
1710900	1713180	I'm going to kill everything here.
1718990	1721050	That was a bad sign.
1721050	1730930	But I copy of the enter nano.
1732050	1732610	All right.
1732610	1733050	You know what?
1733050	1735430	I'm actually deviating from the demo right now.
1735430	1737570	And I think that's a bad idea.
1737570	1739630	We'll get back to this if we have time.
1741950	1743030	No, actually, you know what?
1743030	1743890	I'm stubborn.
1743890	1744690	Let's do the...
1748740	1754980	Yeah, I copy demo AV exclude empty shell.
1754980	1757560	And let's just copy it up on level.
1758720	1764090	We should get alert.
1765950	1767110	Or perhaps not.
1767110	1769370	Maybe we might have to run it to get the alert.
1770270	1772750	But yeah, I'm not going to say you're tinkering with this.
1776050	1777610	Let's get back to PowerPoint.
1778930	1779810	OK.
1779910	1780970	From current slide.
1782650	1784710	So that's our payload.
1784710	1791310	Basically, custom build payload with environmental keying that we literally just created in a second.
1794230	1796490	So mutator modules, right?
1798210	1800070	We mentioned also that we're using...
1810280	1811000	Ignore me.
1811000	1813100	I could have sworn there was something else that I was supposed to talk about there.
1813100	1813620	OK.
1813820	1814200	Yeah.
1814200	1816420	So the other thing, essentially what we've just done.
1817020	1821580	We've said, here's the executor function we want to use.
1821700	1824000	Here's the shellcode runner we want to use.
1824000	1826700	Here's the encryption decryption routines we want to use.
1826900	1830000	And by the way, we want to derive our keys from these two specific functions.
1830000	1832280	And we're going to pull this stuff together and make it into a payload.
1832280	1837500	And by the way, randomize all the variables in variable names in that payload.
1837800	1840460	And just write a command, and then it just does it.
1840460	1842520	And then voila, you have a payload.
1843080	1844620	The way that we did the actual...
1844620	1850940	The changing of the variable names was using basically modular symbolic mutation.
1850940	1854420	So DropEngine supports the use of mutator modules that...
1854420	1855640	I mean, essentially what they do is that they...
1856700	1863200	Every module that corresponds to something that has variable names or function names
1863200	1869100	has a mutator method that gets called in the back end by whatever mutator module that you select.
1869100	1871460	And the mutator module then systematically goes through
1871460	1878700	and takes a list of variable names and maps them using some algorithm.
1878700	1881720	The algorithm is irrelevant. It's module specific.
1882460	1883980	And then when the actual...
1883980	1889380	And returns back to that module, the original module, that mapping.
1889380	1891680	So like a dictionary of like, here's all your variable names,
1891680	1893320	and here's the stuff that we've mapped them to.
1893320	1895300	And then what happens is that when you render...
1895300	1898980	When that module gets rendered into a rendered template,
1898980	1900300	and that's how we're building everything.
1900300	1901720	It's using Jinja templates.
1903680	1904640	We are...
1904640	1908280	Essentially what's going on is that it looks at that mapping
1908280	1911480	in order to figure out what's in the variable.
1911480	1915080	So this is pretty cool because it allows us to create payloads that,
1915080	1918140	you know, circumvent signature-based detections pretty easily.
1918300	1922160	I only have like three supported methods in there right now.
1922300	1925840	Rot13, the random string, and also symbol substitution using a word list.
1925840	1928180	Null mutator doesn't really count because that's just...
1928180	1929220	It just doesn't do anything.
1929220	1930280	It's a null mutator.
1930280	1932660	It's primarily there for debugging purposes.
1933840	1935680	And I've kind of already demonstrated that,
1935680	1937690	but if you want to just go over...
1938680	1941980	Just once again, what that looks like.
1942180	1948260	You know, take this one that we just did,
1948260	1950340	just print to the screen instead of out the file.
1950520	1952010	So for example, here's your...
1953200	1954320	Actually, let me use...
1954320	1958720	I've got another piece of shellcode that isn't so long that we can use for demos.
1961080	1965360	Yeah, so, you know, here's your random strings.
1965740	1966960	You know, if you wanted to use...
1969880	1970760	Rot13.
1973200	1977200	These look an awful lot like the variable names.
1977540	1979080	Let's use a word list.
1982050	1984730	You actually have to specify a word list when you do this.
1984730	1986230	Let's use US cities.
1986230	1987130	And that will...
1987130	1989170	Now all your variable names are corresponding to US cities.
1989170	1991790	A better use of this would just be to make a word list
1991790	1993710	that actually are believable variable names.
1993710	1998470	But I don't know, this is better for doing a demo.
1999090	2000490	Let me go back to PowerPoint.
2000870	2002370	Let's move on from here.
2008370	2010010	And let me just make sure...
2010010	2010950	Okay, cool.
2012810	2016270	So let's talk about some more keying techniques that we support.
2016830	2018490	We talked about environmental keying.
2018490	2019730	Remote keying is also pretty neat.
2019730	2023690	Essentially, instead of deriving the key from some place in your environment,
2023690	2027650	you're actually going to retrieve the encryption key from some remote location,
2027650	2032570	you know, either for HTTP or HTTPS, DNS, or some other communication protocol.
2033410	2034750	This is actually...
2034750	2037230	You know, if you have well-designed non-attributable attack infrastructure,
2037230	2039810	it actually makes this method pretty effective.
2039810	2041950	You know, you can place the key server behind a redirector
2042770	2045570	and only accept requests for that key on very specific...
2046270	2049710	for very specific profile traffic that's being sent to the redirector.
2049730	2053710	If you want to make it even better, you can use a one-time remote key,
2053710	2056330	which is a variant in which your key server,
2056330	2058130	which is the server that's hosting these remote keys...
2059230	2061570	By the way, you want to have one key per payload,
2061570	2063270	and DropEngine does support that.
2065030	2067690	So keys should be unique to the payload that you generate.
2068270	2071310	But essentially, the one-time remote key variant,
2071310	2076510	once that key is successfully retrieved from the key server,
2077050	2079910	it actually is deleted from the key server.
2079910	2083570	So the key server goes back into its database and just nukes the key.
2083590	2085870	And what this means is that any future requests for that key
2085870	2087990	are either going to be ignored by the key server,
2087990	2089890	or return some kind of junk data,
2089890	2093810	or you could even, at that point, respond to that kind of request
2093810	2094890	by returning a redirect.
2094890	2096570	So you could do what a redirect would do
2096570	2099890	and redirect that request to something innocuous,
2099890	2101970	like, you know, remotely hosted jQuery or something.
2101970	2104810	Like, look, it's not... it's just jQuery, right?
2104810	2108030	But so, I mean, there are obviously some obvious advantages
2108030	2109250	to doing keying this way.
2109290	2111230	It's very resistant to analysis.
2111430	2113790	The encryption key is not stored on the payload file.
2114090	2118230	And it's hopefully being protected in transit using TLS.
2118710	2122270	It's also less targeted, right?
2122270	2126050	You know, while highly targeted payloads are good in a lot of cases,
2126050	2126810	sometimes they're not.
2126810	2129410	Sometimes you don't just want to attack the computer
2129410	2132350	of that one person that has that particular hard drive or username.
2132350	2134590	Sometimes you want a little more breadth.
2134590	2137890	In this case, you don't have to limit your scope.
2138810	2140710	I mean, you should limit your scope regardless.
2140710	2144390	But I guess what I'm saying is the scope isn't, you know,
2144390	2148330	implicitly limited by your keying mechanism at this point.
2151530	2155810	So I'll show you how this works in Dropbox really fast.
2157310	2160330	And I'm going to go back to my screen here, go back to Hyper.
2164400	2168420	And so in the bottom left, we have this, what looks like a Flask app.
2168860	2170480	It's really, really basic.
2171700	2173800	I honestly didn't put a whole lot of time into this because, you know,
2173800	2175780	I was just trying to get the proof of concept out the door.
2175780	2179440	But this is our remote one-time key server.
2179460	2185060	And what we're going to do here is do a very similar payload
2187140	2189440	to what we just did, right?
2193920	2194800	Hang on, let me...
2208190	2209670	So we're going to grab this.
2211590	2217050	And this is, you know, as you can see here, well, it's just RAM.
2217050	2221590	But what we just did, we created a shellcode using our empty shell,
2221590	2226030	like our interpreter shell that's in that empty shell.bin file.
2226550	2228730	It's pretty much the same attributes we used last time.
2228730	2231830	The difference here is we actually added some keying components.
2232290	2236550	We added a new key here, which you can see right here.
2236550	2240530	It's the D-key one-time remote HTTP and the corresponding decryption key,
2240530	2244090	which is their D-key remote C-sharp OTK HTTP.
2244490	2247270	And essentially what this is doing is it's just providing functions
2247270	2250470	that will attempt to reach out to this server right here
2250470	2253250	that is running at the bottom left to retrieve this encryption key.
2253250	2255410	And it's going to use that by using a specific identifier
2255410	2257690	that you need to your implant.
2258090	2260930	So that, you know, essentially what this guy down here is going to do
2260930	2263590	is look in the database to see if that identifier exists.
2263590	2267890	And if it does, it's going to respond with the decryption key
2267890	2270270	and send it back to our payload.
2270270	2273450	And then, you know, it'll be deleted from the database.
2273450	2276070	So subsequent requests just won't be honored.
2277710	2279990	So let's run that really fast.
2280430	2283310	We just kind of prep the bottom left here.
2283610	2287030	Make sure we don't have any stragglers either in our sessions or...
2288430	2289750	Oh, okay, cool.
2289750	2291610	So we're going to run our handler.
2294270	2296170	And we're going to rebuild this really fast
2296170	2298710	just to make sure everything looks selfless enough.
2298710	2299650	It does.
2301670	2304210	And we're going to call it MSBuild once again.
2305630	2307270	And there we go.
2307810	2310970	And you'll notice here, this traffic showed up in the Flask app.
2310970	2315930	And that is our server going back.
2315930	2318170	That's our payload retrieving the key, right?
2318170	2334230	Now, let's go ahead and kill this session right here, right?
2336670	2339130	And the reason why I'm doing that is I want to show you what happens when we...
2340150	2343450	So we've already retrieved that remote key.
2343450	2345810	So what we're going to do now is we're going to just kind of demonstrate.
2346590	2349870	If we happen to curl for that same value, right?
2350290	2354550	Let's say we do a curl request to 127.
2354550	2358030	This is running on mobile, so we can just do this.
2362570	2365130	HTTP//, we're not using SSL at the moment.
2370150	2370910	Oh, you know what?
2370910	2373130	We'd actually need the implant ID, wouldn't we?
2373470	2374490	Oh, no, here it is.
2374490	2376970	Yeah, let's grab this implant ID right from here.
2377390	2377890	Cool.
2377890	2379990	So we have everything we need to make this work.
2381250	2388530	And you'll see that we don't actually get a response at this time because it's been cleared.
2389830	2393530	All right, so back to our PowerPoint.
2394610	2396590	We've got about 20 minutes left.
2396590	2398910	Open this up for chat for about 10.
2400090	2402330	Let's go back here.
2404590	2406130	Press slide.
2406130	2406570	All right.
2410500	2419880	So one thing you'll notice is that we're actually using multiple encryption keys here.
2419880	2420880	Or it seems like it, right?
2420880	2425020	Because we're specifying these different key types and combining them to create a final
2425020	2426040	encryption key.
2426200	2430140	We're doing this using something that I like to call key stacking.
2432280	2433860	Key stacking is just like a label.
2433860	2438620	I'm sure this has been done before a million times because it's really not that complicated.
2439260	2440780	It's pretty simple in practice.
2440780	2442060	And we'll see that in a minute.
2442060	2446620	But essentially key stacking is the practice of combining the results of multiple keying
2446620	2448620	methods to create a single combined keys.
2448800	2455100	So for example, let's say we want a key that's combined of four parts.
2455100	2458860	The hard drive serial number, external IP address, a non-stored in the payload file,
2458860	2463720	so it's a stored component, and also a one-time key that is retrieved over HTTPS.
2463940	2467580	Well, in that point, we essentially would just make four method calls within our payload.
2469040	2473380	To four different key derivation functions, concatenate the results together.
2473540	2479400	And by doing that, we'd have one encryption key that was derived from all these different
2479400	2480220	sources.
2480440	2483100	So one advantage of doing this is it gives us a little more security.
2483100	2485080	It's difficult to compromise.
2485600	2487700	Disadvantage is kind of complicated.
2487700	2492420	If you do this by hand, it's just adding more moving parts to the equation.
2492420	2497100	But once again, since we're using a framework, it makes it a little less complicated.
2500140	2505380	Essentially, what makes this possible is that the actual architecture that we saw at
2505380	2507820	the very beginning, it has been updated a little bit.
2507820	2511660	So remember, originally, we just had that shellcode runner and a payload main in there
2511660	2514780	and an executor function.
2514780	2516600	In this case, we still have our shellcode runner.
2516600	2517720	It's our outermost wrapper.
2517720	2522320	That's our LulzBot-specific script that encapsulates everything.
2522420	2524120	But we also have our payload main.
2525760	2529860	And within that, we now have, you see here, we all have all these D-key functions.
2531080	2534160	So we have a D-key 1, D-key 2, all the way through D-key N.
2534160	2535960	It's an arbitrary number of D-key functions.
2536640	2543560	And essentially, the way that this works is that each key part is extracted from each
2543560	2548460	of these key derivation functions and passed to the decryptor function along with the
2548460	2554840	shellcode that combined or stacks keys is then used to get the plaintext shellcode and
2554840	2556860	is passed to the executor.
2556960	2561280	So really, it's not too bad.
2563860	2565920	We already went over key stacking.
2566820	2568580	So let's talk about pre-modules and post-modules.
2568580	2571980	And I included the cookie monster here, because who doesn't like the cookie monster?
2576500	2578440	So what are pre-modules and post-modules?
2580280	2581740	Essentially, this is a concept.
2581740	2588020	I mean, there's often when you're executing that initial access payload, right, that shellcode
2588020	2593480	within your shellcode runner, there are things that you want to do first before you actually
2593480	2596240	start trying to execute your shellcode.
2596620	2600440	For one thing, you might want to perform sandbox checks, like if you're trying to see if you're
2600440	2607460	in one of those automated sandboxes, you might want to check for some node attributes of
2607460	2614020	the sandboxes, such as certain file paths or number of CPUs or what have you, to actually
2614020	2619840	see if you're in a quote-unquote real environment or in a sandbox.
2621120	2624380	Also, we mentioned that this is likely going to be going through the CLR.
2624420	2628200	So you might want to try to bypass AMSI, and that's something that you might want to try
2628200	2633060	to do before you execute your shellcode.
2634380	2640940	So what pre-modules do, essentially, they are just subroutines that are pre-pended to
2640940	2642160	everything else in your payload.
2642160	2646040	So what DropEngine lets you do is you can specify any number of pre-modules that you
2646040	2649500	want, and these will just get run before everything else does.
2650440	2655140	So, for example, if you want to run a sandbox check and an AMSI bypass, you pass those both
2655760	2663040	to DropEngine as pre-modules, they then get executed, and then once they finish executing,
2663540	2666240	and they are executed in the order that you specify them, by the way, which is pretty
2666240	2669080	cool because you actually control which order they execute in.
2669080	2673020	But once they finish executing, then we execute the rest of your shellcode here.
2675180	2677400	So post-modules, they're pretty much the opposite thing.
2677400	2682240	Instead of being pre-pended to the beginning of the payload, we append them to the end
2682240	2682820	of the payload.
2682820	2689420	So that's useful for if there's something that you want to do after your shellcode terminates.
2689420	2696740	So cleanup routines, log file deletion, modification, and both pre-modules and post-modules
2696740	2700480	should be completely modular and mutable, just like the rest of the payload's components.
2700480	2707060	So you can mangle all the string names and variable names, however you want.
2709790	2716930	And so if we're going to demo the process of adding pre-modules, here's how you do it.
2718490	2720610	I'll make this a super fast one.
2730060	2736880	So for example, here, you can see if we want to create a payload that, let's say we want
2736880	2743500	to run an empty sandbox check, say like check to see if we're in a sandbox by checking the
2743500	2746040	minimum number of USBs that have ever been installed.
2748580	2753880	Let's say we look for also file paths that can deliver us to the event that we're in
2753920	2754520	a sandbox.
2754520	2757140	A file path is a sandbox check.
2757140	2761960	Then finally, we want to execute an empty scan buffer bypass.
2762560	2765780	We can just append these here as pre-modules.
2777880	2794250	And actually, if you're curious what this looks like, I'm not actually going to save
2794250	2794490	this.
2794490	2796090	I'm just going to send it to the screen.
2798130	2799430	Yeah, that's what I want to do.
2799430	2803830	And then I'm going to use that really, really small shellcode that I showed you earlier.
2803910	2805230	It's easier to read.
2808360	2812120	It should not be from the exclusion folder, because that small shellcode is not in the
2812120	2813140	exclusion folder.
2817340	2825840	And you'll see here that, you know, here are your sandbox checks and your empty bypass,
2825840	2828040	and that's all getting executed up here, essentially.
2828040	2831780	So that all gets done right before you run everything else.
2832360	2836640	So once again, let's get up on our MSVL payload.
2836640	2841100	We're going to start up our handler, and we created it in the last step, so I'm not going
2841100	2842120	to recreate it.
2843580	2847520	And you see that it runs, so everything just kind of goes swimmingly, because we're
2847520	2848400	out of the sandbox.
2851440	2852700	We go ahead and fill this...
2859470	2861330	PowerPoint, just wrap this up.
2870750	2873530	We kind of did both demos at once, and that's all right.
2873770	2876890	The last thing we're going to talk about is, essentially, how do you create DropEngine
2876890	2877450	modules?
2877450	2882510	So the goal of the project isn't really to provide pre-baked methods for bypassing APADDR.
2884650	2885810	It's really more...
2886770	2892890	We did provide some example modules, but really, they're not really doing anything new or novel.
2892950	2897570	And this is by design, because the goal of this framework is to enable red teams to maximize
2897570	2900910	the value that they get from their individual payloads by converting them into reusable
2900910	2901950	modules.
2902010	2905810	And if you're a defender, this is useful, too, because you can use this tool to quickly
2905810	2909850	create large sets of sample payloads from which to build a learning strategy.
2912010	2915630	So there are two types of modules that you can build, input modules and output modules.
2915750	2918910	Essentially, input modules are anything that's going in before it hits your payload.
2918910	2925310	So your encryption function is an input module, whereas, for example, your executor function
2925310	2926570	is going to be an output module.
2926890	2928430	This is super important.
2928570	2935910	Shout out to Marcelo, my leader, because basically the loader that he's using to build these
2935910	2939510	is heavily based off of some of the stuff he's done.
2941630	2945110	When I think about input modules, they always have to correspond to one or more matching
2945110	2946230	output modules.
2946490	2948750	But they're relatively simple to implement.
2948750	2954430	As you can see here, what we're doing is we're building an encryption key module.
2954430	2959630	And we're just inheriting from this base class and then creating a constructor, which is
2959630	2962490	just kind of setting the various attributes associated with this.
2964130	2966350	All the argument handling is up on the back end.
2966350	2970150	If you want to pass command line arguments to your module, you just add an add arguments
2970150	2970590	function.
2970590	2975370	If you've ever used parse in Python before, you can just add all these here.
2975370	2979790	The parser is already initialized by one of the parent classes of your module.
2980030	2984130	So you can just make calls to self.parse.addArgument and add all the arguments you want.
2984130	2988690	And that will get parsed automatically, essentially, once your payload is generated.
2989050	2990230	And then you have your generate routine.
2990230	2990830	And this is essentially...
2991970	2995030	Well, for encryption keys, it's generate, but depending on the module type you're using,
2995030	2997890	you're going to have your function that actually does stuff.
2998590	3002490	Output modules, very similar, but even simpler.
3002650	3005830	So the way the output modules work, this is the actual...
3006990	3009250	These actually get rendered into your payload.
3009710	3012410	They may potentially correspond to an input module.
3012410	3015870	They may not, as in the case of an executor, for example.
3015990	3018530	But it's really just a simple two-component design.
3018530	3024810	You have a Jinja template and a Python file that stores metadata that is passed to the Jinja template.
3025430	3028910	So, for example, here I've got a list of all my variables and imports and whatnot.
3029450	3034690	And that gets passed to the interface, then passed back, and then loaded into the template in
3034690	3036570	however format you need it.
3036770	3040030	And then here you just have the Jinja template that you're using.
3041170	3045910	As far as actually creating these things go, how much time do we actually have?
3046870	3048510	I won't spend too much time on this.
3052310	3055550	And it's just that if you want to create one of these modules, aside from the stuff...
3055550	3057530	I guess what we haven't really shown you is the template.
3057650	3060990	But here's just an example module.
3061170	3062450	It doesn't really do anything.
3064550	3068710	But see, all that you have to do is just set these attributes, and then you give it a list
3068710	3073010	of interfaces it's compatible with, and then any input modules it's compatible with.
3073170	3078530	Give it a list of all the variables in your C-sharp file, or whatever kind of file you're using.
3078530	3080530	Really, it's not limited to C-sharp.
3080570	3084490	And then also give it the name of a template, and give it a function and class name.
3085270	3087510	In this particular instance, you have to do that.
3088950	3090090	It's not very long.
3090770	3092410	Then you have to create a template.
3093350	3095550	And so, literally, this is the process of creating a template.
3095550	3097890	And I'm actually working on automating this.
3098530	3101710	But that requires, essentially, you need to write something that can parse C-sharp.
3101710	3104390	And that's coming along, but it's not quite done yet.
3104390	3109790	But for now, what you do, if you want to actually turn just a normal C-sharp file into
3110790	3115210	a template that can be understood by DropEngine, you just find all your variables in here,
3115210	3117550	and just wrap them in this Jinja parameter.
3117550	3121430	So you just say d, and then you use a syntax here.
3121430	3123690	So we've got variable nick.
3125650	3127470	We just kind of edit it like that.
3128450	3132210	And then we can do the same thing here with variable n.
3133030	3134810	It should be our only two variables there.
3135790	3137630	And I just do that once again over here.
3140790	3145690	This is going to be painful for longer ones, but, you know, you only have to do it once in that case.
3146030	3151250	And I'm working on some ways to kind of automate a lot of that.
3153810	3154530	Share screen...
3154530	3155530	Back to PowerPoint...
3160140	3161680	And that's pretty much it.
3161760	3162380	I'm going to...
3163520	3166700	Actually, this is a Zoom thing, so I don't really know.
3166940	3170240	That's the location of the project on GitHub, if you want to check it out.
3171000	3171700	I'm going to...
3172600	3176560	I think it's supposed to be like a Q&A thing right now, and I need to figure out how that works.
3176620	3177200	So I'm going to...
3177800	3183540	Yeah, basically, once again, thank you so much for your time and for the presentation here.
3183540	3184480	Excellent presentation.
3184480	3187580	So for the Q&A, you can jump into Discord.
3187580	3189160	It's going to be offline, of course.
3189160	3193620	There's a little bit of delay between the stream and when they can answer.
3193840	3197420	And there's a lot of people actually already talking about the presentation.
3197520	3198740	So kudos.
3199500	3204000	And for those of you also that probably just joined,
3204000	3207660	please take a look at all the talks and all the activities that we have in our website.
3207660	3211040	The description should be in the bottom of the screen, right?
3211040	3214960	So in the description of the screen, all the links and related material.
3214960	3218260	And also, please join the conversation, as we said, in Discord.
3218520	3223560	So we're going to go in a little break, and the next presentation will start in just a few minutes.
3223560	3224960	Thank you again, Gabriel.
