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
|
function Get-VolumeShadowCopy
{
<#
.SYNOPSIS
Lists the device paths of all local volume shadow copies.
PowerSploit Function: Get-VolumeShadowCopy
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
Version: 2.0.0
#>
$UserIdentity = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $UserIdentity.IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator'))
{
Throw 'You must run Get-VolumeShadowCopy from an elevated command prompt.'
}
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_.DeviceObject }
}
function Mount-VolumeShadowCopy
{
<#
.SYNOPSIS
Mounts a volume shadow copy.
PowerSploit Function: Mount-VolumeShadowCopy
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
Version: 2.0.0
.DESCRIPTION
Mount-VolumeShadowCopy mounts a volume shadow copy volume by creating a symbolic link.
.PARAMETER Path
Specifies the path to which the symbolic link for the mounted volume shadow copy will be saved.
.PARAMETER DevicePath
Specifies the volume shadow copy 'DeviceObject' path. This path can be retrieved with the Get-VolumeShadowCopy PowerSploit function or with the Win32_ShadowCopy object.
.EXAMPLE
Get-VolumeShadowCopy | Mount-VolumeShadowCopy -Path C:\VSS
Description
-----------
Create a mount point in 'C:\VSS' for each volume shadow copy volume
.EXAMPLE
Mount-VolumeShadowCopy -Path C:\VSS -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4'
.EXAMPLE
Get-WmiObject Win32_ShadowCopy | % { $_.DeviceObject -Path C:\VSS -DevicePath $_ }
#>
Param (
[Parameter(Mandatory = $True)]
[ValidateNotNullOrEmpty()]
[String]
$Path,
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[ValidatePattern('^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$')]
[String[]]
$DevicePath
)
BEGIN
{
$UserIdentity = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $UserIdentity.IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator'))
{
Throw 'You must run Get-VolumeShadowCopy from an elevated command prompt.'
}
# Validate that the path exists before proceeding
Get-ChildItem $Path -ErrorAction Stop | Out-Null
$DynAssembly = New-Object System.Reflection.AssemblyName('VSSUtil')
$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('VSSUtil', $False)
# Define [VSS.Kernel32]::CreateSymbolicLink method using reflection
# (i.e. none of the forensic artifacts left with using Add-Type)
$TypeBuilder = $ModuleBuilder.DefineType('VSS.Kernel32', 'Public, Class')
$PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CreateSymbolicLink',
'kernel32.dll',
([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),
[Reflection.CallingConventions]::Standard,
[Bool],
[Type[]]@([String], [String], [UInt32]),
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto)
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
$SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
$SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,
@('kernel32.dll'),
[Reflection.FieldInfo[]]@($SetLastError),
@($true))
$PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)
$Kernel32Type = $TypeBuilder.CreateType()
}
PROCESS
{
foreach ($Volume in $DevicePath)
{
$Volume -match '^\\\\\?\\GLOBALROOT\\Device\\(?<LinkName>HarddiskVolumeShadowCopy[0-9]{1,3})$' | Out-Null
$LinkPath = Join-Path $Path $Matches.LinkName
if (Test-Path $LinkPath)
{
Write-Warning "'$LinkPath' already exists."
continue
}
if (-not $Kernel32Type::CreateSymbolicLink($LinkPath, "$($Volume)\", 1))
{
Write-Error "Symbolic link creation failed for '$Volume'."
continue
}
Get-Item $LinkPath
}
}
END
{
}
}
|