Dev.to Security 🔐 Cybersecurity 👁 0 📖 3 min read

Three ways a third-party Wazuh rules file breaks a 4.14.7 manager

This week we loaded a third-party Wazuh decoder and rules file, exactly as published, into a clean Wazuh 4.14.7 manager (the official wazuh/wazuh-manager:4.14.7 container). It had three separate problems. One stopped the

This week we loaded a third-party Wazuh decoder and rules file, exactly as published, into a clean Wazuh 4.14.7 manager (the official wazuh/wazuh-manager:4.14.7 container). It had three separate problems. One stopped the manager. The other two left it running with rules that could never fire.

None of the three is exotic, so we rebuilt each one with made-up names (myapp) and measured it again on its own. Everything below is from those reruns.

The test line, a syslog line with a JSON body:

Nov 10 10:30:00 web01 myapp: {"event":"deny","user":"alice","action":"block"}

1. <field name="action"> on a static field: the manager does not start

action is one of Wazuh's static fields, like srcip or dstuser. A rule that matches it with the dynamic-field syntax:

<rule id="100501" level="12">
  <if_sid>100500</if_sid>
  <field name="action">block</field>
  <description>myapp: request blocked for $(user)</description>
</rule>

is rejected when the ruleset loads:

wazuh-analysisd: ERROR: Failure to read rule 100501. Field 'action' is static.
wazuh-analysisd: CRITICAL: (1220): Error loading the rules: 'etc/rules/myapp_rules.xml'.

and wazuh-control status then reports wazuh-analysisd not running.... One wrong tag in one added file, and nothing gets analysed at all. The fix is the static-field tag:

<action>block</action>

2. PCRE syntax without type="pcre2": the decoder extracts nothing

<decoder name="myapp-event">
  <parent>myapp</parent>
  <regex>"event":"deny".*"user":"([^"]+)".*"action":"(\w+)"</regex>
  <order>user,action</order>
</decoder>

Wazuh's default regex engine (OS_Regex) is not PCRE. With this decoder the manager runs, logtest shows the myapp decoder matching, and no fields come out. The parent rule still fires (level 8), but the level 12 rule that needs action never does, and there is no error anywhere. Adding the type fixes it:

<regex type="pcre2">"event":"deny".*"user":"([^"]+)".*"action":"(\w+)"</regex>

3. decoded_as pointing at the child decoder: the rule never matches

<rule id="100500" level="8">
  <decoded_as>myapp-event</decoded_as>
  <description>myapp: request denied for $(user)</description>
</rule>

With the decoder fixed, logtest extracts action and the user, and reports the decoder name as myapp, the parent. A rule with decoded_as set to the child name matched nothing in our test. Use the parent name:

<decoded_as>myapp</decoded_as>

With all three changed, the test line raised rule 100501 at level 12.

A smaller one we hit on the way

user in <order> is stored in the static field dstuser. The descriptions above use $(user), and with every other fix in place rule 100501 still came out as "myapp: request blocked for " with nothing after it; changing it to $(dstuser) gave "myapp: request blocked for alice".

Checking a rules file before it goes into /var/ossec/etc/rules

On a test manager (a throwaway container is enough), mount the files, then:

grep -E "ERROR|CRITICAL" /var/ossec/logs/ossec.log
echo '<one real log line>' | /var/ossec/bin/wazuh-logtest

The first line catches case 1. For the second, check three things in the output: that the fields you expect are listed under the decoder, that the decoder name is the one your rule's decoded_as uses, and that the rule id you expect appears in phase 3. Cases 2 and 3 only show up there.

Where our tool fits, and where it doesn't

We make Detection Watch, which reads a manager's alerts and lists custom rules that never fired in the last seven days. Its one-command quick check would list rules like the ones in cases 2 and 3 as never fired. It does nothing for case 1: when analysisd does not start there are no alerts to read, and the manager log above is the place to look.

Quick check: https://vct.atkvn.com/detection-watch.html?src=devto-3ways#quick

All measurements: Wazuh 4.14.7 only. We have not repeated them on 4.14.10 or 5.0.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.