wazuh / wazuh

Wazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.
https://wazuh.com/
Other
10.98k stars 1.67k forks source link

Error with sibling decoders #16524

Open JcabreraC opened 1 year ago

JcabreraC commented 1 year ago
Wazuh version Component Install type Install method Platform
4.3.0 Analysisd Manager Packages/Sources OS version

There is a bug when working with sibling decoders. Let's look at the decoders in the 0040-auditd_decoders.xml file that we have modified to capture EXECVE logs:

<!--
  Audit decoders (logformat must be "audit")
-->

<decoder name="auditd">
  <prematch>^type=</prematch>
</decoder>

<!--
  type=SYSCALL msg=audit(1479982525.380:50): arch=c000003e syscall=2 success=yes exit=3 a0=7ffedc40d83b a1=941 a2=1b6 a3=7ffedc40cce0 items=2 ppid=432 pid=3333 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="touch" exe="/bin/touch" key="audit-wazuh-w" type=CWD msg=audit(1479982525.380:50):  cwd="/var/log/audit" type=PATH msg=audit(1479982525.380:50): item=0 name="/var/log/audit/tmp_directory1/" inode=399849 dev=ca:02 mode=040755 ouid=0 ogid=0 rdev=00:00 nametype=PARENT type=PATH msg=audit(1479982525.380:50): item=1 name="/var/log/audit/tmp_directory1/malware.py" inode=399852 dev=ca:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=CREATE type=PROCTITLE msg=audit(1479982525.380:50): proctitle=746F756368002F7661722F6C6F672F61756469742F746D705F6469726563746F7279312F6D616C776172652E7079
-->
<!-- ID -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <prematch offset="after_parent">^SYSCALL </prematch>
  <regex offset="after_parent">^(SYSCALL) msg=audit\(\d\d\d\d\d\d\d\d\d\d.\d\d\d:(\d+)\): </regex>
  <order>audit.type,audit.id</order>
</decoder>

<!-- SYSCALL -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">^arch=(\S+) syscall=(\d+) success=(\S+) exit=(\S+) a0=\S+ a1=\S+ a2=\S+ a3=\S+ items=\S+ ppid=(\S+) pid=(\S+) auid=(\S+) uid=(\S+) gid=(\S+) euid=(\S+) suid=(\S+) fsuid=(\S+) egid=(\S+) sgid=(\S+) fsgid=(\S+) tty=(\S+) ses=(\S+) comm=\p(\S+)\p exe=\p(\S+)\p</regex>
  <order>audit.arch,audit.syscall,audit.success,audit.exit,audit.ppid,audit.pid,audit.auid,audit.uid,audit.gid,audit.euid,audit.suid,audit.fsuid,audit.egid,audit.sgid,audit.fsgid,audit.tty,audit.session,audit.command,audit.exe</order>
</decoder>

<!-- SYSCALL - command -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">comm=\p*(\w+)\p*</regex>
  <order>audit.command</order>
</decoder>

<!-- SYSCALL - exe -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">exe=\p(\S+)\p</regex>
  <order>audit.exe</order>
</decoder>

<!-- SYSCALL - key -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">key=\((\S+)\)|key="(\S+)"|key=(\S+) </regex>
  <order>audit.key</order>
</decoder>

<!-- EXECVE -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">type=EXECVE msg=audit\(\S+\): argc=\d+ a0="(\.+)" </regex>
  <order>audit.execve.a0</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a1="(\.+)" </regex>
  <order>audit.execve.a1</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a2="(\.+)" </regex>
  <order>audit.execve.a2</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a3="(\.+)" </regex>
  <order>audit.execve.a3</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a4="(\.+)" </regex>
  <order>audit.execve.a4</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a5="(\.+)" </regex>
  <order>audit.execve.a5</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a6="(\.+)" </regex>
  <order>audit.execve.a6</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a7="(\.+)" </regex>
  <order>audit.execve.a7</order>
</decoder>

If we try to decode an EXECVE log:

 /var/ossec/bin/wazuh-logtest
Starting wazuh-logtest v4.3.10
Type one log per line

type=EXECVE msg=audit(1679976881.124:141017): argc=5 a0="/bin/sh" a1="-e" a2="/etc/NetworkManager/dispatcher.d/01-ifupdown" a3="ens33" a4="dhcp4-change"

**Phase 1: Completed pre-decoding.
        full event: 'type=EXECVE msg=audit(1679976881.124:141017): argc=5 a0="/bin/sh" a1="-e" a2="/etc/NetworkManager/dispatcher.d/01-ifupdown" a3="ens33" a4="dhcp4-change"'

**Phase 2: Completed decoding.
        name: 'auditd'

**Phase 3: Completed filtering (rules).
        id: '80700'
        level: '0'
        description: 'Audit: Messages grouped.'
        groups: '['audit']'
        firedtimes: '1'
        mail: 'False'

we can verify that it has not been decoded correctly. However, if between these two types of decoder (SYSCALL and EXECVE) we add a dummy:

<decoder name="auditd-dummy">
  <parent>auditd</parent>
  <prematch>^test</prematch>
  <regex>(\.+)</regex>
  <order>test</order>
</decoder>

and we run the test again:

# /var/ossec/bin/wazuh-logtestl
Starting wazuh-logtest v4.3.10
Type one log per line

type=EXECVE msg=audit(1679976881.124:141017): argc=5 a0="/bin/sh" a1="-e" a2="/etc/NetworkManager/dispatcher.d/01-ifupdown" a3="ens33" a4="dhcp4-change"

**Phase 1: Completed pre-decoding.
        full event: 'type=EXECVE msg=audit(1679976881.124:141017): argc=5 a0="/bin/sh" a1="-e" a2="/etc/NetworkManager/dispatcher.d/01-ifupdown" a3="ens33" a4="dhcp4-change"'

**Phase 2: Completed decoding.
        name: 'auditd'
        parent: 'auditd'
        audit.execve.a0: '/bin/sh'
        audit.execve.a1: '-e'
        audit.execve.a2: '/etc/NetworkManager/dispatcher.d/01-ifupdown'
        audit.execve.a3: 'ens33'
        audit.id: '141017'
        audit.type: 'EXECVE'

**Phase 3: Completed filtering (rules).
        id: '80700'
        level: '0'
        description: 'Audit: Messages grouped.'
        groups: '['audit']'
        firedtimes: '1'
        mail: 'False'

we check that this time it does decode the fields correctly.

Even with this, we can see that the a4="dhcp4-change" field has not been decoded either. The last field is not being decoded due to an extra space at the end of each field in the decoders.

To resolve this, please update the EXECVE decoders to the following:

<!-- EXECVE -->
<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">type=EXECVE msg=audit\(\S+\): argc=\d+ a0="(\.+)" </regex>
  <order>audit.execve.a0</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a1="(\.+)"</regex>
  <order>audit.execve.a1</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a2="(\.+)"</regex>
  <order>audit.execve.a2</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a3="(\.+)"</regex>
  <order>audit.execve.a3</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a4="(\.+)"</regex>
  <order>audit.execve.a4</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a5="(\.+)"</regex>
  <order>audit.execve.a5</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a6="(\.+)"</regex>
  <order>audit.execve.a6</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">a7="(\.+)"</regex>
  <order>audit.execve.a7</order>
</decoder>

output:

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

**Phase 1: Completed pre-decoding.
        full event: 'type=EXECVE msg=audit(1679976881.124:141017): argc=5 a0="/bin/sh" a1="-e" a2="/etc/NetworkManager/dispatcher.d/01-ifupdown" a3="ens33" a4="dhcp4-change"'

**Phase 2: Completed decoding.
        name: 'auditd'
        audit.execve.a1: '-e'
        audit.execve.a2: '/etc/NetworkManager/dispatcher.d/01-ifupdown'
        audit.execve.a3: 'ens33'
        audit.execve.a4: 'dhcp4-change'

**Phase 3: Completed filtering (rules).
        id: '80700'
        level: '0'
        description: 'Audit: Messages grouped.'
        groups: '['audit']'
        firedtimes: '1'
        mail: 'False'
Rebits commented 1 year ago

It appears that the current issue is hindering the creation of custom decoders for auditd, and could potentially being impacting other aspects of the ruleset as well.

This problem has been reported by the community. We aim to enhance the SYSCALL auditd decoder to capture additional fields such as AUID and UID in the provided log:

type=SYSCALL msg=audit(1689686195.372:594462): arch=c000003e syscall=59 success=yes exit=0 a0=1820440 ... SYSCALL=execve AUID="testing" UID="testing" GID="test" EUID="testing"

We have proposed the following decoders:

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">AUID=\p(\S+)\p </regex>
  <order>audit.auid_name</order>
</decoder>

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_regex">UID=\p(\S+)\p </regex>
  <order>audit.uid_name</order>
</decoder>

However, these decoders do not function properly when defined in the local_decoders file. They only seem to work when integrated into the native auditd Wazuh decoders, just before the following decoder:

<decoder name="auditd-config_change">
  <parent>auditd</parent>
  <regex offset="after_regex">res=(\S+)</regex>
  <order>audit.res</order>
</decoder>

Nevertheless, this approach is not maintainable as changes to the ruleset will be lost after an upgrade. Therefore, further investigation into this issue is required.

zbalkan commented 1 year ago

I came here to open an issue on this specific issue. Though, I tried with other fields, too.

<decoder name="auditd-syscall">
  <parent>auditd</parent>
  <regex offset="after_parent" type="pcre2">AUID="(\S+)" UID="(\S+)" GID="(\S+)" EUID="(\S+)" SUID="(\S+)" FSUID="(\S+)" EGID="(\S+)" SGID="(\S+)" FSGID="(\S+)"</regex>
  <order>audit.auid_resolved,audit.uid_resolved,audit.gid_resolved,audit.euid_resolved,audit.suid_resolved,audit.fsuid_resolved,audit.egid_resolved,audit.sgid_resolved,audit.fsgid_resolved</order>
</decoder>

Though, when it comes to auditd, laurel has better parsing and enrichment capabilities. I requested to make use of it too. https://github.com/wazuh/wazuh/issues/14461

I am not sure how it would be possible. But we need the uid -> username resolution for proper alerting.