Malware Detection in Wazuh 4.14
Wazuh takes a multi-layered approach to malware detection. Rather than relying on a single antivirus engine, the platform combines several detection techniques: rootkit identification through the rootcheck module, signature-based analysis via YARA, file hash verification against VirusTotal, log monitoring from third-party antivirus solutions, and custom rules built around indicators of compromise (IoC).
Detection Methods
Wazuh provides eight primary methods for detecting malicious software:
- FIM with detection rules - file integrity monitoring combined with threat detection rules
- Rootcheck - rootkit and trojan detection through behavioral analysis and signatures
- CDB lists - hash and IoC verification against local databases
- VirusTotal - automated file hash checks via the VirusTotal API
- YARA - pattern-based file scanning
- ClamAV - ClamAV antivirus log monitoring
- Windows Defender - Windows Defender event analysis
- Custom IoC rules - detection based on organization-specific indicators
The rootcheck Module
The rootcheck module searches for rootkits, trojans, and anomalies on monitored endpoints. It employs two approaches: matching against known signatures and behavioral anomaly detection.
rootcheck Configuration
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>
<check_trojans>yes</check_trojans>
<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>
<!-- Signature databases -->
<rootkit_files>etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>etc/shared/rootkit_trojans.txt</rootkit_trojans>
<!-- Scan frequency (seconds) -->
<frequency>43200</frequency>
<skip_nfs>yes</skip_nfs>
</rootcheck>rootcheck Checks
| Parameter | Description |
|---|---|
check_files | Searches for files associated with known rootkits |
check_trojans | Detects trojanized system utilities |
check_dev | Inspects /dev for hidden files |
check_sys | Identifies hidden processes and ports |
check_pids | Searches for hidden processes by PID enumeration |
check_ports | Detects hidden network ports |
check_if | Checks network interfaces for promiscuous mode |
Signature Databases
Wazuh ships with two databases:
rootkit_files.txt- file paths characteristic of known rootkits (Adore, Knark, T0rn, Ambient’s Rootkit, and others)rootkit_trojans.txt- signatures of trojanized system utilities (ls, ps, netstat, ifconfig)
Both databases can be updated manually with custom entries.
rootcheck Alert Examples
{
"rule": {
"level": 7,
"description": "Host-based anomaly detection event (rootcheck).",
"id": "510"
},
"full_log": "Rootkit 'Adore' detected by the presence of file '/usr/lib/libt0rn-2.so'."
}{
"rule": {
"level": 7,
"description": "Trojaned version of file detected.",
"id": "510"
},
"full_log": "Trojaned version of file '/usr/bin/ls' detected. Signature used: 'bash|strings|strstrstr'."
}YARA Integration
YARA enables creation of rules for malware detection based on textual and binary patterns. Wazuh integrates with YARA through the Active Response mechanism: when the FIM module detects a new or modified file, a YARA scan is triggered automatically.
How It Works
FIM detects new file -> syscheck alert ->
-> Active Response invokes YARA script -> File scan ->
-> Result written to log -> Wazuh rule generates alertInstalling YARA
# Ubuntu/Debian
apt-get install -y yara
# CentOS/RHEL
yum install -y yara
# Verify installation
yara --versionActive Response Script for YARA
Place the script on the agent at /var/ossec/active-response/bin/yara.sh:
#!/bin/bash
LOCAL=$(dirname $0)
cd $LOCAL
cd ../
PWD=$(pwd)
LOG_FILE="${PWD}/../logs/active-responses.log"
YARA_PATH="/usr/bin/yara"
YARA_RULES="/var/ossec/etc/rules/yara_rules.yar"
read INPUT_JSON
FILENAME=$(echo $INPUT_JSON | jq -r '.parameters.alert.syscheck.path')
if [ -f "$FILENAME" ]; then
YARA_OUTPUT=$("$YARA_PATH" "$YARA_RULES" "$FILENAME" 2>/dev/null)
if [ ! -z "$YARA_OUTPUT" ]; then
YARA_RULE=$(echo "$YARA_OUTPUT" | awk '{print $1}')
echo "$(date '+%Y/%m/%d %H:%M:%S') active-response/bin/yara.sh: $YARA_OUTPUT" >> ${LOG_FILE}
fi
fi
exit 0Active Response Configuration on the Server
<ossec_config>
<command>
<name>yara_scan</name>
<executable>yara.sh</executable>
<timeout_allowed>no</timeout_allowed>
</command>
<active-response>
<command>yara_scan</command>
<location>local</location>
<rules_id>554</rules_id>
</active-response>
</ossec_config>YARA Alert Rules
<group name="yara,">
<rule id="108000" level="0">
<decoded_as>yara</decoded_as>
<description>YARA grouping rule.</description>
</rule>
<rule id="108001" level="12">
<if_sid>108000</if_sid>
<match>yara.sh</match>
<description>YARA: malware detected - $(yara_rule) in $(yara_file).</description>
<mitre>
<id>T1204</id>
</mitre>
<group>malware,yara,</group>
</rule>
</group>Sample YARA Rule
rule Suspicious_Packed_PE
{
meta:
description = "Detects packed PE executables"
author = "Security Team"
severity = "high"
strings:
$mz = { 4D 5A }
$upx = "UPX!" ascii
$aspack = "ASPack" ascii
condition:
$mz at 0 and ($upx or $aspack)
}
rule WebShell_Generic
{
meta:
description = "Detects common web shell patterns"
author = "Security Team"
strings:
$php_eval = "eval($_" ascii nocase
$php_system = "system($_" ascii nocase
$php_exec = "exec($_" ascii nocase
$php_passthru = "passthru(" ascii nocase
$php_base64 = "base64_decode($_" ascii nocase
condition:
2 of them
}VirusTotal Integration
Wazuh integrates with VirusTotal through the integratord module for automated hash verification of files detected by the FIM module.
integratord Configuration
Add the following to /var/ossec/etc/ossec.conf on the Wazuh server:
<integration>
<name>virustotal</name>
<api_key>YOUR_VIRUSTOTAL_API_KEY</api_key>
<group>syscheck</group>
<alert_format>json</alert_format>
</integration>FIM Configuration for VirusTotal
On the agent side, configure monitoring for target directories:
<syscheck>
<directories check_all="yes" realtime="yes">/tmp/downloads</directories>
<directories check_all="yes" realtime="yes">/home/user/Downloads</directories>
<directories check_all="yes" realtime="yes">/var/www/uploads</directories>
</syscheck>VirusTotal Alert Levels
| Level | Rule ID | Description |
|---|---|---|
| 3 | 87101 | API error (invalid key, rate limit exceeded) |
| 3 | 87102 | File not found in VirusTotal database |
| 12 | 87105 | Malware detected |
Detection Alert Example
{
"timestamp": "2024-11-17T19:30:25.085+0000",
"rule": {
"level": 12,
"description": "VirusTotal: Alert - /tmp/downloads/malware.exe - 66 engines detected this file",
"id": "87105",
"groups": ["virustotal"]
},
"data": {
"virustotal": {
"positives": "66",
"total": "68",
"scan_date": "2024-11-17 17:15:04",
"sha1": "abc123...",
"source": {
"file": "/tmp/downloads/malware.exe",
"md5": "def456...",
"sha1": "abc123..."
},
"permalink": "https://www.virustotal.com/gui/file/..."
}
},
"location": "virustotal"
}VirusTotal API Limitations
- Public API - 500 requests per day, 4 requests per minute. Not suitable for commercial use.
- Private API - higher rate limits and priority access (paid subscription).
When the rate limit is exceeded, integratord automatically queues requests.
Windows Defender Monitoring
Wazuh collects and analyzes Windows Defender events through Windows Event Log monitoring.
Agent Configuration
<localfile>
<location>Microsoft-Windows-Windows Defender/Operational</location>
<log_format>eventchannel</log_format>
</localfile>Built-in Rules
Wazuh includes a set of rules for Windows Defender events:
| Rule ID | Level | Description |
|---|---|---|
| 91050 | 3 | Windows Defender: informational event |
| 91051 | 6 | Windows Defender: threat detected |
| 91052 | 12 | Windows Defender: malware not removed |
| 91053 | 3 | Windows Defender: scan completed |
Windows Defender Alert Example
{
"rule": {
"level": 6,
"description": "Windows Defender: Threat detected.",
"id": "91051"
},
"data": {
"win": {
"eventdata": {
"threatName": "Trojan:Win32/Emotet.RPH!MTB",
"severity": "Severe",
"path": "file:_C:\\Users\\admin\\Downloads\\invoice.doc",
"actionStatus": "Quarantined"
}
}
}
}ClamAV Integration
ClamAV is an open-source antivirus engine. Wazuh parses ClamAV logs to generate alerts when malware is identified.
ClamAV Log Monitoring Configuration
<localfile>
<log_format>syslog</log_format>
<location>/var/log/clamav/clamav.log</location>
</localfile>ClamAV Rules
<group name="clamav,">
<rule id="100100" level="0">
<decoded_as>clamav</decoded_as>
<description>ClamAV grouping rule.</description>
</rule>
<rule id="100101" level="6">
<if_sid>100100</if_sid>
<match>FOUND</match>
<description>ClamAV: Malware detected - $(file): $(signature).</description>
<group>malware,clamav,</group>
</rule>
<rule id="100102" level="3">
<if_sid>100100</if_sid>
<match>ERROR</match>
<description>ClamAV: Scan error.</description>
<group>clamav,</group>
</rule>
</group>Automated Scanning via Active Response
To trigger ClamAV automatically when a new file is detected:
<command>
<name>clamav_scan</name>
<executable>clamav_scan.sh</executable>
<timeout_allowed>no</timeout_allowed>
</command>
<active-response>
<command>clamav_scan</command>
<location>local</location>
<rules_id>554</rules_id>
</active-response>CDB Lists and Indicators of Compromise
CDB (Constant Database) lists store local databases of indicators of compromise for verifying file hashes, IP addresses, and other IoC.
CDB List Format
CDB files are stored in /var/ossec/etc/lists/ using a “key:value” format:
44d88612fea8a8f36de82e1278abb02f:malware_md5
e3b0c44298fc1c149afbf4c8996fb924:suspicious_hash
275a021bbfb6489e54d471899f7db9d1:eicar_testRegistering a CDB List
In /var/ossec/etc/ossec.conf on the server:
<ruleset>
<list>etc/lists/malware_hashes</list>
</ruleset>Hash Verification Rule Using CDB
<rule id="100200" level="12">
<if_sid>550,554</if_sid>
<list field="md5" lookup="match_key">etc/lists/malware_hashes</list>
<description>Known malware hash detected: $(file).</description>
<mitre>
<id>T1204</id>
</mitre>
<group>malware,threat_intel,</group>
</rule>Threat Intelligence Feeds
MISP Integration
Wazuh can ingest IoC from the MISP (Malware Information Sharing Platform) and load them into CDB lists:
#!/bin/bash
# Script to update CDB from MISP
MISP_URL="https://misp.example.com"
MISP_KEY="your_misp_api_key"
OUTPUT="/var/ossec/etc/lists/misp_hashes"
curl -sk -H "Authorization: $MISP_KEY" \
"$MISP_URL/attributes/restSearch/type:md5" | \
jq -r '.response.Attribute[].value' | \
while read hash; do
echo "${hash}:misp_indicator"
done > "$OUTPUT"
# Reload rules
/var/ossec/bin/wazuh-control reloadCISA KEV Integration
Downloading the CISA Known Exploited Vulnerabilities catalog for correlation with installed software data:
curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json | \
jq -r '.vulnerabilities[].cveID' | \
while read cve; do
echo "${cve}:cisa_kev"
done > /var/ossec/etc/lists/cisa_kevCustom Detection Rules
Cryptocurrency Miner Detection
<rule id="100300" level="10">
<if_sid>530</if_sid>
<match>stratum+tcp://|xmrig|minerd|cpuminer</match>
<description>Cryptocurrency miner detected in process or log.</description>
<mitre>
<id>T1496</id>
</mitre>
<group>malware,cryptominer,</group>
</rule>Reverse Shell Detection
<rule id="100301" level="12">
<if_sid>530</if_sid>
<match>/dev/tcp/|bash -i|nc -e|python -c.*socket|perl -e.*socket</match>
<description>Possible reverse shell detected.</description>
<mitre>
<id>T1059</id>
</mitre>
<group>malware,reverse_shell,attack,</group>
</rule>Suspicious Script in /tmp
<rule id="100302" level="8">
<if_sid>554</if_sid>
<field name="file">^/tmp/.*\.(sh|py|pl|rb)$</field>
<description>Script file created in /tmp directory.</description>
<mitre>
<id>T1059</id>
</mitre>
<group>malware,suspicious_file,</group>
</rule>Troubleshooting
rootcheck Not Detecting Rootkits
- Verify that rootcheck is enabled:
<rootcheck>
<disabled>no</disabled>
</rootcheck>- Confirm the signature files exist:
ls -la /var/ossec/etc/shared/rootkit_files.txt
ls -la /var/ossec/etc/shared/rootkit_trojans.txt- Check the logs:
grep rootcheck /var/ossec/logs/ossec.log | tail -20VirusTotal Integration Not Working
- Validate the API key:
curl -s "https://www.virustotal.com/api/v3/files/44d88612fea8a8f36de82e1278abb02f" \
-H "x-apikey: YOUR_API_KEY" | jq '.data.attributes.last_analysis_stats'- Review integratord logs:
tail -50 /var/ossec/logs/integrations.log- Confirm that integratord is running:
/var/ossec/bin/wazuh-control status | grep integratordYARA Not Scanning Files
- Confirm YARA is installed:
yara --version- Verify the rules file path:
ls -la /var/ossec/etc/rules/yara_rules.yar- Test the rule manually:
yara /var/ossec/etc/rules/yara_rules.yar /path/to/test/file- Check Active Response logs:
tail -20 /var/ossec/logs/active-responses.logHigh Scan Load
- Increase the rootcheck interval:
<rootcheck>
<frequency>86400</frequency>
</rootcheck>- Exclude network filesystems:
<rootcheck>
<skip_nfs>yes</skip_nfs>
</rootcheck>- Schedule VirusTotal scanning around API rate limits.
Related Sections
- File Integrity Monitoring - FIM as the foundation for malware detection
- Vulnerability Detection - identifying vulnerable software that malware may exploit
- Wazuh Components - agent modules involved in threat detection