start	end	text
0	5560	Welcome everybody to APT's Love PowerShell and Why You Should Too. I'm Anthony. I'm here with
5560	10820	Jake. We're going to be going over some of the interesting things that APTs do for PowerShell.
10940	18000	And here we go. So once again, I'm Anthony. I go by coin. That's my handle. I got a master's in
18000	22260	electrical engineering, same with my bachelor's. Some interesting things about me. I'm a lock
22260	26620	picking hobbyist. You followed some of my work. I did some Bluetooth lock picking hacks over the
26620	32300	years, as well as some wireless stuff. And then a lot of my focus recently has been building up
32300	38240	Empire and Starkiller. And then I got Jake here as well. Yeah, hey guys. I've got... my background's
38560	43600	a BS in astronautical engineering and I have an MBA. I actually ended up getting into cybersecurity
43600	49020	while I was in the Air Force because I showed up at a new unit and they'd been told they had to
49020	54920	have a cybersecurity person and I was voluntold that I was the new person. So after that, I ended
54920	62280	up as a... doing some cyber testing for fighter aircraft for the Air Force. Then went on to a
62280	68740	red team where I was a red team lead for about a year and a half, two years. And then I got out of
68740	75080	the Air Force and now I'm currently focused on embedded systems security. And I'm kind of our
75080	80840	PowerShell obfuscation expert for BC security. So I spend a lot of time on that too. So we get told
80840	85120	this all the time and ask this question, you know, aren't PowerShell attacks dead? You know,
85120	90400	offensive PowerShell's dead. Why don't you just move to C-sharp? Script logging to, you know,
90400	94860	makes PowerShell attack completely impossible. You know, all these sort of things everybody
94860	101420	always brings up. And we're constantly being told this, you know, why use PowerShell? Isn't it dead?
101780	107680	Yeah. And just kind of a fun story about that bottom line about AMSI is going to catch
107680	113860	offensive scripts is we gave a webinar back in February that was actually a workshop we taught
113860	119920	at DEF CON last year. We had a Microsoft security guy show up with and gave us the challenge a
119920	124320	couple of days beforehand that he was curious to see if we'd actually be able to get AMSI
125080	131160	or passed AMSI on a fully patched machine. Whether it was intentional or not, they actually
131160	138940	rolled out some updates to AMSI like the day before we started our course. Like they added
138940	143000	some additional detections when you're using like invoke expression and that kind of stuff that did
143000	148820	throw a little bit of a loop. But by the end of the class, the Microsoft guy was a little bit
148820	156780	blown away by the fact that we could still get default Empire payloads past fully patched AMSI
156780	162860	stuff just using obfuscation and some of the tactics and techniques we'll talk about a little
162860	169100	more going forward. So obviously PowerShell is really, really dead. It can't be used for
169100	175860	offensive PowerShell anymore. So this is just a quick poll that you can just go into Google and
175860	182100	look over the last couple of months. What you can see is just APTs and threats are using offensive
182100	186680	PowerShell pretty regularly for all types of things, not only just for breaches, but for
186680	192900	ransomware attacks, for lateral movements, gaining initial access. It's being used for all sorts of
192900	201840	things. Okay, so just a quick primer in case everyone's not fully aware of PowerShell. Why
201840	206440	PowerShell and how it became a popular offensive tool in the first place is that it gives us full
206440	213840	.NET access to Windows, which is kind of really the underlying architecture for being able to do a
213840	219880	ton of lower level stuff in Windows. It gives us direct access to the Win32 API, which also gives
219880	226960	us low level access to operating system functions. We can operate entirely out of memory, for the
226960	232280	most part, and then installed by default in Windows. And admins typically leave it enabled
232280	239240	because it is a huge efficiency enabler in terms of their jobs and that kind of stuff.
239460	244300	And, you know, the theme of the day is going to be why PowerShell is still relevant and how we still
244300	249680	see it being used by red teams. So this is just another tweet on the side about how Microsoft and
249680	256540	red teams talk about PowerShell being totally played out. Meanwhile, APTs and criminal groups
256540	262160	are using PowerShell every day. They might not be using it for the full attack chain,
262160	267840	but almost every APT is using PowerShell in some way, shape or form during a breach.
268660	274080	So now we're just going to do a quick timeline of PowerShell, like when it was released,
274080	279260	when offensive tooling started coming out and when defenses were incorporated into it.
279260	285140	So PowerShell version 1 came out in 2006. It was released for XP, Service Pack 2, Server
286260	292080	2003, and Vista. When it was first released, it didn't have a ton of capability. It was kind of
292080	299480	more of a novelty thing. And PowerShell version 2 is when we really saw it start getting widely
299480	306540	adopted. It was fully integrated into Windows 7 and Server 2008. It introduced a bunch of new
306540	311760	features such as PowerShell remoting and background jobs. PowerShell version 2 was
311760	317620	like when we saw the real adoption by sysadmins and that kind of stuff, to the point that many
317620	325200	there are sysadmin tools that you will encounter on live networks still that run in PowerShell
325200	330620	version 2 because that is what they were written in and they don't want to take the time to go
330620	336720	port it to a different version. And so you'll find networks that still have PowerShell version 2
336720	344420	enabled because they want to be able to use their automation scripts. And so version 2 and version
344420	350580	5 that we'll talk about in a second are kind of the big delineators of what's going on in PowerShell
350580	354840	version 2. If we can run in version 2, that's where we want to be as offensive people. And
354840	361560	version 5 is where we got the full Gucci set of defenses. It had a few protections, but it had
361560	368200	essentially no protections. And then Trusted Security, David Kennedy and Josh Kelly gave
368200	376500	their PowerShell it's time to own talk in 2010. And that was when we saw the beginning of the
376500	383060	wave of offensive use of PowerShell. They were really kind of the initialization of the movement
383060	388960	for offensive PowerShell tooling was their talk that they gave in 2010. So that's when we started
388960	396540	seeing people begin to adopt things. PowerShell version 3 came out two years later in 2012.
396540	401320	It introduced module logging, which we will talk about that more. I actually think it's one of the
401320	407820	more powerful logging capabilities in PowerShell, and it was introduced all the way back in version
407820	414180	3. But PowerSploit was first published in 2012. A lot of people don't realize just how old
414180	420100	PowerSploit is at this point. And then Metasploit also introduced its execute PowerShell capability
420960	428780	in 2012. And 2013, PowerShell version 4 came out. This was where rudimentary strip block logging
428780	437000	was introduced. It's more akin to what PowerShell version 5 referred to as transcription logging.
437000	441700	So it did do some script block logging, but it's not nearly as powerful as the
441700	448720	one introduced in version 5. And then 2014 is where we start seeing like
449720	455700	the just overwhelming wave of offensive tooling and everyone adopting it. PowerView gets published,
455700	462240	PowerUp gets published, CobaltStrike incorporates PowerShell execution into its tooling,
462240	466480	and that just kind of starts the major wave of offensive PowerShell.
467000	472700	PowerShell version 5 was introduced in 2015 slash 2016. It's got two dates because it was
472700	478160	officially released in 2015, but there was a major bug in it that required it to be re-released
478160	485220	in 2016. So it sort of has two release dates. But in 2015, PowerShell hurts the blue team
485220	492380	was published and it was a article published by Microsoft that introduced this whole host of
492380	500340	PowerShell defenses to combat the offensive movement of malware through PowerShell.
500340	507500	So it introduced what they call deep script block logging, transcription logging, talks about module
507500	513240	logging some more, and then the big game changer was the introduction of AMSI, which we'll go to
513240	519680	in more depth in a second. That's also where PowerShell Empire was released as well as PowerPick.
519680	529640	So now that we've kind of gone through that timeline, we can see who's still using it today
529640	535520	because we hear about people moving to C-sharp and that PowerShell, as we said, played out and
535520	541320	that kind of stuff. But these are all the APTs that are currently still using PowerShell. So
541320	547080	pretty much everyone. That's not to say that they're operating entirely in PowerShell,
547080	557080	but they're using it in some way, shape or form. That's how we'll just said like just about every
557080	562320	threat and every APT is using PowerShell in some sort of capacity. And when you're trying to go out
562320	566120	as a red team and try to emulate those threats, you want to know what they're doing. I know we're
566120	571400	focusing on a lot of PowerShell during this talk, but there are other tactics, techniques, procedures
571400	576820	or TTPs that people use. So be able to do that research. You want to be able to research what
576820	581160	those behaviors of the adversary is doing and kind of build that cyber threat intelligence
581680	586620	based on whatever the threat is that we're looking at. And this is important because this is something
586620	591100	that, you know, a lot of industry is going to be using, governments do, as well as some of the
591100	595560	open source community. You can use things like FireEye if you want to pay for some of that
595560	601520	threat intelligence info. Otherwise, another option is always go on to MITRE's page for the
601520	606100	attack framework. And you can do some research there to see, you know, what techniques certain
606100	611540	APTs are using, maybe get some more info if they're using PowerShell specifically, and then
611540	615580	see, you know, what sort of lateral movements or what sort of privilege escalation techniques
615580	619740	they're leveraging when they're focusing on PowerShell. So just a nice thing to mention,
619740	623100	because we're doing a lot of, we're talking a lot about APTs and being able to go back
623520	626940	and kind of do some more research with them is pretty important.
627340	631380	So when you start doing some of that research on APTs,
632560	637240	you'll find that they're using PowerShell for a lot of different reasons.
637880	641980	Obviously, command and control is a big one. There's a lot of different C2 frameworks out
641980	648060	there that are being used. You'll see some of the APTs using things like Empire or other C2
648060	653840	frameworks to kind of control whatever they're doing for their implants. PowerShell can be
653840	659740	leveraged for their DLL hijacking. It can be used for key logging. One of the really big ones that's
659740	664760	used for is lateral movement and privilege escalation. Lateral movement specifically for
664760	669940	the PS exec, you have PS remoting, you have WIME. All those things are all leveraged using
669940	675920	PowerShell. And then privilege escalation specifically for INVE. So really everybody's
675920	680580	still using a lot of offensive PowerShell. These are some numbers that we pulled pretty recently.
680580	685560	Most of these are within the last couple of months when these reports were published.
685560	690640	Carbon Black put out that about 90% of target attacks are using PowerShell. So it's a very
690640	697380	big significant number. As well as McAfee for this last quarter put out there was a 689%
697380	703520	increase in target attacks using PowerShell. So not only is PowerShell still being used a lot,
703520	708980	its use is increasing significantly by each quarter and every year. And the last one,
708980	714360	CrowdStrike's most recent report said about 50% to 70% of target attacks, they observed PowerShell.
714360	718940	Pretty wide range when you're talking about how many attacks are actually using PowerShell out
718940	725560	there. One of the examples that we're going to talk through is APT33. If you do some research
725560	730220	out there, you can see that they rely pretty significantly on PowerShell to be able to do
730220	736520	their stuff. They are a suspected Iranian threat group. So they are state sponsored.
736580	741320	And they're really going to be focusing on aerospace and energy industries. So a lot of
741320	746720	defense contractors is what they're really aiming for. So trying to hurt the industrial
746720	751000	base of a country when it comes to defense is really what their target is. And they're typically
751000	757120	employing things like Empire, PowerSploit, and Mimikatz, focusing mostly on the PowerShell side
757120	761980	of things. They have been seen to use things like CobaltStrike and other things for some of their
761980	767020	beacons, but they're trying to stick mostly with a lot of the open source stuff that's put out there.
771510	776630	So this is just an excerpt of one of their malicious files that they use that FireEye did
776750	782310	a report on a couple of months ago. And what they did was they used a malicious HTA file,
782310	787810	which is an HTML executable. And what that does, it has just a regular HTML on the top part
787810	794990	that may point to a certain person. In this case, it was this aircraft company. And then after all
794990	801110	that HTML, they embed a script. So the script that they're running launches a PowerShell
801110	807250	hidden window with a base64 encoded payload attached to that. And this launching method
807250	811110	is actually very similar to how Empire does a lot of their things. So you're talking about
811110	818070	emulating what the threat does. Empire emulates this threat pretty well, especially with the HTA
818070	829110	file. Next is WastedLocker ransomware. This has been pretty popular in the news recently.
829110	834270	This is from the EvilCorp group or Drydex. And what this does is it leverages a few different
834270	839250	things to be able to launch the ransomware. First, it leverages a CobaltStrikeBeacon and
839250	845010	PowerView, kind of get that initial foothold. And it contains both PowerShell, JavaScript,
845010	850110	and .NET. So it's really leveraging everything when you look at how they go about launching
850110	854570	this ransomware. And once they get that initial access with that CobaltStrikeBeacon,
854570	859310	what they're going to do is they're going to run PsExec, which is going to launch PowerShell and
859310	864930	run the WastedLocker ransomware. And once that ransomware is in place, that's really where
864930	869310	they're going to make their money. They're going to lock down companies, individuals, whatever they
869310	875190	can, their machines. They're going to put out a Bitcoin address or whatever other cryptocurrency
875190	881490	they want to get paid in. And they're going to then hide those keys until you guys pay the
882370	887370	fees. And they've been very, very successful with this. The numbers being reported at the moment is
887370	892210	they've made at least $100 million using this sort of ransomware. So it's a very profitable
892210	897010	business for a threat to be able to use. So being able to see how they do it and then
897730	901110	emulate what parts we can is very, very important.
902710	910810	Yeah, and then this comes from a case study that Microsoft did on a breach that happened
910810	919210	to Nepone Telegraph and Telephone. They actually didn't have enough indicators of compromise or
919210	928170	enough access to the NTT findings to do a direct analysis of all the techniques themselves.
928170	935810	But what they were able to do was build a lab that restructured the representative
936770	944610	architecture of NTT and then kind of theorized how they would do it, which ended up using
945590	949630	a decent amount of PowerShell. And we just included this one because we thought it was
950510	954410	highly representative of like these major corporations that we're seeing being attacked
954410	960990	now because they use a hybrid infrastructure of on-premise servers as well as cloud servers
961450	968850	and then Active Directory and just it's a very complex attack surface.
969350	975150	They still ended up utilizing PowerShell through several of the steps to pivot through.
977560	982820	So they used phishing to get an initial foothold. Once they had that initial foothold,
982820	989760	they were able to gain domain information. Then they scraped social media in addition to add to
989760	994680	the information they had from the domain information to start building like what people's
994680	999260	emails might look like or their usernames and that kind of stuff. Once they did that, they
999260	1004580	started password spraying to get access to the cloud server, which they designated server B
1004580	1007820	as part of their case study.
1010100	1015060	Once they got access to server B, we start seeing them use a lot more PowerShell
1015860	1020900	because PowerShell in the cloud is still very effective. And what they ended up doing was
1020900	1026000	building a brute force attack on user accounts on server A because server A was a privileged
1026000	1034180	production server. And what they were looking for was accounts that had both cloud privileges
1034180	1038900	as well as local privileges because those users don't always overlap. So they first use PowerShell
1038900	1046720	to start trying to identify users that had had synced accounts between the local network on
1046720	1051140	server A as well as the cloud network that was in server B. Then they were able to brute force
1051140	1058140	those accounts to start trying to get access to server A. Once they got onto server A, they were
1058140	1064620	able to extract passwords from LSAS and remote sessions to get remote access to the Active
1064620	1071600	Directory server. Once the Active Directory server was compromised, they added a backdoor into it to
1071600	1077000	maintain persistence. And if you look at these images, those are just showing some of the
1077000	1082800	PowerShell they used. And again, we're just showing how this was used to target a major
1082800	1090060	international telecommunications company that had servers in multiple locations as well as cloud and
1090060	1096920	local-based. One of the last ones for our case studies that we just want to show some PowerShell
1096920	1102600	usage in the wild is one that we were contacted about a couple of months ago. There was a very
1102600	1106960	large international hotel chain that reached out to us and said that they detected some malicious
1106960	1112280	activity on their network and they were downloading payloads from our GitHub specifically. And what
1112280	1117240	was going on here was they were getting an initial foothold inside the network. They were trying to
1117240	1122240	stay as lean as possible. They were going out through the web, reaching out to our GitHub, which
1122240	1128400	we hosted Empire. They went specifically to one module, which was our Invoke Mimikatz module.
1128400	1132400	Since we keep that pretty up to date, they were downloading that right onto the network so they
1132400	1137000	can run it locally. And that way they could run Invoke Mimikatz completely locally. This technique
1137000	1142380	of downloading things from GitHub and other destinations is a pretty popular technique among
1142380	1147760	APTs. And you can find it in the CrowdStrike report for 2020. It's pretty widely used.
1147760	1152780	One of the interesting traits about this though that really stood out to us was the fact that
1152780	1157600	they were running things completely unobfuscated. They were running it just without any obfuscation
1157600	1161660	or if they had any evasion at all, it was very, very basic techniques. Normally, you wouldn't
1161660	1167780	see this from a threat, but it actually had some really interesting results from it. First,
1167780	1172700	the defenders on this network waived it off initially because they thought it was the
1172700	1178440	internal red team practicing. So since a lot of those weird obfuscation techniques really make
1178440	1182820	things stand out in the logs, their blue team didn't think anything of it because they just
1182820	1187160	thought it was the red team testing internally. So being unobfuscated in this case actually worked
1187160	1191720	to their advantage. They still ended up getting caught eventually, but it really was a benefit
1191720	1199860	for them. Yeah. And just to add to that, the hotel chain did stop them from compromising
1199860	1206180	anything before they lost any user data or anything like that. It was just initially,
1206180	1213540	they thought they waived it off the activity. So the attackers did have some extra time while
1213540	1218900	they were trying to deconflict that it actually wasn't the red team that they thought it was.
1219740	1224820	Now that we've talked about all those case studies, we've mentioned some of these logging
1224820	1230480	techniques and that kind of stuff that have created, when fully implemented, created an
1230480	1237040	environment that's actually fairly difficult to use PowerShell in. If you use the full capabilities
1237040	1242620	of strip block logging and module logging and AMSI combined with an EDR, that does
1243280	1250560	make PowerShell pretty hard to get through. But our point, especially we've specialized in
1250560	1257160	working with smaller to medium-sized businesses, and you just don't see them using this fully.
1257160	1262020	Maybe they do have strip block logging enabled or module logging enabled, but they're not
1262020	1266340	ingesting it properly into their scene because it's producing so much data.
1266340	1269880	And so, or they don't have good signature, they don't know how to build signatures that
1269880	1276960	would flag on malicious data, but not on their admins. So it's not the protections that we
1277680	1285440	often see it portrayed as in the offset community. They're just, oftentimes you see the
1285440	1290180	limitations of real-world implementation don't meet what the full capability can be achieved in
1290380	1296640	a lab. And then also just something else to note is that, you know, AMSI has already been
1297160	1304160	incorporated into .NET. So C-Sharp now has to deal with AMSI and Microsoft is, you know,
1304160	1309960	constantly innovating and looking at ways to start to improve the defense of .NET now that
1309960	1314800	we're seeing a lot of people doing that. So the advantages that C-Sharp have today
1315600	1323380	have already began shrinking from what PowerShell has and are, and will probably continue to shrink
1323380	1329560	into the advantages that it has over PowerShell as Microsoft implements more and better defenses
1329560	1339000	into .NET. So now we're going to talk about AMSI in a little more in-depth. We hear about it a lot,
1339000	1344960	but often people don't really fully understand exactly how AMSI is working. So AMSI is the
1344960	1352320	Windows Anti-Malware Scan Interface. I'm going to go ahead and read off the Microsoft definition
1352320	1358600	for you guys. It's a versatile interface standard that allows your applications and services to
1358600	1363480	integrate with any anti-malware product that's present on a machine. AMSI provides enhanced
1363480	1367700	malware protection for your end users and their data applications and workloads.
1370220	1375980	So that's great, but kind of what does it mean? And what that means is that AMSI, first of all,
1375980	1380600	doesn't work with just PowerShell. It works with VBScript, it works with JScript,
1380600	1384440	as well as other applications that we want to send information to. It's built to be
1384440	1391400	kind of this all-purpose lower level layer that you can tell it has predefined interfaces
1391400	1398140	that can then be connected to an antivirus. Traditionally that's Windows Defender,
1398140	1403400	but also McAfee and others tie into AMSI and rely on its detection capabilities
1404040	1410960	for seeing malicious things going on in memory. And it's also processing... the big advantage
1410960	1417200	of AMSI is that it's processing the commands at as low a level as possible before it enters into
1417200	1422500	the script engine. So a lot of obfuscation that is put in place is removed before AMSI
1422500	1428140	even looks at it. And this is just a diagram of how that data flows through those layers.
1430980	1439040	So as I said, it evaluates commands at runtime. So if you were to use XOR encoding or secure
1439040	1443500	string or some of those other obfuscation techniques that you might see out there,
1443500	1448860	that obfuscation has to be removed before it can go into the scripting engine because the
1448860	1453620	scripting engine doesn't know how to translate a secure string or an XOR encoded string
1453620	1459430	into commands that it knows how to read. So it helps us identify fileless threats.
1460100	1465500	And as I mentioned previously as well, as of .NET 4.8, it is integrated into the common
1465500	1469280	language runtime, which is what PowerShell and all these scripting languages are actually
1469840	1475540	decompiled or compiled into the common language infrastructure that's ran in the common language
1475540	1481820	runtime. So they actually all end up running in the same area. And now C Sharp also uses the
1481820	1487880	common language runtime. And so AMSI has been integrated at that lower level to account for
1487880	1493120	some of the other languages that it didn't initially account for. So AMSI is actually
1493120	1497700	pretty powerful. And we'll talk... we've got a couple examples that we're going to go through
1497700	1503620	here. One that Anthony will talk to more when we get to the obfuscation stuff. But this is just
1503620	1511680	what a standard Empire implant looks like when you put everything in. And if we just make some
1511680	1515800	changes on the structure of the code, it still goes through AMSI. Like it's still very, very
1515800	1523460	heavily dependent on static signatures. So this is just our modified script. You know, we changed
1523460	1531720	some variable names and changed some locations of where things were being done because some of the
1531720	1535620	code was position independent. It just had to be ran before the end of the script. So we moved it
1535620	1542300	around. And now it runs without issue. Well, this did run without issue. They are constantly
1542300	1547820	updating signatures in this one. This specific implementation probably will not pass AMSI
1547820	1554220	anymore. But when new AMSI signatures come out, it typically takes me about 30 minutes to an hour
1554220	1559820	to be able to come up with a workaround for whatever they changed for the detections.
1559820	1564320	It might be... it's worth us also pointing out that we get a lot of questions all the time
1564320	1568500	since we do a lot of work on Empire of, you know, why don't you keep the signatures up to date
1568500	1574800	constantly? So that way it's always avoiding AMSI and Microsoft and all the defenses that are out
1574800	1579300	there. And it's really just a cat and mouse game at the end of the day. So if we go and update it,
1579300	1584220	it's going to take them, you know, hours to get the new signatures updated. And then whatever
1584220	1589620	all the work that we just did is now worthless. So for us, it's easy for us to easily make these
1589620	1594740	changes and do it, but not publish it out there. So that's just something that we see a lot. And
1594740	1599600	we get a lot of questions asked of just why we're not making these changes on the releasable stuff
1599600	1605800	for Empire. And if you are interested in learning more about the obfuscation stuff, we do have like
1605900	1612560	a YouTube video up on that goes like... it's about three and a half hours of how to
1612560	1617020	bypass AMSI and avoid it. So there's plenty of information out there.
1617660	1622280	So now we're going to talk about script block logging. It was first introduced in PowerShell
1622280	1627460	version 4, but it was fairly rudimentary at that time. Version 5 introduced what Microsoft calls
1627460	1633080	deep script block logging. What that means is that it follows the execution down through multiple
1633080	1640740	levels, which we'll talk through in a second on these images. And then it's event ID 4104,
1640740	1646180	if you go look at the PowerShell operational log in Event Viewer. During our demo, I'm going to go
1646180	1651400	over a little more how you can find the Event Viewer and what's in those logs and how we can
1651400	1657060	look at them and that kind of stuff. But for now, if you look over on the image on the left,
1657430	1667100	the first six lines there are defining a function called super decrypt that is removing the XOR
1668100	1674320	encryption of a string and then returning that string in Unicode. Now, if we go down to the
1675530	1686340	next line, it's going to decrypt that string there, store it into a variable,
1686340	1691600	and then they're going to use invoke expression to execute that decrypted string. And we won't
1691600	1697300	see it on the transcription log, we just see what is entered into the command line. But if we go
1697300	1702600	over and look at the script block logs on the right over here, we can see the first one where
1702600	1709740	we defined our function. The next one down is you're running that decrypted equals super decrypt
1709740	1715460	to run our function. Walk down to the next line, where you see invoke expression of the decrypted
1715460	1721300	variable. And then this is where that kind of deep script block logging and following the things
1721300	1728540	down becomes powerful for AMSI. After all of that, we see that what was actually executed
1728540	1735720	from that encrypted string is that write host pwned. So that is like why AMSI is powerful,
1735720	1739580	is even though we had this function that we didn't really know it was going on with like
1739580	1744600	bytes and counter and all that stuff, and decrypting this XOR string that we couldn't
1744600	1750480	see into, we still see what's executed by invoke expression at the end. And that's what makes
1750480	1755200	AMSI power or script block logging powerful. But we'll talk about some ways that you can actually
1755200	1766300	obfuscate the script block logging in a little bit later. So module logging, it was introduced
1766300	1772840	in PowerShell version 3, and I think is the most powerful part of the PowerShell logging
1772840	1777100	capabilities. It does have some issues in implementing and building proper signatures,
1777100	1784780	because it does report each module individually. But it's nearly impossible to hit the log without
1784780	1790480	being unobfuscated. I say nearly impossible because maybe someone knows a way of doing it,
1790480	1794160	but I have never been able, I've never seen or been able to figure out a way
1794760	1801040	where you can not hit this log unobfuscated. If you look over at that image on the right,
1801040	1808080	that kind of setter block, the first line will say like command execution, or sorry,
1808080	1813540	command invocation, new object, and it shows new object. That's telling us what module is being
1813540	1819560	ran, which commandlet. And then the next line down, you know, says parameter binding. And then
1819560	1824480	if you go all the way over to the right, it says value. And that is what is being passed to the
1824480	1830960	commandlet. And that value is always unobfuscated from what I've seen. If someone knows of a way
1830960	1838060	obfuscating this, I'd be really interested in hearing about it afterwards. But that's why it's
1838060	1844160	so powerful, is the values being passed in as arguments for commandlets are always unobfuscated.
1844160	1850780	But it produces a whole lot of alerts. FireEye went and did a study when some of this came out,
1850780	1856240	and running invokeMimikatz, just that, nothing else going on on the network,
1856240	1863240	running just invokeMimikatz produces 2,280 events, generating seven megabytes of logs
1863240	1869320	from just running that one script. So as you can see, that generates a lot of data and a lot of
1869320	1875980	events that we have to sort through to be able to build efficient signatures and not just have
1875980	1886320	this data for after the fact. So PowerShell logging would make for a bad day for red teams
1886320	1892900	if organizations actually use it properly. But unfortunately, we have a bunch of things that are
1892900	1898440	in the operational world that are, you know, making that more difficult. You see alert fatigue,
1898440	1904080	you know, administrators are using sketchy scripts. I've been to a Fortune 500 company where
1904700	1910120	when we went and looked at the local logs on the machines, their EDR was interfacing
1910120	1918720	with AMSI. And each individual machine was producing like 100 alerts every two or three
1918720	1925740	hours because the admins had a script they were using for automation that was running every couple
1925740	1929140	of hours to make sure all the baselines for everything was staying, but it was doing something
1929140	1935060	sketchy that was triggering the EDR to say it was bad. And so basically they had all the alerts set
1935060	1941540	to information only and the EDR wasn't doing anything to kill the PowerShell when it was
1941540	1946840	being flagged as bad because the administrators didn't want their scripts being killed. And you
1946840	1955940	now have your SOC dealing with just, you know, thousands of alerts every day that they know are
1956680	1961500	not really alerts because it's just the admin guys. And, you know, the admin guys update their
1961500	1968820	stuff so they don't necessarily have a good way of automatically knowing or automatically filtering
1968820	1972860	out those admin scripts, although in an ideal world they would be able to do that. And then
1972860	1978680	deep script block logging can result in multiple alerts for a single script execution. Again,
1978680	1984780	FireEye was testing with invoke-mimikatz and it produced 116 events totaling five megabytes when
1984780	1989360	you use just the standard script block logging settings. Script block logging actually has an
1989360	1994280	additional setting that you can turn on that it has it record start and stop events for
1994280	1998760	loading different modules and executing pieces of code and that kind of stuff. And when you
1998760	2005120	enable that, your logs jump to 96,000 events totaling 50 megabytes of logs for running one
2005120	2012480	script. And then on top of all of that, bypasses are still effective because things like script
2012480	2018040	block log bypasses or AMSI bypasses that we'll talk about in a little bit are not considered
2018040	2026180	as crossing the security boundary by Microsoft because it's all operating on its own process.
2026180	2031800	And since it's the owner of that memory space for the process that it's working in,
2031800	2037700	it's not breaking any boundaries because if it turns it off for itself, then there's no way
2037700	2047470	to prevent it from doing that. So this is just a quick overview of kind of what Mandiant says.
2047470	2054630	Should they recommend for doing logging? They say if you can to enable module logging,
2054630	2059170	script block logging, and transcription. We didn't really talk about transcription because
2059170	2064150	it's fairly straightforward. All it is, is recording what is written out on the command
2064150	2069570	line. And it doesn't include... that's all it includes. It's just be... it's a replay
2069570	2075430	or a text version of what was typed into... what you see as you're typing into the command line.
2076190	2081550	And they say the unique data is recorded by each source. And then this is kind of the takeaway I
2081550	2086630	like to point out to people when we... when everyone says like, oh, logging is like, you know,
2086630	2091970	the end-all be-all for PowerShell. They say where log sizes cannot be significantly increased,
2091970	2097530	only enable script block logging and transcription logging because it will cover most data.
2098430	2104810	And module logging only buys you some. But as I talked about, we have some ways of obfuscating
2105430	2110990	transcription and script block logging so that even if you do record that data without bypassing
2110990	2116930	script block logging, you can't tell what's going on in the scripts. And then module logging is
2116930	2123170	basically impossible to hit unobfuscated. So it provides much better insight, in my opinion,
2123170	2127350	but does produce a whole bunch of data. And because events are individual, correlating
2127350	2132870	them becomes harder. So now we're going to talk about why it's still really effective
2132870	2138450	for red teams and APTs to still go after this stuff, you know, mitigating the mitigations.
2138810	2144650	We'll go over a little bit of AMSI bypasses, some obfuscation, like standard obfuscation.
2144650	2151110	What we refer to as keyword obfuscation, which is kind of doing some minimal obfuscation
2152070	2159030	to bypass AMSI because heavily obfuscated scripts can be a flag in and of themselves. We'll talk a
2159030	2163950	little bit about script block logging bypasses and then event tracing bypasses. Those will be
2163950	2172390	primarily in the demo. So reflective bypass. It's the simplest bypass that currently works.
2172390	2179790	It grabs the systemmanagement.automation.amsi.utils.dll. It grabs a reference to it and
2179790	2187450	then changes a field that says AMSI init failed and sets it to true. So why this works is when
2187450	2193770	they were incorporating AMSI into PowerShell, they decided that if there was an issue with
2193770	2198590	AMSI starting up rather than just killing PowerShell, not allowing PowerShell to run
2198590	2205590	if AMSI couldn't run, that it was better to basically fail safe and just have AMSI
2206330	2209990	ignored by PowerShell so that the PowerShell tools could keep working.
2210530	2215690	So when we're reflectively setting this field, we're saying that the initialization of AMSI
2215690	2221930	failed. So just go ahead and return a clean finding regardless of what was actually done.
2222190	2226170	And it doesn't even bother scanning the code. It just says there's something broken with AMSI.
2226170	2231210	So we're just going to tell Defender that everything's fine in terms of malicious content
2231210	2234810	because we don't know what's broken and we don't want to stop PowerShell from running.
2234810	2239670	And then it's also just kind of cool because Matt Graber originally posted this in a tweet
2239670	2245850	all the way back in 2016 and still works. So a more complicated bypass we can look at,
2245850	2253030	and there's a bunch of different implementations floating around. This is one I wrote based off
2253030	2259470	of Tal Lieberman's work that he published at BlackHat. Rostamaus has a very similar one
2260230	2265530	implemented, as well as there's a few other places you can find ones that are based off of this
2266410	2273750	off of this patching of the actual AMSI DOL in memory. So this is using some
2274970	2280870	a C-sharp to export DOL functions to allow us to access some areas of memory.
2281410	2288430	And then we are patching when AMSI goes to return the results, there's actually a numeric
2289610	2296510	value that it measures to define your risk rate. And if it's over x amount, that's considered bad.
2296510	2302950	If it's under x amount, then it's considered mostly good. And if it's a zero, it's considered
2302950	2307670	good. Basically, you never see zero returned in real life. And you actually never see the
2307670	2313650	different values with the actual value of your script rows, because when it returns the value,
2313650	2317410	defaults it to one of those three. There's actually a couple others for
2317970	2322890	policy implementation issues. But those are the three returns if it's just scanning your
2322890	2327790	code without outside influence. And what this does is it patches it to always return that the
2328530	2333090	code was good regardless of what the comparison finds of what the value actually came out from
2333090	2342610	AMSI. It says just return a good value from the comparison and say that the script is fine.
2342610	2350190	And so all of these work because AMSI is loaded as part of the memory space that our process is in,
2350190	2354190	which means that we have unrestricted access to the memory space that we're in. We can modify it
2354190	2361670	however we please. And so the reflective DLL tells AMSI to return a clean result prior to scanning
2361670	2366570	it. And as I mentioned, the patched one tells it to return after it being scanned.
2368350	2373070	So obfuscation, going in kind of a different direction with that, is taking that code that
2373070	2379210	we've established and adding some more noise in there to kind of hide what we're doing.
2379310	2383970	It's still very, very effective, but it does come with some costs. One of those being the
2383970	2387990	complexity of your payload. Your payloads will become really, really complex and they'll add
2388150	2391290	a lot of size to them because you're going to be running a bunch of different techniques. You may
2391290	2398770	be encoding it on top of changing variable names and splitting things up. So you can easily exceed
2399350	2403730	limits that are put in place by PowerShell on the size of a command. It also takes a lot of
2403730	2408030	time to be able to encode these. So if you're running every command that's being sent across
2408030	2414030	your C2 framework as obfuscated, there's going to be a delay there. Now that may not be a big deal
2414030	2417670	to some people, but depending on what you're trying to emulate, that actually could be a big deal.
2417670	2421850	Then, as Hubble talked about, some of the defenses that are in place, if they take all that
2421850	2425910	obfuscation and they wait till the very end, they may be able to detect whatever you're trying to do
2425910	2432910	at the very end because obfuscation helps you in breaking up signatures and dividing things up. So
2432910	2437390	that way they might not be identified, but if they're waiting to the end to run their analysis,
2437390	2444670	you may get caught. Here's just an example of some unobfuscated and obfuscated code for a
2444670	2452190	launcher for Empire. The left one just shows the basic payload without any obfuscation in it.
2452190	2457890	The right one has just the standard token all obfuscation set in place. And what it does,
2457890	2462670	you can see here, it starts breaking things up. It starts encoding things. This right here actually
2462670	2466370	won't get past AMSI, the way it's currently implemented, just because of the way token all
2466370	2471630	does some of its things. I'm sure Hubble will want to chime in a little bit on that. But the
2471630	2476130	important part, though, is really seeing how it actually encodes this and the big red flags
2476130	2483390	that defenders would actually see if they saw this in their logs. Yes, so token all, the way
2483390	2490790	it's implemented in invoke obfuscation, is a pseudo-randomized implementation of a bunch of
2490790	2498050	various different obfuscation techniques. And it has kind of two issues. One, it's pseudo-random.
2498050	2504750	At this point, invoke obfuscation has been out for a very long time. And all of the randomization,
2504750	2509750	or all of the combinations for those six techniques that it has, are fairly well known
2509750	2514970	at this point. And then there's also some issues with certain techniques interfere with each other
2514970	2521250	if they're ran in the wrong order. So sometimes you run into issues with that in invoke obfuscation
2521250	2528410	running token all, as it might run... you see some of the stuff where it's broken things up
2528410	2534610	into a bunch of string numbers. And when it does that, it then can't search for commands to
2534610	2538730	replace the name of the command, because that's already been broken up, so it can't find it.
2538930	2543190	So some of these things work better if you run them in specific orders. And invoke
2544290	2548410	obfuscation's token all doesn't always do that. So that's just some of the limitations on it.
2548410	2553310	And just having those custom cocktails of different obfuscation techniques make a big
2553310	2559030	difference. I know we have a couple that we keep for ourselves that seem to work almost all the time.
2560650	2565250	So the obfuscation really does get you about 90% of the way there. Like I said,
2565250	2569810	those custom cocktails that we have really do get us most of the way there. But there's some
2569810	2573510	things that you just can't get rid of when you're obfuscating. And those are just like those common
2573510	2578970	signatures that require you to restructure the code or eliminate certain keywords. One of the
2578970	2584470	really good examples was something that we saw last year with the original Empire project. Prior
2584470	2590730	to version 3, there was actually a mistake inside of the code where it double appended one of the
2590730	2595650	headers. This allowed signatures to be based off of that issue, because it couldn't be obfuscated
2595650	2601450	away. So any virus and AMSI and everything was detecting off of this specific mistake in the
2601450	2606170	code. So just removing that and then rerunning the obfuscation with a slightly different technique
2606170	2611870	allowed the payload to get through completely undetected. So really, that restructuring
2611870	2616510	and making sure that those signatures are broken is really, really important.
2616590	2622570	So now we're going to talk a little bit more about what we kind of call keyword aliasing.
2622730	2629190	AMSI can search in memory for specific terms and that kind of stuff that are automatically
2629190	2635350	flagged as bad or raise your threat level really high. And these can be triggered even when not
2635350	2642510	ran directly by AMSI. For instance, if you run a PowerShell script as Base64 encoded
2643170	2648550	and AMSI does not flag it as malicious, it still sees that as a very suspicious activity.
2648550	2653890	So then it starts searching strings in memory, or Defender starts searching for strings in memory.
2653890	2658750	And specifically, it'll actually do this even when AMSI has been disabled, because Defender
2658750	2662710	is seeing that as an inherently suspicious activity and Defender goes and looks for it as
2662710	2668690	well. So getting rid of these strings in memory becomes really key to getting our code through,
2668690	2674850	especially in allowing us to not heavily obfuscate everything all the time, which increases our size
2674850	2678830	and the amount of data we have to transfer and all that kind of stuff. Some of these
2678830	2686450	strings to keep in mind are actually invokeMimikatz, invokeEmpire, powersploit.
2687010	2691570	It's not in here, but another one that doesn't necessarily get you flagged as malicious but
2691570	2696970	generates a warning-level event in your logs, which means that it thinks it's highly suspicious
2696970	2701810	and would be a trigger for someone to potentially go look at, is if you're using an assembly and
2701810	2709290	use .getField. GetField is, in and of itself, a string that gets triggered as a warning-level
2709290	2715310	event and will go cause higher-level logs to be produced. Even if script block logging is off,
2715310	2722630	that string will cause a script block log to be saved, even when script block logging is disabled.
2722710	2727290	So if we change those terms, then we can make it really hard to detect us, because
2727950	2732230	if we change all the references in our script, there is nothing to de-obfuscate it from.
2732230	2737530	It just becomes that is the value that we are using. So in the example over on the right,
2737530	2747210	we're changing InvokeMemeCats to QAD45 and InvokeEmpire to DLXZ9. This is how it's done in
2747210	2753410	Empire now. On startup, it automatically makes entries to obfuscate those strings. If you really
2753410	2758170	want to be even stealthier, instead of changing it to just kind of these random letters and numbers,
2758170	2762430	because if you looked at a log, that would be kind of weird that someone's using a function name
2762430	2767270	that's completely random, because what legitimate programmer would be using a completely random
2767270	2773970	name? You could make these something like InvokeFileSearcher, InvokeOrganizer, so that
2773970	2778810	it would look even less suspicious than just a random string. We don't do this to everything
2778810	2785650	for a couple of reasons. You could do it, but it's time consuming to pick which values to alias.
2785650	2790090	And then it also requires us to put in a lot of entries into the database,
2790090	2795150	and that makes it just harder to track, because everything we want to alias has to be tracked
2795150	2799090	individually. And we have to make sure it's being applied across all of our scripts, because if we
2799090	2807030	had a reference in a script in one place and ran it outside of Empire, and it was looking for
2807030	2811290	something that Empire had aliased, or we had aliased by hand, and those don't match anymore, then your
2811290	2815550	stuff's going to break. So there's just some complexity added in the aliasing. And then, as we
2815550	2821290	mentioned, heavy obfuscation can be a flag in and of itself, so we want to minimally obfuscate where
2821290	2830810	we can. So here's a new... I have not seen this on open source stuff yet that I've been working on
2830810	2836410	that's pretty fun to play with. You can actually import to avoid script logs, as well as the
2836410	2841510	transcription log as well. ImportAlias is the one I've been playing with the most.
2841510	2848170	What happens is, when we import our aliases, for those that don't know, let me take a step back.
2848170	2855510	Aliasing, in terms of PowerShell, allows us to set whatever function name we want for any
2855510	2861610	commandlet. So the get command, or get printer, write host, any of those, we can say
2861610	2870750	set alias and change it to print instead of get printer. And then, whenever you type in
2870750	2877490	print into PowerShell, it knows that that is the same as doing get printer.
2878890	2886230	You can then save those aliases using ExportAlias. And then, when you import alias,
2886230	2893570	those terms and different names for your commandlets never get seen by the log.
2893570	2898890	They just get imported into memory. You can now run the command with the name that you gave it,
2898890	2904090	and on the script block log, that's all it sees. It'll see print instead of get printer.
2904310	2910990	If you have module logging enabled, then it will still see the module you're using.
2911290	2917810	And so, ImportAlias does not get you around module logs, although the module logs will not
2917810	2921970	see the values in ImportAlias, which is kind of interesting. But as we said,
2921970	2925670	it's basically impossible to avoid hitting the module logging initially.
2927570	2933510	So, this is kind of what it looks like to change things up. On the right is if I want to do
2935250	2939250	InvokeExpressionNewObjectSystem.net.webClient. That's what it would look like. That's what it
2939250	2945670	would look like in the logs. Instead, to run that, I went and did some aliasing by hand.
2947170	2954830	And we can embed further commands into the alias description. And if you look at the
2954830	2963890	import.alias.csv, that imported all of my alias commands. Now I run this completely
2963890	2970350	nonsensical command to someone looking at it that says I parentheses ca.description.
2970970	2981390	And then that caused another execution that was bcb.description. So, in this case, I was
2982190	2989790	was InvokeExpression. And b was that new object. And then the description for new object was
2989790	2997050	system.net.webClient. And so, I ended up achieving the same thing with this totally nonsensical
2997050	3003250	script block log that there's no way for a defender to go figure out what that actually means.
3003250	3008930	Because as soon as you close the PowerShell session, the aliasing is gone. It is not saved
3010210	3015830	saved permanently anywhere. So, you have to import. If you want to use aliases consistently,
3015830	3019090	you have to import them each time you start a new PowerShell session. That's why the
3019650	3025530	function was built. So, as soon as we kill our PowerShell session, our aliasing is gone. And
3025530	3030810	the key to what the script block log means is gone as well. Now we're going to go into demo
3030810	3035870	where I'll talk a little bit about more the event viewer and how to look at the PowerShell logs,
3035870	3044410	as well as show the script block log bypass and the event tracing bypass that is used by
3044410	3048550	the disables module logging in conjunction with all the other PowerShell logging.
3051250	3057110	First things first, how you get to the operational log for PowerShell is you're
3057110	3061710	going to use event viewer. You're going to come down here and type in event viewer. You want to
3061710	3066690	make sure you run it as an administrator. That just makes it easier to clear the logs when you're
3066690	3071210	testing that kind of stuff. But you can't usually view it even as an unprivileged user. You just
3071210	3082170	can't modify it. You'll then click on Microsoft, then Windows, then come down here to PowerShell,
3082170	3088850	open PowerShell, and then click on operational. Right now I cleared the logs prior to starting
3088850	3093570	this so that we can make it easier to see everything. So, if I go ahead and click on
3093570	3100290	PowerShell and open it, it's actually just starting PowerShell generates some logs.
3103050	3108810	As you can see here, we get these event IDs showing startup, as well as it looks like
3108810	3113250	my computer was a little slow. So, if I refresh it again, we should get a few more. Yeah, there we go.
3113690	3119230	So, you'll see this verbose prompt and script block logging that is just a default that always
3119230	3124230	gets generated when PowerShell starts up and after each command. Then we'll see this strict mode that
3125030	3131950	gets used throughout when you're running PowerShell. But as you can see, this one's 4104,
3131950	3137290	which is our script block logging, and then we have 4103 is our module logging.
3138190	3147050	If I go up and run just this right host test as our kind of test subject, we can come back over
3147050	3153830	and refresh our logs, and we'll see a couple of new entries in here. As I said, prompt comes up
3153830	3159430	after every execution. But if we go down here, we can see this right host test for our script block
3159430	3168510	log in 4104. And then we can see this module logging where we get the command invocation
3168510	3174970	for right host, as well as the value that was passed, which was our string of test.
3175590	3181210	So, now we're going to go over here, now that we've seen that. And the first one we're going
3181210	3187910	to talk about real quick is script block logging. This was published by Matt Graber. It's got a few
3187910	3194230	modifications from his original one, but this comes from a default Empire implementation.
3194230	3202550	All it's doing is it's creating a new dictionary that gets added to our cache group policy
3202550	3207050	settings. We access that reflectively, and we're just telling it that script block logging has
3207050	3212070	been turned off when it goes. So, when PowerShell goes to check if it's supposed to be recording,
3212070	3216750	it sees that the value is set to zero, which means it's not supposed to be recording script block
3216750	3222810	logging. We're able to do this because, just like the AMD bypass, this is all in our process
3223870	3230250	memory. So, we have complete access to it. We can manipulate in essentially whatever way we want.
3231290	3236150	So, if I go drop this in here, like so, and we hit enter,
3237430	3243270	we will generate a bunch of new events because we haven't disabled it yet. So, all of that code
3243270	3251130	that we just ran is going to hit our script block logging. And so, we go up here, and we can see
3251130	3257130	that our script block was ran with all of our different values. Then we get our out default,
3257130	3263570	which is the module when output is sent to the command line, and then some other ones. And since
3263570	3268650	script block logging is using an assembly, that doesn't actually generate any module logging
3268650	3276490	because it's obviously not a module. But now, if we go back up to here, and I do our write host test,
3276490	3281870	we will still generate a new event because module logging is on, and we haven't bypassed that.
3283090	3290030	But if you go look here, as you can see, the last script block log, that 4104,
3290030	3297230	was our disabling a script block logging, and now all we have is module logging, which occurs here
3297230	3306090	with our write host in our test string. So now, the other nice part about this is that
3306090	3310510	only affects our local process. So, if I just close out PowerShell and clear our logs,
3311930	3321450	we will reset everything. So we're going to go ahead and clear, and then when we go, if I open
3321450	3330910	it again, we're now going to use a event tracing bypass that was published about the same time,
3330910	3335210	actually, as the script block logging one. It just never really got a lot of traction.
3335890	3342730	It's, I believe it's linked in our slides. If not, I have the link for everyone that I can share.
3342990	3348670	And all we're doing is it's very similar to that script block logging bypass, where we're getting
3348670	3354410	access to a table that PowerShell is checking to see what it's supposed to be doing for logging.
3354710	3358950	But instead, we're disabling event tracing, which happens at a lower level.
3358950	3366250	This event tracing actually disables our module logging as well. So we run this,
3367030	3371150	and we go look at our logs.
3373110	3377770	And we'll see that we get a warning level event. This is because of some of the strings
3378470	3384910	that we mentioned during the briefing, like the get field string, as well as some of these
3384910	3390070	non-public static and those kinds of things will automatically generate a warning level event,
3390070	3394810	which means this would actually produce a log even if script block logging wasn't explicitly
3394810	3398950	enabled. So we ran this, but as you can see, we don't have any of those standard,
3398950	3405990	like the prompt logging or this out default that's normally there. And if we go run that
3409330	3417790	right host test again, we can see that we have had produced no logs. So we still have viable ways
3417790	3424270	of totally disabling PowerShell logging. And like I said, there are ways to get this down,
3424270	3428670	so it won't produce a warning level event. And then the last thing I was going to show you guys
3428670	3433770	real quick is just that import alias thing we talked about. I was just going to show it to you
3433770	3443210	real time. So we'll go ahead and clear the log. Open PowerShell back up again.
3447010	3451110	We're just going to go ahead and import our alias.csv.
3453210	3459530	I'm going to go ahead and run this nonsensical looking thing. As we can see, it gives us an
3459530	3467130	output that a new web request object was created. So now when we go look at our logging,
3472030	3476950	we can see a couple of different script block logs were called. So I called this
3479210	3485310	ICA.description initially. And this is where we can see that it's still hitting our module
3485310	3497750	logging. Even the script block logging can't see it. It appears that C is aliased to get command,
3497750	3501890	as we can see here. I'm looking through that. But as you can also see, it's a little hard to
3501890	3507570	correlate exactly what's going on and figure out what called this module without some in-depth
3507570	3514430	analysis of what's going on. So we have this value A that gets passed to it. Then we see it execute
3514430	3522990	this bcb.description, which again is a git command. And then we also see that we're executing
3523170	3531110	a new object that was being passed a system.net web client. And so that just shows you module
3531110	3536730	logging is kind of effective at bypassing this import aliasing thing. But the import aliasing
3537810	3542970	totally obfuscates logs in a way that you can't really undo it. And the other nice part is when
3542970	3548190	you import alias, the whole reason that you can import and export aliases is that they are not
3548190	3553970	persistent between sessions. So when we close out PowerShell, all of our aliasing key is gone,
3553970	3560570	so they can't go look it up. So it's just another level of obfuscation. And it also makes it really
3560570	3565290	hard for Amzie to see what's going on. So that's just something kind of fun to play with. But
3565290	3569930	that's all I got. So I'll toss it back over to Anthony. And we should have just a little bit
3569930	3574450	of time left. Thanks for having us at the Red Team Village. We're going to be in the channel
3574450	3576010	for a little bit to answer any questions.
