I wrote an article about extensions on macOS a few weeks ago, and have since written a couple of other extensions. The interesting thing about modern extensions is that different types of extensions can live in different places on a file system, become instantiated in different ways or with different mechanisms, and due to the way message traverse XPC, operate in very different ways.
The tools Apple has made available make it possible to see what’s running are primarily geared towards protecting privacy. This leaves a small gap for those interested more in securing machines and preventing exfiltration. There isn’t a single binary that can provide a simple listing of extensions because system extensions and app extensions are called differently. Seemingly they both originated in a desire to restrict the need to talk directly to the kernel (most notably in support of ACLs in the 10.4 era when the Auxiliary Kernel messaging architecture was initially introduced).
Extensions are used for things like embedding QuickLook functionality into apps so developers don’t have to write their own, but also to interface to I/O kit – programmatically very different. But rather than kernel mode and user land as a binary we now see a spectrum of capabilities. Things like credential providers, SSO, and Safari are app extensions, much like QuickLook and share sheets. Network extensions, I/O kit, and something like Endpoint Security is included in the system extension because EDR software needs certain low-level capabilities. The app extensions are kept in an .appex bundle and the system extensions in a .systemextension bundle (with .networkextension.systemextension as the bundle.
Apple makes a binary called systemsextensionctl that can be used to list and reset system extensions, but it only shows those that are active. However, I’ve found a more reliable way to ascertain what system extensions are running to be to query the property list of extensions at /Library/SystemExtensions/db.plist. Apple also makes the /usr/bin/pluginkit binary available to see information about app extension. Of these, my biggest concern security-wise are Safari Extensions (which are primarily little jsp scripts that have full access to information from web pages), SSO extensions, and credential providers. The common theme between them is that credentials can flow through them.
These list loaded extensions; not all are loaded. Extensions are supposed to live in /Applications or /Applications/Utilities. They get copied to a relative path in /Library/SystemExtensions/<GUID>
) according to the type of extension, so another way look there instead or loop through file paths for .appex or .systemextension. Grabbing running extensions is much cleaner. Although if the app hasn’t been opened then it wouldn’t be registered by kextd/sysextd/endpointsecurityd/nesessionmanager and so won’t appear in the listings yet. Most apps register extensions on first open.
To see a list of these extensions that were concerning, pluginkit with the name of the extension and defaults to get at the system extensions database was the most reliable way I found. So, some grep/awk/cut to parse out just the path to the extensions later and here’s a script (with an extension attribute for Jamf users) to see what extensions are running on a Mac: https://github.com/krypted/extensionslist.