macOS Endpoint Security (im_maces)

This module collects logs from Apple’s Endpoint Security auditing system on MacOS 10.15 and later. Endpoint Security is an audit subsystem for monitoring system events for potentially malicious activity.

It is recommended that FlowControl be disabled for im_maces module instances. If the im_maces module instance is suspended, some events can be lost.

macOS Security & Privacy settings

Due to the nature of security auditing, most auditing systems require special privileges to function properly. To prepare macOS for use with this module, the nxlog application requires Full Disk Access. If NXLog Agent is running, stop the nxlog process.

Stop nxlog
sudo launchctl unload /Library/LaunchDaemons/com.nxlog.plist

Navigate to System Preferences > Security & Privacy and select Full Disk Access from the list on the left. After unlocking the settings as an Administrator and checking nxlog, the nxlog process can be restarted:

Start nxlog
sudo launchctl load /Library/LaunchDaemons/com.nxlog.plist

The module will then have sufficient privileges to capture events from Apple’s Endpoint Security auditing system.

Configuration

The im_maces module accepts the following directives in addition to the common module directives.

Optional directives

MutedPathLiteral

This optional directive specifies a path literal to mute. The client stops receiving events from the executable whose paths exactly matches this literal.

MutedPathPrefix

This optional directive specifies a prefix string to mute. The client stops receiving events from executables whose paths begin with this string.

NotifyEvents

This optional directive specifies a list of Apple Endpoint Security notify events to subscribe to. You can use the value All to subscribe to all supported notify events. By default, the following events are enabled: chroot, close, create, exec, exit, fork, kextload, kextunload, open, unlink.

The complete list of supported notify events is listed in the supported event list section below. The Event name column contains the exact name you need to define in this directive.

The availability of these event types depends on the version of macOS. While NotifyEvents allows all of the event types to be specified, im_maces will silently ignore the event types that aren’t supported by the OS version. This means that no configuration errors will be reported about enabled events which aren’t supported by the operating system, nor will these events be generated.
Setting your macOS system time to a past date may result in not collecting clock-related events, such as the settime event that is used to notify about date and time changes.

Supported event list

The API versions of macOS ES determine which events you can collect with NXLog Agent. The tables below describe the required API versions for each event this module can collect.

File-system event types
Event name macOS API version requirement macOS API tag

access

10.15.1+

es_event_access_t

clone

10.15.1+

es_event_clone_t

copyfile

12.0+

es_event_copyfile_t

create

10.15+

es_event_create_t

dup

10.15.1+

es_event_dup_t

fcntl

10.15.1+

es_event_fcntl_t

open

10.15+

es_event_open_t

close

10.15+

es_event_close_t

rename

10.15+

es_event_rename_t

truncate

10.15+

es_event_truncate_t

exchangedata

10.15+

es_event_exchangedata_t

write

10.15+

es_event_write_t

lookup

10.15+

es_event_lookup_t

searchfs

11.0+

es_event_searchfs_t

File metadata event types
Event name macOS API version macOS API tag

deleteextattr

10.15.1+

es_event_deleteextattr_t

fsgetpath

10.15.1+

es_event_fsgetpath_t

getattrlist

10.15.1+

es_event_getattrlist_t

getextattr

10.15.1+

es_event_getextattr_t

listextattr

10.15.1+

es_event_listextattr_t

readdir

10.15.1+

es_event_readdir_t

setacl

10.15.1+

es_event_setacl_t

setattrlist

10.15+

es_event_setattrlist_t

setextattr

10.15+

es_event_setextattr_t

setflags

10.15+

es_event_setflags_t

setmode

10.15+

es_event_setmode_t

setowner

10.15+

es_event_setowner_t

stat

10.15.1+

es_event_stat_t

utimes

10.15.1+

es_event_utimes_t

File provider event types
Event name macOS API version macOS API tag

file_provider_materialize

10.15+

es_event_file_provider_materialize_t

file_provider_update

10.15+

es_event_file_provider_update_t

Link event types
Event name macOS API version macOS API tag

link

10.15+

es_event_link_t

readlink

10.15+

es_event_readlink_t

unlink

10.15+

es_event_unlink_t

File system mounting event types
Event name macOS API version macOS API tag

mount

10.15+

es_event_mount_t

unmount

10.15+

es_event_unmount_t

remount

11.0+

es_event_remount_t

Memory mapping event types
Event name macOS API version macOS API tag

mmap

10.15+

es_event_mmap_t

mprotect

10.15+

es_event_mprotect_t

FProcess event types
Event name macOS API version macOS API tag

chdir

10.15.1+

es_event_chdir_t

chroot

10.15.1+

es_event_chroot_t

exec

10.15+

es_event_exec_t

fork

10.15+

es_event_fork_t

proc_check

10.15.4+

es_event_proc_check_t

signal

10.15+

es_event__t

exit

10.15+

es_event_exit_t

Interprocess events
Event name macOS API version macOS API tag

proc_suspend_resume

11.0+

es_event_proc_suspend_resume_t

trace

11.0+

es_event_trace_t

remote_thread_create

11.0+

es_event_remote_thread_create_t

Task port event types
Event name macOS API version macOS API tag

get_task

10.15+

es_event_get_task_t

get_task_read

11.3+

es_event_get_task_read_t

get_task_inspect

11.3+

es_event_get_task_inspect_t

get_task_name

11.0+

es_event_get_task_name_t

User and group ID types
Event name macOS API version macOS API tag

setuid

12.0+

es_event_setuid_t

setgid

12.0+

es_event_setgid_t

seteuid

12.0+

es_event_seteuid_t

setegid

12.0+

es_event_setegid_t

setreuid

12.0+

es_event_setreuid_t

setregid

12.0+

es_event_setregid_t

Code signing event types
Event name macOS API version macOS API tag

cs_invalidated

11.0+

es_event_cs_invalidated_t

Socket event types
Event name macOS API version macOS API tag

uipc_bind

10.15.1+

es_event_uipc_bind_t

uipc_connect

10.15.1+

es_event_uipc_connect_t

Clock event types
Event name macOS API version macOS API tag

settime

10.15.1+

es_event_settime_t

Kernel event types
Event name macOS API version macOS API tag

iokit_open

10.15+

es_event_iokit_open_t

kextload

10.15+

es_event_kextload_t

kextunload

10.15+

es_event_kextunload_t

Pseudoterminal event types
Event name macOS API version macOS API tag

pty_close

10.15.4+

es_event_pty_close_t

pty_grant

10.15.4+

es_event_pty_grant_t

New endpoint security API
Event name macOS API version macOS API tag

authentication

13.0+

es_event_authentication_t

btm_launch_item_add

13.0+

es_event_btm_launch_item_add_t

btm_launch_item_remove

13.0+

es_event_btm_launch_item_remove_t

login_login

13.0+

es_event_login_login_t

login_logout

13.0+

es_event_login_logout_t

lw_session_lock

13.0+

es_event_lw_session_lock_t

lw_session_login

13.0+

es_event_lw_session_login_t

lw_session_logout

13.0+

es_event_lw_session_logout_t

lw_session_unlock

13.0+

es_event_lw_session_unlock_t

openssh_login

13.0+

es_event_openssh_login_t

openssh_logout

13.0+

es_event_openssh_logout_t

screensharing_attach

13.0+

es_event_screensharing_attach_t

screensharing_detach

13.0+

es_event_screensharing_detach_t

xp_malware_detected

13.0+

es_event_xp_malware_detected_t

xp_malware_remediated

13.0+

es_event_xp_malware_remediated_t

For detailed descriptions of each event, see Apple’s developer documentation page.

Procedures

The following procedures are exported by im_maces.

mute_path_literal(string path_literal);

Suppresses events from executables matching the given path literal.

mute_path_prefix(string path_prefix);

Suppresses events from executables matching the given path prefix.

subscribe(string event);

Subscribes to the specified event.

subscribe_all();

Subscribes to all supported events.

unmute_all_paths();

Unmutes all previously muted executable paths.

unsubscribe(string event);

Unsubscribes from the specified event.

unsubscribe_all();

Unsubscribes from all events.

Fields

The following fields are used by im_maces.

$raw_event (type: string)

A list of event fields in key-value pairs.

$AccessMode (type: integer)

The file-access flags that were used to acces the file (if applicable).

$AccessTime (type: datetime)

The time when the file was last accessed.

$ACL (type: string)

The ACL used for the file (if applicable). Field available only if $MessageVersion is greater than 2.

$ACLAction (type: string)

The operation that was performed on the file’s ACL (set or cear).

$AvailableBlocks (type: integer)

Free blocks in filesystem that are available to non-superusers (if applicable).

$BlockSize (type: integer)

Fundamental filesystem block size (if applicable).

$ClientClass (type: string)

Meta class name of the user client instance for I/O Kit device events.

$ClientType (type: string)

User client type for I/O Kit device events.

$Command (type: integer)

The cmd argument given to fcntl(2).

$CommonAttributes (type: integer)

Common attributes (if applicable).

$CreateMode (type: integer)

The file-creation flags with which the file was created (if applicable).

$DeviceVersion (type: integer)

Major and minor version of the pseudoterminal device.

$Directory (type: string)

Target directory (if applicable).

$DirectoryAttributes (type: integer)

Directory attributes (if applicable).

$Domain (type: integer)

The communications domain of the socket (see socket(2)).

$EventTime (type: datetime)

The date and time of the event.

$EventType (type: string)

The type of Endpoint Security event.

$ExistingFile (type: boolean)

Field which set to true if the file was already present in the system (if applicable).

$ExitCode (type: integer)

The exit code that was passed to the exit(2) system call.

$ExtendedAttributes (type: string)

The extended attributes of the file (if applicable).

$ExtendedFlags (type: integer)

Extended flags for the mount(2)/unmount(2) system calls.

$File (type: string)

Path to the main file that the event reffers to (if applicable).

$FileAttributes (type: integer)

File attributes (if applicable).

$FileFlags (type: integer)

The file flags that were applied to the file.

$FileMode (type: integer)

The new file mode of the file.

$Filename (type: string)

Target filename, relative to the $Directory path (if applicable).

$FilesystemID (type: integer)

The filesystem ID (if applicable).

$FilesystemSubType (type: integer)

The filesystem sub-type (flavor) (if applicable).

$FilesystemType (type: integer)

The filesystem type (if applicable).

$FilesystemTypeName (type: string)

The filesystem type name (if applicable).

$FirstFile (type: string)

The first file to be exchanged.

$ForkAttributes (type: integer)

Fork attributes (if applicable).

$FreeBlocks (type: integer)

Free blocks in filesystem (if applicable).

$FreeFileNodes (type: integer)

Free file nodes in filesystem (if applicable).

$GID (type: integer)

The new GID of the file.

$KernelExtension (type: string)

A string identifying the kernel extension.

$MachTimestamp (type: string)

The number of Mach system clock ticks, which is effectively elapsed nanoseconds.

$MemoryAddress (type: integer)

The base memory address.

$MemoryMapFilePosition (type: integer)

The file offset of the memory map.

$MemoryMapFlags (type: integer)

The type and attributes of the mapped file.

$MemoryMapMaxProtection (type: integer)

The maximum allowed protection value the operating system will respect.

$MemoryMapProtection (type: integer)

The protection (region accessibility) value.

$MemorySize (type: integer)

The size of the memory region.

$MessageSequence (type: integer)

Per-client, per-event-type sequence number that can be inspected to detect whether the kernel had to drop events for this client. Field available only if $MessageVersion is greater than 2.

$MessageVersion (type: integer)

The event message version.

$Modified (type: boolean)

true if the file was modified before the close(2) system call.

$ModifiedTime (type: datetime)

The time when the file was last modified.

$MountedFrom (type: string)

Mounted filesystem for the mount(2)/unmount(2) system calls.

$MountedOn (type: string)

Directory on which the filesystem is mounted (if applicable).

$MountFlags (type: integer)

The filesystem mount flags (if applicable).

$OpenFlags (type: integer)

The file-open kernel flags that were used to open the file (if applicable).

$OwnerUID (type: integer)

The UID of the user that mounted the filesystem (if applicable).

$ProcessCheckFlavor (type: string)

A representation of the process information that was requested, based on the $ProcessCheckType (if applicable).

$ProcessCheckType (type: string)

The type of call number used to check the access on the target process (if applicable).

$ProcessCodeDirectoryHash (type: string)

The code directory hash value of the source process.

$ProcessCodesigningFlags (type: string)

Formatted string containing the hexadecimal representation of the codesigning flags of the source process, as well as the logical expression used to obtain these flags.

$ProcessEffectiveGID (type: integer)

The effective GID of the source process.

$ProcessEffectiveUID (type: integer)

The effective UID of the source process.

$ProcessESClient (type: boolean)

Set to true if the source process is an Endpoint Security client.

$ProcessExecutable (type: string)

The path to the executable of the source process.

$ProcessOriginalParentPID (type: integer)

The PID of the source process' original parent. This field remains constant even when the process is reparented.

$ProcessParentPID (type: integer)

The PID of the source process' parent.

$ProcessPID (type: integer)

The PID of the source process.

$ProcessPIDVersion (type: integer)

The PID version of the source process.

$ProcessPlatformBinary (type: boolean)

Set to true if the source process is a platform binary (signed with Apple certificates).

$ProcessRealGID (type: integer)

The real GID of the source process.

$ProcessRealUID (type: integer)

The real UID of the source process.

$ProcessSessionID (type: integer)

The session ID of the source process.

$ProcessSigningID (type: string)

The identifier used to sign the source process.

$ProcessTeamID (type: string)

The team identifier used to sign the source process.

$ProcessTty (type: string)

The tty from which the source process was invoked. Note: this field is only available if $MessageVersion is greater than 2.

$ProcessUID (type: integer)

The audit UID of the source process.

$Protection (type: integer)

The new memory protection flags.

$Protocol (type: integer)

The protocol of the socket (see socket(2)).

$SecondFile (type: string)

The second file to be exchanged.

$Signal (type: string)

Signal name and number, as passed to the kill(2) system call.

$SocketMode (type: integer)

The mode of the socket file.

$SocketType (type: integer)

The type of the socket.

$TargetFile (type: string)

Full path to the target file (if applicable).

$TargetProcessArgs (type: string)

Formatted list of command-line arguments that were passed to the target process via the exec(2) system call.

$TargetProcessCodeDirectoryHash (type: string)

The code directory hash value of the target process.

$TargetProcessCodesigningFlags (type: string)

Formatted string containing the hexadecimal representation of the codesigning flags of the target process, as well as the logical expression used to obtain these flags.

$TargetProcessEffectiveGID (type: integer)

The effective GID of the target process.

$TargetProcessEffectiveUID (type: integer)

The effective UID of the target process.

$TargetProcessESClient (type: boolean)

Set to true if the target process is an Endpoint Security client.

$TargetProcessExecutable (type: string)

The path to the executable of the target process.

$TargetProcessOriginalParentPID (type: integer)

The PID of the target process' original parent. This field remains constant even when the process is reparented.

$TargetProcessParentPID (type: integer)

The PID of the target process' parent.

$TargetProcessPID (type: integer)

The PID of the target process.

$TargetProcessPIDVersion (type: integer)

The PID version of the target process.

$TargetProcessPlatformBinary (type: boolean)

Set to true if the target process is a platform binary (signed with Apple certificates).

$TargetProcessRealGID (type: integer)

The real GID of the target process.

$TargetProcessRealUID (type: integer)

The real UID of the target process.

$TargetProcessSessionID (type: integer)

The session ID of the target process.

$TargetProcessSigningID (type: string)

The identifier used to sign the target process.

$TargetProcessTeamID (type: string)

The team identifier used to sign the target process.

$TargetProcessTty (type: string)

The tty from which the target process was invoked. Note: this field is only available if $MessageVersion is greater than 2.

$TargetProcessUID (type: integer)

The audit UID of the target process.

$TotalDataBlocks (type: integer)

Total data blocks in filesystem (if applicable).

$TotalFileNodes (type: integer)

Total file nodes in filesystem (if applicable).

$TransferBlockSize (type: integer)

Optimal transfer block size (if applicable).

$UID (type: integer)

The new UID of the file.

$VolumeAttributes (type: integer)

Volume attributes (if applicable).

Examples

Example 1. Collecting Apple endpoint security events

With this configuration, NXLog Agent will collect the events listed in the Events directive.

nxlog.conf
<Input in>
    Module              im_maces
    NotifyEvents        get_task, proc_check, write
</Input>
Example 2. Using procedures to dynamically change the list of collected events

With this configuration, NXLog Agent will only collect up to MAX_WRITE_EVENTS write events.

nxlog.conf
define MAX_WRITE_EVENTS 100

<Input in>
    Module      im_maces
    <Exec>
        create_stat("nwrites", "COUNT");
        if ( get_stat("nwrites") == 0 )
        {
            subscribe("write");
        }
        if ( get_stat("nwrites") == %MAX_WRITE_EVENTS% )
        {
            unsubscribe("write");
        }
        if ( $EventType == "write" )
        {
            add_stat("nwrites", 1);
        }
    </Exec>
</Input>
Example 3. Using directives to mute "spam" processes

With this configuration, NXLog Agent will collect write events from all processes, except for events generated by /usr/bin/tail, /usr/bin/less and all executables under /usr/local/bin/.

nxlog.conf
<Input in>
    Module              im_maces
    NotifyEvents        write
    MutedPathLiteral    '/usr/bin/tail'
    MutedPathLiteral    '/usr/bin/less'
    MutedPathPrefix     '/usr/local/bin'
</Input>
Example 4. Using procedures to dynamically mute "spam" processes

With this configuration, NXLog Agent will collect write events generated by /usr/bin/tail, /usr/bin/less and all executables under /usr/local/bin/. When more than MAX_TAIL_EVENTS, MAX_LESS_EVENTS or MAX_LOCAL_EVENTS events have been generated for each process respectively, the corresponding executable path(s) are muted, meaning that no further events will be generated for any processes located under these paths.

nxlog.conf
define MAX_TAIL_EVENTS  50
define MAX_LESS_EVENTS  100
define MAX_LOCAL_EVENTS 1000

<Input in>
    Module              im_maces
    NotifyEvents        write
    <Exec>
        create_stat("ntail", "COUNT");
        create_stat("nless", "COUNT");
        create_stat("nlocal", "COUNT");
        if ( $Executable == "/usr/bin/tail" )
        {
            add_stat("ntail", 1);
        }
        if ( $Executable == "/usr/bin/less" )
        {
            add_stat("nless", 1);
        }
        if ( $Executable =~ /^(\/usr\/local\/bin\/)(.*)$/ )
        {
            add_stat("nlocal", 1);
        }
        if ( get_stat("ntail") == %MAX_TAIL_EVENTS% )
        {
            mute_path_literal("/usr/bin/tail");
        }
        if ( get_stat("nless") == %MAX_LESS_EVENTS% )
        {
            mute_path_literal("/usr/bin/less");
        }
        if ( get_stat("nlocal") == %MAX_LOCAL_EVENTS% )
        {
            # Mute all processes from /usr/local/bin
            mute_path_prefix("/usr/local/bin");
        }
    </Exec>
</Input>