forked from nsacyber/Windows-Secure-Host-Baseline
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSMB.psm1
216 lines (167 loc) · 8.57 KB
/
SMB.psm1
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#requires -RunAsAdministrator
#requires -Version 5
Set-StrictMode -Version 5
Function Test-RegistryValueName() {
<#
.SYNOPSIS
Tests if a registry value name exists.
.DESCRIPTION
Tests if a registry value name exists in the specified hive at the specified path.
.PARAMETER Path
The path of the registry key to check, including the hive.
.PARAMETER Name
The name of the registry value to check.
.EXAMPLE
Test-RegistryValueName -Path 'hklm:\Software\Microsoft\Windows\CurrentVersion' -Name 'ProgramFilesDir'
.EXAMPLE
Test-RegistryValueName 'hklm:\Software\Microsoft\Windows\CurrentVersion' 'ProgramFilesDir'
#>
[CmdletBinding()]
[OutputType([bool])]
Param(
[Parameter(Mandatory=$true, HelpMessage='The path of the registry key, including the hive.')]
[ValidateNotNullOrEmpty()]
[string]$Path,
[Parameter(Mandatory=$true, HelpMessage='The name of the registry value to check.')]
[ValidateNotNullOrEmpty()]
[string]$Name
)
$exists = $false
try {
$value = Get-ItemProperty -Path $Path -ErrorAction stop | Select-Object -ExpandProperty $Name -ErrorAction stop
$exists = ($value -ne $null) # catch the case where key exists but value name does not
} catch [System.Management.Automation.PSArgumentException],[System.Management.Automation.ItemNotFoundException],[System.Management.Automation.ActionPreferenceStopException] {
$exists = $false
}
return $exists
}
Function Test-IsSMBEnabled() {
[CmdletBinding()]
[OutputType([void])]
Param(
[Parameter(Mandatory=$true, HelpMessage='The SMB version')]
[ValidateNotNullOrEmpty()]
[ValidateRange(1,3)]
[UInt32]$Version
)
$enabled = $false
$path = 'hklm:\System\CurrentControlSet\Services\{0}'
$service = ''
switch($Version) {
1 { $service = 'mrxsmb10' ; break }
{ $_ -in @(2,3) } { $service = 'mrxsmb20' ; break }
default { throw "Invalid SMB driver version of $Version" }
}
$path = $path -f $service
if (Test-Path -Path $path) {
$startValue = Get-ItemPropertyValue -Path $path -Name 'Start'
$enabled = ($startValue -ne 4)
}
return $enabled
}
Function Disable-SMB1 {
<#
.SYNOPSIS
Disable the SMB 1.0 protocol.
.DESCRIPTION
Disable the SMB 1.0 protocol. Since a system can act as an SMB server and client, SMB is disabled for both. If SMB1 is uninstalled, then the this function does nothing since there is nothing to disable. SMB1 is not actually disabled until the system reboots.
.EXAMPLE
Disable-SMB1
#>
[CmdletBinding()]
[OutputType([void])]
Param()
$smb1Path = 'hklm:\System\CurrentControlSet\Services\mrxsmb10'
$smbClientPath = 'hklm:\System\CurrentControlSet\Services\LanmanWorkstation'
$smbServerPath = 'hklm:\System\CurrentControlSet\Services\LanmanServer\Parameters'
# checking if the registry key exists MUCH faster than using Get-WindowsOptionalFeature -Online -FeatureName 'SMB1Protocol' and checking its State value
# if using Disable-WindowsOptionalFeature -Online -FeatureName 'SMB1Protocol' to uninstall SMB1, then the mrxsmb10 value is removed after reboot
# SMB1 still works until a reboot happens due to the driver still being loaded
if (Test-Path -Path $smb1Path) {
# the SMB1 registry value name used below does not exist by default which means SMB1 is enabled (ONLY if the SMB1Protocol feature State is Enabled as returned by Get-WindowsOptionalFeature OR mrxsmb10 exists)
# SMB1 is disabled when the SMB1 registry value exists AND it is set to 0 (OR if SMB1Protocol feature State is Disabled as returned by Get-WindowsOptionalFeature or mrxsmb10 does not exist) and a reboot has occured
# (Get-SmbServerConfiguration).EnableSMB1Protocol merely reflects the regsitry value information (returns $true if not exist OR exists and value is 1. returns $false if exists and value is 0)
# Get-SmbServerConfiguration does not reflect the Windows feature state which could lead to false positives by solely using that command
if (Test-RegistryValueName -Path $smbServerPath -Name 'SMB1') {
$smb1Value = Get-ItemPropertyValue -Path $smbServerPath -Name 'SMB1'
Set-ItemProperty -Path $smbServerPath -Name 'Previous_SMB1' -Type DWORD -Value $smb1Value -Force
}
Set-ItemProperty -Path $smbServerPath -Name 'SMB1' -Type DWORD -Value 0 -Force # 0 = Disabled, 1 = Enabled
$startValue = Get-ItemProperty -Path $smb1Path -Name 'Start'
Set-ItemProperty -Path $smb1Path -Name 'Previous_Start' -Type DWORD -Value $startValue -Force
Set-ItemProperty -Path $smb1Path -Name 'Start' -Type DWORD -Value 4 -Force # 4 = Disabled, 2 = Automatic (normal value)
$dependOnValue = Get-ItemPropertyValue -Path $smbClientPath -Name 'DependOnService'
Set-ItemPropertyValue -Path $smbClientPath -Name 'Previous_DependOnService' -Type MultiString -Value $dependOnValue -Force
if ('mrxsmb10' -in $dependOnValue) {
$newDependOnValue = ((($dependOnValue -join ',') -replace 'mrxsmb10','') -replace ',,',',') -split ',' # remove the dependency on SMB1
Set-ItemProperty -Path $smbClientPath -Name 'DependOnService' -Type MultiString -Value $newDependOnValue -Force
}
}
}
Function Uninstall-SMB() {
<#
.SYNOPSIS
Uninstalls Server Message Block protocol.
.DESCRIPTION
Uninstalls Server Message Block protocol. Only SMB 1.0 can be uninstalled. SMB 1.0 is only required for communicating with Windows XP and Windows Server 2003 both of which are end of life.
.EXAMPLE
Uninstall-SMB
.EXAMPLE
Uninstall-SMB -Version 1
#>
[CmdletBinding()]
[OutputType([void])]
Param(
[Parameter(Mandatory=$false, HelpMessage='The SMB version')]
[ValidateNotNullOrEmpty()]
[ValidateRange(1,1)]
[UInt32]$Version = 1
)
$ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
# it is much faster just to check if the mrxsmb10 registry key value exists or not rather than using Test-WindowsOptionalFeature
# note that mrxsmb10 still exists when Disable-WindowsOptionalFeature is used. it is not deleted until a reboot, but SMB1 also continues to work until a reboot for that case
# can't avoid the slowness of Disable-WindowsOptionalFeature, but at least by not using the Test- function, it will be as fast as it can be
#if (Test-WindowsOptionalFeature -FeatureName 'SMB1Protocol') {
if (Test-Path -Path 'hklm:\System\CurrentControlSet\Services\mrxsmb10') {
Disable-WindowsOptionalFeature -Online -FeatureName 'SMB1Protocol' -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -NoRestart | Out-Null
}
}
Function Get-SMBDialect() {
<#
.SYNOPSIS
Gets the highest SMB dialect supported by the system.
.DESCRIPTION
Gets the highest SMB dialect supported by the system.
.EXAMPLE
Get-SMBDialect
#>
[CmdletBinding()]
[OutputType([System.Version])]
Param()
$drive = $env:SystemDrive -replace ':',''
$drive = '{0}$' -f $drive
Get-ChildItem -Path "\\localhost\$drive" | Out-Null
$dialect = Get-SmbConnection -ServerName 'localhost' | Where-Object { $_.ShareName -eq $drive } | Select-Object Dialect -ExpandProperty Dialect
return [System.Version]$dialect
}
Function Get-SMBAuditResult() {
<#
.SYNOPSIS
Gets a unique list of IP addresses found in the SMB 1.0 auditing logs.
.DESCRIPTION
Gets a unique list of IP addresses found in the SMB 1.0 auditing logs.
.EXAMPLE
Get-SMBAuditResult
#>
[CmdletBinding()]
[OutputType([string[]])]
Param()
$addresses = [string[]](Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-SmbServer/Audit';ProviderName='Microsoft-Windows-SmbServer';Id=3000;Level=4} -ErrorAction SilentlyContinue| Select-Object { ([xml]$_.ToXml()).Event.EventData.Data.'#text' } -Unique)
if ($addresses -eq $null) {
$addresses = [string[]]@()
}
return ,$addresses
}
#todo: Get-SMBDialectsInUse function. use Get-SMBConnection for client side and Get-SMBSession for server side. return unique list of dialects in use @([Server,1.1],[Client,2.0])
#Get-SMBConnection is the client side of SMB connections
#Get-SMBSession is the server side of SMB connections