Stopping malware scripts in their tracks

Stopping malware scripts in their tracks

Chained Hands Keyboard

In the last few posts, we looked at limiting the fallout of malware on our network shares, we looked at extending what we learned here, to blackhole the DNS of the location that malware came from, and we then followed up by inspecting what the obfuscated malware did and how to alert people it’s in the network, with Script Block Logging. But frankly, wouldn’t you rather it never ran, at all? Again, we have a budget of $0 and only a few minutes to get it done (because I have a real job to do), so let’s see what we can get done.

You’re probably familiar with Powershell Constrained Language Mode. If you’re not – it’s probably worth getting familiar with it. In short, it limits what powershell can run and thus stops many, if not all, of the common attack frameworks, like Mimikatz, Powersploit, Empire, etc. etc.

Basically, you can put a PC in Constrained Language Mode with a registry key:

HKLM\System\CurrentControlSet\Control\SESSION MANAGER\Environment\__PSLockdownPolicy

Set this value to “4” for Constrained Language or “0” for full language (it’s a DWORD btw and that’s 2 x underscore at the start of it). It’s an interesting registry because unlike most cases, the HKLM is not overridden by HKCU. So to get out of constrained language mode, you do need to be a local administrator (or at least be able to modify the HKLM registry hive). Kind of, anyway: there’s another way out, as we’ll see in a minute.

Here’ a normal PC in Full Language Mode

And here we see the same PC, in Constrained Language Mode

So basically, lot’s of red-team or nasty stuff is now broken.

Now, any local admin can just go modify that registry and get out Constrained Language Mode. But guess what? ANYONE can get out of it, simply by loading Powershell Version 2 (powershell -version 2).

Ok, so we need something more robust! Enter: AppLocker.

We’re going to put in place a GPO to lock down which scripts are allowed to be run, and by who, regardless of the language mode on the endpoint;

And in here, we can put whatever rules make sense for our environment. For example:

In this case, users (including local admins) can run scripts from c:\windows and c:\program files but nothing else. Domain admins can run anything. This kind of makes sense because if someone has domain admin, it’s already game over, isn’t it? But you could tighten it however you want. You might want to say that only powershell.admin can run scripts or that people can only run scripts from \\server\share\scripts or whatever works for you.

This overrides the rules of constrained language mode and locks out the ability for Mimikatz or whatever to be really easily run.

But wait – what about powershell -version 2?

Well, in the same GPO, let’s put in a start up script to disable old version of powershell:

Which is just a CMD file:

powershell \\server\share\powershell\no_psv2.ps1

Which just calls no_psv2.ps1:

DisableWindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowershellV2

And now, the powershell -version 2 escape vector is broken.

So we’ve now been able to make life really hard for pen testers and people trying to use powershell exploit frameworks.


About the Author


RodneyI'm a veteran of way too many years of IT (although I still love it) and I currently head up the techincal work over at Host One (major sponsor of this site), where I'm also a partner. Feel free to ask me anything about Cloud Computing and I'll try to be helpful, in a non-salesy kind of way.View all posts by Rodney →

Leave a Reply

Time limit is exhausted. Please reload CAPTCHA.