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:

  1. FIM with detection rules - file integrity monitoring combined with threat detection rules
  2. Rootcheck - rootkit and trojan detection through behavioral analysis and signatures
  3. CDB lists - hash and IoC verification against local databases
  4. VirusTotal - automated file hash checks via the VirusTotal API
  5. YARA - pattern-based file scanning
  6. ClamAV - ClamAV antivirus log monitoring
  7. Windows Defender - Windows Defender event analysis
  8. 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

ParameterDescription
check_filesSearches for files associated with known rootkits
check_trojansDetects trojanized system utilities
check_devInspects /dev for hidden files
check_sysIdentifies hidden processes and ports
check_pidsSearches for hidden processes by PID enumeration
check_portsDetects hidden network ports
check_ifChecks 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 alert

Installing YARA

# Ubuntu/Debian
apt-get install -y yara

# CentOS/RHEL
yum install -y yara

# Verify installation
yara --version

Active 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 0

Active 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

LevelRule IDDescription
387101API error (invalid key, rate limit exceeded)
387102File not found in VirusTotal database
1287105Malware 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 IDLevelDescription
910503Windows Defender: informational event
910516Windows Defender: threat detected
9105212Windows Defender: malware not removed
910533Windows 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_test

Registering 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 reload

CISA 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_kev

Custom 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

  1. Verify that rootcheck is enabled:
<rootcheck>
  <disabled>no</disabled>
</rootcheck>
  1. Confirm the signature files exist:
ls -la /var/ossec/etc/shared/rootkit_files.txt
ls -la /var/ossec/etc/shared/rootkit_trojans.txt
  1. Check the logs:
grep rootcheck /var/ossec/logs/ossec.log | tail -20

VirusTotal Integration Not Working

  1. 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'
  1. Review integratord logs:
tail -50 /var/ossec/logs/integrations.log
  1. Confirm that integratord is running:
/var/ossec/bin/wazuh-control status | grep integratord

YARA Not Scanning Files

  1. Confirm YARA is installed:
yara --version
  1. Verify the rules file path:
ls -la /var/ossec/etc/rules/yara_rules.yar
  1. Test the rule manually:
yara /var/ossec/etc/rules/yara_rules.yar /path/to/test/file
  1. Check Active Response logs:
tail -20 /var/ossec/logs/active-responses.log

High Scan Load

  1. Increase the rootcheck interval:
<rootcheck>
  <frequency>86400</frequency>
</rootcheck>
  1. Exclude network filesystems:
<rootcheck>
  <skip_nfs>yes</skip_nfs>
</rootcheck>
  1. Schedule VirusTotal scanning around API rate limits.

Related Sections

Last updated on