Press "Enter" to skip to content

Automatically detecting Ransomware infections with PowerShell

Joshua Stenhouse 0

Back in July 2016, I posted a script which used PowerShell to send an email alert upon detecting a Ransomware infection by continuously comparing a purposefully vulnerable word doc for changes, deletion etc. The script also integrated into Zerto to insert a checkpoint, but what if you don’t have Zerto and you just want to get the email alerts? I’m presenting at Foxwoods Casino with a Rubrik partner this afternoon on Ransomware (the irony of the venue and subject not lost on me) and so I wanted to post a non-vendor integrated example as a free giveaway for everyone attending the presentation and reading the blog. This post will give you just that.

The script uses the honeypot technique to automatically detect Ransomware infections by comparing 2 files, a honeypot file, and a witness file. Yes, you can always wait for the user to tell you they have been infected, but they might not notice straight away and you’d be amazed at how long it can take for someone to tell you. It might even be too late to stop it spreading!

The honeypot file is stored on a network share with read/write access for everyone mapped to all user PCs etc. This makes it vulnerable to any Ransomware infection on the network as the client will have it mapped, writable, and will infect the honeypot file along with any other files on or mapped to their client. Thus giving you a very good chance of detecting a Ransomware infection as soon as possible so you can isolate and restore from backup (you do have a backup?!) and save the day. The witness file should be placed in a non-shared folder with read-only access to serve as an immutable copy for verification of infection.

Every 30 seconds the script checks to see if they are different, or if the honeypot file has been deleted/renamed, then it performs the following actions:

  1. Gets the last modified time and file owner to aid with finding the infection source
  2. Sends an email alert
  3. Disables the file sharing service on the host which it is run to prevent further infections
  4. Stops running the script

Set the script to run on the file server it is checking and to start on boot. It will then run forever on a loop on the TestInterval defined (in seconds) until an infection is detected. All 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.

You can create your own files for comparison, but I supply an example at the bottom of the post. To clarify; the Honeypot file should be placed on a file share mapped to all user PCs with edit permissions to all users in order to catch the infection. The witness file should be in a non-shared folder with no edit permissions so it cannot be infected. I recommend training users not to touch the honeypot file as they could cause a false positive alert by editing it out of curiosity etc.

The script has been tested as working on the following scenarios:

  1. Honeypot file edited/changed = Ransomware alert actions performed
  2. Honeypot file deleted = Ransomware alert actions performed
  3. Honeypot file renamed = Ransomware alert actions performed
  4. No changes = Nothing happens; script keeps running on a loop

I recommend running the script in PowerShell ISE for the first time for a visual output. 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.
# 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:
# - 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
################################################
# Legal Disclaimer:
# This script is written by Joshua Stenhouse is not supported under any support program or service. 
# All scripts are provided AS IS without warranty of any kind. 
# The author 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 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 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. 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);
################################################################################################
# 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
# 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
# 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")

You can download an example along with the word doc template from this link:

Detecting Ransomware Infections v1.zip

If you found this useful please like and share. Happy scripting!

Joshua

Leave a Reply

%d bloggers like this: