Ransomware protection on Windows with Wazuh

| by | Wazuh 4.9.0
Post icon

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.

Wazuh FIM module

Rule ID 87105 is triggered when VirusTotal detects a malicious file. In the image below, VirusTotal detected a malicious file with ASERT ransomware.

ASERT Ransomware

Rule ID 100092 is triggered when the Wazuh Active Response remove-threat script successfully removes the ransomware detected by VirusTotal.

Ransomware detected 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 when WerFault 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, and 100610 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 Windows WerFault is abused to dump user credentials.
  • Rule IDs 100615, 100616, 100617, 100618, and 100619 are triggered when there is an attempt to delete Windows volume shadow copy.
  • Rule ID 100620, 100622 is triggered when BCDEdit changes boot configuration data to inhibit system recovery.
  • Rule ID 100621 is triggered when wbadmin is used to delete Windows system catalogs.
  • Rule IDs 100623 and 100629 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 activity detected
Ransomware execution
Visualizing alerts
Windows event logs deleted

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 as vssadmin 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.

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:

  1. 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() }
  2. 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.

Wazuh active response script

The following alert triggers when the Wazuh Active Response script successfully recovers encrypted files.

Ransomware scriptsuccessfully recovers

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