auditrd

package module
v1.0.1-0...-644725c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2021 License: MIT Imports: 17 Imported by: 0

README

auditrd - A library to read Linux audit logs

License

About

auditrd is a library implemented in pure Go which exposes an API to read and process the Linux audit logs from an already existing set of audit rules. This library is a fork from slackhq/go-audit which is then transformed to expose a client API. The motive of this library is the ability to manipulate audit logs in a more flexible way than writing a audisp plugin or writing C code.

Goals

To justify yet another audit client other than the go-audit , go-libaudit or osquery is to be able to provide a simpler yet low level API to read audit logs rather than defining what can be done with it. It's implemented in pure Go which adds another layer of flexibility to it in terms of

  • being compiled
  • relatively safe and quick to implement
  • ability to write plugins for osquery using osquery-go

If you are familiar with osquery, it already has an Audit log client, so why use this? The builtin log parser uses a different philosophy to identify FIM events which can be lead to less false positives but can lead to relatively high CPU utilization and subsequent respawns by the watchdog. This library has existing parsers for a more simplified approach which may introduce a few false positives given the rules are configured correctly.

Usage

The library can be used in the following way (checkout pkg/cmd/audit.go which can also be used as a runnable binary on a linux system.

make
sudo ./audit
API Usage
rd, _ := auditrd.NewAuditReader(1100, 1400, 1024, 1024)
for msg := range rd {
    if msg != nil {
        // allocate buffers for audit logs events per event ID
        tokenList := make([]auditrd.AuditMessageTokenMap, 0, 6)

        // Iterate over all events for a single event ID and tokenize them
        for _, d := range msg.Msgs {
            tokenList = append(tokenList, auditrd.AuditMessageTokenMap{
                AuditEventType: d.Type,
                Tokens:         auditrd.Tokenize(d.Data),
            })
        }

        // Run a parser on the Tokenized Events
        ev, ok := auditrd.ParseAuditEvent(tokenList)
        if ok {
            // If a valid event (process_event of fim_event) is found
            // print it to stdout
            json.NewEncoder(os.Stdout).Encode(ev)
        }
    }
}

Documentation

Index

Constants

View Source
const (
	// MAX_AUDIT_MESSAGE_LENGTH see https://github.com/torvalds/linux/blob/v5.6/include/uapi/linux/audit.h#L441
	MAX_AUDIT_MESSAGE_LENGTH = 8970

	AUDIT_NLGRP_READLOG = 1
)
View Source
const (
	AUDIT_GET         uint16 = 1000 /* Get status */
	AUDIT_SET         uint16 = 1001 /* Set status (enable/disable/auditd) */
	AUDIT_LIST        uint16 = 1002 /* List syscall rules -- deprecated */
	AUDIT_ADD         uint16 = 1003 /* Add syscall rule -- deprecated */
	AUDIT_DEL         uint16 = 1004 /* Delete syscall rule -- deprecated */
	AUDIT_USER        uint16 = 1005 /* Message from userspace -- deprecated */
	AUDIT_LOGIN       uint16 = 1006 /* Define the login id and information */
	AUDIT_WATCH_INS   uint16 = 1007 /* Insert file/dir watch entry */
	AUDIT_WATCH_REM   uint16 = 1008 /* Remove file/dir watch entry */
	AUDIT_WATCH_LIST  uint16 = 1009 /* List all file/dir watches */
	AUDIT_SIGNAL_INFO uint16 = 1010 /* Get info about sender of signal to auditd */
	AUDIT_ADD_RULE    uint16 = 1011 /* Add syscall filtering rule */
	AUDIT_DEL_RULE    uint16 = 1012 /* Delete syscall filtering rule */
	AUDIT_LIST_RULES  uint16 = 1013 /* List syscall filtering rules */
	AUDIT_TRIM        uint16 = 1014 /* Trim junk from watched tree */
	AUDIT_MAKE_EQUIV  uint16 = 1015 /* Append to watched tree */
	AUDIT_TTY_GET     uint16 = 1016 /* Get TTY auditing status */
	AUDIT_TTY_SET     uint16 = 1017 /* Set TTY auditing status */
	AUDIT_SET_FEATURE uint16 = 1018 /* Turn an audit feature on or off */
	AUDIT_GET_FEATURE uint16 = 1019 /* Get which features are enabled */

	AUDIT_FIRST_USER_MSG  uint16 = 1100 /* Userspace messages mostly uninteresting to kernel */
	AUDIT_USER_AUTH       uint16 = 1100 /* User system access authentication */
	AUDIT_USER_ACCT       uint16 = 1101 /* User system access authorization */
	AUDIT_USER_AVC        uint16 = 1107 /* We filter this differently */
	AUDIT_USER_TTY        uint16 = 1124 /* Non-ICANON TTY input meaning */
	AUDIT_LAST_USER_MSG   uint16 = 1199
	AUDIT_FIRST_USER_MSG2 uint16 = 2100 /* More user space messages */
	AUDIT_LAST_USER_MSG2  uint16 = 2999

	AUDIT_DAEMON_START  uint16 = 1200 /* Daemon startup record */
	AUDIT_DAEMON_END    uint16 = 1201 /* Daemon normal stop record */
	AUDIT_DAEMON_ABORT  uint16 = 1202 /* Daemon error stop record */
	AUDIT_DAEMON_CONFIG uint16 = 1203 /* Daemon config change */

	AUDIT_SYSCALL uint16 = 1300 /* Syscall event */
	/* AUDIT_FS_WATCHuint16 =      1301     * Deprecated */
	AUDIT_PATH           uint16 = 1302 /* Filename path information */
	AUDIT_IPC            uint16 = 1303 /* IPC record */
	AUDIT_SOCKETCALL     uint16 = 1304 /* sys_socketcall arguments */
	AUDIT_CONFIG_CHANGE  uint16 = 1305 /* Audit system configuration change */
	AUDIT_SOCKADDR       uint16 = 1306 /* sockaddr copied as syscall arg */
	AUDIT_CWD            uint16 = 1307 /* Current working directory */
	AUDIT_EXECVE         uint16 = 1309 /* execve arguments */
	AUDIT_IPC_SET_PERM   uint16 = 1311 /* IPC new permissions record type */
	AUDIT_MQ_OPEN        uint16 = 1312 /* POSIX MQ open record type */
	AUDIT_MQ_SENDRECV    uint16 = 1313 /* POSIX MQ send/receive record type */
	AUDIT_MQ_NOTIFY      uint16 = 1314 /* POSIX MQ notify record type */
	AUDIT_MQ_GETSETATTR  uint16 = 1315 /* POSIX MQ get/set attribute record type */
	AUDIT_KERNEL_OTHER   uint16 = 1316 /* For use by 3rd party modules */
	AUDIT_FD_PAIR        uint16 = 1317 /* audit record for pipe/socketpair */
	AUDIT_OBJ_PID        uint16 = 1318 /* ptrace target */
	AUDIT_TTY            uint16 = 1319 /* Input on an administrative TTY */
	AUDIT_EOE            uint16 = 1320 /* End of multi-record event */
	AUDIT_BPRM_FCAPS     uint16 = 1321 /* Information about fcaps increasing perms */
	AUDIT_CAPSET         uint16 = 1322 /* Record showing argument to sys_capset */
	AUDIT_MMAP           uint16 = 1323 /* Record showing descriptor and flags in mmap */
	AUDIT_NETFILTER_PKT  uint16 = 1324 /* Packets traversing netfilter chains */
	AUDIT_NETFILTER_CFG  uint16 = 1325 /* Netfilter chain modifications */
	AUDIT_SECCOMP        uint16 = 1326 /* Secure Computing event */
	AUDIT_PROCTITLE      uint16 = 1327 /* Proctitle emit event */
	AUDIT_FEATURE_CHANGE uint16 = 1328 /* audit log listing feature changes */
	AUDIT_REPLACE        uint16 = 1329 /* Replace auditd if this packet unanswerd */
	AUDIT_KERN_MODULE    uint16 = 1330 /* Kernel Module events */
	AUDIT_FANOTIFY       uint16 = 1331 /* Fanotify access decision */
	AUDIT_TIME_INJOFFSET uint16 = 1332 /* Timekeeping offset injected */
	AUDIT_TIME_ADJNTPVAL uint16 = 1333 /* NTP value adjustment */
	AUDIT_BPF            uint16 = 1334 /* BPF subsystem */
	AUDIT_EVENT_LISTENER uint16 = 1335 /* Task joined multicast read socket */

	AUDIT_AVC               uint16 = 1400 /* SE Linux avc denial or grant */
	AUDIT_SELINUX_ERR       uint16 = 1401 /* Internal SE Linux Errors */
	AUDIT_AVC_PATH          uint16 = 1402 /* dentry, vfsmount pair from avc */
	AUDIT_MAC_POLICY_LOAD   uint16 = 1403 /* Policy file load */
	AUDIT_MAC_STATUS        uint16 = 1404 /* Changed enforcing,permissive,off */
	AUDIT_MAC_CONFIG_CHANGE uint16 = 1405 /* Changes to booleans */
	AUDIT_MAC_UNLBL_ALLOW   uint16 = 1406 /* NetLabel: allow unlabeled traffic */
	AUDIT_MAC_CIPSOV4_ADD   uint16 = 1407 /* NetLabel: add CIPSOv4 DOI entry */
	AUDIT_MAC_CIPSOV4_DEL   uint16 = 1408 /* NetLabel: del CIPSOv4 DOI entry */
	AUDIT_MAC_MAP_ADD       uint16 = 1409 /* NetLabel: add LSM domain mapping */
	AUDIT_MAC_MAP_DEL       uint16 = 1410 /* NetLabel: del LSM domain mapping */
	AUDIT_MAC_IPSEC_ADDSA   uint16 = 1411 /* Not used */
	AUDIT_MAC_IPSEC_DELSA   uint16 = 1412 /* Not used  */
	AUDIT_MAC_IPSEC_ADDSPD  uint16 = 1413 /* Not used */
	AUDIT_MAC_IPSEC_DELSPD  uint16 = 1414 /* Not used */
	AUDIT_MAC_IPSEC_EVENT   uint16 = 1415 /* Audit an IPSec event */
	AUDIT_MAC_UNLBL_STCADD  uint16 = 1416 /* NetLabel: add a static label */
	AUDIT_MAC_UNLBL_STCDEL  uint16 = 1417 /* NetLabel: del a static label */
	AUDIT_MAC_CALIPSO_ADD   uint16 = 1418 /* NetLabel: add CALIPSO DOI entry */
	AUDIT_MAC_CALIPSO_DEL   uint16 = 1419 /* NetLabel: del CALIPSO DOI entry */

	AUDIT_FIRST_KERN_ANOM_MSG   uint16 = 1700
	AUDIT_LAST_KERN_ANOM_MSG    uint16 = 1799
	AUDIT_ANOM_PROMISCUOUS      uint16 = 1700 /* Device changed promiscuous mode */
	AUDIT_ANOM_ABEND            uint16 = 1701 /* Process ended abnormally */
	AUDIT_ANOM_LINK             uint16 = 1702 /* Suspicious use of file links */
	AUDIT_ANOM_CREAT            uint16 = 1703 /* Suspicious file creation */
	AUDIT_INTEGRITY_DATA        uint16 = 1800 /* Data integrity verification */
	AUDIT_INTEGRITY_METADATA    uint16 = 1801 /* Metadata integrity verification */
	AUDIT_INTEGRITY_STATUS      uint16 = 1802 /* Integrity enable status */
	AUDIT_INTEGRITY_HASH        uint16 = 1803 /* Integrity HASH type */
	AUDIT_INTEGRITY_PCR         uint16 = 1804 /* PCR invalidation msgs */
	AUDIT_INTEGRITY_RULE        uint16 = 1805 /* policy rule */
	AUDIT_INTEGRITY_EVM_XATTR   uint16 = 1806 /* New EVM-covered xattr */
	AUDIT_INTEGRITY_POLICY_RULE uint16 = 1807 /* IMA policy rules */

	AUDIT_KERNEL uint16 = 2000 /* Asynchronous audit record. NOT A REQUEST. */
)
View Source
const (
	HEADER_MIN_LENGTH = 7               // Minimum length of an audit header
	HEADER_START_POS  = 6               // Position in the audit header that the data starts
	COMPLETE_AFTER    = time.Second * 2 // Log a message after this time or EOE
)
View Source
const (
	EVENT_EOE = 1320 // End of multi packet event
)

Variables

This section is empty.

Functions

func IsExecSyscall

func IsExecSyscall(syscallNumber int) bool

func IsFIMSyscall

func IsFIMSyscall(syscallNumber int) bool

func IsUserEvent

func IsUserEvent(eventType uint16) bool

func NewAuditMarshaller

func NewAuditMarshaller(
	writer chan *AuditMessageGroup,
	minAuditEventType uint16, maxAuditEventType uint16,
	trackMessages, logOOO bool, maxOOO int,
) *auditMarshaller

Create a new marshaller

func NewAuditReader

func NewAuditReader(
	minAuditEventType, maxAuditEventType uint16,
	auditMessageBufferSize int,
	recvSize int,
) (chan *AuditMessageGroup, error)

NewAuditReader returns a channel which can be read from for the AuditMessageGroup which are parsed messages from the netlink socket of the NETLINK_AUDIT type.

func SyscallName

func SyscallName(syscallNumber int) string

func SyscallNumber

func SyscallNumber(syscallName string) int

func Tokenize

func Tokenize(data string) map[string]string

Types

type AuditEvent

type AuditEvent struct {
	Name        AuditEventType `json:"name"`
	Arch        string         `json:"arch,omitempty"`
	Success     string         `json:"success,omitempty"`
	Syscall     string         `json:"syscall"`
	Exit        int            `json:"exit"`
	Ppid        int            `json:"ppid"`
	Pid         int            `json:"pid"`
	Auid        int            `json:"auid"`
	Uid         int            `json:"uid"`
	Gid         int            `json:"gid"`
	Euid        int            `json:"euid"`
	Egid        int            `json:"egid"`
	Fsuid       int            `json:"fsuid"`
	Fsgid       int            `json:"fsgid"`
	Suid        int            `json:"suid"`
	Sgid        int            `json:"sgid"`
	Session     int            `json:"session"`
	Msg         string         `json:"msg,omitempty"`
	Terminal    string         `json:"terminal,omitempty"`
	Hostname    string         `json:"hostname,omitempty"`
	Res         string         `json:"res,omitempty"`
	Tty         string         `json:"tty,omitempty"`
	Comm        string         `json:"comm,omitempty"`
	Key         string         `json:"key,omitempty"`
	Cwd         string         `json:"cwd,omitempty"`
	Exectuable  string         `json:"exectuable,omitempty"`
	Commandline string         `json:"commandline,omitempty"`
	Path        string         `json:"path,omitempty"`
	DestPath    string         `json:"dest_path,omitempty"`
}

func ParseAuditEvent

func ParseAuditEvent(tokenList []AuditMessageTokenMap) (*AuditEvent, bool)

ParseAuditEvent is a audit message parser that reads all the events for an audit event id and returns 2 types of AuditEvents, "process_event" and "fim_event" depending on what syscalls they were emitted for. If the list of audit events don't qualify for either of them, a nil event and false is returned which must be checked to identify a failed parsing.

type AuditEventType

type AuditEventType string
var (
	ProcessEvent AuditEventType = "process_event"
	FIMEvent     AuditEventType = "fim_event"
	UserEvent    AuditEventType = "user_event"
)

type AuditMessage

type AuditMessage struct {
	Type      uint16 `json:"type"`
	Data      string `json:"data"`
	Seq       int    `json:"-"`
	AuditTime string `json:"-"`

	Containers map[string]string `json:"containers,omitempty"`
}

AuditMessage represents a single audit message emitted from the netlink socket.

type AuditMessageGroup

type AuditMessageGroup struct {
	Seq           int             `json:"sequence"`
	AuditTime     string          `json:"timestamp"`
	CompleteAfter time.Time       `json:"-"`
	Msgs          []*AuditMessage `json:"messages"`
}

AuditMessageGroup contains a sequence of audit messages that have the same sequence number and it's the sequence number the reply from the socket packet counter. Usually the audit message contains a starting packet and ending packet and some packets in between. They represent the same event.

type AuditMessageTokenMap

type AuditMessageTokenMap struct {
	AuditEventType uint16
	Tokens         map[string]string
}

AuditMessageTokenMap is a struct that contains a single audit log in key value form. The audit log has key values pairs like key=value and a map is created out of it.

type Client

type Client interface {
	Send(*netlinkPacket, *auditStatusPayload) error
	Receive() (*syscall.NetlinkMessage, error)
}

The audit message client interface

func NewNetlinkClient

func NewNetlinkClient(recvSize int, readonly bool) (Client, error)

NewNetlinkClient creates a client to the audit netlink socket to read the audit logs. This accepts a parameter, readonly, which tells the client to bind it's PID or not not. If the client does not bind it's PID, it needs to connect to the socket in the read only group. Note that this flag should only be used in Linux Kernel version v3.16 or above.

Directories

Path Synopsis
pkg
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL