From bb726da6fd75cadf2d7e5ac092baab634d1c4b9b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 22 May 2019 15:19:23 -0700 Subject: [PATCH] Disable the debugger when in system lock-down mode (#9645) Disable the debugger when in system lock-down mode Fixing master for CVE-2019-0733 --- .../engine/debugger/debugger.cs | 52 +- .../ConstrainedLanguageDebugger.Tests.ps1 | 543 +++++++----------- .../ConstrainedLanguageRestriction.Tests.ps1 | 110 ---- 3 files changed, 248 insertions(+), 457 deletions(-) diff --git a/src/System.Management.Automation/engine/debugger/debugger.cs b/src/System.Management.Automation/engine/debugger/debugger.cs index c986f83a2..c5a7964ff 100644 --- a/src/System.Management.Automation/engine/debugger/debugger.cs +++ b/src/System.Management.Automation/engine/debugger/debugger.cs @@ -1132,12 +1132,16 @@ namespace System.Management.Automation internal Breakpoint NewCommandBreakpoint(string path, string command, ScriptBlock action) { WildcardPattern pattern = WildcardPattern.Get(command, WildcardOptions.Compiled | WildcardOptions.IgnoreCase); + + CheckForBreakpointSupport(); return AddCommandBreakpoint(new CommandBreakpoint(path, pattern, command, action)); } internal Breakpoint NewCommandBreakpoint(string command, ScriptBlock action) { WildcardPattern pattern = WildcardPattern.Get(command, WildcardOptions.Compiled | WildcardOptions.IgnoreCase); + + CheckForBreakpointSupport(); return AddCommandBreakpoint(new CommandBreakpoint(null, pattern, command, action)); } @@ -1175,6 +1179,7 @@ namespace System.Management.Automation { Diagnostics.Assert(path != null, "caller to verify path is not null"); + CheckForBreakpointSupport(); return AddLineBreakpoint(new LineBreakpoint(path, line, action)); } @@ -1182,6 +1187,7 @@ namespace System.Management.Automation { Diagnostics.Assert(path != null, "caller to verify path is not null"); + CheckForBreakpointSupport(); return AddLineBreakpoint(new LineBreakpoint(path, line, column, action)); } @@ -1201,11 +1207,13 @@ namespace System.Management.Automation internal Breakpoint NewVariableBreakpoint(string path, string variableName, VariableAccessMode accessMode, ScriptBlock action) { + CheckForBreakpointSupport(); return AddVariableBreakpoint(new VariableBreakpoint(path, variableName, accessMode, action)); } internal Breakpoint NewVariableBreakpoint(string variableName, VariableAccessMode accessMode, ScriptBlock action) { + CheckForBreakpointSupport(); return AddVariableBreakpoint(new VariableBreakpoint(null, variableName, accessMode, action)); } @@ -1761,12 +1769,6 @@ namespace System.Management.Automation originalLanguageMode = _context.LanguageMode; _context.LanguageMode = PSLanguageMode.FullLanguage; } - else if (System.Management.Automation.Security.SystemPolicy.GetSystemLockdownPolicy() == - System.Management.Automation.Security.SystemEnforcementMode.Enforce) - { - // If there is a system lockdown in place, enforce it - originalLanguageMode = Utils.EnforceSystemLockDownLanguageMode(this._context); - } // Update the prompt to the debug prompt if (hadDefaultPrompt) @@ -2060,6 +2062,17 @@ namespace System.Management.Automation { lock (_syncObject) { + // Disable script debugger when in system lock down mode + if (IsSystemLockedDown) + { + if (_context._debuggingMode != (int)InternalDebugMode.Disabled) + { + _context._debuggingMode = (int)InternalDebugMode.Disabled; + } + + return; + } + switch (mode) { case InternalDebugMode.InPushedStop: @@ -2086,6 +2099,24 @@ namespace System.Management.Automation } } + private static bool IsSystemLockedDown + { + get + { + return (System.Management.Automation.Security.SystemPolicy.GetSystemLockdownPolicy() == + System.Management.Automation.Security.SystemEnforcementMode.Enforce); + } + } + + private static void CheckForBreakpointSupport() + { + if (IsSystemLockedDown) + { + // Local script debugging is not supported in locked down mode + throw new PSNotSupportedException(); + } + } + #region Enable debug stepping [Flags] @@ -2323,6 +2354,15 @@ namespace System.Management.Automation { lock (_syncObject) { + // Restrict local script debugger mode when in system lock down. + // DebugModes enum flags provide a combination of values. To disable local script debugging + // we have to disallow 'LocalScript' and 'Default' flags and only allow 'None' or 'RemoteScript' + // flags exclusively. This allows only no debugging 'None' or remote debugging 'RemoteScript'. + if (IsSystemLockedDown && (mode != DebugModes.None) && (mode != DebugModes.RemoteScript)) + { + mode = DebugModes.RemoteScript; + } + base.SetDebugMode(mode); if (!CanEnableDebugger) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 index 31c047a24..04aaa8b38 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 @@ -18,10 +18,89 @@ try $defaultParamValues = $PSDefaultParameterValues.Clone() $PSDefaultParameterValues["it:Skip"] = !$IsWindows - Describe "Trusted module on locked down machine should not expose private functions to script debugger command processing" -Tags 'CI','RequireAdminOnWindows' { + Describe "Local script debugger is disabled in system lock down mode" -Tags 'CI','RequireAdminOnWindows' { BeforeAll { + # Invoke-LanguageModeTestingSupportCmdlet definition + $languageModeCmdletDef = @' + using System; + using System.Globalization; + using System.Reflection; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Security; + using System.Runtime.InteropServices; + using System.Threading; + using System.Management.Automation; + + /// Adds a new type to the Application Domain + [Cmdlet("Invoke", "LanguageModeTestingSupportCmdlet")] + public sealed class InvokeLanguageModeTestingSupportCmdlet : PSCmdlet + { + [Parameter()] + public SwitchParameter EnableFullLanguageMode + { + get { return enableFullLanguageMode; } + set { enableFullLanguageMode = value; } + } + private SwitchParameter enableFullLanguageMode; + + [Parameter()] + public SwitchParameter SetLockdownMode + { + get { return setLockdownMode; } + set { setLockdownMode = value; } + } + private SwitchParameter setLockdownMode; + + [Parameter()] + public SwitchParameter RevertLockdownMode + { + get { return revertLockdownMode; } + set { revertLockdownMode = value; } + } + private SwitchParameter revertLockdownMode; + + protected override void BeginProcessing() + { + if(enableFullLanguageMode) + { + SessionState.LanguageMode = PSLanguageMode.FullLanguage; + } + + if(setLockdownMode) + { + Environment.SetEnvironmentVariable("__PSLockdownPolicy", "0x80000007", EnvironmentVariableTarget.Machine); + } + + if(revertLockdownMode) + { + Environment.SetEnvironmentVariable("__PSLockdownPolicy", null, EnvironmentVariableTarget.Machine); + } + } + } +'@ + + if (-not (Get-Command Invoke-LanguageModeTestingSupportCmdlet -ea Ignore)) + { + $languageModeModuleName = "LanguageModeModule" + $modulePath = [System.IO.Path]::GetFileNameWithoutExtension([IO.Path]::GetRandomFileName()) + $script:moduleDirectory = join-path "$PSScriptRoot\$modulePath" $languageModeModuleName + if (-not (Test-Path $moduleDirectory)) + { + $null = New-Item -ItemType Directory $moduleDirectory -Force + } + + try + { + Add-Type -TypeDefinition $languageModeCmdletDef -OutputAssembly $moduleDirectory\TestCmdletForConstrainedLanguage.dll -ErrorAction Ignore + } catch {} + + Import-Module -Name $moduleDirectory\TestCmdletForConstrainedLanguage.dll + } + # Debugger test type definition $debuggerTestTypeDef = @' using System; @@ -33,29 +112,14 @@ try public class DebuggerTester { private Runspace _runspace; - private readonly string _privateFnName; - [Flags] - public enum TestResults - { - NoResult = 0x0, - DebuggerStopHandled = 0x1, - PrivateFnFound = 0x2 - }; - - public TestResults TestResult + public int DebuggerStopHitCount { private set; get; } - public Exception ScriptException - { - private set; - get; - } - - public DebuggerTester(Runspace runspace, string privateFnName) + public DebuggerTester(Runspace runspace) { if (runspace.Debugger == null) { @@ -63,363 +127,160 @@ try } _runspace = runspace; - _privateFnName = privateFnName; _runspace.Debugger.DebuggerStop += (sender, args) => { - try - { - // Within the debugger stop handler, make sure trusted private functions are not accessible. - string commandText = string.Format(@"Get-Command ""{0}""", _privateFnName); - PSCommand command = new PSCommand(); - command.AddCommand(new Command(commandText, true)); - PSDataCollection output = new PSDataCollection(); - - _runspace.Debugger.ProcessCommand(command, output); - if ((output.Count > 0) && (output[0].BaseObject is CommandInfo)) - { - TestResult |= TestResults.PrivateFnFound; - } - } - catch (Exception e) - { - ScriptException = e; - System.Console.WriteLine(e.Message); - } - TestResult |= TestResults.DebuggerStopHandled; + DebuggerStopHitCount += 1; }; } } } '@ - $modulePath = Join-Path $TestDrive Modules - if (Test-Path -Path $modulePath) - { - try { Remove-Item -Path $modulePath -Recurse -Force -ErrorAction SilentlyContinue } catch { } - } + $script = @' + "Hello" + Wait-Debugger + "Goodbye" +'@ + $scriptFilePath = Join-Path $TestDrive TScript.ps1 + $script > $scriptFilePath - # Trusted module - $trustedModuleName = "TrustedModule_System32" - $trustedModuleDirectory = Join-Path $modulePath $trustedModuleName - New-Item -ItemType Directory -Path $trustedModuleDirectory -Force -ErrorAction SilentlyContinue - $trustedModuleFilePath = Join-Path $trustedModuleDirectory "$($trustedModuleName).psm1" - $trustedManifestFilePath = Join-Path $trustedModuleDirectory "$($trustedModuleName).psd1" - @' - function PublicFn { - Write-Output PrivateFn "PublicFn" - } - - function PrivateFn { - param ([string] $msg) - - Write-Output $msg - } -'@ > $trustedModuleFilePath - $modManifest = "@{ ModuleVersion = '1.0'" + ("; RootModule = '{0}'" -f $trustedModuleFilePath) + "; FunctionsToExport = 'PublicFn' }" - $modManifest > $trustedManifestFilePath - - # Create test runspace - [runspace] $runspace = [runspacefactory]::CreateRunspace() - $runspace.Open() - - # Create debugger test object + # Define debugger test type Add-Type -TypeDefinition $debuggerTestTypeDef } AfterAll { - if ($runspace -ne $null) { $runspace.Dispose() } - } - - It "Verifies that private trusted module function is not available in script debugger" { - - # Run debugger access test - $debuggerTester = [TestRunner.DebuggerTester]::new($runspace, "PrivateFn") - - # Script to invoke the script debugger so that $debuggerTester can handle - # the debugger stop event and test for access of private functions within the - # script debugger command processor. - $script = @' - Import-Module -Name HelpersSecurity - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - Import-Module -Name {0} -Force - Set-PSBreakpoint -Command PublicFn - PublicFn -'@ -f $trustedManifestFilePath - - [powershell] $ps = [powershell]::Create() - $ps.Runspace = $runspace - - try + if (($script:moduleDirectory -ne $null) -and (Test-Path $script:moduleDirectory)) { - $ps.AddScript($script).BeginInvoke() - - # Wait for debugger test result for up to ten seconds - $count = 0 - while (($debuggerTester.TestResult -eq 0) -and ($count++ -lt 40)) - { - Start-Sleep -Milliseconds 250 - } + try { Remove-Item -Path $moduleDirectory -Recurse -Force -ErrorAction SilentlyContinue } catch { } } - finally - { - # Revert lockdown - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode - } - - # Verify that PrivateFn function name is not accessible - $debuggerTester.TestResult | Should -Match "DebuggerStopHandled" - $debuggerTester.TestResult | Should -Not -Match "PrivateFnFound" - $debuggerTester.ScriptException | Should -BeNullOrEmpty - } - } - - Describe "Cross language debugger get-item commands should not have access to FullLanguage trusted functions through provider" -Tags 'Feature','RequireAdminOnWindows' { - - BeforeAll { - - # Trusted module that will always run in FullLanguage mode - $scriptModuleName = "ImportTrustedModuleForTestA_System32" - $moduleFilePath = Join-Path $TestDrive ($scriptModuleName + ".psm1") - $script = @' - function PublicFn { "PublicFn"; PrivateFn } - function PrivateFn { "PrivateFn" } - - Export-ModuleMember -Function PublicFn -'@ - $script > $moduleFilePath - - # Import and run module function script - $scriptIM = @' - Import-Module -Name {0} -Force - $null = Set-PSBreakpoint -command PublicFn - PublicFn -'@ -f $moduleFilePath - - # Debugger stop event handler object. - $type = @' - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Management.Automation; - using System.Management.Automation.Runspaces; - - public class DebuggerStopEventHandler - { - private Runspace _runspace; - public object GetItemResult - { - get; - internal set; - } - public object GetChildItemResult - { - get; - internal set; - } - public object CopyItemResult - { - get; - internal set; - } - public object FunctionVariableResult - { - get; - internal set; - } - public object RenameItemResult - { - get; - internal set; - } - public DebuggerStopEventHandler(Runspace runspace) - { - _runspace = runspace; - _runspace.Debugger.DebuggerStop += (sender, args) => - { - var debugger = sender as Debugger; - - PSDataCollection output = new PSDataCollection(); - PSCommand command = new PSCommand(); - - command.AddScript(@"Get-Item -Path function:\PrivateFn 2>&1"); - debugger.ProcessCommand(command, output); - GetItemResult = (output.Count > 0) ? (output[0].BaseObject) : null; - - command.Clear(); - output.Clear(); - command.AddScript(@"Get-ChildItem -Path function:\PrivateFn 2>&1"); - debugger.ProcessCommand(command, output); - GetChildItemResult = (output.Count > 0) ? (output[0].BaseObject) : null; - - command.Clear(); - output.Clear(); - command.AddScript(@"Copy-Item -Path function:\PrivateFn -Destination function:\MyPrivateFn 2>&1"); - debugger.ProcessCommand(command, output); - CopyItemResult = (output.Count > 0) ? (output[0].BaseObject) : null; - - command.Clear(); - output.Clear(); - command.AddScript(@"${function:\PrivateFn}"); - debugger.ProcessCommand(command, output); - FunctionVariableResult = (output.Count > 0) ? (output[0].BaseObject): null; - - command.Clear(); - output.Clear(); - command.AddScript(@"Rename-Item -Path function:\PrivateFn -NewName function:\MyPrivateFn -Passthru 2>&1"); - debugger.ProcessCommand(command, output); - RenameItemResult = (output.Count > 0) ? (output[0].BaseObject) : null; - }; - } - public void Reset() { GetItemResult = null; GetChildItemResult = null; CopyItemResult = null; } - } -'@ - - try { Add-Type -TypeDefinition $type } catch { } - - # Create runspace and debugger event handler - [runspace] $rs = [runspacefactory]::CreateRunspace($host) - $rs.Open() - $rs.Debugger.SetDebugMode(@('LocalScript','RemoteScript')) - $debuggerStopHandler = [DebuggerStopEventHandler]::New($rs) - - # Create PowerShell to run module script - [powershell] $ps = [powershell]::Create() - $ps.Runspace = $rs - $ps.AddScript($scriptIM) } - AfterAll { - - if ($rs -ne $null) { $rs.Dispose() } - if ($ps -ne $null) { $ps.Dispose() } - } - - It "Verifies that same language mode trusted public functions *are* accessible from debugger through Get-Item, Get-ChildItem, Copy-Item, Rename-Item, Variable" { - - # Test - $results = $ps.Invoke() - - # Results. Only PublicFn is returned since PrivateFn is renamed. - $results[0] | Should Be "PublicFn" - - # Expected Get-Item function:\PrivateFn returns FunctionInfo object - ($debuggerStopHandler.GetItemResult -is [System.Management.Automation.FunctionInfo]) | Should Be $true - - # Expected Get-ChildItem function:\PrivateFn returns FunctionInfo object - ($debuggerStopHandler.GetChildItemResult -is [System.Management.Automation.FunctionInfo]) | Should Be $true - - # Expected Copy-Item function:\PrivateFn succeeds with no error output - $debuggerStopHandler.CopyItemResult | Should Be $null - - # Expected function variable succeeds - ($debuggerStopHandler.FunctionVariableResult -is [scriptblock]) | Should Be $true - - # Expected Rename-Item function:\PrivateFn returns FunctionInfo object - ($debuggerStopHandler.RenameItemResult -is [System.Management.Automation.FunctionInfo]) | Should Be $true - } - - It "Verifies that cross language mode trusted public functions *are not* accessible through Get-Item, Get-ChildItem, Copy-Item, Rename-Item, Variable" { - - # Test - $debuggerStopHandler.Reset() - try - { - $rs.LanguageMode = "ConstrainedLanguage" - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - - $results = $ps.Invoke() - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode - } - - # Results - $results[0] | Should Be "PublicFn" - $results[1] | Should Be "PrivateFn" - - # Expected Get-Item function:\PrivateFn returns error - $debuggerStopHandler.GetItemResult.FullyQualifiedErrorId | Should Be "PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand" - - # Expected Get-ChildItem function:\PrivateFn returns error - $debuggerStopHandler.GetChildItemResult.FullyQualifiedErrorId | Should Be "PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand" - - # Expected Copy-Item fails with error output - $debuggerStopHandler.CopyItemResult.FullyQualifiedErrorId | Should Be "PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" - - # Expected function variable fails - $debuggerStopHandler.FunctionVariableResult | Should Be $null - - # Expected Rename-Item function:\PrivateFn fails with error - $debuggerStopHandler.RenameItemResult.FullyQualifiedErrorId | Should Be "PathNotFound,Microsoft.PowerShell.Commands.RenameItemCommand" - } - } - - Describe "Cross language debugger Action scripts should not have access to FullLanguage trusted functions through provider" -Tags 'Feature','RequireAdminOnWindows' { - - BeforeAll { - - # Trusted script that will always run in FullLanguage mode - $scriptFileName = "TrustedScriptForTestB_System32" - $scriptFilePath = Join-Path $TestDrive ($scriptFileName + ".ps1") - $script = @' - function PublicFn { PrivateFn -typeDef 'public class Hello { public new static void ToString() { System.Console.WriteLine("Hello!"); } }'; [Hello]::ToString(); } - function PrivateFn { param ([string]$typeDef) Add-Type -TypeDefinition $typeDef } - PublicFn - "Complete" -'@ - $script > $scriptFilePath - } - - AfterAll { - - Get-PSBreakpoint | Remove-PSBreakpoint - } - - It "Verifies that debugger stop Action scriptblock cannot access PrivateFn" { + It "Verifies that Set-PSBreakpoint Line is disabled on locked down system" { try { Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - # Set breakpoint on script - Set-PSBreakpoint -Script $scriptFilePath -Line 4 -Action { - & (Get-Item -Path function:\PrivateFn) -typeDef @' - public class Foo { - public new static void ToString() { - System.Console.WriteLine("pwnd!"); - } - } -'@ - } - - # Run script - & $scriptFilePath - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode - } - - try - { - # Verify that Action scriptblock did not create Foo type using PrivateFn - [Foo]::ToString() + Set-PSBreakpoint -Script $scriptFilePath -Line 1 throw "No Exception!" } catch { - $_.FullyQualifiedErrorId | Should Be "TypeNotFound" + $expectedError = $_ } + finally + { + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode + Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode + } + + $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' + } + + It "Verifies that Set-PSBreakpoint Statement is disabled on locked down system" { + + try + { + Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode + $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" + + Set-PSBreakpoint -Script $scriptFilePath -Line 1 -Column 1 + throw "No Exception!" + } + catch + { + $expectedError = $_ + } + finally + { + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode + Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode + } + + $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' + } + + It "Verifies that Set-PSBreakpoint Command is disabled on locked down system" { + + try + { + Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode + $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" + + Set-PSBreakpoint -Command $scriptFilePath + throw "No Exception!" + } + catch + { + $expectedError = $_ + } + finally + { + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode + Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode + } + + $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' + } + + It "Verifies that Set-PSBreakpoint Variable is disabled on locked down system" { + + try + { + Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode + $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" + + Set-PSBreakpoint -Variable HelloVar + throw "No Exception!" + } + catch + { + $expectedError = $_ + } + finally + { + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode + Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode + } + + $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' + } + + It "Verifies that Wait-Debugger is disabled on locked down system" { + + try + { + Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode + + # Create test runspace + [runspace] $runspace = [runspacefactory]::CreateRunspace() + $runspace.Open() + + # Attach TestRuner.DebuggerTester DebugStop event handler to runspace + $debuggerTester = [TestRunner.DebuggerTester]::new($runspace) + + # Run $scriptFilePath script with 'Wait-Debugger' in locked down mode + [powershell] $ps = [powershell]::Create() + $ps.Runspace = $runspace + $null = $ps.AddScript('"Hello"; Wait-Debugger; "Goodbye"').Invoke() + } + finally + { + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode + if ($runspace -ne $null) { $runspace.Dispose() } + if ($ps -ne $null) { $ps.Dispose() } + } + + # Debugger should not have been active in lockdown mode + $debuggerTester.DebuggerStopHitCount | Should Be 0 } } } finally { - if ($defaultParamValues -ne $null) + if ($null -ne $defaultParamValues) { $Global:PSDefaultParameterValues = $defaultParamValues } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageRestriction.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageRestriction.Tests.ps1 index b208197a7..0c85c67a0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageRestriction.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageRestriction.Tests.ps1 @@ -365,116 +365,6 @@ try } } - Describe "Script debugging in constrained language" -Tags 'Feature','RequireAdminOnWindows' { - - It "Verifies that a debugging breakpoint cannot be set in constrained language and no system lockdown" { - - try - { - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - function MyDebuggerFunction {} - - Set-PSBreakpoint -Command MyDebuggerFunction - throw "No Exception!" - } - catch - { - $expectedError = $_ - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode - } - - $expectedError.FullyQualifiedErrorId | Should -BeExactly "CannotSetBreakpointInconsistentLanguageMode,Microsoft.PowerShell.Commands.SetPSBreakpointCommand" - } - - It "Verifies that a debugging breakpoint can be set in constrained language with system lockdown" { - - try - { - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - - function MyDebuggerFunction2 {} - $Global:DebuggingOk = $null - $null = Set-PSBreakpoint -Command MyDebuggerFunction2 -Action { $Global:DebuggingOk = "DebuggingOk" } - MyDebuggerFunction2 - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode - } - - $Global:DebuggingOk | Should -BeExactly "DebuggingOk" - } - - It "Verifies that debugger commands do not run in full language mode when system is locked down" { - - try - { - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - - function MyDebuggerFunction3 {} - - & { - $null = Set-PSBreakpoint -Command MyDebuggerFunction3 -Action { $Global:dbgResult = [object]::Equals("A", "B") } - $restoreEAPreference = $ErrorActionPreference - $ErrorActionPreference = "Stop" - MyDebuggerFunction3 - } - throw "No Exception!" - } - catch - { - $expectedError = $_ - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode - if ($restoreEAPreference -ne $null) { $ErrorActionPreference = $restoreEAPreference } - } - - $expectedError.FullyQualifiedErrorId | Should -BeExactly "CannotSetBreakpointInconsistentLanguageMode,Microsoft.PowerShell.Commands.SetPSBreakpointCommand" - } - - It "Verifies that debugger command injection is blocked in system lock down" { - - $trustedScriptContent = @' - function Trusted - { - param ($UserInput) - - Add-Type -TypeDefinition $UserInput - try { $null = New-Object safe_738057 -ErrorAction Ignore } catch {} - try { $null = New-Object pwnd_738057 -ErrorAction Ignore } catch {} - } - - Trusted -UserInput 'public class safe_738057 { public safe_738057() { System.Environment.SetEnvironmentVariable("pwnd_738057", "False"); } }' - - "Hello World" -'@ - $trustedFile = Join-Path $TestDrive CommandInjectionDebuggingBlocked_System32.ps1 - - try - { - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - - Set-Content $trustedScriptContent -Path $trustedFile - $env:pwnd_738057 = "False" - Set-PSBreakpoint -Script $trustedFile -Line 12 -Action { Trusted -UserInput 'public class pwnd_738057 { public pwnd_738057() { System.Environment.SetEnvironmentVariable("pwnd_738057", "Pwnd"); } }' } - & $trustedFile - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode - } - - $env:pwnd_738057 | Should -Not -Be "Pwnd" - } - } - Describe "Engine events in constrained language mode" -Tags 'Feature','RequireAdminOnWindows' { It "Verifies engine event in constrained language mode, its action runs as constrained" {