From 091bd1e6444a742446dc57108d919238bdf17365 Mon Sep 17 00:00:00 2001 From: Andrew Walker Date: Mon, 9 Dec 2024 14:18:56 -0600 Subject: [PATCH] Cleanup audit rules (#2) Some of rules in base set do not exist in the version of auditd we distribute. A few files in STIG rules do not exist in TrueNAS and prevent auditd load. This commit also adds an optional prefix argument for script to generate privileged rules. This is due to script being run outside chroot environment in scale_build. --- rules/10-base-config.rules | 3 --- rules/30-stig.rules | 4 +--- rules/privileged-rules.py | 29 +++++++++++++++++++++-------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/rules/10-base-config.rules b/rules/10-base-config.rules index ee5ace5..d2fb358 100644 --- a/rules/10-base-config.rules +++ b/rules/10-base-config.rules @@ -7,6 +7,3 @@ ## This determine how long to wait in burst of events --backlog_wait_time 60000 - -## Set failure mode to syslog --f diff --git a/rules/30-stig.rules b/rules/30-stig.rules index 62be71a..3cd69e8 100644 --- a/rules/30-stig.rules +++ b/rules/30-stig.rules @@ -40,8 +40,6 @@ -a always,exit -F arch=b64 -F path=/etc/hosts -F perm=wa -F key=system-locale -a always,exit -F arch=b32 -F path=/etc/hostname -F perm=wa -F key=system-locale -a always,exit -F arch=b64 -F path=/etc/hostname -F perm=wa -F key=system-locale --a always,exit -F arch=b32 -F dir=/etc/NetworkManager/ -F perm=wa -F key=system-locale --a always,exit -F arch=b64 -F dir=/etc/NetworkManager/ -F perm=wa -F key=system-locale ## Things that could affect MAC policy -a always,exit -F arch=b32 -F dir=/etc/selinux/ -F perm=wa -F key=MAC-policy @@ -136,7 +134,7 @@ -a always,exit -F arch=b64 -F path=/usr/bin/systemd-run -F perm=x -F auid!=unset -F key=maybe-escalation ## Always audit call to disable rootfs protection --a always,exit -F arch=b64 -F path=/usr/local/libexec/disable-rootfs-protection -F perm=x -F auid!=unset -F key=maybe-escalation +-a always,exit -F arch=b64 -F path=/usr/local/libexec/disable-rootfs-protection -F perm=x -F key=maybe-escalation ## ZFS-related binares can also be used to bypass system protections. -a always,exit -F arch=b64 -F path=/sbin/zfs -F perm=x -F auid>0 -F key=maybe-escalation diff --git a/rules/privileged-rules.py b/rules/privileged-rules.py index ced53b6..a2cb51d 100755 --- a/rules/privileged-rules.py +++ b/rules/privileged-rules.py @@ -21,30 +21,37 @@ def file_has_setuid_bit(target: str) -> bool: return stat(target).st_mode & S_ISUID -def audit_entry_string(target: str, arch: str) -> str: +def __strip_prefix(target: str, prefix: str) -> str: + return target[len(prefix):] + + +def audit_entry_string(target: str, arch: str, prefix: str) -> str: return ( '-a always,exit ' f'-F arch={arch} ' - f'-F path={target} ' + f'-F path={__strip_prefix(target, prefix)} ' '-F perm=x ' f'-F auid>={USER_ID_MIN} -F auid!=unset ' '-F key=privileged\n' ) -def write_audit_entry(target: str, fh: TextIOWrapper) -> None: - fh.write(audit_entry_string(target, ARCH64)) - fh.write(audit_entry_string(target, ARCH32)) +def write_audit_entry(target: str, fh: TextIOWrapper, prefix: str) -> None: + fh.write(audit_entry_string(target, ARCH64, prefix)) + fh.write(audit_entry_string(target, ARCH32, prefix)) + +def generate_audit_privilege(target_dir: str, privilege_file: str, prefix: str) -> None: + if prefix and not target_dir.startswith(prefix): + raise ValueError(f'{target_dir}: target_dir does not start with prefix [{prefix}]') -def generate_audit_privilege(target_dir: str, privilege_file: str) -> None: with open(privilege_file, 'w') as f: for root, dirs, files in walk(target_dir): for name in files: target = path.join(root, name) try: if file_has_setuid_bit(target) or file_has_capability(target): - write_audit_entry(target, f) + write_audit_entry(target, f, prefix) except FileNotFoundError: # possibly broken symlink pass @@ -62,9 +69,15 @@ def main(): '-p', '--privilege_file', help='File in which to write privilege rules.' ) + parser.add_argument( + '-x', '--prefix', + help='File in which to write privilege rules.', + default='' + ) args = parser.parse_args() - generate_audit_privilege(args.target_dir, args.privilege_file) + + generate_audit_privilege(args.target_dir, args.privilege_file, args.prefix) if __name__ == '__main__':