Restore malware-encrypted files from VSS snapshots

There have sadly been a few cases recently where a user has unwittingly run CryptoWall (or CryptoLocker, TeslaCrypt) on their PC and then encrypted a big chunk of one of my shared network drives. A nice quick way to get the files back is by using the VSS shadow copies of the volume.

This won’t usually work locally on your own PC as one of the things these crypto malwares tend to do is remove all shadow copies, but if your data is on a separate file server they can’t usually remove the shadow copies from that.

The first part is manual, PowerShell doesn’t have any VSS integration still as far as I can tell, and it’s not worth the hassle parsing the output of vssadmin – it’s much easier to do this bit by hand.

I suggest you do all this remotely via PowerShell remoting. As such I’ll be prefixing some of the commands with cmd /c as they only exist in that environment (or PowerShell’s default aliases make them do different things to how they work in the regular command prompt).

Steps to recovery

  1. Enter-PSSession -ComputerName FS01 -Credential (Get-Credential -UserName campus\rc-admin -Message “Gimme”)
    You may not need the -Credential bit, just depends if you’re running PowerShell as a user that has admin rights on the file server or not.
    Your PowerShell prompt prefix should change to show that you’re operating on a remote machine:
    [fs01]:
  2. vssadmin list shadows
    This will give you a list of all the shadow copies. You probably want the most recently created one before your files got encrypted. You’re looking for the “creation time” in the second line of each batch of text, the drive letter the shadow copy is for is shown in brackets in the “Original Volume” line, and then you need to make a note of the “Shadow Copy Volume” line as you need it in the next step but one.
    e.g.:
    Contents of shadow copy set ID: {a8c93c0b-a6c8-4ad9-ab3c-699b36f69915}
    Contained 1 shadow copies at creation time: 26/01/2016 07:00:16
    Shadow Copy ID: {8bc3ce53-831f-41e6-ad75-68384cb74bfb}
    Original Volume: (D:)\\?\Volume{0dac1ea6-f36f-4240-b4c6-a3e8f579ef44}\
    Shadow Copy Volume: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy67
    Originating Machine: FS01.rcmtech.co.uk
    Service Machine: FS01.rcmtech.co.uk
    Provider: ‘Microsoft Software Shadow Copy provider 1.0’
    Type: ClientAccessible
    Attributes: Persistent, Client-accessible, No auto release, No writers, Differential
  3. We’re going to create a symbolic link to the shadow copy, but first we’re going to create a folder to hold the link, to be tidy.
    md VSS
  4. Now create the symbolic link, note that you need to add a backslash to the end of the Shadow Copy Volume path you copied earlier:
    cmd /c mklink /d C:\VSS\67 \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy67\
    Note that with PowerShell 5.0 (half-out at the time of writing) you can now create a symbolic link using New-Item -ItemType SymbolicLink.
  5. Now you can edit the variables and then run the script below.
  6. Once you’ve finished, remove the symbolic link to the VSS shadow copy:
    cmd /c rd C:\VSS\67

PowerShell Script

The script searches the path specified for any encrypted files, these are identified by their encrypted file extension. The last lot of these I had were “.micro”. If your malware variant uses a different random file extension for each file it encrypts, you’ll have a nice coding challenge on your hands!

Once it has identified the encrypted files, it goes through each of them in turn and generates what the original filename would have been, and calculates the path to  the same file inside the volume shadow copy. It then copies the original file back, deletes the encrypted file, and once all that is done, runs through and deletes all the “how to get your files unencrypted” instruction files that the malware leaves all over the place.

Note that PowerShell cannot handle “long” filenames, over 260 characters, (why, still???). If you have any of these you might want to investigate using RoboCopy as it can deal with them, and has been able to for years (which makes the lack of support in PowerShell even more annoying).

# Before running this script:
# Use: vssadmin list shadows to find the latest unencrypted shadow copy - see the date & time they were created
# Record the Shadow Copy Volume, and use this to create a symbolic link:
# Create a folder to hold the symbolic link: md C:\VSS
# Then use: cmd /c mklink /d C:\VSS\67 \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy67\
# You need to add a trailing backslash to the Shadow Copy Volume name produced by vssadmin.
# Once done, remove the symbolic link by using: cmd /c rd C:\VSS\67

# This is the path on the file server that got encrypted:
$EncryptedPath = "D:\SharedFolder\Documents\Guidance\"
# This is the path to your shadow copy symbolic link:
$VSSPath = "C:\VSS\67\"
# File extension that the encrypted files have:
$Extension = ".micro"
# File name (minus extension) used for the "How to get your stuff unencrypted" files:
$RecoverFileFilter = "help_recover_instructions+ntl"

$FileList = Get-ChildItem -LiteralPath $EncryptedPath -Filter *$Extension -Recurse -Force
$TotalFiles = $FileList.Count
Write-Host ("Found "+$TotalFiles)
$Counter = 0
foreach($EncryptedFile in $FileList){
    $DestFileName = $EncryptedFile.FullName.Replace($Extension,"")
    $VSSFileName = $DestFileName.Replace("D:\",$VSSPath)
    try{
        # Use LiteralPath to prevent problems with paths containing special characters, e.g. square brackets
        Copy-Item -LiteralPath $VSSFileName -Destination $DestFileName -ErrorAction Stop
        Remove-Item -LiteralPath $EncryptedFile.FullName -Force
    }
    catch{
        $Error[0]
    }
    Write-Progress -Activity "Fixing" -Status $DestFileName -PercentComplete ($Counter/$TotalFiles*100)
    $Counter++
}
Write-Progress -Activity "Fixing" -Completed
Write-Host "Done recoverying files. Now cleaning up."

$RecoveryFileList = Get-ChildItem -LiteralPath $EncryptedPath -Filter *$RecoverFileFilter* -Recurse
foreach($RecoveryFile in $RecoveryFileList){
    try{
        Remove-Item -LiteralPath $RecoveryFile.FullName -force -ErrorAction Stop
    }
    catch{
        $Error[0]
    }
}

Have fun with it! ;-)

This entry was posted in PowerShell and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

5 Responses to Restore malware-encrypted files from VSS snapshots

  1. Pingback: Using the Windows Volume Shadow Copy Service (VSS) | Robin CM's IT Blog

  2. mart says:

    i keep getting a error that the file cannot be found ? copy-item cannot find path . but if i go to the symbolic link i can see the file. what am i doing wrong ? ( at line 6 char 9)

    • rcmtech says:

      Copy-Item is on line 27, so if you’re getting that error being reported from line 6 you’re not using my script!

      Stick in a Write-Host with the variable name just prior to the line that’s giving the error and see what gets printed to screen. That should help you start to work out where things are going wrong.

  3. Mike says:

    Thanks Man, This script just saved us hours of work. A+

  4. Arjan says:

    Totaly awesome.
    I have improved it a bit: the selection and mklink of the ShadowCopy is also included in my script.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s