-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathDeployCryptoBlocker.ps1
246 lines (200 loc) · 9.17 KB
/
DeployCryptoBlocker.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
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# DeployCryptoBlocker.ps1
#
# This script performs the following actions:
# 1) Checks for network shares
# 2) Install File Server Resource Manager (FSRM) if missing
# 3) Creates Batch and PowerShell scripts used by FSRM
# 4) Creates a File Group within FSRM containing malicious extensions to screen on
# 5) Creates a File Screen Template utilising this File Group, with an Event notification and Command notification
# to run the scripts created in Step 3)
# 6) Creates File Screens utilising this template for each drive containing network shares
################################ Functions ################################
Function PurgeNonAdminDirectoryPermissions([string] $directory)
{
$acl = Get-Acl $directory
if ($acl.AreAccessRulesProtected)
{
$acl.Access | % { $acl.PurgeAccessRules($_.IdentityReference) }
}
else
{
$acl.SetAccessRuleProtection($true, $true)
}
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","FullControl","Allow")
$acl.AddAccessRule($ar)
$ar = $ar = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","FullControl","Allow")
$acl.AddAccessRule($ar)
Set-Acl -AclObject $acl -Path $directory
}
function ConvertFrom-Json20([Object] $obj)
{
Add-Type -AssemblyName System.Web.Extensions
$serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
return ,$serializer.DeserializeObject($obj)
}
################################ Functions ################################
# Add to all drives
$drivesContainingShares = Get-WmiObject Win32_Share | Select Name,Path,Type | Where-Object { $_.Type -eq 0 } | Select -ExpandProperty Path | % { "$((Get-Item -ErrorAction SilentlyContinue $_).Root)" } | Select -Unique
if ($drivesContainingShares -eq $null -or $drivesContainingShares.Length -eq 0)
{
Write-Host "No drives containing shares were found. Exiting.."
exit
}
Write-Host "The following shares needing to be protected: $($drivesContainingShares -Join ",")"
$majorVer = [System.Environment]::OSVersion.Version.Major
$minorVer = [System.Environment]::OSVersion.Version.Minor
Write-Host "Checking File Server Resource Manager.."
Import-Module ServerManager
if ($majorVer -ge 6)
{
$checkFSRM = Get-WindowsFeature -Name FS-Resource-Manager
if ($minorVer -ge 2 -and $checkFSRM.Installed -ne "True")
{
# Server 2012
Write-Host "FSRM not found.. Installing (2012).."
Install-WindowsFeature -Name FS-Resource-Manager -IncludeManagementTools
}
elseif ($minorVer -ge 1 -and $checkFSRM.Installed -ne "True")
{
# Server 2008 R2
Write-Host "FSRM not found.. Installing (2008 R2).."
Add-WindowsFeature FS-FileServer, FS-Resource-Manager
}
elseif ($checkFSRM.Installed -ne "True")
{
# Server 2008
Write-Host "FSRM not found.. Installing (2008).."
&servermanagercmd -Install FS-FileServer FS-Resource-Manager
}
}
else
{
# Assume Server 2003
Write-Host "Other version of Windows detected! Quitting.."
return
}
$fileGroupName = "CryptoBlockerGroup"
$fileTemplateName = "CryptoBlockerTemplate"
$fileScreenName = "CryptoBlockerScreen"
$webClient = New-Object System.Net.WebClient
$jsonStr = $webClient.DownloadString("https://fsrm.experiant.ca/api/v1/get")
$monitoredExtensions = @(ConvertFrom-Json20($jsonStr) | % { $_.filters })
$scriptFilename = "C:\FSRMScripts\KillUserSession.ps1"
$batchFilename = "C:\FSRMScripts\KillUserSession.bat"
$eventConfFilename = "$env:Temp\cryptoblocker-eventnotify.txt"
$cmdConfFilename = "$env:Temp\cryptoblocker-cmdnotify.txt"
$exclusions = @(`
$MyInvocation.MyCommand.Name,
$($MyInvocation.MyCommand.Name + ".*"),
"cryptoblocker-eventnotify.txt",`
"cryptoblocker-cmdnotify.txt"`
)
$excludedPaths = @(`
"C:\Windows",`
"C:\ProgramData\Kaspersky Lab"`
)
$scriptConf = @'
param([string] $DomainUser)
Function DenySharePermission ([string] $ShareName, [string] $DomainUser)
{
$domainUserSplit = $DomainUser.Split("\")
$trusteeClass = [wmiclass] "ROOT\CIMV2:Win32_Trustee"
$trustee = $trusteeClass.CreateInstance()
$trustee.Domain = $domainUserSplit[0]
$trustee.Name = $domainUserSplit[1]
$aceClass = [wmiclass] "ROOT\CIMV2:Win32_ACE"
$ace = $aceClass.CreateInstance()
$ace.AccessMask = 2032127
$ace.AceType = 1
$ace.Trustee = $trustee
$shss = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -Filter "Name='$ShareName'"
$sd = Invoke-WmiMethod -InputObject $shss -Name GetSecurityDescriptor | Select -ExpandProperty Descriptor
$sclass = [wmiclass] "ROOT\CIMV2:Win32_SecurityDescriptor"
$newsd = $sclass.CreateInstance()
$newsd.ControlFlags = $sd.ControlFlags
foreach ($oace in $sd.DACL)
{
$newsd.DACL += [System.Management.ManagementBaseObject] $oace
}
$newsd.DACL += [System.Management.ManagementBaseObject] $ace
$share = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -Filter "Name='$ShareName'"
$setResult = $share.SetSecurityDescriptor($newsd)
return $setResult.ReturnValue
}
# Let's try altering share permissions..
$Username = $DomainUser.Split("\")[1]
$affectedShares = Get-WmiObject -Class Win32_Share |
Select Name, Path, Type |
Where { $_.Type -eq 0 }
$affectedShares | % {
Write-Host "Denying [$DomainUser] access to share [$($_.Name)].."
DenySharePermission -ShareName $_.Name -DomainUser $DomainUser
}
Write-Host $affectedShares
'@
$batchConf = @"
@echo off
powershell.exe -ExecutionPolicy Bypass -File "$scriptFilename" -DomainUser %1
"@
$scriptDirectory = Split-Path -Parent $scriptFilename
$batchDirectory = Split-Path -Parent $batchFilename
if (-not (Test-Path $scriptDirectory))
{
Write-Host "Script directory [$scriptDirectory] not found. Creating.."
New-Item -Path $scriptDirectory -ItemType Directory
}
if (-not (Test-Path $batchDirectory))
{
Write-Host "Batch directory [$batchDirectory] not found. Creating.."
New-Item -Path $batchDirectory -ItemType Directory
}
# FSRM stipulates that the command directories/files can only be accessible by SYSTEM or Administrators
# As a result, we lock down permissions for SYSTEM and local admin only
Write-Host "Purging Non-Admin NTFS permissions on script directory [$scriptDirectory].."
PurgeNonAdminDirectoryPermissions($scriptDirectory)
Write-Host "Purging Non-Admin NTFS permissions on batch directory [$batchDirectory].."
PurgeNonAdminDirectoryPermissions($batchDirectory)
Write-Host "Writing defensive PowerShell script to location [$scriptFilename].."
$scriptConf | Out-File -Encoding ASCII $scriptFilename
Write-Host "Writing batch script launcher to location [$batchFilename].."
$batchConf | Out-File -Encoding ASCII $batchFilename
$eventConf = @"
Notification=E
RunLimitInterval=0
EventType=Warning
Message=User [Source Io Owner] attempted to save [Source File Path] to [File Screen Path] on the [Server] server. This file is in the [Violated File Group] file group, which is not permitted on the server. An attempt has been made at blocking this user.
"@
$cmdConf = @"
Notification=C
RunLimitInterval=0
Command=$batchFilename
Arguments=[Source Io Owner]
MonitorCommand=Enable
Account=LocalSystem
"@
Write-Host "Writing temporary FSRM Event Viewer configuration to location [$eventConfFilename].."
$eventConf | Out-File $eventConfFilename
Write-Host "Writing temporary FSRM Command configuration to location [$cmdConfFilename].."
$cmdConf | Out-File $cmdConfFilename
Write-Host "Adding/replacing File Group [$fileGroupName] with monitored file [$($monitoredExtensions -Join ",")].."
&filescrn.exe filegroup Delete /Filegroup:$fileGroupName /Quiet
&filescrn.exe Filegroup Add "/Filegroup:$fileGroupName" "/Members:$($monitoredExtensions -Join "|")"
&filescrn.exe Filegroup Modify "/Filegroup:$fileGroupName" "/Nonmembers:$($exclusions -Join "|")"
Write-Host "Adding/replacing File Screen Template [$fileTemplateName] with Event Notification [$eventConfFilename] and Command Notification [$cmdConfFilename].."
&filescrn.exe Template Delete /Template:$fileTemplateName /Quiet
&filescrn.exe Template Add "/Template:$fileTemplateName" "/Add-Filegroup:$fileGroupName" "/Add-Notification:E,$eventConfFilename" "/Add-Notification:C,$cmdConfFilename" /Type:Passive
Write-Host "Adding/replacing File Screens.."
$drivesContainingShares | % {
Write-Host "`tAdding/replacing File Screen for [$_] with Source Template [$fileTemplateName].."
&filescrn.exe Screen Delete "/Path:$_" /Quiet
&filescrn.exe Screen Add "/Path:$_" "/SourceTemplate:$fileTemplateName"
}
Write-Host "Adding/replacing File Screen Exceptions..."
$excludedPaths | % {
&filescrn.exe Exception Delete /Path:"$_" /Quiet
&filescrn.exe Exception Add /Path:"$_" /Add-Filegroup:$fileGroupName
}
Write-Host "Removing temporary FSRM Event Viewer configuration file [$eventConfFilename].."
Write-Host "Removing temporary FSRM Event Viewer configuration file [$cmdConfFilename].."
Remove-Item $eventConfFilename
Remove-Item $cmdConfFilename