The post Windows Security change affecting PowerShell appeared first on PowerShell Team.
]]>January 9, 2019
The recent (1/8/2019) Windows security patch CVE-2019-0543, has introduced a breaking change for a PowerShell remoting scenario. It is a narrowly scoped scenario that should have low impact for most users.
The breaking change only affects local loopback remoting, which is a PowerShell remote connection made back to the same machine, while using non-Administrator credentials.
PowerShell remoting endpoints do not allow access to non-Administrator accounts by default. However, it is possible to modify endpoint configurations, or create new custom endpoint configurations, that do allow non-Administrator account access. So you would not be affected by this change, unless you explicitly set up loopback endpoints on your machine to allow non-Administrator account access.
# Create endpoint that allows Users group access PS > Register-PSSessionConfiguration -Name MyNonAdmin -SecurityDescriptorSddl 'O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;BU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)' -Force # Create non-Admin credential PS > $nonAdminCred = Get-Credential ~\NonAdminUser # Create a loopback remote session to custom endpoint using non-Admin credential PS > $session = New-PSSession -ComputerName localhost -ConfigurationName MyNonAdmin -Credential $nonAdminCred New-PSSession : [localhost] Connecting to remote server localhost failed with the following error message : The WSMan service could not launch a host process to process the given request. Make sure the WSMan provider host server and proxy are properly registered. For more information, see the about_Remote_Troubleshooting Help topic. At line:1 char:1 + New-PSSession -ComputerName localhost -ConfigurationName MyNonAdmin - ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotin gTransportException + FullyQualifiedErrorId : -2146959355,PSSessionOpenFailed
The above example fails only when using non-Administrator credentials, and the connection is made back to the same machine (localhost). Administrator credentials still work. And the above scenario will work when remoting off-box to another machine.
# Create Admin credential PS > $adminCred = Get-Credential ~\AdminUser # Create a loopback remote session to custom endpoint using Admin credential PS > $session = New-PSSession -ComputerName localhost -ConfigurationName MyNonAdmin -Credential $adminCred PS > $session Id Name ComputerName ComputerType State ConfigurationName Availability -- ---- ------------ ------------ ----- ----------------- ------------ 1 WinRM1 localhost RemoteMachine Opened MyNonAdmin Available
The above example uses Administrator credentials to the same MyNonAdmin custom endpoint, and the connection is made back to the same machine (localhost). The session is created successfully using Administrator credentials.
The breaking change is not in PowerShell but in a system security fix that restricts process creation between Windows sessions. This fix is preventing WinRM (which PowerShell uses as a remoting transport and host) from successfully creating the remote session host, for this particular scenario. There are no plans to update WinRM.
This affects Windows PowerShell and PowerShell Core 6 (PSCore6) WinRM based remoting.
This does not affect SSH remoting with PSCore6.
This does not affect JEA (Just Enough Administration) sessions.
A workaround for a loopback connection is to always use Administrator credentials.
Another option is to use PSCore6 with SSH remoting.
Paul Higinbotham Senior Software Engineer PowerShell Team
The post Windows Security change affecting PowerShell appeared first on PowerShell Team.
]]>The post PowerShell Constrained Language mode and the Dot-Source Operator appeared first on PowerShell Team.
]]>PowerShell works with application control systems, such as AppLocker and Windows Defender Application Control (WDAC), by automatically running in ConstrainedLanguage mode. ConstrainedLanguage mode restricts some exploitable aspects of PowerShell while still giving you a rich shell to run commands and scripts in. This is different from usual application white listing rules, where an application is either allowed to run or not.
But there are times when the full power of PowerShell is needed, so we allow script files to run in FullLanguage mode when they are trusted by the policy. Trust can be indicated through file signing or other policy mechanisms such as file hash. However, script typed into the interactive shell is always run constrained.
Since PowerShell can run script in both Full and Constrained language modes, we need to protect the boundary between them. We don’t want to leak variables or functions between sessions running in different language modes.
The PowerShell dot-source operator brings script files into the current session scope. It is a way to reuse script. All script functions and variables defined in the script file become part of the script it is dot sourced into. It is like copying and pasting text from the script file directly into your script.
# HelperFn1, HelperFn2 are defined in HelperFunctions.ps1 # Dot-source the file here to get access to them (no need to copy/paste) . c:\Scripts\HelperFunctions.ps1 HelperFn1 HelperFn2
This presents a problem when language modes are in effect with system application control. If an untrusted script is dot-sourced into a script with full trust then it has access to all those functions that run in FullLanguage mode, which can result in application control bypass through arbitrary code execution or privilege escalation. Consequently, PowerShell prevents this by throwing an error when dot-sourcing is attempted across language modes.
System is in WDAC policy lock down. To start with, neither script is trusted and so both run in ConstrainedLanguage mode. But the HelperFn1 function uses method invocation which isn’t allowed in that mode.
PS> type c:\MyScript.ps1 Write-Output "Dot sourcing MyHelper.ps1 script file" . c:\MyHelper.ps1 HelperFn1 PS> type c:\MyHelper.ps1 function HelperFn1 { "Language mode: $($ExecutionContext.SessionState.LanguageMode)" [System.Console]::WriteLine("This can only run in FullLanguage mode!") } PS> c:\MyScript.ps1 Dot sourcing MyHelper.ps1 script file Language mode: ConstrainedLanguage Cannot invoke method. Method invocation is supported only on core types in this language mode. At C:\MyHelper.ps1:4 char:5 + [System.Console]::WriteLine("This cannot run in ConstrainedLangua ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Both scripts are untrusted and run in ConstrainedLanguage mode, so dot-sourcing the MyHelper.ps1 file works. However, the HelperFn1 function performs method invocation that is not allowed in ConstrainedLanguage and fails when run. MyHelper.ps1 needs to be signed as trusted so it can run at FullLanguage.
Next we have mixed language modes. MyHelper.ps1 is signed and trusted, but MyScript.ps1 is not.
PS> c:\MyScript.ps1 Dot sourcing MyHelper.ps1 script file C:\MyHelper.ps1 : Cannot dot-source this command because it was defined in a different language mode. To invoke this command without importing its contents, omit the '.' operator. At C:\MyScript.ps1:2 char:1 + . 'c:\MyHelper.ps1' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [MyHelper.ps1], NotSupportedException + FullyQualifiedErrorId : DotSourceNotSupported,MyHelper.ps1 ...
And we get a dot-source error because we are trying to dot-source script that has a different language mode than the session it is being dot-sourced into.
Finally, we sign as trusted both script files and everything works.
PS> c:\MyScript.ps1 Dot sourcing MyHelper.ps1 script file Language mode: FullLanguage This can only run in FullLanguage mode!
The lesson here is to ensure all script components run in the same language mode on policy locked down systems. If one component must run in FullLanguage mode, then all components should run in FullLanguage mode. This means validating that each component is safe to run in FullLanguage and indicating they are trusted to the application control policy.
So this solves all language mode problems, right? If FullLanguage is not needed then just ensure all script components run untrusted, which is the default condition. If they require FullLanguage then carefully validate all components and mark them as trusted. Unfortuantely, there is one case where this best practice doesn’t work.
The PowerShell profile file (profile.ps1) is loaded and run at PowerShell start up. If that script requires FullLanguage mode on policy lock down systems, you just validate and sign the file as trusted, right?
PS> type c:\users\<user>\Documents\WindowsPowerShell\profile.ps1 Write-Output "Running Profile" [System.Console]::WriteLine("This can only run in FullLanguage!") # Sign file so it is trusted and will run in FullLanguage mode PS> Set-AuthenticodeSignature -FilePath .\Profile.ps1 -Certificate $myPolicyCert # Start a new PowerShell session and run the profile script PS> powershell.exe Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. C:\Users\<user>\Documents\WindowsPowerShell\profile.ps1 : Cannot dot-source this command because it was defined in a different language mode. To invoke this command without importing its contents, omit the '.' operator. At line:1 char:1 + . 'C:\Users\<user>\Documents\WindowsPowerShell\profile.ps1' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [profile.ps1], NotSupportedException + FullyQualifiedErrorId : DotSourceNotSupported,profile.ps1
What gives? The profile.ps1 file was signed and is policy trusted. Why the error? Well, the issue is that PowerShell dot-sources the profile.ps1 file into the default PowerShell session, which must run in ConstrainedLanguage because of the policy. So we are attempting to dot-source a FullLanguage script into a ConstrainedLanguage session, and that is not allowed. This is a catch 22 because if the profile.ps1 is not signed, it may not run if it needs FullLanguage privileges (e.g., invoke methods). But if you sign it, it still won’t run because of how it is dot-sourced into the current ConstrainedLanguage interactive session.
Unfortunately, the only solution is to keep the profile.ps1 file fairly simple so that it does not need FullLanguage, and refrain from making it trusted. Keep in mind that this is only an issue when running with application control policy. Otherwise, language modes do not come into play and PowerShell profile files run normally.
Paul Higinbotham Senior Software Engineer PowerShell Team
The post PowerShell Constrained Language mode and the Dot-Source Operator appeared first on PowerShell Team.
]]>The post DSC Resource Kit Release October 2018 appeared first on PowerShell Team.
]]>We just released the DSC Resource Kit!
This release includes updates to 9 DSC resource modules. In the past 6 weeks, 126 pull requests have been merged and 79 issues have been closed, all thanks to our amazing community!
The modules updated in this release are:
For a detailed list of the resource modules and fixes in this release, see the Included in this Release section below.
xPSDesiredStateConfiguration is also in the pipeline for a release, but the xArchive resource is failing its tests, so that module is currently on hold and will be released when all the tests are passing once again.
Our latest community call for the DSC Resource Kit was on October 10. A recording will be available on YouTube soon. Join us for the next call at 12PM (Pacific time) on November 21 to ask questions and give feedback about your experience with the DSC Resource Kit.
The next DSC Resource Kit release will be on Wednesday, November 28.
We strongly encourage you to update to the newest version of all modules using the PowerShell Gallery, and don’t forget to give us your feedback in the comments below, on GitHub, or on Twitter (@PowerShell_Team)!
Please see our documentation here for information on the support of these resource modules.
You can see a detailed summary of all changes included in this release in the table below. For past release notes, go to the README.md or CHANGELOG.md file on the GitHub repository page for a specific module (see the How to Find DSC Resource Modules on GitHub section below for details on finding the GitHub page for a specific module).
Module Name | Version | Release Notes |
---|---|---|
ComputerManagementDsc | 6.0.0.0 |
|
SharePointDsc | 2.6.0.0 |
|
SqlServerDsc | 12.1.0.0 |
|
StorageDsc | 4.2.0.0 |
|
xActiveDirectory | 2.22.0.0 |
|
xExchange | 1.24.0.0 |
|
xFailOverCluster | 1.11.0.0 |
|
xHyper-V | 3.13.0.0 |
|
xWebAdministration | 2.3.0.0 |
|
To see a list of all released DSC Resource Kit modules, go to the PowerShell Gallery and display all modules tagged as DSCResourceKit. You can also enter a module’s name in the search box in the upper right corner of the PowerShell Gallery to find a specific module.
Of course, you can also always use PowerShellGet (available starting in WMF 5.0) to find modules with DSC Resources:
# To list all modules that tagged as DSCResourceKit
Find-Module -Tag DSCResourceKit
# To list all DSC resources from all sources
Find-DscResource
Please note only those modules released by the PowerShell Team are currently considered part of the ‘DSC Resource Kit’ regardless of the presence of the ‘DSC Resource Kit’ tag in the PowerShell Gallery.
To find a specific module, go directly to its URL on the PowerShell Gallery: http://www.powershellgallery.com/packages/< module name > For example: http://www.powershellgallery.com/packages/xWebAdministration
We recommend that you use PowerShellGet to install DSC resource modules:
Install-Module -Name < module name >
For example:
Install-Module -Name xWebAdministration
To update all previously installed modules at once, open an elevated PowerShell prompt and use this command:
Update-Module
After installing modules, you can discover all DSC resources available to your local system with this command:
Get-DscResource
All resource modules in the DSC Resource Kit are available open-source on GitHub. You can see the most recent state of a resource module by visiting its GitHub page at: https://github.com/PowerShell/< module name > For example, for the CertificateDsc module, go to: https://github.com/PowerShell/CertificateDsc.
All DSC modules are also listed as submodules of the DscResources repository in the DscResources folder and the xDscResources folder.
You are more than welcome to contribute to the development of the DSC Resource Kit! There are several different ways you can help. You can create new DSC resources or modules, add test automation, improve documentation, fix existing issues, or open new ones. See our contributing guide for more info on how to become a DSC Resource Kit contributor.
If you would like to help, please take a look at the list of open issues for the DscResources repository. You can also check issues for specific resource modules by going to: https://github.com/PowerShell/< module name >/issues For example: https://github.com/PowerShell/xPSDesiredStateConfiguration/issues
Your help in developing the DSC Resource Kit is invaluable to us!
If you’re looking into using PowerShell DSC, have questions or issues with a current resource, or would like a new resource, let us know in the comments below, on Twitter (@PowerShell_Team), or by creating an issue on GitHub.
Katie Keim Software Engineer PowerShell DSC Team @katiedsc (Twitter) @kwirkykat (GitHub)
The post DSC Resource Kit Release October 2018 appeared first on PowerShell Team.
]]>NOTE: This post has important information for publishers in the “Accounts and publishing” section.
The post New Look and Features for PowerShell Gallery appeared first on PowerShell Team.
]]>NOTE: This post has important information for publishers in the “Accounts and publishing” section.
The PowerShell Gallery is the place to find PowerShell code that is shared by the community, Microsoft, and other companies. The site has averaged over 21 million downloads per month for the past 6 months, and has more than 3,800 unique packages available for use. It’s amazing when we consider we were handling just under 4 million downloads in July 2017. We clearly needed to invest in the PowerShell Gallery to support that kind of growth.
We have been working for some time to improve the performance of the PowerShell Gallery. The result is now available to everyone, and includes new features, performance enhancements, security improvements to accounts and publishing keys, and better alignment with the NuGet.org codebase that we rely on for our service and cmdlets.
Most users should see an improvement in package download speeds from the PowerShell Gallery. The new release takes advantage of CDN to provide faster downloads, particularly for those outside the United States. This should be most noticeable when installing a module with many dependencies.
The new updates include things users have requested for a long time, including:
The new user experience is more than just a face-lift, as providing a modern UI also improves the performance. The PowerShell Gallery pages now display only the most critical information initially, and move the details to expanding sections in the UI. This makes the pages faster and easier for users to find the content they want to see.
The changes with the most immediate impact in this release are for publishers and users with PowerShell Gallery accounts.
Most important: Publishers must update to PowerShellGet module version 1.6.8 or higher to publish to the PowerShell Gallery. Older versions of PowerShellGet are fine for find, save, install, and update functions, but not for publishing.
The PowerShell Gallery implemented several security best practices:
These changes are explained in more detail in the PowerShell Gallery documentation, and are the most significant changes included in this release.
Account management in the Powershell Gallery is also improved, and adds support for
You can find out more about the new Account settings features here.
The previous versions of PowerShell Gallery and PowerShellGet were based on older versions of NuGet. With this change we are aligning much more closely with the current state of the NuGet server and client. Many of the changes listed above – including the account and API key management – came directly from the NuGet updates. Another feature NuGet implemented is the ability to delete a package they have published accidentally, within the first hour after publishing.
As we move closer to alignment with how NuGet.org works, we expect to provide new features that are available from the NuGet team. Other changes we are considering that are available today at NuGet.org include support for namespaces and organizational accounts.
If you have any feedback on the changes we have made, or future changes we should consider, please do let us know. Visit https://aka.ms/PowerShellGalleryIssues to review what others are saying, or to let us know of other things we should be looking into.
The post New Look and Features for PowerShell Gallery appeared first on PowerShell Team.
]]>The post PowerShell Module Function Export in Constrained Language appeared first on PowerShell Team.
]]>PowerShell offers a number of ways to expose functions in a script module. But some options have serious performance or security drawbacks. In this blog I describe these issues and provide simple guidance for creating performant and secure script modules. Look for a module soon in PSGallery that helps you update your modules to be compliant with this guidance.
When PowerShell is running in Constrained Language mode it adds some restrictions in how module functions can be exported. Normally, when PowerShell is not running in Constrained Language, all script functions defined in the module are exported by default.
# TestModule.psm1
function F1 { }
function F2 { }
function F3 { }
# TestModule.psd1
@{ ModuleVersion = '1.0'; RootModule = 'TestModule.psm1' }
# All functions (Function1, Function2, Function3) are exported and available
Get-Module -Name TestModule -List | Select -ExpandProperty ExportedFunctions
F1
F2
F3
This is handy and works well for simple modules. However, it can cause problems for more complex modules.
Command discovery is much slower when script functions are exported implicitly or explicitly using wildcard characters. This is because PowerShell has to parse all module script content to look for available functions and then match the found function names with a wildcard pattern. If the module uses explicit function export lists, then this parsing during discovery is not necessary. If you have a lot of custom script modules with many functions, the performance hit can become very noticeable. This principal also applies to exporting any other script element such as cmdlets, variables, aliases, and DSC resources.
# TestModule.psm1
function F1 { }
function F2 { }
function F3 { }
...
# This wildcard function export has the same behavior as the default behavior, all module functions are exported and PowerShell has to parse all script to discover available functions
Export-ModuleMember -Function '*'
For large complex modules, exporting all defined functions is confusing to users as to how the module is intended to be used. The number of defined functions can be very large and the handful of user cmdlets can get lost in the noise. It is much better to export just the functions intended for the user and hide all helper functions.
# TestModule.psm1
function Invoke-Program { }
function F1 { }
function F2 { }
...
function F100 { }
# TestModule.psd1
@{ ModuleVersion = '1.0'; RootModule = 'TestModule.psm1'; FunctionsToExport = 'Invoke-Program' }
Get-Module -Name TestModule -List | Select -ExpandProperty ExportedFunctions
Invoke-Program
PowerShell runs in Constrained Language mode when a DeviceGuard or AppLocker policy is enforced on the system. This provides a good user shell experience while allowing trusted script modules to run in Full Language so that system management can still be done. For example, a user from the command line cannot use Add-Type to create and run arbitrary C# types, but a trusted script can.
So, it is important that a trusted script does not expose any vulnerabilities such as script injection or arbitrary code execution. Another type of vulnerability is leaking dangerous module functions not intended for public use. A helper function might take arbitrary source code and create a type intended to be used privately in a trusted context. But, if that helper function becomes publically available it exposes a code execution vulnerability.
# TestModule.psm1
function Invoke-Program { }
# Private helper function
function Get-Type
{
param( [string] $source )
Add-Type -TypeDefinition $source -PassThru
}
# Exposes *all* module functions!
Export-ModuleMember -Function '*'
Get-Module -Name TestModule -List | Select -ExpandProperty ExportedFunctions
Invoke-Program
Get-Type
In the above example, Get-Type
module helper function is exported via wildcard along with the intended Invoke-Program
function. Since this is a trusted module Get-Type
runs in Full Language and exposes the ability to create arbitrary types.
A major problem with exporting module functions using wildcards is that you may end up exporting functions unintentionally. For example, your module may specify other nested modules, or it may explicitly import other modules, or it may dot source script files into the module scope. All of those script functions will become publicly available if wild cards are used to export module functions.
# TestModule.psm1
import-Module HelperMod1
. .\CSharpHelpers.ps1
function Invoke-Program { }
# Exposes *all* module functions!
Export-ModuleMember -Function '*'
Get-Module -Name TestModule -List | Select -ExpandProperty ExportedFunctions
Invoke-Program
HelperFn1
HelperFn2
Compile-CSharp
When PowerShell detects that an application whitelisting policy is enforced it runs in Constrained Language mode as mentioned previously, but it also applies some function export restrictions for imported modules. Remember that these restrictions only apply when PowerShell is running under DeviceGuard or AppLocker policy enforcement mode. Otherwise module function export works as before.
These restrictions are to help prevent inadvertent exposure of functions. By using wildcard based function export, you may be exposing dangerous functions without knowing it.
# TestModule.psm1
Import-Module HelperMod1
. .\CSharpHelpers.ps1
function Invoke-Program { }
Export-ModuleMember -Function '*'
# TestModule.psd1
@{ ModuleVersion='1.0'; RootModule='TestModule.psm1'; FunctionsToExport='Invoke-Program' }
# Importing the psm1 file directly results in error because of the wildcard function export and use of dot source operator
Import-Module -Name TestModule\TestModule.psm1
Error:
'This module uses the dot-source operator while exporting functions using wildcard characters, and this is disallowed when the system is under application verification enforcement.'
# But importing using the module manifest succeeds since the manifest explicitly exports functions by name without wildcards
Import-Module TestModule
Get-Module -Name TestModule | Select -ExpandProperty ExportedFunctions
Invoke-Program
Best practices for module function exporting is pretty simple. Always export module functions explicitly by name. Never export using wild card names. This will yield the best performance and ensure you don’t expose functions you don’t intend to expose. It makes your module safer to use as trusted in a DeviceGuard policy enforcement environment.
# TestModule.psm1
Import-Module HelperMod1
. .\CSharpHelpers.ps1
function Invoke-Program { }
# TestModule.psd1
@ { ModuleVersion='1.0'; RootModule='TestModule.psm1'; FunctionsToExport='Invoke-Program' }
Get-Module -Name TestModule -List | Select -ExpandProperty ExportedFunctions
Invoke-Program
Paul Higinbotham Senior Software Engineer PowerShell Team
The post PowerShell Module Function Export in Constrained Language appeared first on PowerShell Team.
]]>In this talk, we went through some of the incredibly powerful ways that administrators can secure their high-value systems (for example, Just Enough Administration) and also dove into some of the mistakes that administrators sometimes make when exposing their PowerShell code to an attacker. The most common form of mistake is script injection, where a script author takes a parameter value (supplied by an attacker) and runs it in a trusted context (such as a function exposed in a Just Enough Administration endpoint).
The post PowerShell Injection Hunter: Security Auditing for PowerShell Scripts appeared first on PowerShell Team.
]]>In this talk, we went through some of the incredibly powerful ways that administrators can secure their high-value systems (for example, Just Enough Administration) and also dove into some of the mistakes that administrators sometimes make when exposing their PowerShell code to an attacker. The most common form of mistake is script injection, where a script author takes a parameter value (supplied by an attacker) and runs it in a trusted context (such as a function exposed in a Just Enough Administration endpoint). Here’s an example:
There are many coding patterns that can introduce security flaws like this, all of which have secure alternatives. The presentation goes into these in great detail, and what we also promised to release is a tool to help you detect them as you are writing the scripts. We’ve now released this tool, and you can download it from the PowerShell Gallery:
Using it this way from the command line is an excellent way to automate security analysis during builds, continuous integration processes, deployments, and more.
Wouldn’t it be REALLY cool if you could detect these dangers while writing your scripts? I’m glad you asked!
PowerShell’s Visual Studio Code plugin already does live script analysis to help you discover issues like unassigned variables, and we can customize that rule set to include InjectionHunter capabilities. Here’s what Visual Studio Code looks like with this running:
Here’s how to get this on your system:
First, find out the location of the InjectionHunter module. You can do this by typing:
Get-Module InjectionHunter -List | Foreach-Object Path
On my system, this returns:
D:\Lee\WindowsPowerShell\Modules\InjectionHunter\1.0.0\InjectionHunter.psd1
Next, create a file – ‘PSScriptAnalyzerSettings.psd1’ in a location of your choice. Use the following for the content – replacing the path to InjectionHunter with the one on your system.
@{ IncludeDefaultRules = $true CustomRulePath = "D:\Lee\WindowsPowerShell\Modules\InjectionHunter\1.0.0\InjectionHunter.psd1" }
"powershell.scriptAnalysis.settingsPath": "c:/users/lee/PSScriptAnalyzerSettings.psd1"
The post PowerShell Injection Hunter: Security Auditing for PowerShell Scripts appeared first on PowerShell Team.
]]>The post PowerShell Constrained Language Mode appeared first on PowerShell Team.
]]>In addition to the constraints listed in this article, system wide Constrained Language mode now also disables the ScheduledJob module. The ScheduledJob feature uses Dot Net serialization that is vulnerable to deserialization attacks. So now whenever an application whitelisting solution is applied such as DeviceGuard or AppLocker, PowerShell will run in Constrained Language mode and also disable the ScheduledJob module. Use the Windows Task Scheduler or PowerShell ScheduledTasks module as an alternative. For more information see CVE-2018-0958.
PowerShell Constrained Language is a language mode of PowerShell designed to support day-to-day administrative tasks, yet restrict access to sensitive language elements that can be used to invoke arbitrary Windows APIs.
You can place a PowerShell session into Constrained Language mode simply by setting a property:
PS C:\> $ExecutionContext.SessionState.LanguageMode
FullLanguage
PS C:\> $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
PS C:\> $ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage
PS C:\> [System.Console]::WriteLine("Hello")
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:1 char:1
+ [System.Console]::WriteLine("Hello")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Of course, this is not secure. A user can simply start another PowerShell session which will run in Full Language mode and have full access to PowerShell features. As part of the implementation of Constrained Language, PowerShell included an environment variable for debugging and unit testing called __PSLockdownPolicy
. While we have never documented this, some have discovered it and described this as an enforcement mechanism. This is unwise because an attacker can easily change the environment variable to remove this enforcement. In addition, there are also file naming conventions that enable FullLanguage mode on a script, effectively bypassing Constrained Language. Again, this is for unit testing. These test hooks cannot override a Device Guard UMCI policy and can only be used when no policy enforcement is applied.
PowerShell Constrained Language mode was designed to work with system-wide application control solutions such as Device Guard User Mode Code Integrity (UMCI). Application control solutions are an incredibly effective way to drastically reduce the risk of viruses, ransomware, and unapproved software. For DeviceGuard UMCI the approved applications are determined via a UMCI policy. PowerShell automatically detects when a UMCI policy is being enforced on a system and will run only in Constrained Language mode. So PowerShell Constrained Language mode becomes more interesting when working in conjunction with system-wide lockdown policies.
PowerShell’s detection of system policy enforcement through DeviceGuard is supported only for Windows platform running Windows PowerShell version 5.1 or PowerShell 7. It does not work on non-Windows platforms. So this is currently very much a Windows security feature. However, we will continue to enhance this for non-Windows platforms where feasible.
These lockdown policies are important for high-value systems that need to be protected against malicious administrators or compromised administrator credentials. With a policy enforced even administrators are limited to what they can do on the system.
Since Constrained Language is so limited, you will find that many of the approved scripts that you use for advanced systems management no longer work. The solution to this is simple: add these scripts (or more effectively: your code signing authority that signed them) to your Device Guard policy. This will allow your approved scripts to run in Full Language mode.
For example, all PowerShell module files shipped with Windows (e.g., Install-WindowsFeature) are trusted and signed. The UMCI policy allowing signed Windows files lets PowerShell run these modules in Full Language mode. But if you create a custom PowerShell module that is not allowed by the policy then it will be considered untrusted and run with Constrained Language restrictions.
Consequently, any PowerShell module marked as trusted in the policy needs to be carefully reviewed for security vulnerabilities. A vulnerability could allow code injection, or leak private functions not intended for public use. In either case it could allow a user to run arbitrary code in Full Language mode, thus bypassing the system policy protections.
We have described these dangers in much more detail in our post, “Writing Secure PowerShell Scripts” (coming soon).
Constrained Language consists of a number of restrictions that limit unconstrained code execution on a locked-down system. These restrictions are:
As we can see, Constrained Language mode imposes some significant restrictions on PowerShell. Nevertheless, it remains a formidable and capable shell and scripting language. You can run native commands and PowerShell cmdlets and you have access to the full scripting features: variables, statements, loops, functions, arrays, hashtables, error handling, etc.
PowerShell Constrained Language restricts only some elements of the PowerShell language along with access to Win32 APIs. It provides full shell access to all native commands and many cmdlets. It is not designed to operate independently and needs to work with application control solutions such as UMCI to fully lockdown a system and prevent access to unauthorized applications. Its purpose is to provide PowerShell on a locked-down system without compromising the system.
JEA (Just Enough Administration) is a sandboxed PowerShell remote session that is designed to strictly limit what the logged on user can do. It is configured in ‘no language mode’, has no access to file or other drive providers, and makes only a small set of cmdlets available. These cmdlets are often custom and designed to perform specific management functions without giving unfettered access to the system. The set of cmdlets provided in the session is role based (RBAC) and the session can be run in virtual or Group Managed Service accounts.
The JEA scenario is where an administrator needs to perform a management task on a high-value machine (such as collect logs or restart a specific service). The administrator creates a remote PowerShell session to the machine’s JEA endpoint. Within that session the user has access to only those commands needed to perform the task and cannot directly access the file system or the registry or run arbitrary code.
PowerShell Constrained Language is designed to work with application whitelisting solutions in order to restrict what can be accessed in an interactive PowerShell session with policy enforcement. You configure which scripts are allowed full system access through the whitelisting solution policy. In contrast, JEA is a sandboxed PowerShell remote session that restricts an interactive session to specific commands based on user role.
Paul Higinbotham [MSFT] PowerShell Team
The post PowerShell Constrained Language Mode appeared first on PowerShell Team.
]]>The post Defending Against PowerShell Attacks appeared first on PowerShell Team.
]]>The security industry is ablaze with news about how PowerShell is being used by both commodity malware and attackers alike. Surely there’s got to be a way to defend yourself against these attacks!
There absolutely is. PowerShell is – by far – the most securable and security-transparent shell, scripting language, or programming language available.
Our recommendations are:
Some security professionals recommend disabling PowerShell as a method of risk mitigation. Microsoft’s guidance on this falls into two areas:
For further information about these steps and solutions, please see the much more detailed presentation: “Defending Against PowerShell Attacks“.
You can also download the slide deck used for this video: Defending-Against-PowerShell-Attacks.
For further details about PowerShell’s Security features, please see our post: PowerShell the Blue Team.
For further details about implementing Just Enough Administration, please see http://aka.ms/jeadocs.
Lee Holmes [MSFT] Lead Security Architect Azure Management
The post Defending Against PowerShell Attacks appeared first on PowerShell Team.
]]>The post PowerShell in Azure Cloud Shell (Preview) is now publically available in Azure Portal appeared first on PowerShell Team.
]]>Thank you to our private preview users who helped shape the current experience by providing valuable feedback via issues and feature requests. We encourage you to continue your support by sharing your thoughts, experience, and input through the Azure Cloud Shell UserVoice.
Hemant Mahawar – @HemanMahawar Principal Program Manager PowerShell Team
The post PowerShell in Azure Cloud Shell (Preview) is now publically available in Azure Portal appeared first on PowerShell Team.
]]>The post Coming Soon – PowerShell in Azure Cloud Shell appeared first on PowerShell Team.
]]>Sign-up today to participate in a limited preview of PowerShell in Azure Cloud Shell.
We look forward to sharing this awesome new PowerShell experience with you!
Hemant Mahawar – @HemanMahawar Principal Program Manager PowerShell Team
The post Coming Soon – PowerShell in Azure Cloud Shell appeared first on PowerShell Team.
]]>