Providing Ransomware protection on our endpoints is important as these attacks have become one of the most prevalent and damaging cyber threats faced by organizations and individuals. These types of attacks continue to rise due to the lucrative nature of ransom payments.
Ransomware attacks adopt sophisticated techniques, such as advanced encryption algorithms and social engineering tactics to evade detection and improve the success of the attack. Additionally, the emergence of Ransomware-as-a-Service (RaaS) models has lowered the barrier to entry for cybercriminals, enabling even novice attackers to launch ransomware attacks.
By integrating VirusTotal with Wazuh, we can detect malware upon being written to disk and remove them using Wazuh Active Response before they are executed. Where ransomware is not detected by VirusTotal, we use custom rules to detect certain activities associated with ransomware during its execution.
To provide protection, we leverage the Wazuh command module and the built-in Volume Shadow Copy Service (VSS) on Windows to periodically run commands that take snapshots of the monitored endpoint. These snapshots are used to recover files to a state before they are encrypted by malware. The command also disables VSS after every operation to protect the snapshots from deletion by ransomware.
Requirements
We use the following infrastructure:
- Wazuh 4.9.0 central components (Wazuh server, Wazuh indexer, Wazuh dashboard) are installed using the quickstart guide on an Ubuntu 22.04 server.
- A Windows 11 endpoint with Wazuh agent 4.9.0 installed and enrolled to the Wazuh server.
Ransomware pre-execution detection and response
Wazuh detects ransomware upon being written to disk, through its integration with VirusTotal. In this section, we configure the Wazuh File Integrity Monitoring (FIM) module on the monitored Windows endpoint to alert when files are added or modified in the monitored directory. Modified or added files are then scanned with VirusTotal to identify malware. When malware is detected, Wazuh removes the malicious file before it executes using a Wazuh Active Response script.
Windows endpoint
On the Windows endpoint, we configure the Wazuh FIM module and a Wazuh Active Response script that removes malicious files.
File integrity monitoring configuration
Perform the following steps to configure the Wazuh FIM module to monitor near real-time changes in the folders.
1. Add the below entry within the <syscheck>
block to monitor the Downloads
, Documents
, and Desktop
folders of all users for changes:
<directories realtime="yes">C:\Users\*\Downloads</directories> <directories realtime="yes">C:\Users\*\Documents</directories> <directories realtime="yes">C:\Users\*\Desktop</directories>
Malware removal Wazuh Active Response script
Perform the following steps to create a Wazuh Active Response script that removes files detected as malicious by VirusTotal.
1. Download the Python installer from the official Python website.
2. Run the Python installer once downloaded, and make sure to check the following boxes:
Install launcher for all users
Add python.exe to PATH
. This places the Python interpreter in the execution path.
3. Create a Wazuh Active Response script remove-threat.py
in the C:\Program Files (x86)\ossec-agent\active-response\bin\
directory. This script removes any file detected as malicious by the VirusTotal integration:
#!/usr/bin/python3 # Copyright (C) 2015-2022, Wazuh Inc. # All rights reserved. import os import sys import json import datetime if os.name == 'nt': LOG_FILE = "C:\\Program Files (x86)\\ossec-agent\\active-response\\active-responses.log" else: LOG_FILE = "/var/ossec/logs/active-responses.log" ADD_COMMAND = 0 DELETE_COMMAND = 1 CONTINUE_COMMAND = 2 ABORT_COMMAND = 3 OS_SUCCESS = 0 OS_INVALID = -1 class message: def __init__(self): self.alert = "" self.command = 0 def write_debug_file(ar_name, msg): with open(LOG_FILE, mode="a") as log_file: log_file.write(str(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')) + " " + ar_name + ": " + msg +"\n") def setup_and_check_message(argv): # get alert from stdin input_str = "" for line in sys.stdin: input_str = line break try: data = json.loads(input_str) except ValueError: write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format') message.command = OS_INVALID return message message.alert = data command = data.get("command") if command == "add": message.command = ADD_COMMAND elif command == "delete": message.command = DELETE_COMMAND else: message.command = OS_INVALID write_debug_file(argv[0], 'Not valid command: ' + command) return message def send_keys_and_check_message(argv, keys): # build and send message with keys keys_msg = json.dumps({"version": 1,"origin":{"name": argv[0],"module":"active-response"},"command":"check_keys","parameters":{"keys":keys}}) write_debug_file(argv[0], keys_msg) print(keys_msg) sys.stdout.flush() # read the response of previous message input_str = "" while True: line = sys.stdin.readline() if line: input_str = line break # write_debug_file(argv[0], input_str) try: data = json.loads(input_str) except ValueError: write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format') return message action = data.get("command") if "continue" == action: ret = CONTINUE_COMMAND elif "abort" == action: ret = ABORT_COMMAND else: ret = OS_INVALID write_debug_file(argv[0], "Invalid value of 'command'") return ret def main(argv): write_debug_file(argv[0], "Started") # validate json and get command msg = setup_and_check_message(argv) if msg.command < 0: sys.exit(OS_INVALID) if msg.command == ADD_COMMAND: alert = msg.alert["parameters"]["alert"] keys = [alert["rule"]["id"]] action = send_keys_and_check_message(argv, keys) # if necessary, abort execution if action != CONTINUE_COMMAND: if action == ABORT_COMMAND: write_debug_file(argv[0], "Aborted") sys.exit(OS_SUCCESS) else: write_debug_file(argv[0], "Invalid command") sys.exit(OS_INVALID) try: file_path = msg.alert["parameters"]["alert"]["data"]["virustotal"]["source"]["file"] if os.path.exists(file_path): os.remove(file_path) write_debug_file(argv[0], json.dumps(msg.alert) + " Successfully removed threat") except OSError as error: write_debug_file(argv[0], json.dumps(msg.alert) + "Error removing threat") else: write_debug_file(argv[0], "Invalid command") write_debug_file(argv[0], "Ended") sys.exit(OS_SUCCESS) if __name__ == "__main__": main(sys.argv)
4. Run the following commands to install pyinstaller
and convert the remove-threat.py Wazuh Active Response script to a Windows executable:
> pip install pyinstaller > pyinstaller -F "C:\Program Files (x86)\ossec-agent\active-response\bin\remove-threat.py"
The second command creates a remove-threat.exe
executable in a folder called dist
in your working directory.
5. Copy the remove-threat.exe
executable file to the C:\Program Files (x86)\ossec-agent\active-response\bin\
directory.
6. Restart the Wazuh agent using PowerShell with administrative privilege to apply the configuration changes:
> Restart-Service -Name wazuh
Wazuh server
We configure the Wazuh VirusTotal integration to scan modified or added files. We also configure the Wazuh Active Response module to trigger the remove-threat.exe
executable.
Wazuh VirusTotal integration
Perform the following step on the Wazuh server to configure the VirusTotal integration.
1. Add the following configuration within the <ossec>
block of the /var/ossec/etc/ossec.conf
file to enable the VirusTotal integration. Replace <YOUR_VIRUS_TOTAL_API_KEY>
with your VirusTotal API key. This allows Wazuh to trigger a VirusTotal query on the file whenever a file addition or modification is detected:
<integration> <name>virustotal</name> <api_key><YOUR_VIRUS_TOTAL_API_KEY></api_key> <rule_id>554,550</rule_id> <alert_format>json</alert_format> </integration>
Note The free VirusTotal API rate limits requests to four per minute. If you have a premium VirusTotal API key, with a high frequency of queries allowed, you can configure Wazuh to monitor more directories besides the Downloads
, Desktop
and Documents
.
Wazuh Active Response module configuration
Perform the following steps on the Wazuh server to configure the Wazuh Active Response module.
1. Add the following configuration within the <ossec>
block of the /var/ossec/etc/ossec.conf
file to configure the Wazuh Active Response command:
<command> <name>remove-threat</name> <executable>remove-threat.exe</executable> <timeout_allowed>no</timeout_allowed> </command> <active-response> <disabled>no</disabled> <command>remove-threat</command> <location>local</location> <rules_id>87105</rules_id> </active-response>
When VirusTotal detects malware written to disk, remove-threat.exe
is triggered to remove the malware from the monitored endpoint.
Custom rules configuration
Perform the following steps to create custom rules that trigger alerts when the Wazuh Active Response script successfully or unsuccessfully removes a threat file.
1. Create a virustotal_rules.xml
rule file in the /var/ossec/etc/rules/
directory:
# touch /var/ossec/etc/rules/virustotal_rules.xml
2. Add the following custom rules to the /var/ossec/etc/rules/virustotal_rules.xml
rule file:
<group name="virustotal,"> <rule id="100092" level="12"> <if_sid>657</if_sid> <match>Successfully removed threat</match> <description>$(parameters.program) removed threat located at $(parameters.alert.data.virustotal.source.file)</description> </rule> <rule id="100093" level="12"> <if_sid>657</if_sid> <match>Error removing threat</match> <description>Error removing threat located at $(parameters.alert.data.virustotal.source.file)</description> </rule> </group>
3. Restart the Wazuh manager to apply the configuration changes:
# systemctl restart wazuh-manager
Visualizing the alerts
Rule ID 554
is triggered when Wazuh FIM module detects a newly added file to the monitored directory.
Rule ID 87105
is triggered when VirusTotal detects a malicious file. In the image below, VirusTotal detected a malicious file with ASERT ransomware.
Rule ID 100092
is triggered when the Wazuh Active Response remove-threat
script successfully removes the ransomware detected by VirusTotal.
Ransomware execution detection
Wazuh can detect some ransomware variants during its execution using custom rules. These rules monitor for common activities associated with ransomware attacks such as deleting volume shadow copies or restricting system recovery.
Windows endpoint
Perform the following steps to install and configure Sysmon. Sysmon is a Windows system service that logs detailed information on system activities like process creation, network connections, and file access for security monitoring.
Sysmon configuration
1. Run the following commands on PowerShell with admin privileges to install and configure Sysmon:
> # Set Variables > $url = "https://download.sysinternals.com/files/Sysmon.zip" > $outputPath = "C:\Temp\Sysmon.zip" > $extractPath = "C:\Temp" > $configUrl = "https://wazuh.com/resources/blog/emulation-of-attack-techniques-and-detection-with-wazuh/sysmonconfig.xml" > $configPath = "$extractPath\sysmonconfig.xml" > # Install Sysmon > New-Item -ItemType Directory -Path C:\Temp > Invoke-WebRequest -Uri $url -OutFile $outputPath > Expand-Archive -Path $outputPath -DestinationPath $extractPath > wget -Uri $configUrl -OutFile $configPath & "$extractPath\Sysmon64.exe" -accepteula -i $configPath
2. Add the following configuration within the <ossec_config>
block of the C:\Program Files (x86)\ossec-agent\ossec.conf
file to collect Sysmon logs and forward them to the Wazuh server for analysis:
<localfile> <location>Microsoft-Windows-Sysmon/Operational</location> <log_format>eventchannel</log_format> </localfile>
3. Restart the Wazuh agent using PowerShell with administrative privilege to apply the configuration changes:
> Restart-Service -Name wazuh
Wazuh server
On the Wazuh server, we configure custom rules to generate alerts when ransomware execution activities are detected.
Custom rules configuration
Perform the following steps on the Wazuh server to create custom rules.
1. Create a ransomware_rules.xml
rule file in the /var/ossec/etc/rules/
directory:
# touch /var/ossec/etc/rules/ransomware_rules.xml
2. Add the following custom rules to the /var/ossec/etc/rules/ransomware_rules.xml
rule file. These rules are made up of a group of likely ransomware actions observed on affected endpoints and are not specific to one type of malware. The rules may trigger or not trigger depending on the ransomware:
<group name="malware,ransomware,ransomware_pre_detection"> <!-- Rules to detect Ransomware attack --> <!-- Suspicious command execution --> <rule id="100600" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.parentCommandLine" type="pcre2">(?i)[c-z]:\\\\Windows\\\\System32\\\\svchost\.exe\s-k\sWerSvcGroup</field> <field name="win.eventdata.commandLine" type="pcre2">(?i)[c-z]:\\\\Windows\\\\system32\\\\WerFault\.exe\s-pss\s-s\s\d+\s-p\s\d+\s-ip\s\d+</field> <description>Possible WerFault DLL Sideloading $(win.eventdata.commandLine).</description> <mitre> <id>T1546.008</id> </mitre> </rule> <rule id="100601" level="10" > <if_sid>61603</if_sid> <field name="win.eventdata.parent.image.path" type="pcre2">(?i)regedit.exe</field> <field name="win.eventdata.commandLine" type="pcre2">(?i)schtasks.exe \/create.*\\cmd.exe.*start wordpad.exe.*.dll</field> <description>Suspicious scheduled task created.</description> <mitre> <id>T1546.008</id> </mitre> </rule> <rule id="100602" level="7"> <if_sid>92027</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">Install-WindowsFeature.*RSAT-ADPowerShell</field> <description>Remote Server Administration Tools installed.</description> <mitre> <id>T1562</id> </mitre> </rule> <!-- Impair defenses --> <rule id="100603" level="10"> <if_sid>92042</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">netsh advfirewall set currentprofile state off</field> <description>Windows firewall disabled.</description> <mitre> <id>T1562</id> </mitre> </rule> <rule id="100604" level="10"> <if_sid>61614</if_sid> <field name="win.eventdata.targetObject" type="pcre2" >HKLM\\\\System\\\\CurrentControlSet\\\\Services\\\\WinDefend</field> <field name="win.eventdata.eventType" type="pcre2">^DeleteKey$</field> <field name="win.eventdata.user" type="pcre2" >NT AUTHORITY\\\\SYSTEM</field> <description>Windows defender service $(win.eventdata.user) has been deleted on $(win.system.computer). Possible malicious activity.</description> <mitre> <id>T1562.001</id> </mitre> </rule> <rule id="100605" level="10"> <if_sid>92027,92021</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)powershell.*New-ItemProperty.*Windows Defender.*DisableAntiSpyware.*-Value 1.*</field> <description>Windows defender service has been deleted on $(win.system.computer). Possible malicious activity.</description> <mitre> <id>T1562.001</id> </mitre> </rule> <rule id="100606" level="10"> <if_sid>92008,92027</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)powershell.*Set-MpPreference.*-DisableRealTimeMonitoring.*true</field> <description>Windows defender realtime protection has been disabled on $(win.system.computer). Possible malicious activity.</description> <mitre> <id>T1562.001</id> </mitre> </rule> <rule id="100607" level="10"> <if_sid>92042</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">reg.exe .*Windows Defender\\Real-Time Protection.*Disable|\/d</field> <description>Windows defender realtime protection has been disabled on $(win.system.computer). Possible malicious activity.</description> <mitre> <id>T1562</id> </mitre> </rule> <rule id="100608" level="10"> <if_sid>92042</if_sid> <field name="win.eventdata.ruleName" type="pcre2">(?i)Disabling Security Tools</field> <field name="win.eventdata.targetObject" type="pcre2">(?i)Windows Defender</field> <description>Windows Defender feature disabled on $(win.system.computer). Possible malicious activity</description> <mitre> <id>T1562</id> </mitre> </rule> <rule id="100609" level="10"> <if_sid>92042</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">dism .* \/Disable-feature \/FeatureName:Windows-Defender</field> <description>Windows Defender disabled.</description> <mitre> <id>T1562</id> </mitre> </rule> <rule id="100610" level="10"> <field name="win.system.providerName" type="pcre2">(?i)SecurityCenter</field> <field name="win.eventdata.data" type="pcre2">(?i)Windows Defender, SECURITY_PRODUCT_STATE_SNOOZED</field> <description>Windows Defender snoozed on $(win.system.computer). Possible malicious activity</description> <mitre> <id>T1562</id> </mitre> </rule> <!-- System recovery inhibition --> <rule id="100611" level="10"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)bcdedit\s\s\/set\s{default}\sbootstatuspolicy\signoreallfailures</field> <description>Boot configuration data edited.</description> <mitre> <id>T1059</id> </mitre> </rule> <!-- Persistence detection --> <rule id="100612" level="10"> <if_sid>92300</if_sid> <field name="win.eventdata.image" type="pcre2">(?i)\.exe</field> <field name="win.eventdata.eventType" type="pcre2">(?i)SetValue</field> <field name="win.eventdata.targetObject" type="pcre2">(?i)HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\[A-Za-z0-9]+</field> <description>New run key added to registry by $(win.eventdata.image).</description> <mitre> <id>T1547.001</id> </mitre> </rule> <rule id="100613" level="10"> <if_sid>61613</if_sid> <field name="win.eventdata.image" type="pcre2">\.exe</field> <field name="win.eventdata.targetFilename" type="pcre2">(?i)ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\\\\.+\.exe</field> <description>$(win.eventdata.targetFilename) added to Startup programs by $(win.eventdata.image).</description> <mitre> <id>T1547.001</id> </mitre> </rule> <rule id="100614" level="10"> <field name="win.eventdata.ruleName" type="pcre2">(?i)Credential Dumping</field> <field name="win.eventdata.sourceImage" type="pcre2">WerFault.exe</field> <description>WerFault abused to dump credentials.</description> <mitre> <id>T1003</id> </mitre> </rule> <!-- System recovery inhibition --> <rule id="100615" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)vssadmin\s\sdelete\sshadows\s\/all\s\/quiet</field> <description>Volume shadow copy deleted using $(win.eventdata.originalFileName). Potential ransomware activity detected.</description> <mitre> <id>T1490</id> <id>T1059.003</id> </mitre> </rule> <rule id="100616" level="12"> <if_sid>92032</if_sid> <field name="win.eventdata.parentCommandLine" type="pcre2">(?i)vssadmin.*delete.*shadow</field> <description>Volume shadow copy deleted using $(win.eventdata.originalFileName). Potential ransomware activity detected.</description> <mitre> <id>T1490</id> <id>T1059.003</id> </mitre> </rule> <rule id="100617" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i).*Shadowcopy .*Delete</field> <description>Volume shadow copy deleted using $(win.eventdata.originalFileName). Potential ransomware activity detected.</description> <mitre> <id>T1490</id> <id>T1059.003</id> </mitre> </rule> <rule id="100618" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">wmic shadowcopy delete</field> <description>$(win.eventdata.originalFileName) invoked to delete shadow copies. Potential ransomware activity detected.</description> <mitre> <id>T1490</id> <id>T1059.003</id> </mitre> </rule> <rule id="100619" level="12"> <field name="win.system.providerName" type="pcre2">(?i)Microsoft-Windows-Sysmon</field> <field name="win.eventdata.CommandLine" type="pcre2">(?i)delete shadows</field> <description>Volume Shadow copy deleted on $(win.system.computer). Potential ransomware activity detected.</description> <mitre> <id>T1490</id> <id>T1059.003</id> </mitre> </rule> <rule id="100620" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)bcdedit\s\s\/set\s{default}\srecoveryenabled\sNo</field> <description>System recovery disabled. Possible ransomware activity detected.</description> <mitre> <id>T1059</id> </mitre> </rule> <rule id="100621" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)wbadmin\s\sdelete\scatalog\s-quiet</field> <description>System catalog deleted. Possible ransomware activity detected.</description> <mitre> <id>T1059</id> </mitre> </rule> <rule id="100622" level="12"> <if_sid>61603</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)bcdedit\s\s\/set\s{default}\srecoveryenabled\sNo</field> <description>System recovery disabled. Possible ransomware activity detected.</description> <mitre> <id>T1059</id> </mitre> </rule> <rule id="100623" level="12"> <if_sid>92032</if_sid> <field name="win.eventdata.CommandLine" type="pcre2">(?i)wevtutil.*cl</field> <description>Windows event logs deleted. Possible malicious activity detected.</description> <mitre> <id>T1070.001</id> </mitre> </rule> <!-- Ransom note file creation --> <rule id="100626" level="10" timeframe="50" frequency="3" ignore="300"> <if_matched_sid>554</if_matched_sid> <same_field>md5</same_field> <different_field>file</different_field> <description>The file $(file) has been created in multiple directories in a short time. Possible ransomware activity.</description> </rule> <rule id="100627" level="7" timeframe="30" frequency="10" ignore="300"> <if_matched_sid>550</if_matched_sid> <field name="file" type="pcre2">(?i)C:\\Users</field> <description>Multiple Files modified in the User directory in a short time.</description> </rule> <rule id="100629" level="7" timeframe="300" frequency="2" ignore="300"> <if_matched_sid>63104</if_matched_sid> <field name="win.system.message" type="pcre2">(?i)log file was cleared</field> <description>Windows Log File Cleared.</description> <mitre> <id>T1070.001</id> </mitre> </rule> </group> <group name="ransomware,ransomware_detection"> <rule id="100628" level="12" timeframe="300" frequency="2" ignore="300"> <if_matched_group>ransomware_pre_detection</if_matched_group> <if_sid>100626,100627,100615,100616,100617,100618,100619</if_sid> <description>Ransomware activity detected.</description> </rule> </group>
Where:
- Rule ID
100600
is triggered whenWerFault
has been possibly abused via DLL Sideloading. - Rule ID
100601
is triggered when a suspicious scheduled task has been created. - Rule ID
100602
is triggered when malware installs Remote Server Administration Tools. - Rule ID
100603
is triggered when the Windows firewall is disabled. - Rule IDs
100604
,100605
,100606
,100607
,100608
,100609
, and100610
are triggered when Windows Defender service is tampered with. - Rule ID
100611
is triggered when Windows boot configuration data is edited. - Rule ID
100612
is triggered when a new run key is added to the Windows registry. - Rule ID
100613
is triggered when a program is added to Startup programs. - Rule ID
100614
is triggered when WindowsWerFault
is abused to dump user credentials. - Rule IDs
100615
,100616
,100617
,100618
, and100619
are triggered when there is an attempt to delete Windows volume shadow copy. - Rule ID
100620
,100622
is triggered whenBCDEdit
changes boot configuration data to inhibit system recovery. - Rule ID
100621
is triggered whenwbadmin
is used to delete Windows system catalogs. - Rule IDs
100623
and100629
are triggered when there is an attempt to delete Windows event logs. - Rule ID
100626
is triggered when a file is created in multiple directories within a short period, denoting a possible ransom note creation. - Rule ID
100627
is triggered when multiple files are modified in the user directory within a short period, denoting a possible ransomware file encryption activity. - Rule ID
100628
is triggered when multiple ransomware execution activities are detected, denoting a ransomware activity. - Rule ID
100800
is triggered when the Wazuh Active Response module successfully recovers encrypted files on a monitored endpoint.
3. Restart the Wazuh manager to apply the configuration changes:
# systemctl restart wazuh-manager
Note: While the detection technique described in this blog post detects multiple variants of Ransomware, it is worth noting that it does not detect all types of Ransomware. This technique was tested with Crosslock, Phobos, BlackCat, Babuk, AESRTRansomware, AgendaRansomware, BlackBasta, LockBit, and Chaos ransomware variants.
Visualizing the alerts
In the images below, rule IDs 100630
, 100616
, 100617
, and 100623
are triggered when a ransomware execution is detected. Activities such as ransomware attempting to delete volume shadow copies or clearing Windows event logs are detected.
Ransomware protection with Wazuh Active Response
Wazuh provides protection against some ransomware variants by preserving volume shadow copies that are used to recover encrypted files. In this section, we configure the Wazuh Command and Active Response module to automatically recover files when a ransomware execution is detected.
Windows endpoint
On the Windows endpoint, we configure a Wazuh Active Response script and Command module.
Wazuh Command module configuration
Perform the steps below to configure the Wazuh Command module.
1. Append the following configuration to the C:\Program Files (x86)\ossec-agent\ossec.conf
local configuration file:
<ossec_config> <wodle name="command"> <disabled>no</disabled> <tag>vss</tag> <command>C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe -c "net stop VSS ; sc.exe config VSS start=Demand ; net start VSS ; WMIC shadowcopy call create Volume=C:\ ; net stop VSS ; sc.exe config VSS start=disabled"</command> <interval>12h</interval> <run_on_start>yes</run_on_start> <timeout>300</timeout> </wodle> </ossec_config>
This configures a command that does the following:
- Changes the startup configuration of the volume shadow service to
Demand
. This prevents the service from starting on its own when the system boots. Instead, it will only start when a user or another process explicitly requests it. - Runs a command that takes a volume shadow copy of the endpoint using
vssadmin
. - Stops the volume shadow service and sets its startup type to
disabled
. This action protects the endpoint from ransomware successfully deleting volume shadow copies. Ransomware typically tries to delete VSS snapshots using commands such asvssadmin delete shadows /all
. With VSS turned off, the command fails to run.
Note: VSS does not save copies of mapped network shares. Change the drive letter in the command if your endpoint does not use C:\
drive.
The frequency at which the shadow copies are taken is 12 hours. You can adjust this setting by changing the value of <interval>
to your preferred frequency.
Wazuh Active Response script configuration
To recover encrypted files, we use a custom Wazuh Active Response script rollback.ps1
that recovers our files into a backup folder.
1. Create a rollback.ps1
script in the C:\Program Files (x86)\ossec-agent\active-response\bin\
directory and add the below script to it. This script recovers files from the volume shadow copies:
# Define the base paths $EncryptedPath = "C:\users" $RecoveryPath = "C:\Recovered_Files" # Default recovery path, change as needed # Paths to ignore during restoration and deletion $IgnorePaths = @( "C:\Windows", "C:\Program Files", "C:\Program Files (x86)", "C:\C:\Recovered_Files" # Add more paths as needed ) # Log file location $LogFile = "$RecoveryPath\RecoveryLog.txt" # Ensure the log file directory exists $LogFileDirectory = [System.IO.Path]::GetDirectoryName($LogFile) if (-not (Test-Path -Path $LogFileDirectory)) { New-Item -Path $LogFileDirectory -ItemType Directory -Force } # Clear or create the log file if (Test-Path -Path $LogFile) { Clear-Content -Path $LogFile } else { New-Item -Path $LogFile -ItemType File } # Function to log messages function Log-Message { param ( [string]$Message ) $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content -Path $LogFile -Value "$Timestamp - $Message" Write-Host "$Timestamp - $Message" } try { Log-Message "Starting recovery process..." # Run vssadmin list shadows and capture the output start-sleep 120 cmd /c sc config VSS start=Demand cmd /c net start VSS start-sleep 5 Log-Message "Listing shadow copies..." # Extract the shadow copy volume path using Select-String $ShadowCopyVolumes = C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe -c "Get-WmiObject -Query 'SELECT * FROM Win32_ShadowCopy' | Select-Object -ExpandProperty DeviceObject" if ($ShadowCopyVolumes.Count -gt 0) { $ShadowCopyVolume = $ShadowCopyVolumes[-1] # Select the last shadow copy volume Log-Message "Latest Shadow Copy Volume found: $ShadowCopyVolume" } else { throw "Unable to find Shadow Copy Volume path in vssadmin output." } # Ensure ShadowCopyVolume ends with a backslash if (-not $ShadowCopyVolume.EndsWith("\")) { $ShadowCopyVolume += "\" } # Log the adjusted ShadowCopyVolume path Log-Message "Adjusted Shadow Copy Volume path: $ShadowCopyVolume" # Create symbolic link between shadow copy and backup folder $LinkPath = Join-Path -Path $RecoveryPath -ChildPath "backup" Log-Message "Creating symbolic link at $LinkPath..." # Remove any existing symbolic link or folder if (Test-Path -Path $LinkPath) { Remove-Item -Path $LinkPath -Recurse -Force Log-Message "Existing symbolic link or folder removed at $LinkPath" } # Create the symbolic link $linkCmdOutput = cmd /c mklink /d "$LinkPath" "$ShadowCopyVolume" Log-Message "Symbolic link command output: $linkCmdOutput" # Verify symbolic link creation if (-not (Test-Path -Path $LinkPath)) { throw "Failed to create symbolic link at $LinkPath" } Log-Message "Symbolic link created successfully: $LinkPath -> $ShadowCopyVolume" Write-Host "Files restore completed." "Wazuh_Ransomware_Protection: File restore completed for $($env:computername) at $(Get-Date)" | Out-File -FilePath "C:\Program Files (x86)\ossec-agent\active-response\active-responses.log" -Append -Encoding UTF8 } catch { $ErrorMsg = $Error[0].ToString() Log-Message "Error: $ErrorMsg" Write-Error "An error occurred: $ErrorMsg" } # Stop VSS service cmd /c sc config VSS start=disabled cmd /c net stop VSS start-sleep 5 Log-Message "Turned off VSS service..."
2. Create a rollback.bat
script in the C:\Program Files (x86)\ossec-agent\active-response\bin\
directory and add the below script to it. This script executes the rollback.ps1
script via Windows Batch launcher as the Wazuh Active Response module cannot execute PowerShell scripts directly:
@echo off Powershell -ExecutionPolicy bypass -File "C:\Program Files (x86)\ossec-agent\active-response\bin\rollback.ps1"
3. Restart the Wazuh agent using PowerShell with administrative privilege to apply the configuration changes:
> Restart-Service -Name wazuh
Wazuh server
On the Wazuh server, we configure the Wazuh Active Response module to trigger the rollback script when ransomware execution is detected.
Custom decoders configuration
We add the following decoders to decode logs generated by the rollback.bat
Wazuh Active Response script.
1. Add the following decoders to the /var/ossec/etc/decoders/local_decoder.xml
file to decode the logs generated by the rollback.ps1
Wazuh Active Response script:
<decoder name="Wazuh_Ransomware"> <prematch>Wazuh_Ransomware_Protection:</prematch> </decoder> <decoder name="Wazuh_Ransomware_child"> <parent>Wazuh_Ransomware</parent> <regex type="pcre2">Wazuh_Ransomware_Protection: (.*)</regex> <order>rollback_status</order> </decoder>
Custom rules configuration
Perform the following step to add a custom rule.
1. Add the following custom rule to the /var/ossec/etc/rules/ransomware_rules.xml
rule file.
<group name="ransomware,ransomware_rollback,"> <rule id="100800" level="5"> <field name="rollback_status">completed</field> <description>Wazuh_Ransomware_Protection: Files restored successfully.</description> </rule> </group>
This rule triggers an alert when the Wazuh Active Response script successfully recovers files on the monitored endpoint.
Wazuh Active Response module configuration
Perform the following steps to configure the Wazuh Active Response module.
1. Add the following configuration within the <ossec>
block of the /var/ossec/etc/ossec.conf
file to configure the Wazuh Active Response command:
<command> <name>rollback_windows</name> <executable>rollback.bat</executable> <timeout_allowed>no</timeout_allowed> </command> <active-response> <command>rollback_windows</command> <location>local</location> <rules_id>100628</rules_id> </active-response>
The rollback_windows
command is triggered when our custom rules detect a ransomware execution. This triggers the Wazuh Active Response script to recover our files from the last stored volume shadow copy. The recovered files are stored in a folder located at C:\Recovered_Files
.
Warning
The file recovery method described in this post is particularly effective for ransomware that does not encrypt the system and program files. The Wazuh Active Response module cannot trigger when the program files folder is encrypted because it also encrypts the Wazuh files required for operating the Active Response module. This Wazuh Active Response script was tested using the Babuk ransomware.
In cases where the Wazuh Active Response module does not trigger, administrators can manually recover their systems from the VSS snapshots by manually running the rollback.ps1
script via Powershell with administrative privilege with the following steps:
- Edit the script and replace
$ShadowCopyVolumes = C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe -c "Get-WmiObject -Query 'SELECT * FROM Win32_ShadowCopy' | Select-Object -ExpandProperty DeviceObject"
with$ShadowCopyVolumes = cmd /c vssadmin list shadows | Select-String -Pattern 'Shadow Copy Volume:\s*(.+)' | ForEach-Object { $_.Matches.Groups[1].Value.Trim() }
- Execute the script with the following command:
Powershell -ExecutionPolicy bypass -File "C:\Program Files (x86)\ossec-agent\active-response\bin\rollback.ps1"
Storage availability is crucial for successful file recovery, as insufficient space will cause the recovery process to fail. When a system lacks enough free storage, administrators may need to manually delete files to free up space.
2. Restart the Wazuh manager to apply the configuration changes:
# systemctl restart wazuh-manager
Visualizing the alerts
Running ransomware samples on the monitored Windows endpoint generates alerts on the Wazuh dashboard.
Once the ransomware execution is detected, the Wazuh Active Response script triggers and recovers the encrypted files as seen below.
The following alert triggers when the Wazuh Active Response script successfully recovers encrypted files.
Conclusion
In this blog post, we demonstrated how we use Wazuh to detect some strains of ransomware. We also show how you can protect your backups and recover files encrypted by ransomware on Windows endpoints.
Wazuh is a free and open source SIEM and XDR solution. Wazuh is deployed and managed on-premises, or on Wazuh cloud. Check out our community for support and updates.
References