mandiant / macos-UnifiedLogs

Apache License 2.0
215 stars 20 forks source link

macos-unifiedlogs

A simple Rust library that can help parse the macOS Unified Log files.

Unified Logs were introduced in macOS version 10.12 (Sierra, 2016). Part of Apple's goal to create a unified log format for all Apple products. They exist on macOS, iOS, watchOS, tvOS. The Unified Logs replace many of the old log formats Apple used. This simple library can be used to parse files.
Data that is currently extracted includes:

Running

Three (3) simple example binaries are available in examples.

See RUNNING.md for overview of running the example binaries

Using as Library

If you want to import this project into a Rust application add the following to you Cargo.toml file

macos-unifiedlogs = {git = "https://github.com/mandiant/macos-UnifiedLogs"}

If you want to pin to a specific commit

macos-unifiedlogs = {git = "https://github.com/mandiant/macos-UnifiedLogs", rev = "commit hash"}

See Library.md for overview of how to use the library. Simple example projects are also available to review and use

Status

This library has been heavily tested on log data from macOS Sierra (10.12.5) to Monterey (12).
Its been tested against 100+ million log entries. However, due the complexity of the Unified Log format there are some limitations:

  1. No printf style error code lookup support. This library does not do any error code lookups for log messages. The native log command on macOS supports error code lookups when it encounters printf style %m messages.
    An example base log messsage: 'Failed to open file, error: %m'
    a. This Library outputs:

      Failed to open file, error: 1

    b. The macOS Log command outputs:

      Failed to open file, error: no such file or directory

    Here the error code 1 gets translated to the error string message

  2. No support for custom object decoders. The Unified Log format allows a developer to log abrirtary data to the logs. Apple also includes a handful of custom objects that developer can use to log raw data. An example list can be found in man os_log. However, it is not a complete list.

    man os_log
    ...
     To format a log message, use a printf(3) format string.  You may also use the "%@" format specifier for use with Obj-C/CF/Swift objects, and %.*P which can be used to decode arbitrary binary data.  The logging system also supports custom decoding of values by denoting value types inline in the format %{value_type}d.  The built-in value type decoders are:
    
     Value type      Custom specifier         Example output
     BOOL            %{BOOL}d                 YES
     bool            %{bool}d                 true
     darwin.errno    %{darwin.errno}d         [32: Broken pipe]
     darwin.mode     %{darwin.mode}d          drwxr-xr-x
     darwin.signal   %{darwin.signal}d        [sigsegv: Segmentation Fault]
     time_t          %{time_t}d               2016-01-12 19:41:37
     timeval         %{timeval}.*P            2016-01-12 19:41:37.774236
     timespec        %{timespec}.*P           2016-01-12 19:41:37.2382382823
     bytes           %{bytes}d                4.72 kB
     iec-bytes       %{iec-bytes}d            4.61 KiB
     bitrate         %{bitrate}d              123 kbps
     iec-bitrate     %{iec-bitrate}d          118 Kibps
     uuid_t          %{uuid_t}.16P            10742E39-0657-41F8-AB99-878C5EC2DCAA
     sockaddr        %{network:sockaddr}.*P   fe80::f:86ff:fee9:5c16
     in_addr         %{network:in_addr}d      127.0.0.1
     in6_addr        %{network:in6_addr}.16P  fe80::f:86ff:fee9:5c16

    Currently when the library encounters log messages that contain arbitrary binary data, it will base64 the data as a string. Support for custom decoders will hopefully be added in version 2 of the library.

  3. No support for log messages that have custom object structures or protocol buffer data. Some logs contain binary plist files, custom object structures, or protocol buffer data. This library currently supports parsing binary plist data, but it does not support custom object structures, or protocol buffer data. The custom object structures are similar to the custom decoders mentioned above. But there is no list of decoders
    Support for custom object structures will hopefully be added in version 2 of the library

References

https://github.com/ydkhatri/UnifiedLogReader
https://github.com/libyal/dtformats/blob/main/documentation/Apple%20Unified%20Logging%20and%20Activity%20Tracing%20formats.asciidoc
https://eclecticlight.co/2018/03/19/macos-unified-log-1-why-what-and-how/
https://www.crowdstrike.com/blog/how-to-leverage-apple-unified-log-for-incident-response/