PowerShell: the Killer Queen

PowerShell: the Killer Queen

This blog will show you which options you have in Intune when you want to deploy a PowerShell script with an HKCU registry change but of course, you blocked PowerShell.exe on your Windows 10 Endpoints. I am also going to explain why you need to block PowerShell or which defences you need to put in place when you are allowing it.

When you are allowing your employees to run PowerShell you could be exposed to an Insider threat. The employee who has access to PowerShell could misuse his access. PowerShell can be used for initial access, local reconnaissance, privilege escalation and lateral movement.

Command and Scripting Interpreter: PowerShell, Sub-technique T1059.001 – Enterprise | MITRE ATT&CK®

PowerShell access could be the first phase (reconnaissance) into “hacking”.  There are a lot of techniques available which can be used with PowerShell. The damage that could be done depends on what kind of setup you have. When all of your devices are Azure Ad Joined and there are no on-premise servers left, the impact is significantly lower than with a hybrid setup. With a hybrid setup, there could be a lot of on-premise servers left that could be targeted.

We also must not forget PowerShell Scripts are a key ingredient in many malware attacks.

So what options do we have?

*Are we going to allow it with no security in place?

*Are we going to make PowerShell a little bit more secure?

*Are we going to block PowerShell?

Securing PowerShell

Let’s talk about hardening PowerShell first.  With the release of PowerShell 5.0, there are a lot of security features added. When your Windows 10 devices are up to date, you have these security features at your disposal. Beware! Most of them need to be enabled or configured manually.

1. Antimalware Integration (AMSI)

The Windows Antimalware Scan Interface (AMSI) is a versatile interface standard that allows your applications and services to integrate with any antimalware product that’s present on a machine. AMSI provides enhanced malware protection for your end-users and their data, applications, and workloads. The AMSI feature is integrated into PowerShell.

2. Script Block Logging

When you enable Script Block Logging, PowerShell records the content of all script blocks that it processes. Once enabled, any new PowerShell session logs this information.

# Module Logging
$RegistryPath = "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
$Name = "EnableModuleLogging"
$Value = "1"
If (!(Test-Path $RegistryPath)) { # Value Doesn't Exist, so create it
New-Item -Path $RegistryPath -Force | Out-Null
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}
Else {
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}
$Name = "ModuleNames"
$Value = "*"
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType String -Force | Out-Null
# Script Block Logging
$RegistryPath = "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
$Name = "EnableScriptBlockLogging"
$Value = 1
If (!(Test-Path $RegistryPath)) { # Value Doesn't Exist, so create it
New-Item -Path $RegistryPath -Force | Out-Null
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}
Else {
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}

3. System Wide Transcripts

If you enable this function, the system-wide transcription feature logs PowerShell use on a per user basis. If you enter a PowerShell command, a record of that command is written to a document within the outputdirectory

$RegistryPath = "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription"
$Name = "EnableTranscripting"
$Value = "1"
If (!(Test-Path $RegistryPath)) { # Value Doesn't Exist, so create it
New-Item -Path $RegistryPath -Force | Out-Null
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}
Else {
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null}
$Name = "EnableInvocationHeader"
$Value = "1"
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | Out-Null
$Name = "OutputDirectory"
$Value = "C:\Temp\PSLogs"
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType String -Force | Out-Null 

4. Constrained PowerShell

Constrained Language consists of a number of restrictions that limit unconstrained code execution on a locked-down system.

Configure Applocker to enforce constrained Powershell language mode. The only thing you will need to configure in Applocker are the Script Rules. Scripts that are allowed in the trusted directories or signed by a trusted code-signing certificate will run in full language mode all other scripts will be run in constrained language mode.

Another possibility would be configuring Device Guard (UMCI). But if you are new to securing devices, stick to Applocker for now. In my opinion managing, Applocker on an enterprise-scale is a lot easier and configuring an exclusion can be done a lot faster.

Please note: I will assume we all made sure, all users are no local admins!

Adminless – Call4Cloud

5. Powershell 2.0

So you are all good? Nope. PowerShell 2.0 is still installed by default in Windows 10.

Beware, when you installed dot.net  3.5 because some apps are requiring it, you could launch a PowerShell -version 2

So please make sure you remove it:

Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

Blocking Powershell

Now we have a pretty good understanding of how to secure PowerShell, I will show how you need to block PowerShell and how you could bypass the issue when you want to deploy user based PowerShell script in Intune.

Some time ago I was speaking with Damien van Robaeys about his systray tool he created.  It’s a wonderful tool if PowerShell is allowed to run. For most of our customers, PowerShell is blocked so running this tool was no go. I decided to start converting the app to exe files. While I was busy converting it, I realised this also could be the solution when you want to deploy user based PowerShell scripts but PowerShell is blocked.

First some background information about blocking PowerShell. When you have deployed AppLocker with the default rules, PowerShell is not blocked!.

Please take a look at my AppLocker baseline, PowerShell will be blocked when deploying this baseline.

Applocker à la minute – Call4Cloud Powershell Automated

But not every company has blocked PowerShell! Why you might ask?

There could be a lot of really good reasons why most of the companies are not blocking PowerShell. One of them is definitely the need to configure some HKCU registry settings, by deploying an Intune PowerShell script. You can guess what happens when you blocked PowerShell.

First, let’s see what happens when you want to deploy a HKCU registry setting and PowerShell is blocked.  Before we are publishing the script, we need to know the difference between running the script in the User or System context.

User Context –> When you want to deploy user settings –> Bound to the security applied to the user

System Context –> When you want to deploy system settings –> Not bound to the security applied to the user

You can take this sample script and upload it to Intune and select: “Run this script using the logged on credentials” and set it to yes.

$registryPath = "HKCU:\Software\call4cloud\Scripts"
$Name = "Version"
$value = "1"
IF(!(Test-Path $registryPath))
  {
    New-Item -Path $registryPath -Force | Out-Null
    New-ItemProperty -Path $registryPath -Name $name -Value $value `
    -PropertyType DWORD -Force | Out-Null}
 ELSE {
    New-ItemProperty -Path $registryPath -Name $name -Value $value `
    -PropertyType DWORD -Force | Out-Null}

When you deployed the script, watch the Applocker event log. You will notice within a few minutes PowerShell was prevented from running.

But what If there are different options available on how you could deploy user settings but without using PowerShell Scripts.

A year ago I wrote a blog about how you could configure some HKCU settings without the need for PowerShell. Please note, It was one of my first blogs so I had a lot to learn about writing a blog.

How to deploy HKCU registry changes while blocking powershell. – Call4Cloud

Of course, this option works but after some work trying to convert the PowerShell tool from Damien to an Exe I realised the same can be done when you want to deploy user settings.

UPDATE 05-05 2021

You could also use this ps2exe tool instead of using PowerShell scripts in Intune. When you want to make sure some device information is uploaded to a storage blob with the use of a storage key, you need to beware when you are using PowerShell scripts the full content of the PowerShell Script will be visible in the intunemanagementextension.log. You really don’t want to have sensitive information in this log file, so convert your sensitive PowerShell Script to an Exe

So why not convert your PowerShell scripts to executables files?  To do so, you will need to install this module first.

With a simple command line, you can convert the PS1 to an exe file …. After we converted it to an exe we can create a Intunewin file and upload it to Intune. It might be useful, to create an additional file in your PowerShell script so you can set this file in the win32 app detection rule.

After you have made sure the app is installed on the device open the AppLocker event log, you will notice the file is allowed to run from the %windir%\imecache folder.

The Microsoft Intune Management extension downloads the file into the  C:\Program Files (x86)\Microsoft Intune Management Extension\Content and unzips it to the %windir%\imecache folder. That’s great because this folder is NOT blocked by default or in my AppLocker baseline or in the default Applocker rules.

To be sure, open the registry to check if the registry key is created. As shown below, it’s created without any issue.

Conclusion:

Allowing PowerShell to make your life easier to deploy user settings is not necessary anymore.  You have the option to block it and work around the blockade.

Now I showed you the options available, go and block PowerShell…………or harden PowerShell but please do not allow it without any security barriers or logging.

Please note: Before PowerShell 5.0, PowerShell was the ultimate hacking tool but now with some additional security features it made PowerShell a little bit more secure.

If you want to read some more information about red teaming, attack simulation and other it security stories from the trenches without using PowerShell.

Publications | Outflank

Leave a Reply

Your email address will not be published. Required fields are marked *

  +  6  =  9