From ec4536debc6441e26b6f2ee2c8f818a858648d9e Mon Sep 17 00:00:00 2001 From: Darragh O'Reilly Date: Tue, 21 Jul 2026 09:23:52 +0000 Subject: [PATCH] audit: rewrite artifacts to use syscall form watch rules According to `man auditctl` the `-w` form has been deprecated due to poor system performance, and rules should be converted to use the syscall form. --- .../SUSE/Linux/Events/NewFiles.yaml | 34 ++++++++++++++++--- .../SUSE/Linux/Events/NewFilesNoOwner.yaml | 7 ++-- .../SUSE/Linux/Events/NewZeroSizeLogFile.yaml | 5 ++- .../SUSE/Linux/Events/UserAccount.yaml | 9 ++++- .../Events/UserGroupMembershipUpdates.yaml | 7 +++- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/artifacts/definitions/SUSE/Linux/Events/NewFiles.yaml b/artifacts/definitions/SUSE/Linux/Events/NewFiles.yaml index 6a51a0a84..7d790fdf6 100644 --- a/artifacts/definitions/SUSE/Linux/Events/NewFiles.yaml +++ b/artifacts/definitions/SUSE/Linux/Events/NewFiles.yaml @@ -1,20 +1,46 @@ name: SUSE.Linux.Events.NewFiles + description: | This artifact collects Every new file in monitored directory from the Linux kernel. +parameters: + - name: watch_paths + description: List of files and directories to be monitored. + type: json_array + default: '["/etc/init.d", "/etc/rc.local", "/etc/modules", "/etc/cron.allow", "/etc/cron.deny", "/etc/cron.d", "/etc/cron.daily", "/etc/cron.hourly", "/etc/cron.monthly", "/etc/cron.weekly", "/etc/crontab", "/var/spool/cron"]' + precondition: SELECT OS From info() where OS = 'linux' type: CLIENT_EVENT -required_permissions: - - EXECVE - sources: - query: | LET MachineID <= strip(string=read_file(filename="/etc/machine-id"), suffix="\n") - LET new_file_rules = ("-w /etc/init.d -p wa -k vrr_etc_update", "-w /etc/rc.local -p wa -k vrr_etc_update", "-w /etc/modules -p wa -k vrr_etc_update", "-w /etc/cron.allow -p wa -k vrr_etc_update", "-w /etc/cron.deny -p wa -k vrr_etc_update", "-w /etc/cron.d/ -p wa -k vrr_etc_update", "-w /etc/cron.daily/ -p wa -k vrr_etc_update", "-w /etc/cron.hourly/ -p wa -k vrr_etc_update", "-w /etc/cron.monthly/ -p wa -k vrr_etc_update", "-w /etc/cron.weekly/ -p wa -k vrr_etc_update", "-w /etc/crontab -p wa -k vrr_etc_update", "-w /var/spool/cron -p wa -k vrr_etc_update") + LET create_rule(watch_path, is_dir, arch) = if( + condition=is_dir, + then=format(format="-a always,exit -F arch=%s -F dir=%s -F perm=wa -k vrr_etc_update", args=[arch, watch_path]), + else=format(format="-a always,exit -F arch=%s -F path=%s -F perm=wa -k vrr_etc_update", args=[arch, watch_path]) + ) + + LET new_file_rules = array(_={ SELECT Rule FROM foreach( + row={ + SELECT * FROM foreach( + row={ + SELECT _value AS arch FROM foreach(row=["b32", "b64"]) + }, + query={ + SELECT arch, _value as watch_path FROM foreach(row=watch_paths) + } + ) + }, + query={ + SELECT create_rule(watch_path=FullPath, is_dir=IsDir, arch=arch) AS Rule + FROM stat(filename=watch_path) + } + )} + ) LET new_file_log = SELECT timestamp(string=Timestamp) AS Time, Sequence, atoi(string=Summary.Actor.Primary) AS UserId, diff --git a/artifacts/definitions/SUSE/Linux/Events/NewFilesNoOwner.yaml b/artifacts/definitions/SUSE/Linux/Events/NewFilesNoOwner.yaml index 3ac817580..fd673b612 100644 --- a/artifacts/definitions/SUSE/Linux/Events/NewFilesNoOwner.yaml +++ b/artifacts/definitions/SUSE/Linux/Events/NewFilesNoOwner.yaml @@ -29,7 +29,9 @@ sources: // ["/home", "/var/log"] -> ["-w /home -p w -k vrr_home", "-w /var/log -p w -k vrr_var_log"] LET new_files_audit_rules = array( - a={ SELECT "-w " + _value + " -p w -k " + path2key(path=_value) + a={ SELECT "-a always,exit -F arch=b32 -F perm=w -F dir=" + _value + " -k " + path2key(path=_value) + FROM foreach(row=directories) }, + b={ SELECT "-a always,exit -F arch=b64 -F perm=w -F dir=" + _value + " -k " + path2key(path=_value) FROM foreach(row=directories) } ) @@ -64,7 +66,8 @@ sources: Uid, set(item=known_uids, field=Uid, value=TRUE) FROM Artifact.Linux.Sys.Users() } AS _update_known_uids - FROM audit(rules="-w /etc/passwd -p wa -k vrr_etc_passwd") + FROM audit(rules=["-a always,exit -F arch=b32 -F path=/etc/passwd -F perm=wa -F key=vrr_etc_passwd", + "-a always,exit -F arch=b64 -F path=/etc/passwd -F perm=wa -F key=vrr_etc_passwd"]) WHERE "vrr_etc_passwd" IN Tags AND Result = "success" AND Summary.action = "opened-file" diff --git a/artifacts/definitions/SUSE/Linux/Events/NewZeroSizeLogFile.yaml b/artifacts/definitions/SUSE/Linux/Events/NewZeroSizeLogFile.yaml index aa7ea866f..d0854c17d 100644 --- a/artifacts/definitions/SUSE/Linux/Events/NewZeroSizeLogFile.yaml +++ b/artifacts/definitions/SUSE/Linux/Events/NewZeroSizeLogFile.yaml @@ -11,7 +11,10 @@ sources: - query: | LET MachineID <= strip(string=read_file(filename="/etc/machine-id"), suffix="\n") - LET audit_rules = ("-w /var/log -p w -k vrr_var_log") + LET audit_rules = ( + "-a always,exit -F arch=b32 -F dir=/var/log -F perm=w -k vrr_var_log", + "-a always,exit -F arch=b64 -F dir=/var/log -F perm=w -k vrr_var_log" + ) // cleans path with relpath - see https://pkg.go.dev/path/filepath#Rel LET clean_path(path) = "/" + relpath(path=path, base="/") diff --git a/artifacts/definitions/SUSE/Linux/Events/UserAccount.yaml b/artifacts/definitions/SUSE/Linux/Events/UserAccount.yaml index f1411d6fe..4166bc89d 100644 --- a/artifacts/definitions/SUSE/Linux/Events/UserAccount.yaml +++ b/artifacts/definitions/SUSE/Linux/Events/UserAccount.yaml @@ -11,7 +11,14 @@ sources: - query: | LET MachineID <= strip(string=read_file(filename="/etc/machine-id"), suffix="\n") - LET user_acct_rules = ("-w /etc/shadow -p wa -k vrr_etc_shadow", "-w /etc/passwd -p wa -k vrr_etc_passwd", "-w /etc/nsswitch.conf -p wa -k vrr_etc_nsswitch_conf") + LET user_acct_rules = ( + "-a always,exit -F arch=b32 -F path=/etc/shadow -F perm=wa -k vrr_etc_shadow", + "-a always,exit -F arch=b64 -F path=/etc/shadow -F perm=wa -k vrr_etc_shadow", + "-a always,exit -F arch=b32 -F path=/etc/passwd -F perm=wa -k vrr_etc_passwd", + "-a always,exit -F arch=b64 -F path=/etc/passwd -F perm=wa -k vrr_etc_passwd", + "-a always,exit -F arch=b32 -F path=/etc/nsswitch.conf -F perm=wa -k vrr_etc_nsswitch_conf", + "-a always,exit -F arch=b64 -F path=/etc/nsswitch.conf -F perm=wa -k vrr_etc_nsswitch_conf" + ) LET user_acct_log = SELECT timestamp(string=Timestamp) AS Time, Sequence, atoi(string=Process.PID) AS Pid, diff --git a/artifacts/definitions/SUSE/Linux/Events/UserGroupMembershipUpdates.yaml b/artifacts/definitions/SUSE/Linux/Events/UserGroupMembershipUpdates.yaml index f0a6143e1..9e7789e96 100644 --- a/artifacts/definitions/SUSE/Linux/Events/UserGroupMembershipUpdates.yaml +++ b/artifacts/definitions/SUSE/Linux/Events/UserGroupMembershipUpdates.yaml @@ -14,7 +14,12 @@ sources: - query: | LET MachineID <= strip(string=read_file(filename="/etc/machine-id"), suffix="\n") - LET change_log_rules = ("-w /etc/group -p wa -k vrr_etc_group", "-w /etc/nsswitch.conf -p wa -k vrr_etc_nsswitch_conf") + LET change_log_rules = ( + "-a always,exit -F arch=b32 -F path=/etc/group -F perm=wa -k vrr_etc_group", + "-a always,exit -F arch=b64 -F path=/etc/group -F perm=wa -k vrr_etc_group", + "-a always,exit -F arch=b32 -F path=/etc/nsswitch.conf -F perm=wa -k vrr_etc_nsswitch_conf", + "-a always,exit -F arch=b64 -F path=/etc/nsswitch.conf -F perm=wa -k vrr_etc_nsswitch_conf", + ) LET change_log = SELECT timestamp(string=Timestamp) AS Time, Sequence, atoi(string=Summary.Actor.Primary) AS UserId,