(@hashcat) January 26, 2017
This is only useful if the backup was encrypted by setting a backup password on the iOS device. If the backup is not encrypted then all the files are in clear and there is nothing to bruteforce.
The keys used to encrypt the backup are stored in the BackupKeyBag, which can be found in the
Manifest.plist file. This keybag is a binary blob, the format of which has already been documented by researchers from Sogeti ESEC Lab.
I have written a simplified script which dumps the
You will need the Python bindings from libplist for the script to work. If you cannot get it to work, you can try the Perl script from philsmd instead.
Speeding up iOS Backups
iOS device backups usually take a while, depending on how much storage has been used on your device.
The iOS backup process is driven by the device itself, through the
BackupAgent process. This process treats the host PC like a dumb disk store, by sending it commands like
DLMessageGetFreeDiskSpace, etc. so that it can determine what has been backed up previously and what to send/update for incremental backups.
For password cracking, we don’t need the entire 64 GB (or God forbid, 128 GB) of data on the iOS device. We just need the
Manifest.plist, which is typically less than 50 KB. But because the backup process is controlled by the device and not the PC, we can’t simply ask it to send over that single file. Sometimes when we setup a VM with libimobiledevice, we might also not have allocated such a large virtual disk. Of course when I say “we”, I really mean “I”.
To solve these issues, I created a FUSE-based filesystem called the Fake iOS Backup Filesystem, or fibfs for short. I’m particularly proud of this name because my project names are usually very unoriginal. This file system exposes a “disk” (or mount point) that reports at least 128 GB of free space, and will preserve file names and other metadata but not the file contents. It contains a hard-coded list of files, like a white list, that should have their contents preserved,
Manifest.plist being one of them. Because it discards most of the backed up data, such a backup will consume less than 10 MB of real disk space.
This filesystem is to be used when specifying a backup directory for
idevicebackup2. It will then lie to the iOS device that it has sufficient disk space to perform the backup, while actually discarding the backup data instead of writing them to disk.
Thus, using fibfs allows you to retrieve
Manifest.plist without spending too much time or disk space for the iOS backup process.
Quick note: if your iOS 10 backups are failing due to an error removing snapshot directory, it has been fixed in the tree but just not put into a release yet. The current version with this bug is libimobiledevice 1.2.0. All the backed up data is still there anyway.
You will need the latest version of hashcat (at least 3.40), released just a few days ago.
The hash format for iTunes Backups look like this (everything is delimited by asterisks):
For iOS versions earlier than 10.2,
DPSL are not required, so just leave them blank. That means your constructed hash will look like this:
For iOS 10.2 and above, the
DPSL parameters will be required. You will see these parameters when you dump the keybag.
The hash type (or hash mode) for iOS versions < 10.2 is
-m 14700. For iOS 10.2 that introduced the
DPSL parameters, you will have to use
-m 14800. Setting the hash mode will instruct hashcat to use the correct OpenCL kernel.
When you dump the keybag (using the above-mentioned script or other methods), you should see something like this:
VERS 3 TYPE 1 ---------- UUID: b6ed25...d71a, HMCK: 0000...0000, WRAP: 0, SALT: 2b06ba3c6281ce101a0bd0249c1203cc9c8da1a8, ITER: 10000 UUID: 3a8bcc...baaf, CLAS: 11, WRAP: 3, KTYP: 0, WPKY: c1212e8754a1db6dfddc4fc6a386795eda88c18b865742e6fbd961b13e3229efda50dc0b69bdfc2e UUID: 47386f...58d1, CLAS: 10, WRAP: 3, KTYP: 0, WPKY: d025009b7eaa016d756d6862c71856e76b060e1ee6f69e6c805852008757f1cb25110025a2e4fcb6 UUID: 24ac76...af0c, CLAS: 9, WRAP: 3, KTYP: 0, WPKY: baa24719f865afe330b85f26468e787c0115339407ad950935070cd5e7cc27a5d6c811e716b38741 . . .
UUID of each entry is not important, which is why the script truncates it for brevity. Only the first entry (where
0) will contain the
ITER parameters. For an iOS version 10.2 keybag, this is where you will also find the
Subsequent keybag entries contain the encryption key for each
NSFileProtection class and
kSecAttrAccessible class. There's currently a total of 11
CLAS types (including undocumented classes). The actual key for each entry is stored in the
WPKY attribute (wrapped key). Any
WPKY value can be used, as long as the
WRAP_PASSCODE bit (0x2) is set. Usually, all keys will have this bit set, so any keybag entry can be used.
The reason this works is because we are not cracking the key itself, but rather the backup password that protects these keys. Each key is "wrapped" using AES and a successful unwrapping can be verified by checking the IV for a known value (
A6A6A6A6A6A6A6A6). This allows hashcat to know when it has found the right password.
So to summarize, these parameters are used to construct a hash for hashcat to crack:
WPKYfrom any entry
ITERparameters from the first entry
DPICparameters (only for iOS 10.2 and later)
Note that this is not a hashcat tutorial; I assume you already know how to use it.
Here's a worked example for cracking the password to the keybag above. In this case, the backup is from an iOS version 9.x device, and we are using the key for the
CLAS 11 entry.
> hashcat64 -m 14700 -a 3 "$itunes_backup$*9*c1212e8754a1db6dfddc4fc6a386795eda88c18b865742e6fbd961b13e3229efda50dc0b69bdfc2e*10000*2b06ba3c6281ce101a0bd0249c1203cc9c8da1a8**" pa?l?l?l?l?l?l ... $itunes_backup$*9*c1212e8754a1db6dfddc4fc6a386795eda88c18b865742e6fbd961b13e3229efda50dc0b69bdfc2e*10000*2b06ba3c6281ce101a0bd0249c1203cc9c8da1a8**:password Session..........: hashcat Status...........: Cracked Hash.Type........: iTunes Backup < 10.0 Hash.Target......: $itunes_backup$*9*c1212e8754a1db6dfddc4fc6a386795eda88c18b865742e6fbd961b13e3229efda50dc0b69bdfc2e*10000*2b06ba3c6281ce101a0bd0249c1203cc9c8da1a8** Time.Started.....: Thu Mar 02 22:16:09 2017 (9 secs) Time.Estimated...: Thu Mar 02 22:16:18 2017 (0 secs) Input.Mask.......: pa?l?l?l?l?l?l  Input.Queue......: 1/1 (100.00%) Speed.Dev.#1.....: 55659 H/s (6.43ms) Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts Progress.........: 540672/308915776 (0.18%) Rejected.........: 0/540672 (0.00%) Restore.Point....: 360448/308915776 (0.12%) Candidates.#1....: paydbfer -> panpjurd HWMon.Dev.#1.....: Temp: 47c Fan: 33% Util: 92% Core:1100Mhz Mem:1500Mhz Lanes:16
If you do get some "separator unmatched" error, check that the "iTunes version" in the hash matches the hash mode being used.
To give you an idea of the performance of cracking iTunes Backup passwords, here's a comparison against other well-known algorithms that have been long supported by hashcat:
Note that the graph has a logarithmic scale. These measurements were taken using my Radeon HD 7900; your mileage may vary.
There’s no cause for concern here. The security measures in place to protect the iTunes Backup password are in line with current practices. Apple has taken steps to further secure iOS 10 backups by introducing an additional layer of 10,000,000 rounds (yes, that’s 10 million!) of SHA-256. That is why the new iTunes 10.2 backups now take at least 3 orders of magnitude longer to crack.
This is also a reminder to use a sufficiently strong password for your encrypted iOS backups.
If you are interested in reading more about the security architecture for iOS backups, you can check out the following links:
- “iPhone data protection in depth” (presentation at HITB 2011 Amsterdam): http://esec-lab.sogeti.com/static/publications/11-hitbamsterdam-iphonedataprotection.pdf
- iphone-dataprotection code: https://code.google.com/archive/p/iphone-dataprotection/
- iOS Security Guide, May 2016 from Apple
- Behind the Scenes with iOS Security @ Black Hat US 2016, by Ivan Kristić at Apple