threathunters-io / laurel

Transform Linux Audit logs for SIEM usage
GNU General Public License v3.0
695 stars 56 forks source link

Add simple message filters #24

Closed hillu closed 2 years ago

hillu commented 3 years ago

If the SYSCALL message contains a specific key (from the -k option in audit rules), there should at least the following options:

aderumier commented 2 years ago

Hi, could it be possible to also filter based on exe ? it could be very usefull to filter cron, as it's very difficult with auditd rules when selinux is not used.

example of cron generate events:

{"ID":"1660300620.052:41286155","CRED_ACQ":{"pid":19691,"uid":0,"auid":4294967295,"ses":4294967295,"subj":"=unconfined","msg":"op=PAM:setcred grantors=pam_permit acct=\"root\" exe=\"/usr/sbin/cron\" hostname=? addr=? terminal=cron res=success","UID":"root","AUID":"unset","UID":"root","AUID":"unset"}}
{"ID":"1660300620.936:41286173","CRED_DISP":{"pid":19453,"uid":0,"auid":0,"ses":2702944,"subj":"=unconfined","msg":"op=PAM:setcred grantors=pam_permit acct=\"root\" exe=\"/usr/sbin/cron\" hostname=? addr=? terminal=cron res=success","UID":"root","AUID":"root","UID":"root","AUID":"root"}}
{"ID":"1660300740.034:41286600","USER_START":{"pid":20198,"uid":0,"auid":0,"ses":2702972,"subj":"=unconfined","msg":"op=PAM:session_open grantors=pam_loginuid,pam_env,pam_env,pam_permit,pam_unix,pam_limits acct=\"root\" exe=\"/usr/sbin/cron\" hostname=? addr=? terminal=cron res=success","UID":"root","AUID":"root","UID":"root","AUID":"root"}}
{"ID":"1660300740.834:41286606","USER_END":{"pid":19937,"uid":0,"auid":0,"ses":2702965,"subj":"=unconfined","msg":"op=PAM:session_close grantors=pam_loginuid,pam_env,pam_env,pam_permit,pam_unix,pam_limits acct=\"root\" exe=\"/usr/sbin/cron\" hostname=? addr=? terminal=cron res=success","UID":"root","AUID":"root","UID":"root","AUID":"root"}}
{"ID":"1660300740.034:41286596","USER_ACCT":{"pid":20201,"uid":0,"auid":4294967295,"ses":4294967295,"subj":"=unconfined","msg":"op=PAM:accounting grantors=pam_permit acct=\"root\" exe=\"/usr/sbin/cron\" hostname=? addr=? terminal=cron res=success","UID":"root","AUID":"unset","UID":"root","AUID":"unset"}}

with auditbeat, it's possible to do something like

processors:
        - drop_event:
            when:
              equals:
                process.executable: "/usr/sbin/cron"

Also, if filtering from exe from parent_info could be great too:

here an example of telegraf parent daemon , calling sudo to launch another executable. I would like to filter all the parent exe events.

{"ID":"1660300798.511:41286809","SYSCALL":{"arch":"0xc000003e","syscall":257,"success":"yes","exit":4,"items":1,"ppid":32229,"pid":20451,"auid":4294967295,"uid":0,"gid":0,"euid":1,"suid":0,"fsuid":1,"egid":0,"sgid":0,"fsgid":0,"tty":"(none)","ses":4294967295,"comm":"sudo","exe":"/usr/bin/sudo","subj":"=unconfined","key":"priv_esc","AUID":"unset","UID":"root","GID":"root","EUID":"daemon","SUID":"root","FSUID":"daemon","EGID":"root","SGID":"root","FSGID":"root","ARGV":["0xffffff9c","0x5642f6302f84","0x0","0x0"],"ARCH":"x86_64","SYSCALL":"openat","AUID":"unset","UID":"root","GID":"root","EUID":"daemon","SUID":"root","FSUID":"daemon","EGID":"root","SGID":"root","FSGID":"root"},"PATH":[{"item":0,"name":"/etc/sudoers.d/50_telegraf_unbound","inode":17778432,"dev":"08:01","mode":"0o100440","ouid":0,"ogid":0,"rdev":"00:00","nametype":"NORMAL","cap_fp":"0x0","cap_fi":"0x0","cap_fe":0,"cap_fver":"0x0","OUID":"root","OGID":"root","OUID":"root","OGID":"root"}],"PROCTITLE":{"ARGV":["sudo","/usr/sbin/unbound-control","-s","127.0.0.1@8953","stats_noreset"]},"PARENT_INFO":{"comm":"telegraf","exe":"/usr/bin/telegraf","ppid":1}}
hillu commented 2 years ago

@aderumier I'd like to use the process labels for that.

Currently, a key can be turned into a process label (which may then be inherited by the children of the process.) A filtering mechanism that drops events based on those labels would satisfy your requirement.

(I'm sure that the filtering mechanism of auditbeat is more powerful, but I'd rather solve those more complex use-cases with a proper embedded programming language.)

aderumier commented 2 years ago

yes, sure, if we can do it on a process label, it could be great too !

hillu commented 2 years ago

Filtering based on process labels has been implemented as of 3ef7c45f08f9cdd132eca6fe58082816b8dab25c by @Hublerho. Closing this issue.

Hu6li commented 1 year ago

Hi @hillu, I am not sure if the following can be considered an issue and thus if resolved an improvement but I discovered the following use case:

Minimizing/Optimizing the data which is being sent into ones SIEM is of general concern (either due to storage, performance or money reasons). Auditd generates a lot of data and most of the time only a subset of this is required to be sent or stored inside a SIEM. In our custom rules we can flag events using keys and then we are able to filter based on those keys.

Unfortunately there are some situations where it is required to log an event but no key can be set or auditd generates an entry without specifying a rule (for example if SELinux is enforced). This will end with auditd logging "key=(null)" which in turn ends up not being de-serialized in Laurel. This means we cannot filter based on null value keys and all that data will end up in our SIEM.

If you also consider this an issue/improvement I suggest fixing it adding the following code:

https://github.com/threathunters-io/laurel/blob/040b278df534c5aeff71d4cf5864f30108fb286e/src/coalesce.rs#L777-L782

else
        {
            if self.settings.filter_keys.contains("null".as_bytes()) {
                ev.filter = true;
                return;
            }
        }

What do you think?