Automated Malware Removal with Wazuh Active Response
Building on the foundational Wazuh SEIM setup, this guide shows you how to take your lab to the next level by automatically detecting and neutralizing malicious files in real time. We'll integrate VirusTotal with Wazuh and deploy an Active Response script to automatically remove flagged files, creating a robust automated defense chain.
Prerequisites and Setup
Before starting, make sure you have a Wazuh manager and agent already installed and running, along with the File Integrity Monitoring (FIM) setup completed. You'll also need a VirusTotal API key; free accounts allow 4 lookups per minute and 500 requests per day.
Step 1: Set Up the Monitored Directory (Agent)
On your Ubuntu agent, create a directory to monitor for malicious files:
mkdir /tmp/malware
chmod 777 /tmp/malware
The
chmod 777is fine for a lab demo. In production, use restrictive permissions on any monitored directory.
Step 2: Configure File Integrity Monitoring (Wazuh Manager)
Open the Wazuh Dashboard, navigate to Agent management → Groups, and edit the configuration for the group containing your agent. Add the following syscheck block to monitor the directory in real time:
<agent_config os="Linux">
<syscheck>
<directories check_all="yes" realtime="yes">/tmp/malware</directories>
</syscheck>
</agent_config>
Back on the agent, restart the Wazuh agent so it pulls the new configuration:
systemctl restart wazuh-agent
Test FIM: Create a dummy file and confirm Rule 554 fires in the Wazuh Dashboard:
echo "hello" > /tmp/malware/hello.txt
Integrating Threat Intelligence
Step 3: Enable the VirusTotal Integration (Wazuh Manager)
Enabling VirusTotal integration provides real-time file reputation checks. On the Wazuh server, open the manager configuration file:
nano /var/ossec/etc/ossec.conf
Scroll to the bottom and paste the following inside the <ossec_config> block:
<integration>
<name>virustotal</name>
<api_key>YOUR_VIRUS_TOTAL_API_KEY</api_key>
<group>syscheck</group>
<alert_format>json</alert_format>
</integration>
Replace YOUR_VIRUS_TOTAL_API_KEY with your actual API key from virustotal.com. Save the file and restart the Wazuh manager:
systemctl restart wazuh-manager
Test the integration by downloading the EICAR test file on the agent:
curl -Lo /tmp/malware/eicar https://secure.eicar.org/eicar.com.txt
Check the Wazuh Dashboard — you should see Rule ID 87105 fire, showing detection details including the number of engines that flagged the file and a link to VirusTotal.
Automating the Response
Step 4: Create the Active Response Script (Agent)
The Active Response feature in Wazuh enables automated actions based on alerts, providing real-time cybersecurity defenses beyond simple notifications. We'll create a script on the agent to delete malicious files.
First, install jq, which is required for the script to parse JSON:
apt install jq
Next, navigate to the Active Response scripts directory and create the script:
cd /var/ossec/active-response/bin
nano remove-threat.sh
Paste in the following script (from the Wazuh PoC documentation):
#!/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;
Save the file and set the correct permissions:
chmod 750 /var/ossec/active-response/bin/remove-threat.sh
chown root:wazuh /var/ossec/active-response/bin/remove-threat.sh
Restart the Wazuh agent to apply the changes:
systemctl restart wazuh-agent
Step 5: Configure Active Response Rules (Wazuh Manager)
Open the Wazuh manager configuration file again:
nano /var/ossec/etc/ossec.conf
Add the following command and active-response blocks inside <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>
This tells Wazuh to run the remove-threat.sh script locally on the agent whenever rule 87105 (VirusTotal — malicious file detected) fires.
Next, add custom rules so the dashboard shows whether the threat was successfully removed. Open the local rules file:
nano /var/ossec/etc/rules/local_rules.xml
Append the following rules:
<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>
Save both files and restart the Wazuh manager:
systemctl restart wazuh-manager
Testing the Automated Workflow
Step 6: Final Test
Download the EICAR test file again on the agent to trigger the full workflow:
curl -Lo /tmp/malware/eicar https://secure.eicar.org/eicar.com.txt
The file should briefly appear in /tmp/malware and then instantly disappear as the Active Response script deletes it. You can verify by listing the directory:
ls /tmp/malware/
In the Wazuh Dashboard, navigate to Threat Hunting and filter by rule IDs 554,87105,100092 to see the full chain of events:
- Rule 554 — FIM detects the new file
- Rule 87105 — VirusTotal flags it as malicious
- Rule 100092 — Active Response confirms the threat was successfully removed
Common Pitfalls
- Misconfigured FIM: Improper configuration can prevent malicious files from being detected in real-time. Always double-check your directory paths and permissions.
- Script Permission Issues: Incorrect permissions on the active response script can prevent it from executing. Ensure the
chownandchmodcommands are run correctly.
Key Takeaways
By setting up this workflow, you now have a fully automated malware removal system using Wazuh SEIM, VirusTotal, and active response scripts. This setup allows instant neutralization of malicious files and can be adapted for other automated defensive actions, such as blocking IPs or disabling accounts. This provides a strong foundation for building a comprehensive automated cybersecurity environment.
Additional Resources
- Wazuh PoC: Detect and Remove Malware Using VirusTotal
- Wazuh SEIM Documentation
- VirusTotal API Documentation
- EICAR Test File
Want to see this setup in action? Watch the accompanying YouTube tutorial for a full step-by-step walkthrough.

