Following the recent announcement of LUKS support in hashcat, I noticed that there have been some commits to support iTunes Backup passwords as well.
Support added to hashcat to crack iTunes Backups (iOS 6/7/8/9/10): hashcat.net/forum/thread-6… https://t.co/MKhPzW6Q2j
—
(@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 BackupKeyBag
.
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 DLMessageCreateDirectory
, DLMessageUploadFiles
, DLMessageRemoveFiles
, 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.
Using Hashcat
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):
$itunes_backup$*<ver>*<WPKY>*<ITER>*<SALT>*<DPIC>*<DPSL>
For iOS versions earlier than 10.2, DPIC
and DPSL
are not required, so just leave them blank. That means your constructed hash will look like this:
$itunes_backup$*9*<WPKY>*<ITER>*<SALT>**
For iOS 10.2 and above, the DPIC
and 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 DPIC
and 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 . . .
The UUID
of each entry is not important, which is why the script truncates it for brevity. Only the first entry (where WRAP
is 0
) will contain the SALT
and ITER
parameters. For an iOS version 10.2 keybag, this is where you will also find the DPSL
and DPIC
parameters.
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:
- a
WPKY
from any entry SALT
andITER
parameters from the first entryDPSL
andDPIC
parameters (only for iOS 10.2 and later)
Example
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 [8] 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.
Performance
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.
Further Reading
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
Hi,
Thanks for this interesting Post. I’m trying to follow it, but block at the first step using the Python script to dump the BackupKeyBag.
May you specify which “plist” module you are using please? I could not find one making your script working.
Thanks ahead!
Note: it seems “StringIO” module has been replaced by module “io” (using Python 3.6 (64 bit) on Windows 7)
Regards
Damien
Hi Damien, it’s the libplist C library – it has Python bindings. It should be relatively easy to adapt the script to use some other Python plist library.
Mr. Tan,
This was incredibly useful for me! I’m examining an iPhone 6 for a forensics case and the need to access an encrypted backup arose. I also had a few issues running your script to dump the BackupKeyBag, but after some tinkering I got it working. I was only able to achieve 28K H/s with my GTX 750Ti, but it was enough to crack it in a reasonable amount of time.
Thanks again!
-Tommy
What error? No matter what I try, I get “global name Structure not defined” and I’m not smart enough to figure it out…
have you try it using the 10.2 backup. i am currently working on this. i do not remenber my password
Hi iḿ having trouble with the script, iḿ a python newbie so i can’t figure out the solution here is the shell output
$ python parse_keybag.py Manifest.plist
Traceback (most recent call last):
File “parse_keybag.py”, line 99, in
main()
File “parse_keybag.py”, line 93, in main
stream = getKeybagFile(sys.argv[1])
File “parse_keybag.py”, line 26, in getKeybagFile
pl = Structure.from_bin(data) if data.startswith(‘bplist’) \
NameError: global name ‘Structure’ is not defined
best regards
Hi, as mentioned in the above comments, you need to install libplist with Python support. If your distro doesn’t have packages for that, you will need to compile it yourself.
https://github.com/libimobiledevice/libplist
I might consider porting to another Python plist library if I have the time. You can check back maybe next week.
Hi,
I got the same error, but have installed lipplist, any clue?
Thanks
You can try the Perl script instead. I’ve updated the blog post above.
I failed on libplist for what seemed like an eternity at the time, but was probably closer to 3 or 4 hours. Then I found the philsmd perl script – it was like magic. Unfortunately I never did crack the password but at least I got cake.
hi i`m binding c
but, importerror undefined symbol : plist_new_array
why??
Has anyone completed this successfully? Very interested in getting some help trying to get my backup file open.
i have done it. and if youre still interested, i can help you with your problem
Use the Perl script from philsmd to extract the hash in hc format.
can you help me with this?
Sorry, but no.
hello can i ask you for a favor i can give you my files plist and stuff and u give me the password and i l wil pay u any amout of money you need okay ?
Sorry I do not provide such services. You may want to try somewhere else.
Hi! Do you need data from the iOS device (iphone) for this? I need to crack the encrypted backup password (encrypted through iTunes). However, i already reset my Iphone. I still have the encrypted back up on the iMac.
Hi Rose, the backup is all you need. With the password, you can then restore the backup onto your new (or existing) iPhone.
I have a 10.4 back up (27GB) and a 9.3 back up (10GB). I’m assuming the size won’t matter since we’re just dealing with the plist. Will OS version matter with respect to speed or accuracy?
Sorry, just saw the graph that answers the question.
[…] 12. Cracking iTunes Backup Passwords with hashcat « irq5.io […]
Is there a possibility do find out, how long the password is? I forgot mine 😦
Thank you!
Not that I know of. If iOS stored the number of characters in the password, it might help attackers to narrow down likely password choices.
If you still have your device, you can reset the backup password from the device, then make another backup. It’s under General > Reset > Reset All Settings. You will lose some settings doing this, but the backup password will also be removed. https://support.apple.com/en-us/HT205220
Hi, does this way work ios 14.6?
I forgot my password and lost my photos I’m so sorry. 😭😭
Is there anyone here who can do this for a fee?
Yes I don’t believe there have been any changes to it. I think you can search for some password recovery services who may be able to do it for you.