Cracking iTunes Backup Passwords with hashcat

Following the recent announcement of LUKS support in hashcat, I noticed that there have been some commits to support iTunes Backup passwords as well.

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 and ITER parameters from the first entry
  • DPSL and DPIC 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:

Chart of hashcat cracking speeds

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:

27 comments on “Cracking iTunes Backup Passwords with hashcat

  1. Damien2678 says:

    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

  2. Tommy says:

    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

    • -Jack says:

      What error? No matter what I try, I get “global name Structure not defined” and I’m not smart enough to figure it out…

    • franc right says:

      have you try it using the 10.2 backup. i am currently working on this. i do not remenber my password

  3. darkgilder says:

    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

    • darell tan says:

      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.

      • forondosco says:

        Hi,
        I got the same error, but have installed lipplist, any clue?
        Thanks

        • darell tan says:

          You can try the Perl script instead. I’ve updated the blog post above.

        • -Jack says:

          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.

  4. kgc says:

    hi i`m binding c
    but, importerror undefined symbol : plist_new_array
    why??

  5. cfitz@hotmail.com says:

    Has anyone completed this successfully? Very interested in getting some help trying to get my backup file open. :/

  6. pop carry says:

    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 ?

  7. Rose says:

    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.

  8. Chesterrrrrr says:

    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?

  9. […] 12. Cracking iTunes Backup Passwords with hashcat « irq5.io […]

  10. Tom says:

    Is there a possibility do find out, how long the password is? I forgot mine 😦
    Thank you!

    • darell tan says:

      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

  11. Arzu says:

    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?

    • darell tan says:

      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.

Leave a reply to darkgilder Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.