Through my work at Zerto I’ve delivered multiple presentations and webinars on ransomware and how Zerto enables you to recover VMs, files and folders from seconds before the data was encrypted to minimize data loss and avoid having to pay a ransom. One question I’ve often been asked is how do I know what point in time my files were encrypted? And in one recent presentation a customer told me that their user didn’t tell IT until 3 days after the infection had occurred!
This got me thinking on how we could alert on this which led me to evaluate the different ransomware honeypot example scripts available online. These scripts validate a file placed on a user mapped share, where everyone has write permissions, against a gold or witness copy to catch the ransomware infection then perform a set of actions when found. In testing the multiple examples I struggled to find one that coped with the file itself being changed, I.E the extension changing, that ran consistently and none indicated this alert in the Zerto journal so I decided to write an example that did all of this and more.
This script uses the honeypot technique to detect ransomware infections by comparing 2 files, a honeypot file and a witness file. If they are different, or it has been deleted/renamed it performs the following actions:
- Gets the last modified time and file owner to aid with finding the infection source
- Sends an email alert
- Disables the file sharing service on the host which it is run to prevent further infections
- Inserts a Zerto Checkpoint to indicate the point in time using the Zerto PS CMDLets
- Stops running the script
The script should therefore be set to run on the file server it is checking and set to start on boot. It will then run forever on a loop on the TestInterval defined until an infection is detected.
All of the variables required are configured at the start of the script and it is clearly indicated at which point nothing needs to be configured, but everything is commented if you want to edit any setting. It is also possible to remove the Zerto CMDlets if you don’t want Zerto integration.
You can create your own files for comparison, of which the Honeypot file should be placed on a file share mapped to all user PCs with the first available drive letter and edit permissions to all users to catch the infection. I also recommend training users so they know not to touch it as they could cause an alert by editing it out of curiosity. The witness file should be on a non-shared folder with no edit permissions so it cannot be infected thereby breaking the validation.
The script has been tested as working against the following scenarios:
- Honeypot file edited/changed = ransomware alert actions performed
- Honeypot file deleted = ransomware alert actions performed
- Honeypot file renamed = ransomware alert actions performed
- No changes = nothing happens; it keeps running on a loop
I recommend running the script in PowerShell ISE for the first time for a visual output and please note that when specifying the VPG on which to add the checkpoint the VPG name is case sensitive. You can copy and paste the script from the below:
######################################################################################################################## # Start of the script - Description, Requirements & Legal Disclaimer ######################################################################################################################## # Written by: Joshua Stenhouse joshuastenhouse@gmail.com ################################################ # Description: # This script uses a honeypot technique to detect ransomware infections by comparing 2 files, a honeypot file and a witness file. # If they are different, or it has been deleted/renamed it sends an email alert, disables the file sharing service on the host which it is run and inserts a Zerto Checkpoint to indicate the point in time. # The script should be set to run on the file server it is checking, and set to start on boot. It will then run forever on a loop on the TestInterval defined. # The script supports detection of ransomware that changes the file data as well as changing the file extension ################################################ # Requirements: # - ZVM ServerName, Username and password with permission to access PowerShell of the ZVM # - Zerto PowerShell CMDlets # - Access to Port 9080 of the ZVM # - 2 identical .docx files # - 1 placed in a fileshare mapped to all users PCs, preferably the first drive letter available to increase likelihood with write permission for all users # - 1 placed in a non-shared folder with no edit permissions as a witness to check against so it cannot also be encrypted # - Configure the SMTP email settings # - Uncomment "LoadSnapin -PSSnapinName "Zerto.PS.Commands" and "Set-Checkpoint -ZVMIP $ZVMIP" lines if you don't want Zerto integration ################################################ # Legal Disclaimer: # This script is written by Joshua Stenhouse is not supported under any Zerto support program or service. # All scripts are provided AS IS without warranty of any kind. # The author and Zerto further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. # The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. # In no event shall Zerto, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if the author or Zerto has been advised of the possibility of such damages. ################################################ # Configure the variables below ################################################ # Step 1. Specify the HoneyPot and Witness File & Folder locations along with the testing interval (in seconds) $HoneypotDir = "C:\Honeypot" $HoneypotFile = "HoneypotFile.docx" $HoneypotWitenessDir = "C:\HoneypotWitness" $TestInterval = "30" # Step 2. Configure the name of the VPG in which the FileServer exists and customize the tag to insert # Warning - the VPG name is CASE sensitive when using the ZVR PS CMDlets $VPGName = "FileServers" $ZVMCPTag = "Potential Ransomware Infection Found" # Step 3. Configure the IP address of the ZVM and the PowerShell login credentials (edit the users.txt file in ZVM Program Files, restart ZVM service) $ZVMIP = "192.168.0.31" $ZVMPSPort = "9080" $ZMVPSUser = "administrator" $ZVMPSPasswd = "password" # Step 4. Specify the SMTP Email Settings $EmailTo = "joshua@lab.local" $EmailFrom = "admin@lab.local" $SMTPServer = "192.168.1.151" $SMTPPort = "25" $SMTPUser = "admin@lab.local" $SMTPPassword = "password" $SMTPSSLEnabled = "FALSE" ######################################################################################################################## # Nothing to configure below this line - Starting the main function of the script ######################################################################################################################## ################################################ # Honeypot File and Email Settings ################################################ # Setting the HoneyPot file to be the witness $HoneypotWitnessFile = $HoneypotFile # Building SMTP settings based on the settings $emailsetting = New-Object System.Net.Mail.MailMessage $Emailsetting.to.add($EmailTo) $Emailsetting.from = $EmailFrom $Emailsetting.IsBodyHTML = "TRUE" # Creating SMTP object $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort); # Enabling SSL if set if ($SMTPSSLEnabled -eq "TRUE") { $smtp.EnableSSL = "TRUE" } # Setting credentials $smtp.Credentials = New-Object System.Net.NetworkCredential($SMTPUser, $SMTPPassword); ################################################ # Loading the Zerto PS CMdlets ################################################ function LoadSnapin{ param($PSSnapinName) if (!(Get-PSSnapin | where {$_.Name -eq $PSSnapinName})){ Add-pssnapin -name $PSSnapinName } } LoadSnapin -PSSnapinName "Zerto.PS.Commands" ################################################################################################ # Starting Continuous Loop of Ransomware Check ################################################################################################ Do { # Testing to see if file exists first, the extension may of changed or it may have been deleted $TestHoneypotPath = test-path "$HoneypotDir\$HoneypotFile" ################################################ # If the Honeypot file doesn't exist it may have been renamed indicating a potential infection, running ################################################ if ($TestHoneypotPath -eq $False) { # File not found or renamed from original file $HoneyPotFileFound = Get-ChildItem $HoneypotDir | Sort {$_.LastWriteTime} | select Name -expandproperty Name -last 1 $HoneyPotFileLastWriteTime = Get-ChildItem "$HoneypotDir\$HoneyPotFileFound" | select lastwritetime $HoneyPotFileOwner = get-acl "$HoneypotDir\$HoneyPotFileFound" | select owner # Configuring email settings $EmailSubject = "Potential Ransomware Infection Found" $EmailBody = "Honeypot file $HoneypotDir\$HoneypotFile on $env:computername has been deleted or file extension changed. Found $HoneyPotFileFound instead, modified by $HoneyPotFileOwner @ $HoneyPotFileLastWriteTime indicating a possbile ransomware infection." # Outputting to screen write-host $EmailBody # Stopping loop of script $StopScript ="Y" # Disabling File share service Stop-Service "LanmanServer" -force –PassThru # Inserting a Zerto checkpoint Try { Set-Checkpoint -ZVMIP $ZVMIP -ZVMPORT $ZVMPSPort -Username $ZMVPSUser -password $ZVMPSPasswd -VirtualProtectionGroup $VPGName -Wait 300 -confirm:$false -Tag $ZVMCPTag } Catch [system.exception] { } Finally { } # Building email Subject & Body $Emailsetting.subject = $EmailSubject $Emailsetting.body = $EmailBody # Sending Email Try { $smtp.send($Emailsetting) } Catch [system.exception] { # Trying to send email again if first attempt fails sleep 20 $smtp.send($Emailsetting) } Finally { } # Finished sending email } ################################################ # If the Honeypot file does exist running a comparison of the HoneyPot and witness files ################################################ if ($TestHoneypotPath -eq $True) { # File found so comparing files try { # If file is currently being encrypted the get-content can fail, so adding try command with a wait $ReadHoneypotFile = Get-Content "$HoneypotDir\$HoneypotFile" } catch { sleep 60 $ReadHoneypotFile = Get-Content "$HoneypotDir\$HoneypotFile" } # Reading witness file $ReadHoneypotWitenessFile = Get-Content "$HoneypotWitenessDir\$HoneypotWitnessFile" # Comparing files to check for modifications if (Compare-Object $ReadHoneypotFile $ReadHoneypotWitenessFile) { $HoneypotFileMatch = "FALSE" } else { $HoneypotFileMatch = "TRUE" } ################################################ # If the Honeypot and witness files do not match ################################################ if ($HoneypotFileMatch -eq "FALSE") { $HoneyPotFileLastWriteTime = Get-ChildItem "$HoneypotDir\$HoneypotFile" | select lastwritetime $HoneyPotFileOwner = get-acl "$HoneypotDir\$HoneypotFile" | select owner # Configuring email settings $EmailSubject = "Potential Ransomware Infection Found" $EmailBody = "Honeypot file $HoneypotDir\$HoneypotFile on $env:computername has been modified by $HoneyPotFileOwner @ $HoneyPotFileLastWriteTime. Indicative of a potential ransomware infection." # Outputting to screen write-host $EmailBody # Stopping loop of script $StopScript ="Y" # Disabling File share service Stop-Service "LanmanServer" -force –PassThru # Inserting a Zerto checkpoint Try { Set-Checkpoint -ZVMIP $ZVMIP -ZVMPORT $ZVMPSPort -Username $ZMVPSUser -password $ZVMPSPasswd -VirtualProtectionGroup $VPGName -Wait 300 -confirm:$false -Tag $ZVMCPTag } Catch [system.exception] { } Finally { } # Sending email Try { $smtp.send($Emailsetting) } Catch [system.exception] { # Trying to send email again if first attempt fails sleep 20 $smtp.send($Emailsetting) } Finally { } # Finished sending email } ################################################ # If the Honeypot and witness files MATCH then no ransomware infection detected and script loops to the start where it sleeps for the $TestInterval ################################################ # if the files were found and do match if ($HoneypotFileMatch -eq "TRUE") { # Files do match, repeating test in $Message = "No infection detected, repeating in $testinterval seconds" write-host $Message $StopScript = "N" } # End of Honeypot File does exist below } # End of Honeypot File does exist above sleep $TestInterval # } # End of Do Loop Until ($StopScript -eq "Y")
Or download an example from this link:
I’ve heard some of my European blogger friends are working on way more advanced examples than the one provided here, which I will reference when I hear more on this. Happy scripting!
Joshua