From 25934d4719faabfb2d94645e1ed2cd5738ead2d7 Mon Sep 17 00:00:00 2001 From: Jared Atkinson Date: Wed, 8 Jul 2015 16:57:31 -0400 Subject: Added New-VolumeShadowCopy and Remove-VolumeShadowCopy Cmdlets --- Exfiltration/VolumeShadowCopyTools.ps1 | 169 ++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/Exfiltration/VolumeShadowCopyTools.ps1 b/Exfiltration/VolumeShadowCopyTools.ps1 index e8c28a1..6d47c34 100644 --- a/Exfiltration/VolumeShadowCopyTools.ps1 +++ b/Exfiltration/VolumeShadowCopyTools.ps1 @@ -20,7 +20,174 @@ Throw 'You must run Get-VolumeShadowCopy from an elevated command prompt.' } - Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_.DeviceObject } + Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy | ForEach-Object { $_.DeviceObject } +} + +function New-VolumeShadowCopy +{ +<# +.SYNOPSIS + + Creates a new volume shadow copy. + + PowerSploit Function: New-VolumeShadowCopy + Author: Jared Atkinson (@jaredcatkinson) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + Version: 2.0.0 + +.DESCRIPTION + + New-VolumeShadowCopy creates a volume shadow copy for the specified volume. + +.PARAMETER Volume + + Volume used for the shadow copy. This volume is sometimes referred to as the original volume. + The Volume parameter can be specified as a volume drive letter, mount point, or volume globally unique identifier (GUID) name. + +.PARAMETER Context + + Context that the provider uses when creating the shadow. The default is "ClientAccessible". + +.EXAMPLE + + New-VolumeShadowCopy -Volume C:\ + + Description + ----------- + Creates a new VolumeShadowCopy of the C drive +#> + Param( + [Parameter(Mandatory = $True)] + [ValidatePattern('^\w:\\')] + [String] + $Volume, + + [Parameter(Mandatory = $False)] + [ValidateSet("ClientAccessible")] + [String] + $Context = "ClientAccessible" + ) + + $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.' + } + + $class = [WMICLASS]"root\cimv2:win32_shadowcopy" + + $return = $class.create("$Volume", "$Context") + + switch($return.returnvalue) + { + 1 {Write-Error "Access denied."; break} + 2 {Write-Error "Invalid argument."; break} + 3 {Write-Error "Specified volume not found."; break} + 4 {Write-Error "Specified volume not supported."; break} + 5 {Write-Error "Unsupported shadow copy context."; break} + 6 {Write-Error "Insufficient storage."; break} + 7 {Write-Error "Volume is in use."; break} + 8 {Write-Error "Maximum number of shadow copies reached."; break} + 9 {Write-Error "Another shadow copy operation is already in progress."; break} + 10 {Write-Error "Shadow copy provider vetoed the operation."; break} + 11 {Write-Error "Shadow copy provider not registered."; break} + 12 {Write-Error "Shadow copy provider failure."; break} + 13 {Write-Error "Unknown error."; break} + default {break} + } +} + +function Remove-VolumeShadowCopy +{ +<# +.SYNOPSIS + + Deletes a volume shadow copy. + + PowerSploit Function: Remove-VolumeShadowCopy + Author: Jared Atkinson (@jaredcatkinson) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + Version: 2.0.0 + +.DESCRIPTION + + Remove-VolumeShadowCopy deletes a volume shadow copy from the system. + +.PARAMETER InputObject + + Specifies the Win32_ShadowCopy object to remove + +.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 | Remove-VolumeShadowCopy + + Description + ----------- + Removes all volume shadow copy + +.EXAMPLE + + Get-WmiObject Win32_ShadowCopy | Remove-VolumeShadowCopy + + Description + ----------- + Removes all volume shadow copy + +.EXAMPLE + + Remove-VolumeShadowCopy -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4' + + Description + ----------- + Removes the volume shadow copy at the 'DeviceObject' path \\?\GLOBALROOT\DeviceHarddiskVolumeShadowCopy4 +#> + Param( + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [ValidateNotNullOrEmpty()] + [Object] + $InputObject, + + [Parameter(Mandatory = $False)] + [ValidatePattern('^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$')] + [String] + $DevicePath + ) + + PROCESS + { + if($PSBoundParameters.ContainsKey("InputObject")) + { + if($InputObject.GetType().Name -eq "String") + { + (Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy | Where-Object {$_.DeviceObject -eq $InputObject}).Delete() + } + else + { + $InputObject.Delete() + } + } + elseif($PSBoundParameters.ContainsKey("DevicePath")) + { + (Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy | Where-Object {$_.DeviceObject -eq $DevicePath}).Delete() + } + else + { + $vsc = Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy + foreach($copy in $vsc) + { + $copy.Delete() + } + } + } } function Mount-VolumeShadowCopy -- cgit v1.2.3 From c29f9b4743b5451e12d270da45072e72d1a480af Mon Sep 17 00:00:00 2001 From: Jared Atkinson Date: Wed, 8 Jul 2015 22:27:12 -0400 Subject: Cleaned up Remove-VSC and New-VSC - Changed Remove-VSC to have a single mandatory parameter (DevicePath) - Updated New-VSC to check initial state of the VSS Service and return VSS to its inital state after execution --- Exfiltration/VolumeShadowCopyTools.ps1 | 46 +++++++++------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/Exfiltration/VolumeShadowCopyTools.ps1 b/Exfiltration/VolumeShadowCopyTools.ps1 index 6d47c34..49fe22d 100644 --- a/Exfiltration/VolumeShadowCopyTools.ps1 +++ b/Exfiltration/VolumeShadowCopyTools.ps1 @@ -77,6 +77,9 @@ function New-VolumeShadowCopy Throw 'You must run Get-VolumeShadowCopy from an elevated command prompt.' } + # Save VSS Service initial state + $running = (Get-Service -Name VSS).Status + $class = [WMICLASS]"root\cimv2:win32_shadowcopy" $return = $class.create("$Volume", "$Context") @@ -98,6 +101,12 @@ function New-VolumeShadowCopy 13 {Write-Error "Unknown error."; break} default {break} } + + # If VSS Service was Stopped at the start, return VSS to "Stopped" state + if($running -eq "Stopped") + { + Stop-Service -Name VSS + } } function Remove-VolumeShadowCopy @@ -134,14 +143,6 @@ function Remove-VolumeShadowCopy ----------- Removes all volume shadow copy -.EXAMPLE - - Get-WmiObject Win32_ShadowCopy | Remove-VolumeShadowCopy - - Description - ----------- - Removes all volume shadow copy - .EXAMPLE Remove-VolumeShadowCopy -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4' @@ -150,13 +151,9 @@ function Remove-VolumeShadowCopy ----------- Removes the volume shadow copy at the 'DeviceObject' path \\?\GLOBALROOT\DeviceHarddiskVolumeShadowCopy4 #> + [CmdletBinding(SupportsShouldProcess = $True)] Param( - [Parameter(Mandatory = $False, ValueFromPipeline = $True)] - [ValidateNotNullOrEmpty()] - [Object] - $InputObject, - - [Parameter(Mandatory = $False)] + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [ValidatePattern('^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$')] [String] $DevicePath @@ -164,29 +161,10 @@ function Remove-VolumeShadowCopy PROCESS { - if($PSBoundParameters.ContainsKey("InputObject")) - { - if($InputObject.GetType().Name -eq "String") - { - (Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy | Where-Object {$_.DeviceObject -eq $InputObject}).Delete() - } - else - { - $InputObject.Delete() - } - } - elseif($PSBoundParameters.ContainsKey("DevicePath")) + if($PSCmdlet.ShouldProcess("The VolumeShadowCopy at DevicePath $DevicePath will be removed")) { (Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy | Where-Object {$_.DeviceObject -eq $DevicePath}).Delete() } - else - { - $vsc = Get-WmiObject -Namespace root\cimv2 -Class Win32_ShadowCopy - foreach($copy in $vsc) - { - $copy.Delete() - } - } } } -- cgit v1.2.3