Jamf Threat Labs: Fake Lockdown Mode proof of concept
This research explores a scenario in which a vulnerable device is compromised by an attacker who plants the code to implement Fake Lockdown Mode. When a high-risk user (e.g., journalists, government officials, executives) of the compromised device initiates Lockdown Mode, they trigger the attacker’s code that implements the visual cues of Lockdown Mode, but makes no changes to the device’s configuration.
Has your Lockdown Mode been tampered with?
Apple’s Lockdown mode in iOS 16 is a useful feature for certain situations, but if your phone has already been compromised, Lockdown Mode won’t protect you. This blog post delves into our research on Fake Lockdown Mode which shows that if a hacker has already infiltrated your device, they can cause Lockdown Mode to be “bypassed” when you trigger its activation.
The introduction of Lockdown Mode
Apple introduced Lockdown Mode in September 2022 in response to the surge in global cyber attack campaigns. As shown below and according to Google’s Threat Analysis Group (TAG), the years 2021 and 2022 saw the highest number of in-the-wild zero-day attacks detected since they began tracking such incidents in mid-2014. Notably, one of the most infamous spyware brands, Pegasus, can infect the latest iPhone without requiring any user interaction, known as a zero-click attack. Despite Apple’s ongoing efforts to enhance its security architecture in recent years, operators of Pegasus have demonstrated a remarkable ability to discover new vulnerabilities and execute zero-click attacks. This situation raised concerns among users, prompting the development of Lockdown Mode as a solution to counter this growing trend, as well as providing reassurance for iPhone users.
Lockdown Mode works by minimizing the functionality that is remotely accessible to potential attackers. This approach, while straightforward, is robust because the less code you expose, the less code attackers can leverage to exploit vulnerabilities. Apple describes Lockdown Mode as:
Lockdown Mode is an optional, extreme protection that’s designed for the very few individuals who, because of who they are or what they do, might be personally targeted by some of the most sophisticated digital threats. Most people are never targeted by attacks of this nature.
When Lockdown Mode is enabled, your device won’t function like it typically does. To reduce the attack surface that potentially could be exploited by highly targeted mercenary spyware, certain apps, websites, and features are strictly limited for security and some experiences might not be available at all.
Lockdown Mode is available in iOS 16 or later, iPadOS 16 or later, watchOS 10 or later, and macOS Ventura or later. Additional protections are available in iOS 17, iPadOS 17, watchOS 10, and macOS Sonoma. For a complete set of protections, update your devices to the latest software before turning on Lockdown Mode.
For example, Lockdown Mode adopts a restricted web browser engine for use with captive portals. A captive portal is a web page that typically pops up when you connect to a public Wi-Fi network and is often used for advertising or authentication purposes. The web engine behind captive portals imposes more constraints, with one prominent restriction being the disabling of Just-In-Time (JIT) JavaScript compilation for security considerations. This restriction also extends to Lockdown Mode. Consequently, the use of Lockdown Mode has been found to result in performance and responsiveness reductions of up to 95 percent in web applications when it comes to the JavaScript engine.
Turning on Lockdown Mode will remove support for particular file formats, primarily due to their history of exploitation. It will also disable convenience features, for example, no longer showing previews of links sent through Messages, disabling shared albums and preventing the installation of configuration profiles and enrollment in mobile device management (MDM) software.
The image below, from blacktop on GitHub, lists what Lockdown Mode disables.
Fast forward to 2023 — the effectiveness of Lockdown Mode has become apparent. In September 2023, CitizenLab identified an actively exploited zero-click exploit chain called BLASTPASS, which targeted the latest iOS 16 version available at the time. Both CitizenLab and Apple have affirmed that enabling Lockdown Mode will block this particular attack. While they haven’t disclosed further details to avoid potential misuse, it’s likely that some level of user interaction is now required to trigger the exploit after Lockdown Mode is enabled, thus disabling the zero-click capability of the attack, allowing users an opportunity to react.
Limitations of Lockdown Mode
While Lockdown Mode has proven its effectiveness in certain scenarios, our evaluation of Lockdown Mode emphasizes that it won’t stop an attack that has already been initiated on the device. iPhone users should be aware that if their device has already been infected, activating Lockdown Mode will not affect a trojan that has already breached the system. Lockdown Mode’s primary purpose is to reduce potential attack vectors, rather than add additional security measures to prevent the execution of malicious payloads.
In the rest of the article, we will demonstrate how, in the scenario of an iPhone that’s already been infected, Lockdown Mode might be manipulated, potentially giving users a false sense of security.
The switch
As shown below, we begin by examining the Lockdown Mode toggle within the Settings app. Many of the actions happening behind the scenes are invisible to the user, except the reboot. We conducted a search for the “lockdownMode” string within the dyldcache and found that a framework called PrivacySettingsUI
has implemented two C functions with the following names:
bool isLockdownModeEnabled()
void setLockdownModeEnabled(bool)
Within the void setLockdownModeEnabled(bool)
function, it configures the Boolean value of the key LDMGlobalEnabled
to “Yes” via NSUserDefaults API. By monitoring file change events, we found the path of this file: /var/mobile/Library/Preferences/.GlobalPreferences.plist
This single value serves as the primary indicator for whether the system considers Lockdown Mode to be active or not. By manually overwriting the user’s defaults database, setting this value to “Yes”, achieved through a command like
[[NSUserDefaults standardUserDefaults] setObject: [NSNumber numberWithBool: 1] forKey:@"LDMGlobalEnabled" inDomain: @"NSGlobalDomain"]
This command can be executed in nearly any process outside of the sandbox. Changes can be observed in the return values of numerous functions, you can find these functions by running “grep -i lockdownMode” within the dyldcache.
-[PUILockdownModeController lockdownModeEnabled]
+[SUUtility isLockdownModeEnabled]
+[WBSUIFeatureAvailability isLockdownModeEnabledForSafari]
+[WKProcessPool _lockdownModeEnabledGloballyForTesting]
-[WKWebpagePreferences isLockdownModeEnabled]
-[MCProfileConnection(Misc) isLockdownModeEnabled]
+[NSUserDefaults(Email) em_lockdownModeEnabled]
-[TUMomentsController lockdownModeEnabled]
-[PUILockdownModeController lockdownModeEnabled]
+[SUUtility isLockdownModeEnabled]
+[WBSUIFeatureAvailability isLockdownModeEnabledForSafari]
+[WKProcessPool _lockdownModeEnabledGloballyForTesting]
-[WKWebpagePreferences isLockdownModeEnabled]
-[MCProfileConnection(Misc) isLockdownModeEnabled]
+[NSUserDefaults(Email) em_lockdownModeEnabled]
-[TUMomentsController lockdownModeEnabled]
A few functions, such as PUILockdownModeController
, require initializing a new instance because file reading occurs in the initialization method. Nevertheless, after these processes are restarted, all return positive results which activate Lockdown Mode across the whole device, and this adjustment takes effect without a full device reboot.
This confirms our suspicion that, as of iOS 16.5, Lockdown Mode remains to function as a userspace artifact (kernel is not aware of it). We did not find any code implementation related to Lockdown Mode within the iOS 16.5 kernel. A system reboot is entirely not needed for activating or deactivating Lockdown Mode at this stage.
However, that’s just for now. Referring to insights from the “Anatomy of Lockdown Mode” by blacktop, Since iOS 17, Apple has elevated Lockdown Mode to kernel level. It now includes its own background daemon, found at /System/Library/PrivateFrameworks/LockdownMode.framework/lockdownmoded, and a KEXT called com.apple.driver.AppleLockdownMode
. This strategic move is a great step in enhancing security, as changes made by Lockdown Mode in the kernel typically cannot be undone without undergoing a system reboot, thanks to existing security mitigations.
Dudded the reboot
Back to the topic of manipulating Lockdown Mode, our objective regarding the Settings app is to render Lockdown Mode ineffective and replace system reboot for a user space reboot. This demonstration aims to showcase how malware could trick the user. In the case of an infected phone, there are no safeguards in place to stop the malware from running in the background, whether the user activates Lockdown Mode or not.
When a user opts to turn on Lockdown Mode in the Settings app, that will trigger the method -[PUILockdownModeController setLockdownModeGloballyEnabled:]
, and inside, you can see the sequence of events provides a clear overview of how Lockdown Mode functions. It begins by deactivating shared albums and link previews, followed by the disabling of developer mode and enabling of USB restricted mode. Profile installation is also disabled, and the LDMGlobalEnabled
key in the user’s defaults database is set to “YES”, with the changes synchronized. Inside the _DaemonReady function
, CFNotificationCenterPostNotification()
is invoked to notify WebKit processes about the configuration change. Finally, the device is rebooted.
Given that -[PUILockdownModeController setLockdownModeGloballyEnabled:]
is an objective-C method, you can utilize the method_exchangeImplementations
Method Hooking technique to replace its content. What we did is straightforward: Whenever the user turns on the Lockdown Mode, a file named /fakelockdownmode_on is created as an indicator, and a userspace reboot is initiated. We also hooked other functions, such as –[PUILockdownModeController lockdownModeEnabled]
, to return results based on the existence of this file.
This way, the device did not really reboot, and allowed our injected code to maintain adaptable control over the Lockdown Mode. This also means that even malware lacking persistence can persistently run and monitor the user.
Fake Lockdown Mode in Safari
To further demonstrate manipulation of the Lockdown Mode, we chose Safari, one of the most commonly used applications. When a user is browsing a website using Safari, they will observe a conspicuous label that reads “Lockdown Enabled”. This label serves as an indicator that a captive portal version of the web engine is used to render the current webpage. If, for any reason, the regular web engine is used instead, Safari will prominently display “Lockdown Off” in a red, attention-grabbing font. This scenario happens when a user is browsing a trusted website, a configuration that can be adjusted in the website settings.
Safari relies entirely on a single function, +[WBSUIFeatureAvailability isLockdownModeEnabledForSafari]
, to determine the status of Lockdown Mode. By hooking this function, we then can make this function return desired results at different scenarios. For example, we can make it return “No” when making decisions about whether to use the captive portal web engine and “Yes” when determining the appearance of surface-level elements, like the “Lockdown Ready” label in the User Interface.
Now, Safari will behave as if all websites are trusted, and we need to take some steps to alter the “Lockdown Off” label. To accomplish this, we first search for the string “Lockdown Off” and locate the function called WBSAnnotationStringForLockdownModeStatus
, By monitoring its backtrace, we see it was invoked by –[SFLockdownStatusBar _updateLabelWithLockdownStatus:]
, an objective-C method that can be conveniently hooked. We proceed to modify this function to display “Lockdown Enabled” when it would normally display “Lockdown Off”.
Demo Video
In this demonstration video, a user activates Lockdown Mode in Settings. Although the device appears to be in Lockdown Mode, it is, in fact, not activated, as we can still view PDF files in safari. Our demonstration also employed a site developed by crypt.ee, which utilizes technical means to verify the status of Lockdown Mode.