In the previous post, I tried to explain some inconsistences in the current implementation of Constrained PowerShell feature that is introduced in PowerShell 5.0: PowerShell 5.0 and Applocker. When security doesn’t mean security. After having a long email and twitter conversations I realized that many of readers blame me for being against Constrained PowerShell feature. It is not true. In this post, I would like to summarize what is going wrong now and how it should work in my opinion.
The whole idea to protect PowerShell from being used by attackers is good.
I clearly understand that an attacker could run arbitrary in-memory code without having to touch filesystem by calling
powershell.exe -command <evil code> and this ultimately makes AWL (Application Whitelisting) weaker.
First fault: PowerShell team made new security feature dependent on a non-security feature.
Although many of AWL users and PS team consider AWL as a security feature, not all in Microsoft thinks the same. Especially, Microsoft Security Response Center (MSRC). Proof: https://github.com/kasif-dekel/Microsoft-Applocker-Bypass (image at the bottom).
Instead of relying on AWL status, I would propose to make an entry in group policies that would configure interactive language mode. Administrators would be able to control Constrained PowerShell separately from AWL status.
It should be possible for PowerShell.exe to differentiate the code called from interactive shell and from PowerShell.exe parameters (i.e. -command parameter).
In my opinion, interactive shell is not that insecure like direct powershell.exe calls. So, PS itself should be able to differentiate input sources.
In addition, there should be a GPO entry that would configure language mode for admins (elevated shell) and non-admins (standard users and non-elevated shells).
By having all three, we would propose a new PS security baseline like this:
powershell.exe -commandwill always run in constrained language mode.
powershell.exe -commandwill always run in constrained language mode.
powershell.exe -commandwill run in constrained mode even in admin mode.
Such baseline would improve PS security, while administrators will be able to perform their usual (or unusual when something is failed) tasks without worrying that something calls
powershell.exe -command <evil> in background.
AWL is not security boundary, consider it bypassable.
There are number of issues with Microsoft implementations of AWL that potentially allow to bypass it and run arbitrary executable/dll. Link to GitHub is just *another* example. The things goes worse, because new similar issues with Applocker won’t be patched (see response from MSRC). As the result, PowerShell is still the target and attacker is potentially capable to utilize PowerShell class in
System.Management.Automation.dll assembly. At this point, an attacker is able to call
PowerShell.Create().AddScript(<evil>) that will execute the code in Full Language mode. As the result, PS team should enforce constrained language mode (if it is selected by an administrator) to PS .NET calls too. This would be more complete solution from security perspective.
Considering, the company is using AWL. As the result, all interactive sessions will be run in constrained language mode. Including ISE.
How Microsoft would support script authoring/debugging and various administration operations from interactive shell when AWL is enforced? In the current implementation it is impossible and we are forced to disable new feature by creating appropriate rules in AWL, because it is unreliable and unusable at this point. This question is still open.
Hope, this adds some clarity to my position in this question.
Are there updates in the meantime, how I should organize this stuff for my powershell developers?
So if we run an environment with AppLocker how can we run scripts in full language mode without launching in Admin mode?
> So if we run an environment with AppLocker how can we run scripts in full language mode without launching in Admin mode?
if you have scripts ready for execution, just digitally sign them and execute. They should run in full language mode. If not -- you are out of luck, you are always limited to constrained language in interactive sessions.
This post covers how to add an Applocker rule to allow PS to run in full language mode.
This rule can then be targerted at AD groups / individual users etc as required.
You are NOT always limited to constrained mode when using Applocker!
> This post covers how to add an Applocker rule to allow PS to run in full language mode.
The only way to allow PS in full language mode is to disable PS1 file screening through SRP/Applocker. There is no need in so complex rules, you can simplify it to "*.ps1" and that's all. The point here is that PS1 files are no longer screened by AWL.
That's not the only way becasue I'm running it in my environment
allowing *.ps1 will open you up to any PS script running.
The process outlined in that spiceworks post will allow you to get PS out of constrained mode but still allow to granularly control which scrips can execute or indeed who can execute them
In my environment one AD group can run powersehll outside of contrained mode. No one else.
I should point out that I'm on Win 10 1803 and the path has changed that you need to allow via Applocker.
If you are interested in seeing what is and isn't being blocked and thus what needs to be allowed (or indeed not!) you look here:
Eventvwr -> Apps & Services -> MS -> Widows -> Applocker -> MSI & Scripts
Sorry 3rd follow up haha.
You are correct. However you can use a targeted rule to constrain this to groups of approved users whilst still keeping applockers 'protection' for others. That's an important distinction.
> allowing *.ps1 will open you up to any PS script running.
this is the problem. If PowerShell started in full lnaguage mode, PS script execution is no longer screened by Applocker. So, whether you enable ps1 files in %temp% folder or completely enable ps1 files (*.ps1), the effect is identical. This is why I'm using simplest solution to remove ps1 files from SRP/Applocker.
Modules won't load with or without custom XML definitions (I can't remember what the proper term is). The 365 2FA module won't run without a *.ps1 rule, you need to import into an open session using a more specific rule.
So you're not giving up complete control and I still say that the ability to target a group and retain protection for anyone outside that group is useful.
Code signing won't be implemented everywhere and this at least means you can restrict PS access to certain users and still use Applocker to protect the majority.
Why do you want to screen .PS1 files yet have the interactive prompt fully open?
There's a multitude of ways to execute PowerShell code that doesn't rely on a PS1 file. If the interactive prompt is open, your system is open. PowerShell -command is not the only way to use the interactive prompt. I could just as easilly send keyboard commands to a machine.
> Why do you want to screen .PS1 files yet have the interactive prompt fully open?
the idea behind this is that PS1 screening still helps to prevent automatic (mostly accidental) script execution. SRP is bypassable, Applocker too. These are not security features and they won't get fixed. This means that PS constrained mode makes very little sense. Maybe against unexperienced users only.
> If the interactive prompt is open, your system is open.
If I have interactive access, nothing will keep me from executing arbitrary PS code. I won't even use powershell.exe console. There are plenty ways to execute arbitrary PS code without executing powershell.exe console and these ways are not protected in any way.
Post your comment: