SIP/Rootless Internal in El Capitan and later

As many people already found out, the next OS X El Capitan introduced a new mechanism of system security policy called “Rootless”, which officially named “System Integrity Protection” (SIP).

According to the security session in WWDC2015, the rootless is a complete infrastructure built for the OS X security and it contains three parts:

– Filesystem protection: Important system files are protected and cannot be modified.

– Runtime protection: Important system process cannot be attached or code injected.

– Kext signing: Introduced in 10.9, enhanced in 10.10(kext signing required for all kexts), now become part of rootless(SIP).

Be advised that these protection do apply to all users in system even including the root(“Cannot trust root”).

Undoubtedly, these security mechanism working together provide a solid protection shell for OS X and should not be turned off for most users. However, in some case, these protection would become a restriction for testing, modification or development purposes. Actually, Apple do provide a tool called “Security Configuration” “csrutil” to turn off some of these protection. This tool can be used in the Recovery or installation environment and it set csr-active-config flags stored in the NVRAM.

# csrutil disable

By comparing the NVRAM data before and after using the “Security Configuration” “csrutil” tool to turn off the SIP, the first 1 byte of the csr-active-config data has been set to 0x77(1110111). So what the meaning of these flags?

After analyze the source code from the Apple open source program, the rootless/SIP could be fully configured by setting the flags properly:

/* Rootless configuration flags */
#define CSR_ALLOW_UNTRUSTED_KEXTS       (1 << 0)
#define CSR_ALLOW_UNRESTRICTED_FS       (1 << 1)
#define CSR_ALLOW_TASK_FOR_PID          (1 << 2)
#define CSR_ALLOW_KERNEL_DEBUGGER       (1 << 3)
#define CSR_ALLOW_APPLE_INTERNAL        (1 << 4)
#define CSR_ALLOW_UNRESTRICTED_DTRACE   (1 << 5)
#define CSR_ALLOW_UNRESTRICTED_NVRAM    (1 << 6)
#define CSR_ALLOW_DEVICE_CONFIGURATION  (1 << 7)
#define CSR_ALLOW_ANY_RECOVERY_OS       (1 << 8)    //added in 10.12
#define CSR_ALLOW_UNAPPROVED_KEXTS      (1 << 9)    //added in 10.13, aka Kext User Consent
#define CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE  (1 << 10)   //added in 10.14
#define CSR_ALLOW_ANY_SYSTEM_SNAPSHOTS  (1 << 11)   //added in macOS 11, aka authenticated-root

And also a special BootArgs flag “kBootArgsFlagCSRBoot” is set in the Recovery or Installation environment. This flag is kind of overkill by turning off the all the protections listed above.

This code snippet comes from the OS X 10.10. Clearly these security feature are planning and developing for a long time.

The “Security Configuration” “csrutil” tool set config bit 0, 1, 2, 4, 5 and 6 (0x77), which will turn off almost the entire rootless/SIP except the kernel debugger. If we only need to turn off kext signing check, 0x1 could be set instead of 0x67. The “rootless=0” put into boot-args should never be used because it would turn off ALL these protection and it will also be deprecated in the public release of 10.11.

For Hackintosh, since the “rootless=0” & “kext-dev-mode=1” boot flags will be are removed in the 10.11 and it is not safe to use (put down all these protection and open the gate for everyone), setting the proper CSR BootArgs flags by bootloader should be a more secure solution instead of just kick all these guards away.

Update 1: For Hackintosh, boot loader like Chameleon and Clover already support setting CSR valid flags to turn off protections for the hack.
Update 2: Begin with 10.11.1, Apple Internal bit won’t allowed to be set. This Apple Internal status provided by csrutil tool shall always be “Disabled”.
Update 3: For the filesystem protection, the protected targets list could be found in:

/System/Library/Sandbox/rootless.conf

While the exclusion list could be automatically updated and stored in:

/System/Library/Sandbox/Compatibility.bundle/Contents/Resources/paths

Update 4: Update flags added in 10.12 and 10.13. Start with macOS 10.13, set allow untrusted kexts/Apple internal bits would also set the allow kernel debugger.