Adversaries are finding new methods of subverting two of macOS’s key security checks: Gatekeeper and File Quarantine.
Editor’s note: While the detection opportunities and analysis on this page are still relevant, it has not been updated since 2023.
Note: For additional information on the architecture of Gatekeeper, how it works, and conceptual descriptions of how adversaries bypass it, refer to our previous research: Gatekeeping in macOS: Keeping adversaries off our Apples.
Adversaries attempt to bypass Apple’s Gatekeeper security checks in order to gain execution on a host. Since Gatekeeper’s introduction, the security control has hampered adversaries’ ability to execute untrusted code (i.e., code that does not conform to the system’s security policy). Adversaries may also circumvent the older File Quarantine feature and some of the high-level security checks that Gatekeeper performs, but the objective remains the same: to execute untrusted code.
Since Gatekeeper relies on a separate feature called File Quarantine to identify the files that it will inspect, it makes sense to start this section with a brief explanation of File Quarantine and an examination of the ways that adversaries can circumvent it.
Our previous research includes a thorough examination of File Quarantine that we encourage you to read. In brief, it’s generally an opt-in security feature for applications like browsers, work management tools, and torrenting clients that applies a quarantine extended attribute to files downloaded by users of those applications. This file quarantine attribute signals Gatekeeper to inspect files marked with it. File Quarantine is essentially a macOS version of Mark-of-the-Web for Windows systems.
Non-LSFileQuarantineEnabled
apps and/or binaries like /usr/bin/curl
and /usr/bin/wget
are two examples of binaries that do not append the quarantine extended attribute to downloaded files. WindTail, “VPN Trojan” (Covid), oRAT, and ChromeLoader, just to name a few, have all been known to abuse wget
or curl
to sidestep File Quarantine.
An adversary could also target users of non-quarantine-aware applications to download content without the quarantine attribute and circumvent File Quarantine and Gatekeeper in the process. While possible, this is also complicated as the adversary would need to identify a non-quarantine-aware application being used by a victim and then socially engineer the victim into downloading a malicious file with that application. By contrast, utilities like wget
and curl
offer adversaries a seemingly normal and widely available mechanism for downloading files from the internet without the quarantine attribute.
The name of the game here is to trick macOS into launching an executable without first passing a full Gatekeeper check. Before we document existing methods of bypassing Gatekeeper, we should revisit some of the properties that Gatekeeper checks include:
System Policy
File type
Static properties
Code-signing properties
cdhash
(Code Directory hash)codesign --verify --deep --strict --verbose=2 <code-path>
Notarization (stapled and remote tickets)
XProtect scan result
Defenders can also inspect many of the database tables the Gatekeeper creates and updates via syspolicyd
.
Gatekeeper is a large security control on macOS with responsibilities ranging from initiating XProtect scans, static analysis, code-signing/notarization validation, and now application bundle anti-tamper. There’s no surefire way to bypass Gatekeeper, and most methods involve use of an exploit or two. However, researchers have uncovered exploits with overlapping tradecraft:
Clever archives
.ipa
.Symlinks
../Contents/MacOS/
to a local copy on the system.Clever app bundles
../Contents/MacOS/
Open Scripting Architecture (OSA)
.sdef
(scripting definitions) file that contains HTML/JavaScriptWebKit
Miscellaneous impacted components:
You can help mitigate Gatekeeper bypasses by doing the following:
Note: The visibility sections in this report are mapped to MITRE ATT&CK data sources and components.
Although there is no completely reliable way to engineer a detection analytic for bypassing Gatekeeper—in part due to the sheer size of the security control—there are clever combinations of endpoint security events and additional enrichment we can monitor for high-fidelity detection. For one, Gatekeeper also makes liberal use of the Unified Audit Log. Additionally, many of the analytics we’ll describe here focus on process and file monitoring—data sources described by MITRE here. Leverage native macOS tools to record process and file level system events as they occur.
File Quarantine-aware applications should not be making unquarantined file downloads. Additional noise may be seen in /private/var/folders
. You can determine if an application is file quarantine aware by checking its Info.plist
/the exceptions list at: /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist
, which forces applications into quarantine.
While a file’s extended attributes (or the existence of the quarantine attribute) are not directly reported by Endpoint Security (for file creation, rename, etc), it’s possible to directly check over API using getxattr
or using the URL resource key quarantinePropertiesKey
from the Foundation framework. File creation operations will be helpful for checking if a File Quarantine-aware app makes an unquarantined file download. However, these will not be as helpful when dealing with archives. File rename operations, resulting from inflating an archive using Archive Utility.
/private/var/folders/…/…/T/com.apple.desktopservices.ArchiveService/TemporaryItems/…/
~/
Note: The collection sections of this report showcase specific log sources from Windows events, Sysmon, and elsewhere that you can use to collect relevant security information.
The com.apple.quarantine
extended attribute/notarization is key in alerting Gatekeeper that it should assess an object. LSFileQuarantineEnabled
applications should always download files with the quarantine extended attribute tagged.
File Quarantine-enabled applications opt users into File Quarantine protection by adding the LSFileQuarantineEnabled
key to their Info.plist
.
Apple’s Endpoint Security subsystem provides notification/authorization events that defenders can subscribe to and incorporate into for detection. Process execution, file rename/creation events can be particularly useful. These events are triggered when macOS notifies Endpoint Security that either a process has/will execute or that a file creation operation is taking place. For simplicity, here we will discuss only notification events—but defenders can easily adapt this logic for authorization events that could theoretically block a Gatekeeper bypass event.
ES_EVENT_TYPE_NOTIFY_EXEC
Beyond what’s available in Endpoint Security, grab the property list of the application that launched (if it exists) as well.
ES_EVENT_TYPE_NOTIFY_RENAME
The source and destination paths are important here (directly provided by Endpoint Security). We’ll use the destination path to check for quarantine (use the method described above).
ES_EVENT_TYPE_NOTIFY_CREATE
Like the above, beyond what Endpoint Security provides, record:
While it might seem like bypass activity happens outside the bounds of a security team’s visibility, there are a couple of detection analytics that might help security teams develop coverage for this technique. Here we will focus on the File Quarantine violation type, but other detection opportunities (which may be more complicated and should be done at the EDR level) exist for:
The following detection logic should identify files created by a File Quarantine-aware application that did not receive the quarantine extended attribute. This detection analytic handles the File Quarantine bypass type.
process_is == FileQuarantineAware
&& filemod_path_does_not_include ('/private/var/folders')
&&
filemod_propery_does_not_include ('com.apple.quarantine')
The following analytic is specific to Safari.app
and is based on research from Jamf Threat labs with CVE-2022-22616. This analytic checks to ensure that a file downloaded and expanded by Safari is quarantined.
process == "com.apple.Safari.SandboxBroker"
&&
(filemod_path_includes ('.download' || '.app')
&&
filemod_propery_does_not_include ('com.apple.quarantine'))
This analytic is added for EDR developers who want to gain insight into potential File Quarantine bypasses. This analytic will need to be developed at the sensor level.
// isFileQuarantined(path: String) -> Bool
// filesNotQuarantined(directoryPath: String, options: [...] = []) -> [String]
file_rename_destination_path_includes ('$HOME') && file_rename_source_path_includes ('com.apple.desktopservices.ArchiveService') && isFileQuarantined(file_rename_destination_path) && filesNotQuarantined(file_rename_destination_path).count > 0
The best way to test for a Gatekeeper bypass event is to think like an adversary and come up with some atomic examples of behavior:
Info.plist
…something like TEST-LSFileQuarantineEnabled
.Additionally, more tests like the above can be created for other classes of bypasses (those independent of File Quarantine) like application bundle tampering, which instead largely relies on code-signing properties.
Get curated insights on managed detection and response (MDR) services, threat intelligence, and security operations—delivered straight to your inbox every month.