Update 2020/01/29: I have since done a bit more work with this app and have found a way to bruteforce the PIN without keychain access. I also created a Python based decryptor script (instead of the C# one attached to this post). Rather than make them publicly available, please contact me and I will be happy to share the scripts with you. You can do so on the DFIR Discord or Twitter @forensicmike1.
EPB is able to decrypt keychain data from password-protected backups (iOS 4 and later) if the backup password is known (or has been recovered using EPB for Windows). For iTunes backups that do not have the password set, as well as for iCloud backups, keychain can be decrypted only if. Keychain encrypts the stored passwords and credit card numbers with 256-bit AES, which is one of the most advanced encryption standards available. The facility also employs end-to-end encryption tech and works to provide a device with a unique key and passcode. Only the user is supposed to know the passcode used to access keychain.
It’s been a while since I posted anything, and I suppose that’s a natural part of having a blog. I decided not to force myself to procure content and instead wait until I had something I really wanted to write about. And so here we are! In this article I’m going to talk about a process brand new to me until a few days ago. This has been an absolute blast to learn about, although I will admit it was frustrating at times.
This article focuses more on the outcome of my research, without dwelling too much on exactly how I got there. I am however planning a follow-up post with a whole pile of lessons learned as I think there are a lot of gotchas and overall frustrations that could very possibly be skipped.
Why target this app specifically?
com.enchantedcloud.photovault or “Private Photo Vault” (hereafter PPV) has been the subject of security research before. In November 2015, a detailed breakdown was published by Michael Allen at IOActive and he found that the app didn’t actually encrypt anything! It’s security amounted to blocking users from seeing any media inside until the passcode had been entered and this was extremely easy to defeat. I figured revisiting this same app in 2019 could be fun/interesting just to see how far it has or hasn’t come since then.
Key Takeaways
Whether you consider this app secure or not depends on what kind of access you’ve got to various extraction methods. For examiners with filesystem type extractions (GrayKey / Cellebrite CAS / jailbroken devices), the security of PPV is trivial to defeat and I will demonstrate how below. For examiners obtaining logical type extractions (iTunes backup, UFED 4PC, Magnet ACQUIRE, etc.) decryption will be more challenging and further reversing work will be required. I do believe it is possible though.
PPV uses RNCryptor, an encryption library with implementations available in ObjectiveC, C#, JS etc. RNCryptor is open source and we can absolutely use that to our advantage. One thing RNCryptor doesn’t manage is key storage, and the developer of PPV has apparently decided to rely on the security of the iOS Keychain to store, well, everything we need to perform decryption.
The master key is stored in the keychain under “ppv_DateHash”. The plaintext PIN, which is a maximum 4 digits, is also stored in the keychain as “ppv_uuidHash1”.
Each encrypted media file (found with its original in the app’s sandbox at /Library/PPV_Pics/) is essentially a container. The first two bytes can be safely ignored, the next 16 bytes are the IV (Initialization Vector), and the remaining bytes are the cipher text with the exception of the last 32 bytes which are related to HMAC and can safely be ignored.
Once generated, the master encryption key never changes even if you change your PIN. This might seem like a poor design choice, but it’s actually how your iPhone works too and it can be quite secure as long as the master key is well protected. Secure Enclave makes sure that this key never sees the light of day but this is not true for keychain data.
Basic Outline of the Process / Tools Used
- Locate and jailbreak test iOS device (I used Electra root for my test device, an iPhone 6S running iOS 11.2.1).
- Installed PPV (target app) by sideloading with Cydia Impactor (app store works too).
- Setup access over USB with ITNL (iTunnel) and obtained root access to device via SSH.
- Installed and verified operation of frida-server on the device – I did this using Sileo but should be doable via Cydia as well.
- Used frida-ios-dump by AloneMonkey to obtain decrypted binary of the target app (recommend Python 3.7)
- Conducted static analysis of decrypted binary using Hopper . I had great success with searching for a value from the plist I believed to be associated to crypto. This app is not free but the trial is fully functional for 15 minutes – make sure you hurry! 🙂
- With my newly discovered knowledge I fired up Frida with this little gem: ObjC Method Observer, an awesome codeshare script by mrmacete (@bezjaje) to snoop on iOS method invocations of a specific class on a live device. (I targetted LSLCrypt and RNCryptor classes on PPV)
- Switched back and forth between Hopper and Frida console until I established a good idea of what was going on. The biggest breakthrough here was that the encryption key doesn’t change when you change the passcode, and that it is stored in keychain.plist
Decrypt Keychain.plist File
- Studied the RNCryptor-objc github repo to develop an understanding of how this AES wrapper works.
- Develop PoC in C# using the amazing LINQpad to decrypt media in PPV_Photos given the keychain.plist
Decryption PoC
This script is C# and was written in/for Linqpad, but could be adapted to a Visual Studio project very easily. It uses only native libraries. You will need to plugin your AES Key as base64 in the “USER CONFIGURATION REQUIRED” section 😀 ! I call this a PoC because it does zero error checking and may or may not work for you without tweaking.
I might throw together a GUI app to do this more easily if people would use it. DM me on Twitter or Discord and let me know if that sounds interesting/useful.
Decrypt Keychain.plist Mac
Acknowledgements
Decrypt Keychain.plist Codes
I’d like to thank the following people for their assistance on this research project:
- Braden Thomas (@drspringfield) at Grayshift for his always spot-on advice and extensive depth of knowledge on all things iOS.
- Ivan Rodriguez (@ivRodriguezCA) for his excellent blog and great advice.
- @karate on DFIR Discord (Magnus RC3 Sweden) (@may_pol17) for his excellent guidance and urging to get Frida working.
- Or Begam (@shloophen) from Cellebrite for reviewing my decryption PoC and spotting that final bug, connecting me with Ivan Rodriguez and generally being awesome.