Skip Navigation
Get a Demo
 
 
 
 
 
 
 
 
 
Resources Blog Threat detection

Gatekeeping in macOS: Keeping adversaries off our Apples

Gatekeeper is the centerpiece of Apple’s effort to protect macOS users from suspicious applications, malicious software, and other untrusted code.

Brandon Dalton
Originally published . Last modified .

Apple is famously choosy about what users are allowed to install on their operating systems. It’s a philosophical position that shields macOS users from the profusion of malware that impacts Windows, but the philosophy is backed up by a confusing array of distinct and complementary technologies. In this article, we explain where Gatekeeper came from, how it works, and hopefully clear up any confusion about this fascinating security technology.

Ultimately, this blog is intended as context for how and why adversaries bypass Gatekeeper, which you can read more about in our newly released Threat Detection Report. As such, we’ll start by examining the standard industry definition of a Gatekeeper bypass and work our way back into all the various components that stand between an adversary and their intention to run sketchy code on your macOS device.

Addressing past confusion

In the past, MITRE’s definition of the Gatekeeper bypass technique has been tightly linked to an older, distinct technology called File Quarantine, initially called Download Validation in Mac OS X 10.4 Tiger and later expanded in Snow Leopard 10.6. File Quarantine is a largely opt-in system for applications that’s intended to protect its users from potentially malicious content. This is particularly important for web browsers and file-sharing applications that are routinely used to download files, applications, and more. For applications that opt in, macOS automatically applies a quarantine extended attribute (com.apple.quarantine) to files the application creates. The presence of this quarantine flag initiates a Gatekeeper check.

macOS supports the forceful deletion of extended attributes, and, therefore, simply deleting the com.apple.quarantine attribute does not necessarily indicate or constitute a Gatekeeper bypass event.

The Atomic Red Team test for a Gatekeeper Bypass does exactly this: it forcefully removes the quarantine extended attribute from a file using the /usr/bin/xattr binary, which will essentially exclude the file from being checked by Gatekeeper, adding to the confusion:

sudo xattr -d com.apple.quarantine #{app_path}

While adversaries certainly have forcefully deleted the quarantine extended attribute in the past, it is far more frequently used in benign self-contained application updates like Google Chrome’s Keystone installer ksinstall (see below).

Gatekeeper bypasses, as we will explain in the following sections and in future research, encompass a far more diverse collection of offensive and overtly malicious tradecraft that is largely separate from the supported deletion of the quarantine extended attribute.

So, what goes into a Gatekeeper bypass?

Since the introduction of the Gatekeeper Bypass technique, MITRE has revised T1553.001 to focus on the following:

 

  • Exploitation of logic errors within the Gatekeeper stack. This could include exploiting weaknesses in file-type checking, “cross process communication” (XPC) implementation, notarization ticket lookup service, SQLite3 operations, and more.
  • Exploitation of logic errors within dependent macOS services: This could include Security.framework—secure code (code signing), authorization, secure data, cryptography, sandboxing, and hardened runtime—but the surface here is large. Other exploited frameworks include:
    • PackageKit.framework
    • XprotectFramework.framework
    • ConfigurationProfiles.framework
    • SoftLinking.framework
    • Note: A good way to think about this is that Gatekeeper will call into these frameworks to ask questions about a given target. Can you confuse one or more of these frameworks into giving an incorrect answer?
  • File Quarantine extended attribute propagation: Does the quarantine extended attribute get correctly applied to all “File Quarantine-aware” downloads? More on this later.

Bypassing the Gatekeeper security control typically involves exploitation at least one of those levels. We will discuss historical examples in the later sections, but first, a quick tour through File Quarantine and Gatekeeper.

File Quarantine

Before we get too deep intoGatekeeper, we need to talk about a closely related security control called File Quarantine. It’s important to mention this technology not only because it’s been cause for confusion in the past, but also because Gatekeeper partially relies on it. macOS is no stranger to inherently distrusting third-party software. Tiger’s initial Download Validation feature (the predecessor to File Quarantine) simply alerted users if the file they downloaded “from the internet” was actually an application (an early version of masquerading detection). In Snow Leopard, Apple took things further by expanding into static signature-based malware detection with YARA. Today, we recognize this feature as XProtect, which now includes remediation features along with a host of other new features in macOS 13 Ventura.

File Quarantine as we know it today is largely enabled by app developers opting in. When developers do this, the system applies a com.apple.quarantine extended attribute (a file system feature: key-value pair) to downloaded files. Extended attributes are a key-value pair, and for the quarantine extended attribute, the semicolon-separated value consists of a launch flag, timestamp, app name, and a unique ID. This information is used to populate the File Quarantine database (discussed below).

File Quarantine is responsible for ensuring that files downloaded by opted-in applications are tagged with the com.apple.quarantine extended attribute. Applications opt into File Quarantine by adding the LSFileQuarantineEnabled key to their Info.plist. Applications that opt in are known as “File Quarantine-aware.” Interestingly enough, macOS is shipped with a list of hardcoded app-signing identifiers for which the opt-in process is not optional. This list can be found at /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist.

A sample entry is shown below for Mozilla Firefox and Transmission, which, as a web browser and bittorrent client respectively, should be File Quarantine-aware to protect users from potentially malicious software. While this hardcoded list of signing identifiers provides an additional level of protection for end users, it should be noted that not all “internet-enabled” applications are File Quarantine-enabled.

Two exceptions we’ve come across are Arc, a new, currently macOS-exclusive web browser from The Browser Company, and Notion, a collaborative workspace and knowledge management app. We submitted a security feature request to both of their development teams.

"org.mozilla.firefox": {
  "LSFileQuarantineEnabled": true,
  "LSApplicationCategoryType": "public-category.productivity"
},
"org.m0k.transmission": {
  "LSFileQuarantineEnabled": true,
  "LSApplicationCategoryType": "public-category.internet"
}

We want to thank the wonderful teams at The Browser Company for quickly enabling File Quarantine in the Arc browser before publication.

Arc screenshot

Gatekeeper

It wasn’t until Mac OS X 10.7.3 Lion that Gatekeeper was added to the operating system (albeit in a preview state)—in Mountain Lion 10.8, Gatekeeper was enabled by default for users. Since then, Gatekeeper’s role in protecting Mac users from untrusted software has expanded to include application bundle anti-tamper features—publicly known as secure app updates. One of the overarching goals of Apple’s app security model is “by default all software in macOS is checked for known malicious content the first time it’s opened, regardless of how it arrived on the Mac.” As we mentioned earlier, we know this mission can really only be achieved with the help of Mac app developers.

A key point to note about this statement is that Gatekeeper, by default, will check every notarized or quarantined app, executable, UEFI disk image, and flat package installer on first launch (to name a handful of download types). Additionally, new for macOS 13 is the ability of Gatekeeper to handle anti-tampering for notarized apps. This feature works by ensuring that only approved developers can update/modify select notarized apps (part of Gatekeeper’s EvaluationPolicy class definition). This is an elegant workaround to the computationally intensive work it takes to fully validate the code signature of large apps (looking at you, Xcode). Instead of validating the code signature on each app launch, Gatekeeper will simply block unauthorized tampering attempts. macOS keeps a list of System Policy anti-tampering exceptions at /var/db/SystemPolicyConfiguration/TamperExceptions.plist. The listing contains both Apple and third-party applications. Gatekeeper will refer to this exceptions list before making an anti-tampering decision.
Before we go any further, we need to understand the types of system policies enforced by Gatekeeper.

Gatekeeper app security policies

Within System Settings.app users have the option to allow applications from:

The Mac App Store (introduced in Mac OS X Lion 10.7)

Applications hosted on the Mac App Store are required to adhere to a strict app security model. Namely, they are required to opt in to Hardened Runtime (runtime code integrity) and allow application sandboxing, and they cannot contain a System Extension, may not request elevation to root, and must be standalone. These apps are checked for malware known to Apple prior to hosting. Additionally, they have the following certificate chain:

- Apple Mac OS Application Signing 
- Apple Worldwide Developer Relations Certification Authority 
- Apple Root CA 

Trusted developers

These are notarized apps/plugins and apps that have been manually approved. Notarization (introduced in 2018 with macOS 10.14 Mojave) essentially gives Apple the opportunity to validate a few key elements of an app (or an executable, a plugin, a kernel extension, a UDIF disk image, a flat installer package, etc.) being prepared for distribution:

  • All “code places” have a complete and valid code signature signed by the developer’s “Developer ID” application distribution certificate.
  • A secure timestamp is included: This enables macOS to check the signing time against the signatures with cryptographic timestamps (timestamp.apple.com).
  • The app opts into Hardened Runtime: Runtime integrity protection helps prevent common code injection attacks on macOS, including dynamically linked library (DLL) hijacking and in-memory tampering. Hardened Runtime protection can have a host of exceptions that developers can selectively apply for additional functionality at the expense of a larger attack surface (a good example is Microsoft’s Visual Studio Code, which elected to lower the security level of Hardened Runtime by opting into the first four entitlements below). Common runtime exceptions include:
    • com.apple.security.cs.allow-dyld-environment-variables
    • com.apple.security.cs.allow-jit
    • com.apple.security.cs.allow-unsigned-executable-memory
    • com.apple.security.cs.disable-library-validation
    • com.apple.security.cs.disable-executable-page-protection
    • com.apple.security.cs.debugger
  • The app does not allow debugging: disallow an arbitrary process from being able to connect to your app’s Mach Task/kernel port. Simply do not sign your app with the com.apple.security.get-task-allow entitlement. This entitlement is auto-added by Xcode when building for debug. *Building for release should not include this entitlement.
  • The app is linked against a macOS SDK ≥ 10.9 (Mavericks).
  • The app does not contain malware known to Apple.

*To avoid Gatekeeper Path Randomization (GPR), sign and notarize your UDIF disk image.

Notarized apps have the following certificate chain:

- Developer ID Application: <Developer_Name> (<Team_ID>)
- Developer ID Certification Authority
- Apple Root CA 

Gatekeeper in 10.9.5 will block notarized apps with a code signature created by a version of macOS older than 10.9. This ensures there are no signature holes and blocks any app that attempts to load a library from outside the app bundle with @rpath (10.10.4 Yosemite).
Additionally, organizations can create their own System Policy rules through the use of Mobile Device Management (MDM) by specifying the SystemPolicyRule profile-specific payload key. Gatekeeper’s assessments as a whole can also be managed with the help of MDM and the SystemPolicyControl key.

Gatekeeper supports an additional class of applications called “Developer Tools” that are a broad exception for apps that do not meet the system’s security policy. Gatekeeper tracks this as the kTCCServiceDeveloperTool key in the “service” column of the (Transparency, Consent, and Control) TCC database. This database also lists the reason why an application was authorized for access to a TCC-protected service, such as MDM policy, system set, system policy, preflight unknown, entitled, and app type policy.

Apart from MDM, end users can manage Gatekeeper via the /usr/bin/spctl command-line tool. The spctl binary also enables users to:

  • enable Terminal.app as a developer tool
  • assess objects such as app bundles, installer packages, disk images, etc.
  • add a custom allow rule to Gatekeeper
  • change a rule in the Gatekeeper database
  • get the status of Gatekeeper
  • globally enable or disable Gatekeeper

 

Gatekeeper architectural overview

Fundamentally, Gatekeeper exists to help users and their organizations specify a system app security policy. Gatekeeper is then responsible for enforcing that policy in a few key ways. We can get a good idea of what’s going on by investigating the implemented XPC services and the protocols they talk over.

Gatekeeper runs in the system domain as a LaunchDaemon (with root privileges) at: /usr/libexec/syspolicyd.launchd. This is responsible for hosting the daemon with the label and Mach (XPC) service names of:

  • com.apple.security.syspolicy
  • com.apple.security.syspolicy.kext
  • com.apple.security.syspolicy.exec
  • com.apple.security.AppleSystemPolicy.mig (a special Mach IPC communication channel with the kernel)

 

Scott Knight’s article on syspolicyd internals features a comprehensive analysis (as of macOS Mojave). Here we’ll briefly touch on each of the functions implemented by the com.apple.security.syspolicy XPC service. This service runs under the Grand Central Dispatch (GCD) queue label of syspolicyd.secassessment.xpc:

  • assess: Given the path to a target, extracts or creates static properties (like the Core Foundation URL to the target). At a high level, this function kicks off a series of procedures that eventually call into the Security.framework to ask the system for an assessment on the proposed operation (execute, install, and open a document through Launch Services)
  • update: Performs an update to the System Policy database (discussed below)
  • record: Ensures that the connected client has the com.apple.private.assessment.recording entitlement
  • cancel: Cancels an in-progress Gatekeeper object assessment
  • check-dev-id: This function, while a little ambiguous, attempts to determine if the current system policy allows for app launches from identified developers (instead of just the App Store).
    • To do this, the -[EvaluationManager currentPolicyRequirement] function is called with the operation selector string of ui-get-devid-local. This function then calls CFPreferencesAppValueIsForced for the key of AllowIdentifiedDevelopers and the applicationID of com.apple.systempolicy.control
    • The arming status of Gatekeeper can be retrieved in a similar way with the ui-status string
  • check-notarized: Similar to the above function, this one will attempt to check if the current system policy will allow application launches from notarized applications. This time the operation string is ui-get-notarized-local
  • ticket-register: Adds local stapled notarization tickets to the tickets table of the Ticket database (discussed below) if one is found during assessment
  • ticket-lookup: Unlike the above function, which handles locally “stapled” notarization tickets, this function will attempt to validate notarization status by checking with Apple’s com.apple.gk.ticket-delivery CloudKit lookup service. Evidence of this is written out to the Unified Audit Log (viewable with Console.app—be sure to enable private logging). A sample log message can be found on Apple’s developer forums
  • legacy-check*: Appears to be a relatively new function that attempts to check the legacy policy of a given notarization ticket. The function will call the TicketDatabase function -[TicketDatabase isLegacyPolicy:], which will execute the query SELECT 1 FROMlegacy_policy WHERE hash = ?1.This query will quickly return if a given notarization ticket hash is part of the legacy policy

 

Additionally, its LaunchDaemon defining property list (plist) is protected by the System Integrity Protection (SIP) at /System/Library/LaunchDaemons/com.apple.security.syspolicy.plist. Within this plist, we can note its XPC launch events, which enable the XPC service to react to requests on-demand:

  • com.apple.security.syspolicy.kext.deprecation
  • com.apple.security.syspolicy.check.revocation
  • com.apple.security.syspolicy.legacypolicy
  • com.apple.security.syspolicy.find.bundles
  • com.apple.security.syspolicy.measure
  • com.apple.security.syspolicy.kext.mt
  • com.apple.security.syspolicy.gatekeeper.policy-metrics
  • com.apple.security.syspolicy.report
  • com.apple.security.syspolicy.invalidate
  • com.apple.security.syspolicy.rearm

 

Backing databases

Gatekeeper is backed by several SQLite3 databases that it uses to enforce policies and access rules and exceptions. These databases are not necessarily created by Gatekeeper (see the Appendix for a list of those), but rather, databases that Gatekeeper touches at runtime. Below is a listing of some of these databases and properties on an Apple Silicon Mac running macOS 13.2.

TCC: /Library/Application Support/com.apple.TCC/TCC.db

  • Tables include: access, access_overrides, active_policy, admin, expired, policies
  • Keys from the service column of the access table Gatekeeper would be interested in:
    • kTCCServiceDeveloperTool: Allows app to run software locally that do not meet the system’s security policy
  • When TCC access is granted to a resource, this will be reflected here.
  • This database is protected by System Integrity Protection (SIP).

 

Quarantine: ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2

  • Tables include: LSQuarantineEvent
  • This single table contains columns for: LSQuaranineEventIdentifier, LSQuarantineTimeStamp, LSQuarantineBundleIdentifier, LSQuarantineAgentName
  • When new items are quarantined by macOS, they’re added here.
  • This database is not protected by SIP.

 

System Policy: /var/db/SystemPolicy

  • Tables include: authority, bookmarkhints, feature, object
  • The authority table is a ledger consisting of an allow/deny decision, the assessed code-signing requirements’ string or cdhash, and the responsible assessor. Most entries have the GKE (Gatekeeper’s exclusions) as the assessor. A SIP-protected (plist) listing enumeration of these exclusions is found at /var/db/SystemPolicyConfiguration/gke.bundle/Contents/Resources/gke.auth. See the Appendix for example exclusions.
  • When new apps are assessed by Gatekeeper, that will be reflected in the authority table. As noted in *OS Internals Volume III (pg 106), the feature table consists of metadata-like features validated by code and those validated by GKE.
  • This database is not protected by SIP.

 

ExecPolicy: /var/db/SystemPolicyConfiguration/ExecPolicy

  • Tables include: executable_measurements_v2, policy_scan_cache, legacy_exec_history_v4, policy_scan_cache_by_path, old_platform_cache, provenance_tracking, policy_cache_by_path_meta, scan_targets_v2, policy_cache_meta, settings
  • This database is extensively used by Gatekeeper, and the scan cache tables are updated with the results of any scan that occurs.
  • This database is protected by SIP.

 

KextPolicy: /var/db/SystemPolicyConfiguration/KextPolicy

  • We chose not to analyze this database further due to the phase out of macOS kernel extensions.
  • This database is protected by SIP.

 

Tickets: /var/db/SystemPolicyConfiguration/Tickets

  • Tables include: hashes, legacy_policy, settings, tickets
  • This database often includes a persistent store of notarization ticket hashes, however, the settings and legacy_policy tables were empty during our analysis.
  • This database is protected by SIP.

 

Conclusion

We hope this information helps you better understand how Gatekeeper works and the various technologies that it relies on. While we briefly addressed Gatekeeper exploitation and bypass techniques on a conceptual level, we’re saving a more detailed exploration of Gatekeeper bypasses for future publications.

To that point, we’re publishing the Threat Detection Report later this month, and it will include a detailed analysis of T1553.001: Gatekeeper Bypass, including:

  • how and why adversaries bypass Gatekeeper
  • data sources that offer visibility into the technique and how to collect them
  • specific examples of how you can detect Gatekeeper bypass activity
  • tests for emulating how adversaries bypass gatekeeper
  • mitigation advice for limiting the impact of Gatekeeper bypasses

Appendix

syspolicyd embedded plist and entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>BuildMachineOSBuild</key>
	<string>20A241133</string>
	<key>CFBundleAllowMixedLocalizations</key>
	<true/>
	<key>CFBundleIdentifier</key>
	<string>com.apple.syspolicyd</string>
	<key>CFBundleSupportedPlatforms</key>
	<array>
		<string>MacOSX</string>
	</array>
	<key>DTCompiler</key>
	<string>com.apple.compilers.llvm.clang.1_0</string>
	<key>DTPlatformBuild</key>
	<string>22D46</string>
	<key>DTPlatformName</key>
	<string>macosx</string>
	<key>DTPlatformVersion</key>
	<string>13.2</string>
	<key>DTSDKBuild</key>
	<string>22D46</string>
	<key>DTSDKName</key>
	<string>macosx13.2.internal</string>
	<key>DTXcode</key>
	<string>1400</string>
	<key>DTXcodeBuild</key>
	<string>14A6270d</string>
	<key>LSMinimumSystemVersion</key>
	<string>13.2</string>
</dict>
</plist>

Gatekeeper has received a host of new entitlements since macOS Mojave. In his in-depth walkthrough of syspolicyd internals, Scott Knight notes that there are were six entitlements syspolicyd was signed with—compared to the 26 it’s now signed with in macOS 13.2 Ventura.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.keystore.filevault</key>
	<true/>
	<key>com.apple.private.IASInstallerAuthAgent</key>
	<true/>
	<key>com.apple.private.applecredentialmanager.allow</key>
	<true/>
	<key>com.apple.private.bootability</key>
	<true/>
	<key>com.apple.private.endpoint-security.submit.xp</key>
	<true/>
	<key>com.apple.private.iokit.nvram-panicmedic</key>
	<true/>
	<key>com.apple.private.iokit.system-nvram-allow</key>
	<true/>
	<key>com.apple.private.managedclient.configurationprofiles</key>
	<true/>
	<key>com.apple.private.quarantine.control</key>
	<true/>
	<key>com.apple.private.security.appbundle-authority</key>
	<true/>
	<key>com.apple.private.security.bootpolicy</key>
	<true/>
	<key>com.apple.private.security.register-xprotect-profile</key>
	<true/>
	<key>com.apple.private.security.storage.MobileIdentityService</key>
	<true/>
	<key>com.apple.private.security.storage.SystemPolicyConfiguration</key>
	<true/>
	<key>com.apple.private.syspolicy.perform-evaluations</key>
	<true/>
	<key>com.apple.private.tcc.allow</key>
	<array>
		<string>kTCCServiceSystemPolicyAllFiles</string>
	</array>
	<key>com.apple.private.tcc.manager.access.modify</key>
	<array>
		<string>kTCCServiceDeveloperTool</string>
	</array>
	<key>com.apple.private.tcc.manager.access.read</key>
	<array>
		<string>kTCCServiceAll</string>
	</array>
	<key>com.apple.private.tcc.manager.check-by-audit-token</key>
	<array>
		<string>kTCCServiceDeveloperTool</string>
	</array>
	<key>com.apple.private.xprotect</key>
	<true/>
	<key>com.apple.rootless.restricted-nvram-variables</key>
	<true/>
	<key>com.apple.rootless.storage.SystemPolicyConfiguration</key>
	<true/>
	<key>com.apple.rootless.volume.Preboot</key>
	<true/>
	<key>com.apple.rootless.volume.Recovery</key>
	<true/>
	<key>com.apple.rootless.volume.iSCPreboot</key>
	<true/>
	<key>com.apple.rootless.volume.iSCRecovery</key>
	<true/>
</dict>
</plist>

ExecManagerService

The following functions are implemented by the ExecManagerService.

@protocol ExecManager {
    -copyLegacyExecutionHistoryWithReply:
    -canInstallPackage:withUserConsent:withHash:evaluateOnly:synchronousPrompt:withReply:
    -trustPackagePayload:withDestinationTarget:withHashMap:withUserConsent:withReply:
    -notifyInstalledContent:withInstallationType:withReply:
    -performGatekeeperScan:withScanOptions:withUserID:withProgress:withReply:
    -isDeveloperModeEnabledWithReply:
    -setDeveloperModeEnabled:withReply:
    -copyBlockedExecutionPolicyItemsWithReply:
    -isDeveloperToolEnvironmentWithReply:
    -addExceptionForURL:withReply:
    -requestDeveloperToolAccessWithReply:
    -addGatekeeperUserIntent:withReply:
    -addBlockedSoftwareOverride:withReply:
    -setBlockedSoftwareOverride:isEnabled:withReply:
    -getBlockedSoftwareOverride:withReply:
    -isBlockedSoftware:withReply:
    -urlHasGatekeeperException:withReply:
    -showGatekeeperPreflightError:forApp:forUser:withReply:
    -getAllProvenanceEntriesWithReply:
    -findProvenanceEntry:withReply:
    -findProvenanceEntryByID:withReply:
    -findAssociatedProvenanceEntries:withReply:
};

KextManagerService

Similarly, the KextManagerService implements the following functions:

@protocol KernelExtensionPolicyAPI {
	-canLoadKernelExtension:withReply:
	-canLoadKernelExtensionInCache:withReply:
	-teamIdentifierIsAllowed:withReply:
	-isKernelExtensionApprovedByUser:withBundleID:withReply:
	-updatePolicyItems:withContext:withReply:
	-setUserApprovalAllowed:withReply:
	-setApprovalRequiresAdministrator:withReply:
	-getApprovalRequiresAdministratorWithReply:
	-installMDMPayload:withTeams:withExtensions:withContext:withReply:
	-removeMDMPayload:withContext:withReply:
	-enableKernelExtensionManagementForMDM:withReply:
	-copyCurrentPolicyWithReply:
	-copyPendingApprovalsWithReply:
	-areKernelExtensionsApproved:withReply:
	-requestKernelExtensionApprovals:withReply:
	-triggerKernelCollectionRebuildFlow:withKernelExtensions:withReply:
	-triggerKernelCollectionRebuildForMDM:withContext:withReply:
	-getCurrentUAKLHashWithReply:
	-updateLastUsedTimes:withReply:
	-triggerRecoveryJumpToSecurityStartupUtility:
	-triggerPanicMedic:
};

@protocol KernelExtensionPolicyAPI {
	-canLoadKernelExtension:withReply:
	-canLoadKernelExtensionInCache:withReply:
	-teamIdentifierIsAllowed:withReply:
	-isKernelExtensionApprovedByUser:withBundleID:withReply:
	-updatePolicyItems:withContext:withReply:
	-setUserApprovalAllowed:withReply:
	-setApprovalRequiresAdministrator:withReply:
	-getApprovalRequiresAdministratorWithReply:
	-installMDMPayload:withTeams:withExtensions:withContext:withReply:
	-removeMDMPayload:withContext:withReply:
	-enableKernelExtensionManagementForMDM:withReply:
	-copyCurrentPolicyWithReply:
	-copyPendingApprovalsWithReply:
	-areKernelExtensionsApproved:withReply:
	-requestKernelExtensionApprovals:withReply:
	-triggerKernelCollectionRebuildFlow:withKernelExtensions:withReply:
	-triggerKernelCollectionRebuildForMDM:withContext:withReply:
	-getCurrentUAKLHashWithReply:
	-updateLastUsedTimes:withReply:
	-triggerRecoveryJumpToSecurityStartupUtility:
	-triggerPanicMedic:
}

Gatekeeper exclusions

Here are two sample exclusions added by Gatekeeper. GKEs serve as a allowlist on macOS.

"38d5fef8-b3cd-4dd2-ad2d-a40e93f18f74": {
  "path": "(gke)",
  "screen": "Id0cf666125d330191b3fd13eea8fc956dbfdbdd2",
  "cdhash": "5a4e4dc97878a7ef283db76cdf584aa4e2de13c8",
  "type": "1",
  "version": 2
},
"8d583ec1-dc81-453c-8a61-2abb4358685c": {
  "path": "(gke)",
  "screen": "R20b40f3d65d00c7ff59802e9a1f50076e50d974c4787837471ad3af4cfd527d7",
  "cdhash": "b4f580ee04aeaaaf48e2647666f4dbed0ce4c502",
  "type": "3",
  "version": 3
}

Database schemas

The following is an abridged list of database schemas that are created and regularly used by Gatekeeper.

ExecPolicy Database

Executable_measurements_v2

Executable_measurements_v2 database screenshot

CREATE TABLE IF NOT EXISTS executable_measurements_v2 (  is_signed INTEGER,  file_identifier TEXT NOT NULL,  bundle_identifier TEXT,  bundle_version TEXT,  team_identifier TEXT,  signing_identifier TEXT,  cdhash TEXT NOT NULL,  main_executable_hash TEXT,  executable_timestamp INTEGER,  file_size INTEGER,  is_library INTEGER,  is_used INTEGER,  responsible_file_identifier TEXT,  is_valid INTEGER,  is_quarantined INTEGER,  timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now')),  reported_timestamp INTEGER,  PRIMARY KEY (cdhash))

old_platform_cache

CREATE TABLE IF NOT EXISTS old_platform_cache ( key TEXT, ts INTEGER, PRIMARY KEY (key) )CREATE TABLE IF NOT EXISTS scan_targets_v2 (  path TEXT NOT NULL,  responsible_path TEXT,  is_library INTEGER,  is_used INTEGER,  timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now')),  measured_timestamp INTEGER,  deferral_count INTEGER,  PRIMARY KEY (path))

policy_cache_by_path_meta

CREATE TABLE policy_cache_by_path_meta ( meta_id INTEGER PRIMARY KEY AUTOINCREMENT, miss_count INTEGER NOT NULL, last_miss INTEGER NOT NULL, for_entry INTEGER NOT NULL UNIQUE, CONSTRAINT fk_for_entry_by_path  FOREIGN KEY (for_entry)  REFERENCES policy_scan_cache_by_path(pk)  ON DELETE CASCADE )

policy_cache_meta

CREATE TABLE policy_cache_meta ( meta_id INTEGER PRIMARY KEY AUTOINCREMENT, miss_count INTEGER NOT NULL, last_miss INTEGER NOT NULL, for_entry INTEGER NOT NULL UNIQUE, CONSTRAINT fk_for_entry  FOREIGN KEY (for_entry)  REFERENCES policy_scan_cache(pk)  ON DELETE CASCADE )

policy_scan_cache

policy_scan_cache database screenshot

CREATE TABLE policy_scan_cache (  pk INTEGER PRIMARY KEY AUTOINCREMENT,  volume_uuid TEXT NOT NULL,  object_id INTEGER,  fs_type_name TEXT NOT NULL,  bundle_id TEXT NOT NULL,  cdhash TEXT,  team_identifier TEXT,  signing_identifier TEXT,  policy_match INTEGER,  malware_result INTEGER,  flags INTEGER,  mod_time INTEGER,  timestamp INTEGER NOT NULL,  revocation_check_time INTEGER,  scan_version INTEGER,  UNIQUE(volume_uuid, object_id, fs_type_name))

policy_scan_cache_by_path

policy_scan_cache database screenshot

CREATE TABLE policy_scan_cache_by_path (  pk INTEGER PRIMARY KEY AUTOINCREMENT,  mount_point TEXT NOT NULL,  mount_relative_path NOT NULL,  fs_type_name NOT NULL,  bundle_id TEXT NOT NULL,  cdhash TEXT,  team_identifier TEXT,  signing_identifier TEXT,  policy_match INTEGER,  malware_result INTEGER,  flags INTEGER,  mod_time INTEGER,  last_used_time INTEGER,  timestamp INTEGER NOT NULL,  revocation_check_time INTEGER,  scan_version INTEGER,  UNIQUE(mount_point, mount_relative_path, fs_type_name))

provenance_tracking

provenance_tracking database screenshot

CREATE TABLE provenance_tracking (  pk INTEGER PRIMARY KEY,  url TEXT NOT NULL,  bundle_id TEXT,  cdhash TEXT,  team_identifier TEXT,  signing_identifier TEXT,  flags INTEGER,  timestamp INTEGER NOT NULL,  link_pk INTEGER)

scan_targets_v2

scan_targets_v2 database screenshot

CREATE TABLE IF NOT EXISTS scan_targets_v2 (  path TEXT NOT NULL,  responsible_path TEXT,  is_library INTEGER,  is_used INTEGER,  timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now')),  measured_timestamp INTEGER,  deferral_count INTEGER,  PRIMARY KEY (path))

Settings

settings database screenshot

CREATE TABLE IF NOT EXISTS settings ( name TEXT, value TEXT, PRIMARY KEY (name) )

Ticket database

hashes 

hashes database screenshot

CREATE TABLE IF NOT EXISTS hashes (  id INTEGER PRIMARY KEY AUTOINCREMENT,  hash BLOB,  hash_type INTEGER,  ticket_id INTEGER,  FOREIGN KEY(ticket_id) REFERENCES tickets(id) ON DELETE CASCADE)

legacy_policy

CREATE TABLE IF NOT EXISTS legacy_policy (  id INTEGER PRIMARY KEY AUTOINCREMENT,  hash BLOB)

tickets

tickets database screenshot

CREATE TABLE IF NOT EXISTS tickets (  id INTEGER PRIMARY KEY AUTOINCREMENT,  hash BLOB,  hash_type INTEGER,  timestamp INTEGER,  flags INTEGER)
 

How adversaries use Entra ID service principals in business email compromise schemes

 

MSIX and other tricks: How to detect malicious installer packages

 

The detection engineer’s guide to Linux

 

The Trainman’s Guide to overlooked entry points in Microsoft Azure

Subscribe to our blog

 
 
Back to Top