|
6 | 6 |
|
7 | 7 | Kernel extensions (Kexts) are **packages** with a **`.kext`** extension that are **loaded directly into the macOS kernel space**, providing additional functionality to the main operating system. |
8 | 8 |
|
| 9 | +### Deprecation status & DriverKit / System Extensions |
| 10 | +Starting with **macOS Catalina (10.15)** Apple marked most legacy KPIs as *deprecated* and introduced the **System Extensions & DriverKit** frameworks that run in **user-space**. From **macOS Big Sur (11)** the operating system will *refuse to load* third-party kexts that rely on deprecated KPIs unless the machine is booted in **Reduced Security** mode. On Apple Silicon, enabling kexts additionally requires the user to: |
| 11 | + |
| 12 | +1. Reboot into **Recovery** → *Startup Security Utility*. |
| 13 | +2. Select **Reduced Security** and tick **“Allow user management of kernel extensions from identified developers”**. |
| 14 | +3. Reboot and approve the kext from **System Settings → Privacy & Security**. |
| 15 | + |
| 16 | +User-land drivers written with DriverKit/System Extensions dramatically **reduce attack surface** because crashes or memory corruption are confined to a sandboxed process rather than kernel space. |
| 17 | + |
| 18 | +> 📝 From macOS Sequoia (15) Apple has removed several legacy networking and USB KPIs entirely – the only forward-compatible solution for vendors is to migrate to System Extensions. |
| 19 | +
|
9 | 20 | ### Requirements |
10 | 21 |
|
11 | 22 | Obviously, this is so powerful that it is **complicated to load a kernel extension**. These are the **requirements** that a kernel extension must meet to be loaded: |
@@ -34,16 +45,41 @@ In Catalina it was like this: It is interesting to note that the **verification* |
34 | 45 |
|
35 | 46 | If **`kextd`** is not available, **`kextutil`** can perform the same checks. |
36 | 47 |
|
37 | | -### Enumeration (loaded kexts) |
| 48 | +### Enumeration & management (loaded kexts) |
| 49 | + |
| 50 | +`kextstat` was the historical tool but it is **deprecated** in recent macOS releases. The modern interface is **`kmutil`**: |
| 51 | + |
| 52 | +```bash |
| 53 | +# List every extension currently linked in the kernel, sorted by load address |
| 54 | +sudo kmutil showloaded --sort |
| 55 | + |
| 56 | +# Show only third-party / auxiliary collections |
| 57 | +sudo kmutil showloaded --collection aux |
| 58 | + |
| 59 | +# Unload a specific bundle |
| 60 | +sudo kmutil unload -b com.example.mykext |
| 61 | +``` |
| 62 | + |
| 63 | +Older syntax is still available for reference: |
38 | 64 |
|
39 | 65 | ```bash |
40 | | -# Get loaded kernel extensions |
| 66 | +# (Deprecated) Get loaded kernel extensions |
41 | 67 | kextstat |
42 | 68 |
|
43 | | -# Get dependencies of the kext number 22 |
| 69 | +# (Deprecated) Get dependencies of the kext number 22 |
44 | 70 | kextstat | grep " 22 " | cut -c2-5,50- | cut -d '(' -f1 |
45 | 71 | ``` |
46 | 72 |
|
| 73 | +`kmutil inspect` can also be leveraged to **dump the contents of a Kernel Collection (KC)** or verify that a kext resolves all symbol dependencies: |
| 74 | + |
| 75 | +```bash |
| 76 | +# List fileset entries contained in the boot KC |
| 77 | +kmutil inspect -B /System/Library/KernelCollections/BootKernelExtensions.kc --show-fileset-entries |
| 78 | + |
| 79 | +# Check undefined symbols of a 3rd party kext before loading |
| 80 | +kmutil libraries -p /Library/Extensions/FancyUSB.kext --undef-symbols |
| 81 | +``` |
| 82 | + |
47 | 83 | ## Kernelcache |
48 | 84 |
|
49 | 85 | > [!CAUTION] |
@@ -78,7 +114,7 @@ It's usually composed of the following components: |
78 | 114 | Decompress the Kernelcache: |
79 | 115 |
|
80 | 116 | ```bash |
81 | | -# img4tool (https://github.com/tihmstar/img4tool |
| 117 | +# img4tool (https://github.com/tihmstar/img4tool) |
82 | 118 | img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e |
83 | 119 |
|
84 | 120 | # pyimg4 (https://github.com/m1stadev/PyIMG4) |
@@ -140,14 +176,68 @@ kextex_all kernelcache.release.iphone14.e |
140 | 176 | nm -a binaries/com.apple.security.sandbox | wc -l |
141 | 177 | ``` |
142 | 178 |
|
143 | | -## Debugging |
| 179 | +## Recent vulnerabilities & exploitation techniques |
144 | 180 |
|
145 | | -## Referencias |
| 181 | +| Year | CVE | Summary | |
| 182 | +|------|-----|---------| |
| 183 | +| 2024 | **CVE-2024-44243** | Logic flaw in **`storagekitd`** allowed a *root* attacker to register a malicious file-system bundle that ultimately loaded an **unsigned kext**, **bypassing System Integrity Protection (SIP)** and enabling persistent rootkits. Patched in macOS 14.2 / 15.2. | |
| 184 | +| 2021 | **CVE-2021-30892** (*Shrootless*) | Installation daemon with the entitlement `com.apple.rootless.install` could be abused to execute arbitrary post-install scripts, disable SIP and load arbitrary kexts. | |
146 | 185 |
|
147 | | -- [https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/](https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/) |
148 | | -- [https://www.youtube.com/watch?v=hGKOskSiaQo](https://www.youtube.com/watch?v=hGKOskSiaQo) |
| 186 | +**Take-aways for red-teamers** |
149 | 187 |
|
150 | | -{{#include ../../../banners/hacktricks-training.md}} |
| 188 | +1. **Look for entitled daemons (`codesign -dvv /path/bin | grep entitlements`) that interact with Disk Arbitration, Installer or Kext Management.** |
| 189 | +2. **Abusing SIP bypasses almost always grants the ability to load a kext → kernel code execution**. |
| 190 | + |
| 191 | +**Defensive tips** |
| 192 | + |
| 193 | +*Keep SIP enabled*, monitor for `kmutil load`/`kmutil create -n aux` invocations coming from non-Apple binaries and alert on any write to `/Library/Extensions`. Endpoint Security events `ES_EVENT_TYPE_NOTIFY_KEXTLOAD` provide near real-time visibility. |
151 | 194 |
|
| 195 | +## Debugging macOS kernel & kexts |
152 | 196 |
|
| 197 | +Apple’s recommended workflow is to build a **Kernel Debug Kit (KDK)** that matches the running build and then attach **LLDB** over a **KDP (Kernel Debugging Protocol)** network session. |
153 | 198 |
|
| 199 | +### One-shot local debug of a panic |
| 200 | + |
| 201 | +```bash |
| 202 | +# Create a symbolication bundle for the latest panic |
| 203 | +sudo kdpwrit dump latest.kcdata |
| 204 | +kmutil analyze-panic latest.kcdata -o ~/panic_report.txt |
| 205 | +``` |
| 206 | + |
| 207 | +### Live remote debugging from another Mac |
| 208 | + |
| 209 | +1. Download + install the exact **KDK** version for the target machine. |
| 210 | +2. Connect the target Mac and the host Mac with a **USB-C or Thunderbolt cable**. |
| 211 | +3. On the **target**: |
| 212 | + |
| 213 | +```bash |
| 214 | +sudo nvram boot-args="debug=0x100 kdp_match_name=macbook-target" |
| 215 | +reboot |
| 216 | +``` |
| 217 | + |
| 218 | +4. On the **host**: |
| 219 | + |
| 220 | +```bash |
| 221 | +lldb |
| 222 | +(lldb) kdp-remote "udp://macbook-target" |
| 223 | +(lldb) bt # get backtrace in kernel context |
| 224 | +``` |
| 225 | + |
| 226 | +### Attaching LLDB to a specific loaded kext |
| 227 | + |
| 228 | +```bash |
| 229 | +# Identify load address of the kext |
| 230 | +ADDR=$(kmutil showloaded --bundle-identifier com.example.driver | awk '{print $4}') |
| 231 | + |
| 232 | +# Attach |
| 233 | +sudo lldb -n kernel_task -o "target modules load --file /Library/Extensions/Example.kext/Contents/MacOS/Example --slide $ADDR" |
| 234 | +``` |
| 235 | + |
| 236 | +> ℹ️ KDP only exposes a **read-only** interface. For dynamic instrumentation you will need to patch the binary on-disk, leverage **kernel function hooking** (e.g. `mach_override`) or migrate the driver to a **hypervisor** for full read/write. |
| 237 | +
|
| 238 | +## References |
| 239 | + |
| 240 | +- DriverKit Security – Apple Platform Security Guide |
| 241 | +- Microsoft Security Blog – *Analyzing CVE-2024-44243 SIP bypass* |
| 242 | + |
| 243 | +{{#include ../../../banners/hacktricks-training.md}} |
0 commit comments