Trouble implementing custom decoder for Draytek Router

440 views
Skip to first unread message

Arthur Dent

unread,
Mar 24, 2023, 6:45:02 PM3/24/23
to Wazuh mailing list

Hi, I'm trying to get a custom decoder working for a Draytek Router, but I can’t seem to get the phase 2 decoder to work.

 

Logs sent directly to Wazuh Manager - Syslog "remote" configured and working. The Logs are being successful received and show in archives.json.  The example log matches the “full log” field.

 

The decoder is successfully trigging a basic "show all" custom rule alert that I've created, and Security events are listed in the console but I'm struggling to decode the fields within the message itself. 

 

Can anyone point me in the right direction on how to get the fields out of the message body. I’ve tested the regex out in regex101 and both pre-match and main body work OK.

 

Example log ("X" substituted here in example for the actual IP address )

 

Mar 23 21:10:36 vigor.router DrayTek: Local User (MAC=00-04-4D-83-0A-65): XXX.XXX.XXX.XXX:36301 -> XXX.XXX.XXX.XXX:443 (UDP)

 

The following decoder is entered in the local_decoder.xml

 

<decoder name="draytek_usr">

    <prematch>^\w+ \d+ \d+:\d+:\d+ \w+.\w+ \w+: \w+ \w+\s</prematch>

    <regex offset="after_prematch">\SMAC\S(\w+-\w+-\w+-\w+-\w+-\w+)\S: (\d+.\d+.\d+.\d+):(\d+) \S+ (\d+.\d+.\d+.\d+):(\d+) \S(\w+)\S</regex>

    <order>rule_type, mac, srcip, srcport, dstip, dstport, protcol</order>

</decoder>

 

Custom Rule Created – draytek.xml

 

<group name="draytek">

 <rule id="100021" level="5">

    <decoded_as>DrayTek</decoded_as>

        <description>Draytek Events</description>

 </rule>

</group>

 

 

The Log Decoder Test Returns the following.

 

**Phase 1: Completed pre-decoding.

              full event: 'Mar 23 21:10:36 vigor.router DrayTek: Local User (MAC=00-04-4D-83-0A-65): XXX.XXX.XXX.XXX:36301 -> XXX.XXX.XXX.XXX:443 (UDP)'

              timestamp: 'Mar 23 21:10:36'

              hostname: 'vigor.router'

              program_name: 'DrayTek'

 

**Phase 2: Completed decoding.

              name: 'DrayTek'

 

**Phase 3: Completed filtering (rules).

              id: '100021'

              level: '5'

              description: 'Draytek Events'

              groups: '["draytek"]'

              firedtimes: '1'

              mail: 'false'

**Alert to be generated.

 

Henadence Anyam

unread,
Mar 26, 2023, 9:50:04 AM3/26/23
to Wazuh mailing list
Hello Arthur,

You can use the following decoders to extract the fields:

<decoder name="draytek-usr">
  <program_name>DrayTek</program_name>
</decoder>

<decoder name="draytek-usr-child">
  <parent>draytek-usr</parent>
  <regex type="pcre2">(.*) \(MAC=(\S+)\): (\S+):(\d+) -> (\S+):(\d+) \((\S+)\)</regex>

  <order>rule_type, mac, srcip, srcport, dstip, dstport, protcol</order>
</decoder>

You can now create a custom rule based on the decoder using the <decoded_as> tag as in the following example rule:

<group name="draytek">
  <rule id="100021" level="5">
    <decoded_as>draytek-usr</decoded_as>

    <description>Draytek Events</description>
  </rule>
</group>

After using the Wazuh-Logtest tool, we obtained the following result:

Starting wazuh-logtest v4.3.10
Type one log per line


Mar 23 21:10:36 vigor.router DrayTek: Local User (MAC=00-04-4D-83-0A-65): XXX.XXX.XXX.XXX:36301 -> XXX.XXX.XXX.XXX:443 (UDP)

**Phase 1: Completed pre-decoding.
        full event: 'Mar 23 21:10:36 vigor.router DrayTek: Local User (MAC=00-04-4D-83-0A-65): XXX.XXX.XXX.XXX:36301 -> XXX.XXX.XXX.XXX:443 (UDP)'
        timestamp: 'Mar 23 21:10:36'
        hostname: 'vigor.router'
        program_name: 'DrayTek'

**Phase 2: Completed decoding.
        name: 'draytek-usr'
        dstip: 'XXX.XXX.XXX.XXX'
        dstport: '443'
        mac: '00-04-4D-83-0A-65'
        protcol: 'UDP'
        rule_type: 'Local User'
        srcip: 'XXX.XXX.XXX.XXX'
        srcport: '36301'


**Phase 3: Completed filtering (rules).
        id: '100021'
        level: '5'
        description: 'Draytek Events'
        groups: '['draytek']'
        firedtimes: '1'
        mail: 'False'
**Alert to be generated.

Follow the custom rules and decoders guide to get more information on writing custom decoders and rules.

Hope you find this information helpful.

Arthur Dent

unread,
Mar 26, 2023, 7:54:03 PM3/26/23
to Wazuh mailing list
Thank you! that's very helpful I've been struggling for a while to get my head around the regex structure.  It works perfectly Thank you.

I've some other message formats that appear in the log that I'd also like to consume. For example 
Mar 26 21:55:50 DrayTek: Local User (MAC=10-2B-31-CD-BF-07): 192.168.1.14 DNS -> 192.168.5.2 inquire push.prod.netflix.com

I've created the following. The phase 2 decoder works when I replace the "draytek-usr-child" with the following but when I try and add both (with the usr-dns decoder added after the usr-child decoder) It doesn't decode the DNS messages and only decodes the original connection message. 
<decoder name="draytek-usr-dns">
  <parent>draytek-usr</parent>
  <regex type="pcre2">(.*) \(MAC=(\S+)\): (\S+) DNS -> (\S+) (\S+) (\S+.*$)</regex>
  <order>rule_type, mac, srcip, dstip, dns_action, url</order>
</decoder>

 I'm presuming I need to set up sibling decoders slightly differently.  I've tried moving parts of the regex into the parent and using offsets but with no luck.
How do I go about structuring the decoder so I can extract different messages after  Mar 26 21:55:50 DrayTek: Local User

Henadence Anyam

unread,
Mar 27, 2023, 3:15:06 AM3/27/23
to Wazuh mailing list
Hello Arthur,

We recommend creating sibling decoders with the same name to avoid unexpected results.
You just need to focus on the correct regex pattern in each child decoder. The log will be sequentially checked by the child decoders and when a match is found, the log will be decoded.
In the second case, you can use the following child decoder:

<decoder name="draytek-usr-child">
  <parent>draytek-usr</parent>
  <regex type="pcre2">(.*) \(MAC=(\S+)\): (\S+) DNS -> (\S+) (\S+) (\S+$)</regex>

  <order>rule_type, mac, srcip, dstip, dns_action, url</order>
</decoder>

The above child decoder produces the following results using the wazuh-logtest tool:

Starting wazuh-logtest v4.3.10
Type one log per line

Mar 26 21:55:50 DrayTek: Local User (MAC=10-2B-31-CD-BF-07): 192.168.1.14 DNS -> 192.168.5.2 inquire push.prod.netflix.com

**Phase 1: Completed pre-decoding.
        full event: 'Mar 26 21:55:50 DrayTek: Local User (MAC=10-2B-31-CD-BF-07): 192.168.1.14 DNS -> 192.168.5.2 inquire push.prod.netflix.com'
        timestamp: 'Mar 26 21:55:50'
        hostname: 'DrayTek:'

        program_name: 'DrayTek'

**Phase 2: Completed decoding.
        name: 'draytek-usr'
        dns_action: 'inquire'
        dstip: '192.168.5.2'
        mac: '10-2B-31-CD-BF-07'
        rule_type: 'Local User'
        srcip: '192.168.1.14'
        url: 'push.prod.netflix.com'

Let me know if that helps.

Alistair Thomas

unread,
Mar 27, 2023, 8:07:26 AM3/27/23
to Wazuh mailing list
Hi, thank you. That works perfectly.  Thanks for the quick and full response, it's been invaluable. 
Reply all
Reply to author
Forward
0 new messages