Linux auditd for Threat Hunting [Part 1]

  • Quick intro to the Linux Audit System
  • Tips when writing audit rules
  • Designing a configuration for security monitoring
  • What to record with auditd
  • Tips on managing noise

The Linux Audit System

The Linux Audit system provides a way to log events that happen on a Linux system. The recording options offered by the Audit system is extensive — process, network, file, user login/logout events, etc. In this series, I only focus on the security-relevant events from a detection standpoint. The entire list of types that can be recorded are listed here. This list will come handy when analyzing logs.

Audit System Architecture (source: RedHat)
  • audit.rules: Tells the audit daemon what to record. This is where most of one’s time should go — deciding what events are most important to you
  • audit.conf: Governs how the audit daemon runs. Log file location, buffer size, log rotation criteria, etc. I would not mess around too much with this file, but we’ll get to some important parameters of it later

Writing Audit rules

What you specify in the audit.rules file is what finally lands up in the audit.log. When the audit daemon (auditd) is started (ensure that’s on system startup), rules defined in this file is what gives you events in the audit.log.

  • File watches — can watch read, write, execute or attribute changes
  • Syscalls — record syscalls sent to the kernel by the application
  • Utilize tagging — audit rules allow for tagging (-k) which is very helpful when analyzing events later. You could use your own custom tags or even tag rules with MITRE IDs (see bfuzzy1’s link above)
  • When monitoring syscalls, it’s often better to monitor the syscall upon exit rather than entry (-always,exit). Important parameters may not be available at the time of function entry because they aren’t defined yet, hence you miss it too
  • When doing syscall auditing always try to combine rules where you can (-a always,exit -S rmdir -S unlink -S rename). Each syscall rule gets evaluated for every syscall every program makes. It adds up, thereby impacting performance
  • When writing rules, you may come across a filter criteria ‘-F auid!=4294967295’. This number is the equivalent of 0xFFFFFFFF which is the highest unsigned int number. It evaluates to -1 which in auditd world is equivalent to “unset”, i.e, it’s not defined yet. It’s common for this to happen with processes that initialize before the audit daemon. As in the audit.rules man page
  • A note on exclusions — ensure your exclusions (-a never,exclude) are specific and placed on top so they get matched first. There are debates on whether specific includes or excludes should go on top. Specific includes would be the best for performance but I don’t find this a feasible option for large environments. Often times, the syscalls (like execve) are where you gain maximum visibility from a security detection perspective. Were you to place them right on top, you’d have little scope for performance tuning thereafter.

What to record?

The Linux audit subsystem allows us to record a lot of information. The question I look to provide some clarity to is — what’s worth recording and what isn’t?

Source: https://github.com/mitre-attack/attack-datasources
Data Source to Audit Rule Mapping

Closing Notes

I believe auditd can indeed be used as a means for detecting threats on Linux endpoints, even in large environments. Throwing in a pre-configured rule set from the internet will give you issues however. Knowing exactly what you want to monitor and eliminating noisy events using methods described in this post, will help you arrive at a configuration suitable for even large, complex environments.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store