OpenBSM is an implementation of the now decades old
Sun Basic Security Module (BSM) API and file format, written for OS X Panther (10.3) by McAfee Research under contract to Apple. The work was completed to provide OS X with security auditing, a core component required for Common Criteria evaluation, which is itself a necessary step for doing business with the US Federal Government and other governments around the world that respect
the standard.
Robert Watson, one of the original authors, gives some
background on the project in this interview, including the rationale for choosing BSM:
During the work for Apple, we identified Sun's BSM API and file format as the de facto industry standard for UNIX audit implementations -- it was extensively documented, the foundation of a previously evaluated system, and was extensible to new events and data types.
Apple
released the code under a FreeBSD license, enabling
inclusion in FreeBSD, currently maintained
by Trusted BSD.
Before 10.6 the common criteria audit tools needed to be
downloaded and installed separately, but have been
installed by default since then. The functionality is a little-known goldmine for security purposes. Der Flounder has a
good introduction to the configuration, but I'm going to cover some different aspects.
The /etc/security/audit_control file specifies what to log and retention/rotation policies:
#
# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_control#8 $
#
dir:/var/audit
minfree:5
flags:zz
naflags:zz
policy:cnt,argv
filesz:2M
expire-after:60d AND 1G
superuser-set-sflags-mask:has_authenticated,has_console_access
superuser-clear-sflags-mask:has_authenticated,has_console_access
member-set-sflags-mask:
member-clear-sflags-mask:has_authenticated
The /etc/security/audit_class file defines some default groups of events, which you can use in flags/naflags above to decide which events to record. I found I needed to create a custom class to log the right types of events. Here's the default file with a custom class added:
#
# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_class#6 $
# $FreeBSD$
#
0x00000000:no:invalid class
0x00000001:fr:file read
0x00000002:fw:file write
0x00000004:fa:file attribute access
0x00000008:fm:file attribute modify
0x00000010:fc:file create
0x00000020:fd:file delete
0x00000040:cl:file close
0x00000080:pc:process
0x00000100:nt:network
0x00000200:ip:ipc
0x00000400:na:non attributable
0x00000800:ad:administrative
0x00001000:lo:login_logout
0x00002000:aa:authentication and authorization
0x00004000:ap:application
0x00008000:zz:mycustomclass
0x20000000:io:ioctl
0x40000000:ex:exec
0x80000000:ot:miscellaneous
0xffffffff:all:all flags set
Then you need to annotate the events you want to log with your custom class in /etc/security/audit_event. An example line to log execve (process execution) is below:
23:AUE_EXECVE:execve(2):pc,ex,zz
There is a huge menu of events to choose from, here are some examples: network socket connect/bind/accept, clock changes, auditctl, login/logout, mount, reboot, passwd, crontab modification, ssh, create/modify/update user/group, execve, fork, chmod, chown and many more.
The final piece of configuration is /etc/security/audit_user, which allows for per-user customisation that is combined with the global settings. This allows you to, for example, treat root differently to other users. The format is
username:alwaysaudit:neveraudit
and the default, below, only contains an customisation for root. alwaysaudit is 'lo' which records login/logout, password changes etc. while neveraudit is 'no' which is no exclusions.
#
# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_user#3 $
# $FreeBSD: head/contrib/openbsm/etc/audit_user 157137 2006-03-26 01:44:35Z rwatson $
#
root:lo:no
The auditd LaunchDaemon (/System/Library/LaunchDaemons/com.apple.auditd.plist which runs /usr/sbin/auditd) is responsible for handling the logfiles, rotation etc. There is a commandline utility /usr/sbin/audit which can be used to start/stop/reconfigure the daemon. "audit -s" is supposed to cause a re-sync of configuration, but I found a reboot was often the only really reliable way of making sure new config was applied.
You can get a live feed of the events being logged using praudit, which is very handy for debugging and checking configuration:
sudo praudit -l /dev/auditpipe
This is also the tool to use to get a textual representation of the binary auditlog files which are in the format of starttime.endtime:
praudit -l /var/audit/20130921124047.20130924235958
There is a
GUI app available in the app store for visualising the binary log files, I haven't used it, but it looks reasonable for inspecting small amounts of logs. I wanted to apply existing large-scale log analysis capabilities, which would have been easy had the logs been sent to Apple SysLog (ASL) in plaintext. Sadly they aren't, so if you want to use them off the host you're going to need to either use praudit to convert them to text and ship them, or pump them into ASL yourself, or ship the binary log and convert it to text on the server-side. Running praudit over a set of logs is quite CPU intensive.
auditreduce allows you to read binary audit files and output filtered binary files, but its capabilities are very limited. You can't filter by IP for example (although the functionality was obviously planned
since it is partially implemented, it will take a -o sock="" value, but the filter doesn't get applied). This produces events related to any file under /etc:
auditreduce -o file="/etc" /var/audit/20131018010044.20131023043346 | praudit -l
An event output by praudit will look like this (the one I grabbed happened to be an auditd log rotation):
# auditreduce -m AUE_EXECVE /var/audit/20131023061325.20131023062325 | praudit -l
header,159,11,execve(2),0,Tue Oct 22 23:23:25 2013, + 131 msec,exec arg,/usr/sbin/audit,-n,path,/usr/sbin/audit,path,/usr/sbin/audit,attribute,100755,root,wheel,16777220,2190270,0,subject,-1,root,wheel,root,wheel,50716,100000,0,0.0.0.0,return,success,0,trailer,159,
Since that is basically gibberish, you can use the praudit xml output to get a better idea of what each value means:
# auditreduce -m AUE_EXECVE /var/audit/20131023061325.20131023062325 | praudit -x
<record version="11" event="execve(2)" modifier="0" time="Tue Oct 22 23:23:25 2013" msec=" + 131 msec" >
<exec_args><arg>/usr/sbin/audit</arg><arg>-n</arg></exec_args>
<path>/usr/sbin/audit</path>
<path>/usr/sbin/audit</path>
<attribute mode="100755" uid="root" gid="wheel" fsid="16777220" nodeid="2190270" device="0" />
<subject audit-uid="-1" uid="root" gid="wheel" ruid="root" rgid="wheel" pid="50716" sid="100000" tid="0 0.0.0.0" />
<return errval="success" retval="0" />