By Sharvil Shah, Senior Software Engineer
Originally published on October 6, 2021
TL;DR: Version 5.0.1 of osquery, a cross-platform, open-source endpoint visibility agent, is now available. This release is an exciting milestone for the project, as it introduces an EndpointSecurity-based process events table for macOS. Read on to learn how we integrated EndpointSecurity into osquery and how you can begin using it in your organization.
Apple’s New Rules for macOS Security
Over the years, Apple has been gradually taking pages from its iOS playbook to spruce up macOS security, beginning five years ago with the introduction of System Integrity Protection (SIP) to contain the root user in OS X 10.11 El Capitan. Since then, Apple has accelerated its efforts to improve macOS security by introducing stricter requirements for GateKeeper and the enforcement of code signing and of notarizing application binaries and packages.
Entitlements are another feature strengthening macOS security. Granted by Apple and baked in with a corresponding code signature, an entitlement allows an application or binary to use restricted APIs or frameworks. These new locked-down APIs replace the APIs that were formerly available only in kernel-mode “kernel extensions.” As a user-mode-only executable, following the same out-from-the-kernel OS integrity trends that many platforms are adopting, the osquery project was already well positioned to adopt these new APIs.
What is EndpointSecurity?
Apple has gradually deprecated kernel extensions with its recent releases of macOS. To replace kernel extensions, Apple developed the EndpointSecurity framework and API. When combined with the required entitlements, the EndpointSecurity framework enables user-mode processes to subscribe to events of interest from the macOS kernel in real time. EndpointSecurity replaces kauth, the kernel-mode authorization framework, and OpenBSM, the legacy framework used to grab the audit trail from the kernel.
Compared to OpenBSM, EndpointSecurity is more reliable, is more performant, and anecdotally captures more process events. For a more in-depth review of EndpointSecurity, check out our Sinter blog post, our team’s first demonstration of EndpointSecurity.
These security features are a great boon to end users. We were on a steep learning curve as we retrofitted osquery—which has always been deployed as a basic, standalone CLI executable—with new signing and packaging procedures, but we believe it was well worth the effort.
How to Use osquery with EndpointSecurity: A Mini Tutorial
With the 5.0.1 release of osquery, we have implemented the es_process_events table. Check the schema for this table before following along with the tutorial.
Following along in osqueryi
The simplest way to get started with osquery is by using osqueryi, the interactive osquery shell. Download the official macOS installer package from osquery.io and install it as you would any other application.
With the release of version 5.0.1, osquery is now installed as an app bundle in /opt/osquery/lib/osquery.app, and osqueryi is a symlink in /usr/local/bin.
Next up, grant your terminal emulator application—whether it be Terminal.app, iTerm2.app, or any other terminal emulator—Full Disk Access permissions in System Preferences. Full Disk Access is part of Apple’s Transparency Consent and Control (TCC) framework, another macOS security feature, and is required to enable EndpointSecurity. In the next section, we explain how to grant this permission automatically for Macs that are enrolled in a mobile device management (MDM) solution.
Finally, run osqueryi with root permissions and provide the –disable_events=false and –disable_endpointsecurity=falseflags to launch osquery interactively, with ephemeral events and the EndpointSecurity-based es_process_events table enabled.
Below is an example of osqueryi capturing recent process events that have occurred since the last time osqueryi was launched.
➜ ~ sudo osqueryi --disable_events=false --disable_endpointsecurity=false Using a virtual database. Need help, type '.help' osquery> .mode line osquery> select * from es_process_events; version = 4 seq_num = 178 global_seq_num = 574 pid = 8522 path = /Applications/Xcode.app/Contents/Developer/usr/share/xcs/Nginx/sbin/nginx parent = 1 original_parent = 1 cmdline = /Library/Developer/XcodeServer/CurrentXcodeSymlink/Contents/Developer/usr/share/xcs/Nginx/sbin/nginx -c /Library/Developer/XcodeServer/CurrentXcodeSymlink/Contents/Developer/usr/share/xcs/xcsnginx/xcsnginx.conf cmdline_count = 3 env = XPC_SERVICE_NAME=com.apple.xcsnginx PATH=/usr/bin:/bin:/usr/sbin:/sbin XPC_FLAGS=1 LOGNAME=_xcsnginx USER=_xcsnginx HOME=/var/_xcsnginx SHELL=/bin/false TMPDIR=/var/folders/xl/xl5_qxqd1095w75dfmq92c4w0000f3/T/ env_count = 8 cwd = /Applications/Xcode.app/Contents/Developer/usr/share/xcs/Nginx uid = 451 euid = 450 gid = 450 egid = 450 username = _xcsnginx signing_id = com.apple.nginx team_id = cdhash = 7fde0ccc9dcdb7d994e82a880d684c5418368460 platform_binary = 1 exit_code = child_pid = time = 1631617834 event_type = exec version = 4 seq_num = 193 global_seq_num = 552 pid = 8077 path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared parent = 1 original_parent = 1 cmdline = cmdline_count = 0 env = env_count = 0 cwd = uid = 501 euid = 20 gid = 20 egid = 20 username = sharvil signing_id = com.apple.mdworker_shared team_id = cdhash = 993abbb7ffcd0d3216808513f8212f4fa1fa07d7 platform_binary = 1 exit_code = 9 child_pid = time = 1631617820 event_type = exit
Deploying a PPPC Profile for an MDM-Managed Mac
While osqueryi is a great tool for interactively introspecting, monitoring, and developing queries suitable to your environment, most deployments of osquery are in daemon mode with a configuration file.
For a Mac host that is enrolled in MDM, you can grant Full Disk Access permissions automatically and silently by pushing a Privacy Preferences Policy Control (PPPC) configuration profile. For this profile, you need both the systemPolicyAllFiles key, which grants Full Disk Access, and a CodeRequirement key.
Use the codesign tool to output CodeRequirement and copy everything in the output after
“designated =>.”
> codesign -dr - /opt/osquery/lib/osquery.app/Contents/MacOS/osqueryd Executable=/opt/osquery/lib/osquery.app/Contents/MacOS/osqueryd designated => identifier "io.osquery.agent" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "3522FA9PXF"
To complete systemPolicyAllFiles, the Identifier should be io.osquery.agent and IdentifierType should be bundleID.
Pulling it all together, below is an example of a complete PPPC profile granting Full Disk Access to osquery. Please note that you will need to update the PayloadOrganization and other relevant fields, shown here in bold.
You may need to consult the documentation of your MDM provider for more information on PPPC profiles.
Migrating from osquery 4.x to 5.x
With the release of version 5.0.1, osquery now installs on macOS as an app bundle in /opt/osquery/lib/osquery.app, and the new package identifier is io.osquery.agent. If you are upgrading osquery from version 4.9, you need to stop the osquery launchd service and restart it after version 5.0.1 is installed, since osquery itself doesn’t provide a mechanism to clean up artifacts, binaries, and configuration files for older versions. Also of note is that the package installer does not install a LaunchDaemon to start osqueryd. You may use the provided osqueryctl start script to copy the sample LaunchDaemon plist and associated configuration to start the osqueryd daemon.
Similar changes apply to Linux and Windows hosts. Please consult the installation guide on the osquery wiki to learn more.
A Stronger Foundation
We developed a working proof-of-concept of osquery with an EndpointSecurity integration rather quickly; in fact, we merged the feature into osquery months before the version 5.0.1 release. But to actually “switch on” the EndpointSecurity functionality, we had to conquer a mountain of technical debt:
- Migrating to a CI runner with a compatible version of macOS
- Updating the SDK requirements for the builds and dropping macOS 10.11 support
- Entirely repackaging osquery as an app bundle
- Setting up a new private GitHub repo to hold the new signing secrets
- Setting up a public repo to host new automated CI/CD pipelines that produce the signed packages
- Changing the default install paths on the POSIX systems
- Researching and implementing macOS notarization
- Documenting the new macOS privacy permissions and the process for generating the MDM profiles to apply these permissions</li>
And finally, we had to socialize all these breaking changes and navigate all the community’s feedback. Indeed, the number of changes we needed to make warranted a new major version of osquery, from version 4.9 to 5.0.1.
In June 2019, Facebook and the Linux Foundation formed the osquery Foundation, a new community entity intended to accelerate the development and open participation around the osquery project. A multi-stakeholder Technical Steering Committee (which includes Trail of Bits) has been updating and maintaining osquery ever since. Throughout the project’s development, one of the biggest technical obstacles to the project’s independence was the lack of an automated packaging and code-signing pipeline. Thanks to the community’s efforts this year to integrate EndpointSecurity into osquery, this pipeline is finally in place. Facebook’s original osquery developers can now fully hand over the keys (literally and figuratively) to the community.
The osquery project is undoubtedly only made possible by the continuing involvement and support of its open-source community. We especially want to thank our client sponsor, Atlassian, and our fellow contributors to the osquery community, past and present.
Future Directions
Now that we have integrated EndpointSecurity into osquery, the tool comes with a variety of new detection capabilities on macOS. It should now be much easier to add a file event monitor, kernel extension loading events, and even memory mapping events. The automated code-signing and packaging groundwork that we’ve laid for EndpointSecurity could pave the way for other permissioned/entitled macOS event monitoring frameworks, like NetworkExtension, to be integrated into osquery.
Trail of Bits has been at the forefront of osquery development for years. Where do you want us to take the project next? Drop us a line to chat about how we can help implement your idea!