Skip to content

Instantly share code, notes, and snippets.

@Brandon7CC
Created April 8, 2024 04:07
Show Gist options
  • Save Brandon7CC/6e183b94d3c98239297694fcb6984fc0 to your computer and use it in GitHub Desktop.
Save Brandon7CC/6e183b94d3c98239297694fcb6984fc0 to your computer and use it in GitHub Desktop.
What SIP flags are enabled / disabled on macOS using the csr_get_active_config and csr_check syscalls?
//
// csr_check.swift
// csr_check
//
// Created by Brandon Dalton on 01/11/24.
//
// Compile: `swiftc -import-objc-header SystemConfig-Bridging-Header.h csr_check.swift -o csr_check.o`
//
import Foundation
/// Mapping the SIP binary flags to their respective descriptions
struct SIPFlag {
let value: UInt32
let description: String
}
class SIPConfigurationManager {
/// Represents a collection of System Integrity Protection (SIP) policy flags.
///
/// This static array defines the known SIP flags as specified in the macOS system header `csr.h`.
/// Each `SIPFlag` instance comprises a bitmask value representing the flag and a human-readable
/// description.
///
/// - `CSR_ALLOW_UNTRUSTED_KEXTS`: Allows loading of unsigned kernel extensions.
/// - `CSR_ALLOW_UNRESTRICTED_FS`: Disables restrictions on filesystem modifications by root.
/// - `CSR_ALLOW_TASK_FOR_PID`: Allows use of the `task_for_pid()` function, enabling processes to control other processes.
/// - `CSR_ALLOW_KERNEL_DEBUGGER`: Permits kernel debugging, allowing low-level access to the operating system.
/// - `CSR_ALLOW_APPLE_INTERNAL`: Enables features reserved for Apple's internal development.
/// - `CSR_ALLOW_UNRESTRICTED_DTRACE`: Allows unrestricted use of the DTrace diagnostic tool.
/// - `CSR_ALLOW_UNRESTRICTED_NVRAM`: Permits modifications to NVRAM variables without restrictions.
/// - `CSR_ALLOW_DEVICE_CONFIGURATION`: Allows certain device configurations to be modified that would otherwise be protected.
/// - `CSR_ALLOW_ANY_RECOVERY_OS`: Enables booting to any recovery OS without restrictions.
/// - `CSR_ALLOW_UNAPPROVED_KEXTS`: Allows kernel extensions to load without user approval.
/// - `CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE`: Permits bypassing Gatekeeper checks for executing unsigned code.
/// - `CSR_ALLOW_UNAUTHENTICATED_ROOT`: Disables the requirement for authentication before modifying the root filesystem.
///
/// Reference: https://opensource.apple.com/source/xnu/xnu-4570.41.2/bsd/sys/csr.h.auto.html
static let flags: [SIPFlag] = [
SIPFlag(value: 1 << 0, description: "CSR_ALLOW_UNTRUSTED_KEXTS"),
SIPFlag(value: 1 << 1, description: "CSR_ALLOW_UNRESTRICTED_FS"),
SIPFlag(value: 1 << 2, description: "CSR_ALLOW_TASK_FOR_PID"),
SIPFlag(value: 1 << 3, description: "CSR_ALLOW_KERNEL_DEBUGGER"),
SIPFlag(value: 1 << 4, description: "CSR_ALLOW_APPLE_INTERNAL"),
SIPFlag(value: 1 << 5, description: "CSR_ALLOW_UNRESTRICTED_DTRACE"),
SIPFlag(value: 1 << 6, description: "CSR_ALLOW_UNRESTRICTED_NVRAM"),
SIPFlag(value: 1 << 7, description: "CSR_ALLOW_DEVICE_CONFIGURATION"),
SIPFlag(value: 1 << 8, description: "CSR_ALLOW_ANY_RECOVERY_OS"),
SIPFlag(value: 1 << 9, description: "CSR_ALLOW_UNAPPROVED_KEXTS"),
SIPFlag(value: 1 << 10, description: "CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE"),
SIPFlag(value: 1 << 11, description: "CSR_ALLOW_UNAUTHENTICATED_ROOT")
]
/// Retrieves the currently active System Integrity Protection (SIP) configuration bitmask.
///
/// This function calls into the underlying C function `csr_get_active_config` to obtain
/// the active SIP configuration from the system. Each bit in the returned UInt32 value
/// corresponds to a specific SIP policy flag, where a set bit (1) indicates that the
/// corresponding SIP restriction is disabled, and a cleared bit (0) means the restriction
/// is enabled.
///
/// - Returns: A UInt32 bitmask representing the active SIP configuration.
func csrGetActiveConfig() -> UInt32 {
var config: UInt32 = 0
let result = csr_get_active_config(&config)
guard result == 0 else {
fatalError("Failed to get active CSR config")
}
return config
}
/// Checks if a specific System Integrity Protection (SIP) policy flag is allowed.
///
/// Interfaces with the underlying C function `csr_check` to determine
/// whether a specific SIP policy, identified by the `flag` parameter, is currently
/// allowed (i.e., the corresponding SIP restriction is disabled). The `flag` parameter
/// should be a single SIP policy flag represented as a UInt32 bitmask, where each bit
/// corresponds to a different SIP policy.
///
/// - Parameter flag: A UInt32 bitmask representing a single SIP policy flag to check.
/// This bitmask should have exactly one bit set, corresponding to the policy being checked.
/// - Returns: A Boolean value where `true` indicates that the specified SIP policy is
/// allowed (the restriction is disabled), and `false` indicates that the policy is
/// not allowed (the restriction is enabled).
func csrCheck(flag: UInt32) -> Bool {
return csr_check(flag) == 0
}
func listEnabledSIPFlags() {
let activeConfig = csrGetActiveConfig()
print("Active SIP Configuration: \(String(format: "%#x", activeConfig))")
for flag in SIPConfigurationManager.flags {
if csrCheck(flag: flag.value) {
print("✅ \(flag.description)")
} else {
print("❌ \(flag.description)")
}
}
}
}
let manager = SIPConfigurationManager()
manager.listEnabledSIPFlags()
@Brandon7CC
Copy link
Author

Bridging header

You'll need this when compiling swiftc -import-objc-header SystemConfig-Bridging-Header.h csr_check.swift -o csr_check.o

// SystemConfig-Bridging-Header.h

#ifndef SystemConfig_Bridging_Header_h
#define SystemConfig_Bridging_Header_h

#include <stdint.h>

extern int csr_get_active_config(uint32_t *);
extern int csr_check(uint32_t);

#endif /* SystemConfig_Bridging_Header_h */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment