Detecting and removing malware using VirusTotal integration
Wazuh uses the integrator module to connect to external APIs and alerting tools such as VirusTotal.
In this use case, you use the Wazuh File Integrity Monitoring (FIM) module to monitor a directory for changes and the VirusTotal API to scan the files in the directory. Then, configure Wazuh to trigger an active response script and remove files that VirusTotal detects as malicious. We test this use case on Ubuntu and Windows endpoints.
You need a VirusTotal API key in this use case to authenticate Wazuh to the VirusTotal API.
For more information on this integration, check the VirusTotal integration section of the documentation.
Infrastructure
Endpoint |
Description |
---|---|
Ubuntu 22.04 |
This is the Linux endpoint where you download a malicious file. Wazuh triggers an active response script to remove the file once VirusTotal flags it as malicious. |
Windows 11 |
This is the Windows endpoint where you download a malicious file. Wazuh triggers an active response script to remove the file once VirusTotal flags it as malicious. |
Configuration for the Ubuntu endpoint
Configure your environment as follows to test the use case for the Ubuntu endpoint. These steps work for other Linux distributions as well.
Ubuntu endpoint
Perform the following steps to configure Wazuh to monitor near real-time changes in the /root
directory of the Ubuntu endpoint. These steps also install the necessary packages and create the active response script that removes malicious files.
Search for the
<syscheck>
block in the Wazuh agent configuration file/var/ossec/etc/ossec.conf
. Make sure that<disabled>
is set tono
. This enables the Wazuh FIM to monitor for directory changes.Add an entry within the
<syscheck>
block to configure a directory to be monitored in near real-time. In this case, you are monitoring the/root
directory:<directories realtime="yes">/root</directories>
Install
jq
, a utility that processes JSON input from the active response script.$ sudo apt update $ sudo apt -y install jq
Create the
/var/ossec/active-response/bin/remove-threat.sh
active response script to remove malicious files from the endpoint:#!/bin/bash LOCAL=`dirname $0`; cd $LOCAL cd ../ PWD=`pwd` read INPUT_JSON FILENAME=$(echo $INPUT_JSON | jq -r .parameters.alert.data.virustotal.source.file) COMMAND=$(echo $INPUT_JSON | jq -r .command) LOG_FILE="${PWD}/../logs/active-responses.log" #------------------------ Analyze command -------------------------# if [ ${COMMAND} = "add" ] then # Send control message to execd printf '{"version":1,"origin":{"name":"remove-threat","module":"active-response"},"command":"check_keys", "parameters":{"keys":[]}}\n' read RESPONSE COMMAND2=$(echo $RESPONSE | jq -r .command) if [ ${COMMAND2} != "continue" ] then echo "`date '+%Y/%m/%d %H:%M:%S'` $0: $INPUT_JSON Remove threat active response aborted" >> ${LOG_FILE} exit 0; fi fi # Removing file rm -f $FILENAME if [ $? -eq 0 ]; then echo "`date '+%Y/%m/%d %H:%M:%S'` $0: $INPUT_JSON Successfully removed threat" >> ${LOG_FILE} else echo "`date '+%Y/%m/%d %H:%M:%S'` $0: $INPUT_JSON Error removing threat" >> ${LOG_FILE} fi exit 0;
Change the
/var/ossec/active-response/bin/remove-threat.sh
file ownership, and permissions:$ sudo chmod 750 /var/ossec/active-response/bin/remove-threat.sh $ sudo chown root:wazuh /var/ossec/active-response/bin/remove-threat.sh
Restart the Wazuh agent to apply the changes:
$ sudo systemctl restart wazuh-agent
Wazuh server
Perform the following steps on the Wazuh server to alert for changes in the endpoint directory and enable the VirusTotal integration. These steps also enable and trigger the active response script whenever a suspicious file is detected.
Add the following rules to the
/var/ossec/etc/rules/local_rules.xml
file on the Wazuh server. These rules alert about changes in the/root
directory that are detected by FIM scans:<group name="syscheck,pci_dss_11.5,nist_800_53_SI.7,"> <!-- Rules for Linux systems --> <rule id="100200" level="7"> <if_sid>550</if_sid> <field name="file">/root</field> <description>File modified in /root directory.</description> </rule> <rule id="100201" level="7"> <if_sid>554</if_sid> <field name="file">/root</field> <description>File added to /root directory.</description> </rule> </group>
Add the following configuration to the Wazuh server
/var/ossec/etc/ossec.conf
file to enable the Virustotal integration. Replace<YOUR_VIRUS_TOTAL_API_KEY>
with your VirusTotal API key. This allows to trigger a VirusTotal query whenever any of the rules100200
and100201
are triggered:<ossec_config> <integration> <name>virustotal</name> <api_key><YOUR_VIRUS_TOTAL_API_KEY></api_key> <!-- Replace with your VirusTotal API key --> <rule_id>100200,100201</rule_id> <alert_format>json</alert_format> </integration> </ossec_config>
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 add more rules besides these two. You can also configure Wazuh to monitor more directories.
Append the following blocks to the Wazuh server
/var/ossec/etc/ossec.conf
file. This enables active response and triggers theremove-threat.sh
script when VirusTotal flags a file as malicious:<ossec_config> <command> <name>remove-threat</name> <executable>remove-threat.sh</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> </ossec_config>
Add the following rules to the Wazuh server
/var/ossec/etc/rules/local_rules.xml
file to alert about the active response results:<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>
Restart the Wazuh manager to apply the configuration changes:
$ sudo systemctl restart wazuh-manager
Attack emulation
Download an EICAR test file to the
/root
directory on the Ubuntu endpoint:$ sudo curl -Lo /root/eicar.com https://secure.eicar.org/eicar.com && sudo ls -lah /root/eicar.com
Visualize the alerts
You can visualize the alert data in the Wazuh dashboard. To do this, go to the Threat Hunting module and add the filters in the search bar to query the alerts.
Linux -
rule.id: is one of 553,100092,87105,100201
Configuration for the Windows endpoint
Windows endpoint
Perform the following steps to configure Wazuh to monitor near real-time changes in the /Downloads
directory. These steps also install the necessary packages and create the active response script to remove malicious files.
Search for the
<syscheck>
block in the Wazuh agentC:\Program Files (x86)\ossec-agent\ossec.conf
file. Make sure that<disabled>
is set tono
. This enables the Wazuh FIM module to monitor for directory changes.Add an entry within the
<syscheck>
block to configure a directory to be monitored in near real-time. In this use case, you configure Wazuh to monitor theC:\Users\<USER_NAME>\Downloads
directory. Replace the<USER_NAME>
variable with the appropriate user name:<directories realtime="yes">C:\Users\<USER_NAME>\Downloads</directories>
Download the Python executable installer from the official Python website.
Run the Python installer once downloaded. Make sure to check the following boxes:
Install launcher for all users
Add Python 3.X to PATH
(This places the interpreter in the execution path)
Once Python completes the installation process, open an administrator PowerShell terminal and use
pip
to install PyInstaller:> pip install pyinstaller > pyinstaller --version
You use Pyinstaller here to convert the active response Python script into an executable application that can run on a Windows endpoint.
Create an active response script
remove-threat.py
to remove a file from the Windows endpoint:#!/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)
Convert the active response Python script
remove-threat.py
to a Windows executable application. Run the following PowerShell command as an administrator to create the executable:> pyinstaller -F \path_to_remove-threat.py
Take note of the path where
pyinstaller
createdremove-threat.exe
.Move the executable file
remove-threat.exe
to theC:\Program Files (x86)\ossec-agent\active-response\bin
directory.Restart the Wazuh agent to apply the changes. Run the following PowerShell command as an administrator:
> Restart-Service -Name wazuh
Wazuh server
Perform the following steps on the Wazuh server to configure the VirusTotal integration. These steps also enable and trigger the active response script whenever a suspicious file is detected.
Add the following configuration to the
/var/ossec/etc/ossec.conf
file on the Wazuh server to enable the VirusTotal integration. Replace<YOUR_VIRUS_TOTAL_API_KEY>
with your VirusTotal API key. This allows to trigger a VirusTotal query whenever any of the rules in the FIMsyscheck
group are triggered:<ossec_config> <integration> <name>virustotal</name> <api_key><YOUR_VIRUS_TOTAL_API_KEY></api_key> <!-- Replace with your VirusTotal API key --> <group>syscheck</group> <alert_format>json</alert_format> </integration> </ossec_config>
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 add more rules besides these two. You can configure Wazuh to monitor more directories besides
C:\Users\<USER_NAME>\Downloads
.Append the following blocks to the Wazuh server
/var/ossec/etc/ossec.conf
file. This enables active response and trigger theremove-threat.exe
executable when the VirusTotal query returns positive matches for threats:<ossec_config> <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> </ossec_config>
Add the following rules to the Wazuh server
/var/ossec/etc/rules/local_rules.xml
file to alert about the active response results.<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>
Restart the Wazuh manager to apply the configuration changes:
$ sudo systemctl restart wazuh-manager
Attack emulation
Follow the next steps to temporarily turn off real-time Microsoft Defender antivirus protection in Windows Security:
Click on the Start menu and type
Windows Security
to search for that app.Select the Windows Security app from results, go to Virus & threat protection, and under Virus & threat protection settings select Manage settings.
Switch Real-time protection to Off.
Download an EICAR test file to the
C:\Users\<USER_NAME>\Downloads
directory on the Windows endpoint.> Invoke-WebRequest -Uri https://secure.eicar.org/eicar.com.txt -OutFile eicar.txt > cp .\eicar.txt C:\Users\<USER_NAME>\Downloads
This triggers a VirusTotal query and generates an alert. In addition, the active response script automatically removes the file.
Visualize the alerts
You can visualize the alert data in the Wazuh dashboard. To do this, go to the Threat Hunting module and add the filters in the search bar to query the alerts.
Windows -
rule.id: is one of 554,100092,553,87105