kmutil
kmutil is the KernelManagement command-line tool for kernel extensions on macOS 11 and later, the supported replacement for kextload, kextunload, and kextcache. Its subcommands each have an offensive counterpart. showloaded inventories kernel-resident security tooling, unload stops a legacy security kext or IOService, load installs attacker-supplied kernel code via a kernelmanagerd rebuild of the auxiliary kext collection, and the Recovery-only subcommands place code ahead of the OS in the boot chain or strip every third-party kext approval. Loading a third-party kext is heavily gated (root, an administrator approval prompt, a reboot, and on Apple silicon a machine already in Reduced Security), but kmutil ships with the base OS and is the expected tool for these operations.
Paths
/usr/bin/kmutil Example Use Cases
Inventory loaded kernel extensions and DriverKit extensions to locate security tooling #
showloaded queries the kernel directly for load information. --list-only --no-kernel-components lists non-codeless kexts with their bundle identifiers, versions, load addresses, and reference counts. Codeless kexts and DriverKit extensions require --collection codeless --show all to enumerate. Together these identify any legacy kernel-resident or DriverKit-based endpoint security product. They do not cover System Extensions, which systemextensionsctl enumerates instead.
kmutil showloaded --list-only --no-kernel-components Unload a kernel extension to disable a kernel-resident security product #
unload invokes a kext's stop function and ends its IOKit lifecycle, stopping a legacy security kext from observing the system. It requires root and fails if another loaded kext holds a reference to the target (shown by the Refs column of showloaded). The kext stays in its collection, so the change does not survive a reboot. Applies only to products still shipping a kext rather than a System Extension.
sudo kmutil unload --bundle-identifier <TARGET_KEXT_BUNDLE_ID> Terminate IOService instances to disable a driver without fully unloading its kext #
unload --class-name terminates all instances of a named IOService class while leaving the kext loaded. Adding --personalities-only also removes the kext's personalities so the driver cannot restart. Either form stops the driver from doing work while leaving the kext visible in showloaded output. Requires root.
sudo kmutil unload --class-name <TARGET_IOSERVICE_CLASS> Install an attacker-supplied kernel extension for boot persistence #
load stages a kext bundle from disk and, if it is not already in the auxiliary kext collection, has kernelmanagerd rebuild that collection so the kext loads at every subsequent boot. The prerequisites are steep. It requires root; with SIP enabled the signature is verified before the kext is added; kernelmanagerd prompts a logged-in administrator to approve the rebuild; the machine must reboot; and on Apple silicon it must already be in Reduced Security with third-party kexts enabled. kmutil signals the last two states with exit codes 27 (approval required) and 28 (reboot required).
sudo kmutil load --bundle-path /Library/Extensions/<PAYLOAD>.kext Install a custom boot object to gain pre-boot code execution on Apple silicon #
The Recovery-only configure-boot subcommand installs a Mach-O that iBoot loads and starts, placing attacker-controlled code ahead of the OS in the boot chain by setting the CustomOS Image4 manifest hash in a Mac's LocalPolicy. The prerequisites are interactive. The machine must be in Recovery, an administrator must already have selected Reduced Security in Startup Security Utility, and kmutil prompts for confirmation before downgrading further to Permissive Security. It needs physical access or a management path that can force a Recovery boot, not remote code execution alone.
kmutil configure-boot --custom-boot-object <PAYLOAD_MACHO> --volume /Volumes/<TARGET_VOLUME> Strip all third-party kext approvals with trigger-panic-medic #
trigger-panic-medic is meant to recover a machine from a kext that panics at boot. It removes the auxiliary kext collection and revokes every kext approval on the next boot, which on a managed fleet drops any third-party kernel extension the organization deployed, including a security vendor's kext, and forces user re-approval before any can load again. It runs only in Recovery Mode, needing the same access as configure-boot.
kmutil trigger-panic-medic Detections
Resources
- kmutil(8) man page
- EndpointSecurity ES_EVENT_TYPE_NOTIFY_KEXTLOAD and ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD event types
- Apple Platform Security - Startup disk security policy control
- MITRE ATT&CK T1547.006 - Boot or Logon Autostart Execution: Kernel Modules and Extensions
- Atomic Red Team T1547.006 - MacOS - Load Kernel Module via kextload and kmutil
- Apple Platform Security - Contents of a LocalPolicy file for a Mac with Apple silicon (the CustomOS Image4 manifest hash set by kmutil configure-boot)
- Apple Platform Security - Boot process for a Mac with Apple silicon