analysis

Part 3: Step-by-step Tooling for iOS Research (via @bizzybarney)

This is the third and final piece of the Mac and iPhone setup process!  Sorry for the long delay between the last one and this one, but better late than never right?

giphy-3.gif

This guide will help you setup your iDevice with two binaries that can greatly assist with targeted testing and analysis.  My goal is to equip you to do your own research and testing to confidently answer the questions you will surely have as you learn this beautiful dance we call DFIR.  If you currently rely on a commercial tool to extract your iDevice data and then parse the data for you, that is totally normal and this article is absolutely for YOU!  Years ago, @iamevltwin broke my thought process on how to address mobile devices.  My training and education up to that point was great, and I knew a LOT about mobile devices and strategies for finding the evidence I was looking for.  But….I relied on data extraction methods by commercial tools and mostly parsing by commercial tools as well.  While that is acceptable and perfectly fine to do, it can be very time consuming.  Trust me when I say, if @iamevltwin asked me a question, and my response was “I’ll let you know in a few hours”…she would probably throw a steak and cheese egg roll at my head. [*Editors Note: I would never waste a delicious steak and cheese egg roll, instead I would deeply judge and give him the side eye.—S]  So for the sake of never wanting to waste a good egg roll, I learned how to target just the data I want and address it in a very specific way.  

To summarize what we are about to do:

  1. 1. Install and run “fsmon” and “cda” binaries that already have proper entitlements, so you don’t have to make the files.

  2. 2. Very basically learn what they do and how to run them.

  3. 3. Use them to target a specific piece of data on the iPhone.

  4. 4. Extract that specific piece of data to my desktop so I can “GET SHIT DONE” 

**If you are reading this, please make sure you have read and followed the instructions for Part 1 and Part 2 .  If you are jumping in here and trying to follow along, I assume your Mac and iDevice are the same as mine from the end of Part 2.  It is strongly advised that you do this on a secondary, test / research device and not your primary use device.  Nothing we are doing here should break anything, but things happen when you are in a root shell into your device and you have been warned!.**

Download iOS Binaries

I have both binaries you will need already made and entitled, trying to make this process as easy as possible to get you setup for testing!  The link below will take you to a .zip file containing ‘cda’ and ‘fsmon’, which are both Mach-O 64-bit ARM executables.  

The ‘cda’ binary helps locate where an app is storing it’s data! iOS stores most app data behind randomly generated GUID’s in the file system, so finding where a certain app is storing its user data can be a real pain.  This binary makes quick work of telling us exactly the directories we need to pay attention to, and does so in seconds.

The ‘fsmon’ binary is a file system monitor.  Plain and simple, it prints to your screen the changes occurring in the file system.  For research purposes, this is priceless.  If you need to know what happens when you take a photo, send an SMS, install an app, etc. you can run ‘fsmon’ while pressing the buttons on your device and watch your screen light up with what changed!

1. Click this link and download the .zip file. (Not (knowingly) malware, I promise!)

If you want to do it yourself, or are simply curious about what you’re downloading - here are the links to the GitHub repo’s where I got them:

  • cda - “A simple iOS command line tool to search for installed apps and list container folders (bundle, data, group). Thank you, Andreas Kurtz!!

  • fsmon - A file system monitor. Thank you, Sergi Àlvarez & Nowsecure!!

2. Now that you have the binaries, we will put them into a folder on your Desktop for simplicity.  Create a folder on your Desktop named ‘binaries’ and move the .zip file there.  Unzip it so the two binaries are in the ‘binaries’ folder.  It should look like this:

Connect to Test iDevice

Now that we have the files we need, we need to make sure our iDevice is connected to our Mac via USB and we are able to communicate with it.  Following the instructions from the Part 2 article, get connected to your iDevice via USB.  I’m going to show my actions below but if you have any trouble, go back and make sure your system is setup correctly from the previous articles.

My test device is an iPhone X (A1865) on iOS 14.2 that is jailbroken with checkra1n.

1. Open Terminal window on Mac.  Type iproxy 4242 44 and press return.  (If you’re on a device using unc0ver jailbreak you might need to use port 22 instead of 44).

2. Still working within your Terminal window, press command+T on the keyboard to open a new Terminal tab.  In the new tab, type ssh root@127.0.0.1 -p 4242 and press return.  You will be prompted for your password to access the device via SSH.  If you haven’t set a unique password, your default password is alpine.  Nothing appears when you type, so type your password and press return.  You should then see some version of a bash prompt with a # like in the screenshot below:

You’re now essentially in a CLI (command line interface) on your iPhone via your Mac.  What does this mean?  Well, it means you should be careful.  There isn’t an operating system lifeguard to keep you from removing files and directories you didn’t intend to.  If you aren’t familiar with navigating via CLI, that’s ok, do some research.  Look for a Mac Terminal cheat sheet online to expand your knowledge, but I’ll try to be very descriptive with the commands we use here.  

If you’re keeping score, we now have one Terminal window open that we used to iproxy into the iPhone.  We won’t use that window again unless our connection fails and we have to start it up again.  Your second Terminal tab should be a shell into your test iPhone.  

3. In the tab with the shell into your iPhone, type pwd and press return and it will show you your current directory or “Print Working Directory”.  We can see that we are in the directory /var/root.  Now type ls -la and press return to list the files in the current directory you are in.  

**For any of the CLI utilities we use in this exercise, in a Mac terminal shell you can type man <name_of_utility> and press return to see the manual for it, with all of the available flags you can use.  For example, if I wanted to remember how to use ‘ls’ to recursively list all the files in a directory and subdirectories, I would type man ls and press return.  Using the man page, I could see that using ls -laR will (l) list long format, (a) revealing directory entries beginning with a dot (.), (R) and the recursively list subdirectories encountered - respectively.  To leave a man page, just press Q and it will jump back out to your Terminal shell.**

Copy Binaries from Mac to iPhone

Now that we have the files downloaded and on our Desktop, and have a shell into our iPhone - we can move the files onto the iPhone.  

1. From your Terminal shell into your iPhone, press command+T again to open a new Terminal tab.  This new tab is a shell on your Mac, not the iPhone.  Click into the newly opened Terminal tab on your Mac and type the following: scp -P 4242 ~/Desktop/binaries/cda root@127.0.0.1: then press return.  You will be prompted for the password to access the iPhone - not the pin to unlock it, but instead either alpine or the unique password you set if you changed it.  Enter the password and press return.

We are using ‘scp’ to “secure copy” or remotely copy a file between our host Mac and our connected iPhone.  The command we typed and entered would more literally read: “scp (secure copy) -P (port) 4242 (port number) ~/Desktop/binaries/cda (a file named cda located at /Users/<your_username>/Desktop/binaries/) root@127.0.0.1: (root is the username and 127.0.0.1 is our localhost and you have to have the : at the end!).

If it worked successfully, you should see this:

2. To be super, extra sure it worked, you can check the list of file present on the iPhone.  Click into the Terminal tab that is the shell into your iPhone.  Type ls -la again and press return.  Assuming you didn’t leave the /var/root directory, you should see a list of the files present at the root of the file system and you should now see ‘cda’ in your list.

Yay!  One down, one to go.  Let’s do it again but this time let’s send ‘fsmon’ to the iPhone.

3. Click back over to your Mac Terminal tab we just used to send the ‘cda’ file to the iPhone.  We are simply repeating the same thing we just did, but for ‘fsmon’ this time.  Type scp -P 4242 ~/Desktop/binaries/fsmon root@127.0.0.1: and press returnEnter the password and press return.

4. That should work pretty cleanly if the first one did, but let’s check to be sure.  Click into the Terminal tab that is the shell into your iPhone.  Type ls -la and press return.  You should now see ‘fsmon’ in the file list as well.

If you see both files, feel free to pour yourself your favorite beverage and sip that for a moment.  You might need it for the next part..

5. The next thing we are going to do is copy these binaries to a different directory on the iPhone.  Assuming you’re following the directions explicitly, you should still be in /var/root on your iPhone, which is where both binaries should be.  In that shell, type cp ./cda /usr/bin/ and press return.  Nothing appears to happen, but we just copied the ‘cda’ file to the directory /usr/bin/.  Let’s quickly do the same for fsmon, type cp ./fsmon /usr/bin/ and press return.

6. Now that we copied them to the /usr/bin/ directory, lets go there and check it out.  To change directories, we will use ‘cd’ and then simply type where we want to go.  Type cd /usr/bin/ and press return.  Then let’s check this directory and make sure our files copied here correctly.  Type ls -la and press return and you should see a longer list of files here, but make sure you see ‘cda’ and ‘fsmon’.  If you see both, give yourself a high-five for making it this far.  We are now one step away from being able to use these things!!

7. Ok, we now have the binaries where we want them, but we have to give them permission to execute on our device.  Type chmod +x cda and press return, and then type chmod +x fsmon and press return.  You shouldn’t get any visible or affirmative response to entering the command, but we just set both binaries so they can execute, or run on your device.

The Moment of Truth - Do the Binaries Work?

Alright, this is it.  This is the moment where you are going to fist pump and exclaim for joy - or cuss, kick things and go back through the instructions above and figure out what you did wrong.  Let’s hope for shouts of joy.  We will start with ‘cda’ because it is going to tell us which directories we might want to run ‘fsmon’ on to monitor activity.

1. Type cda safari and press return.  I picked Safari because pretty much every iDevice you might be doing this on has it and should yield a result.  You should immediately see results populate on your screen.  My device displayed two different results for the native Safari application, one for com.apple.SafariViewService and the other for com.apple.mobilesafari.  Both results are quite typical for any application you might search for, it commonly displays a path to the Bundle, the Data, and Group (if one exists).  We aren’t going to get too deep into the details of explaining these three paths, but generally, here’s a synopsis:  

  • Bundle - This path is where the actual application files exist.  The code that is the application itself, but not the user’s data.  You can find language packs, plugins, and other stuff here but unless your goal is to reverse engineer the application - you probably don’t need to spend any time here.  Think of these files as the files that are downloaded when you install an application, so it appears on your device - but you haven’t opened it and interacted with it yet so no user data has been generated.

  • Data - Go here.  You want to go here.  User data exists here.  Every application you locate using ‘cda’ will have a Data path.

  • Group - Yeah, you’re going to want to go here too.  User data exists here too.  Not every application uses a ../Shared/AppGroup/ directory to store user data.  Don’t be concerned if you don’t see a Group path for an application, but you also cannot ignore one if you see one.  Some applications store the juicy goodness here!

(Optional) Now that we know ‘cda’ is working, I’m going to use it once more, but this time to address a third party application - Google Voice.  You may not have Google Voice, but feel free to use ‘cda’ to search for a third party application if you have one!  I wanted to show this to you so you can see more than one example of ‘cda’ because it tells us exactly where we need to look to do our research!  In the photo below, you can see I typed cda google voice and pressed return and it displayed a bundle, data, and two different group paths to data for Google Voice.

2. Alright, we are moving on to a pointed example of using ‘cda’ to appropriately leverage ‘fsmon’ to GET SHIT DONE!  But, we first have to make sure ‘fsmon’ is going to work for us.  This binary is simple to use, we just have to start it and tell it which directory we want it to monitor.  One thing I have learned from using it is the less you monitor, the easier it is to see what’s going on.  Before I tell you how to start it I’m going to tell you how to STOP IT!  You will press control+C to stop it after it’s started.  

3. To make sure it’s working, type fsmon / and press return.  This is running the file system monitor on the root of the file system.  (**If you get an error, you might have to type /usr/bin/fsmon / to get it to work.)  As soon as you press return to start ‘fsmon’ just open any app on your phone such as Settings, Mail, whatever it doesn’t really matter.  You should see your screen light up with file system creation, modification, and deletion entries.  Your output is definitely going to look different than mine, that’s expected.  Press control+C and stop it.  Hopefully that worked nicely for you like it did for me, and you can now start to play with it and develop strategies for using it.

Now I’m going to walk you through one approach to using these binaries to target specific data, and then we are going to extract that data from our iPhone out to our Desktop.  

1. I am choosing to install the application, Viber Messenger: Chats & Calls, and I will use ‘cda’ to tell me where it stores data, then use ‘fsmon’ to try to see the results of a specific action.  I navigated to the App Store on my iPhone and searched for Viber, then pressed GET to install it onto my device.  (If you’re wondering, yes, you could technically be running ‘fsmon’ while doing all of this to see what’s happening on the file system!)

Alright, I have Viber installed.  But…before I open it I want to get setup to see what it’s doing.

2. In your shell into your iPhone, type cda viber and press return.  I see that Viber returns a path to its Bundle, as everything will.  It has a Data path, as everything will, but also has one Group path that I need to pay attention to.

Now that I know where Viber might store user data, I am going to monitor the Data path only.

3. For my installation of Viber, the Data path is /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE.  To monitor that path while I setup the application, type fsmon /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE and press return.  Once it is up and running, open the app and set it up.   As you can see in the image below, the file system goes crazy while I start to setup the application, but I’m seeing everything happening.

**If you wanted or needed to monitor the Group path too, you could simply open a new Terminal tab, and open another shell into your iPhone (ssh root@127.0.0.1 -p 4242, return, enter password, return) and run ‘fsmon’ on that Group directory too.**

Ok, you setup the app, and did whatever actions you wanted and you watched it all printing to your screen thanks to ‘fsmon’ doing an amazing job.  I hope you can see how this can assist you in doing research, and quickly honing in on pertinent files and folders as you work.  You make a specific action, and quickly go look at that file and find what you’re looking for.  Make sense?  Easy right?  Let’s target the Viber data and extract it out to our Desktop so we can quickly investigate it!

From the output for ‘cda viber’ I need to get the contents of the Data and the Group paths.  I’m not going to get the Bundle path…ever.  But for the example I’m about to show you below, your paths are going to differ from mine.  If you installed Viber to follow along, your path is not the same as mine, so you will have to copy your Data and Group paths and follow the template I’m giving you to achieve the same outcome.

4. Go back into Terminal but click over to the shell of your Mac, not the iPhone tab.  We are going to use ’tar’ via SSH to make a .tar of the Data and Group directories for Viber on our Desktop.  

In the Mac Terminal shell, type ssh root@127.0.0.1 -p 4242 ‘tar -cvf - <paste_path_to_Data> <paste_path_to_Group>’ > ~/Desktop/Viber1.tar and press returnEnter the password for SSH access to your iPhone (alpine or what you changed it to)  and press return.  You should see a long list of files populate on your screen and you should have a new file on your Desktop named Viber1.tar.

**We preserved timestamps for the data with this .tar command, so if you care about timestamp integrity make sure manage the data you extracted as READ ONLY to not update the timestamps each time you open a file.**

I pasted the exact text I typed into my Terminal window to successfully copy this data out to my Desktop below (to clarify any spaces or issues with the command above):  

bizzybarney@MacBook-Pro ~ % ssh root@127.0.0.1 -p 4242 'tar -cvf - /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE /private/var/mobile/Containers/Shared/AppGroup/1195ECFB-4F5B-4BC0-9E7F-490418D1651C' > ~/Desktop/Viber1.tar

You now have all of the files and folders attributed to Viber’s Data and Group paths on your Desktop.  Crack that thing open and dig in!  You have successfully extracted these files without using any commercial tools to extract a bunch of other data you don’t need or care about, and can start into examining your results in seconds without need to wait for any lengthy parsing process either!  You can easily go back into Viber and take more actions that create new data, then pull these files again and just change the output filename to Viber2.tar or whatever you choose.  If you are doing a full teardown of an application, don’t be surprised if you have pulled the data dozens of times, each time learning a bit more about how the data is being stored.

In the image below, you can see the Data and Group (../Shared/AppGroup/) files and folders for Viber, and I can quickly open the Preferences - com.viber.plist and see the user phone number I entered during setup!

Feel free to practice with the steps outlined above on different applications, and target their specific data.  Also, don’t forget about the native iOS files in /private/var/mobile/Library/ on your iPhone - we can monitor those directories as well and there is an insane amount of awesomeness there!

If you followed all of these steps and arrived here successfully, congratulations!! I know this setup is taxing, and especially difficult if you’re just starting out in CLI.  I hope I can offer encouragement by saying it wasn’t so long ago that I was doing this for the first time.  After lots of practice, failures, and cussing - I am now able to find the data I want to research using ‘cda’, watch the file system with ‘fsmon’, then ‘tar’ out the data I want in just minutes.  

Thanks again to @iamevltwin for hosting this content! Also a huge thanks to the people developing and supporting unc0ver, checkra1n, cda, and fsmon - you make this type of research possible!

Please contact me on Twitter @bizzybarney with any questions or concerns, and I will help as I have time.

Until next time, “Stay classy, forensicators.”

giphy-2.gif

Analysis of Apple Unified Logs [Entry 12] – Quick & Easy Unified Log Collection from iOS Devices for Testing

Collection of Unified Logs on macOS systems is pretty straight forward. You can use the command, and yes – you do have to be root.

sudo log collect 

Collection from iOS device is not as obvious. I think most of us are doing the sysdiagnose/AirDrop method which is tricky. Trying to trigger a sysdiagnose on an iOS device can be frustrating to get the right button hits with the right timing. (Not completely unlike trying to get a device in DFU mode!)

In my recent testing, I noticed the argument--device-udid in ‘log’ man page. This functionality seems to have made an appearance in 10.15. The following also appeared

  • --device-name – The device name, ie: “Elwood’s iPhone”

  • --device – “First device found”. I guess I would consider this the #YOLO option. 🤷🏻‍♀️

This argument has been super handy in recent testing to bypass the frustration of sysdiagnose on iOS devices. I like using the UDID instead of the name, so I will use idevice_id from libimobiledevice to quickly get that.

I have a choice between two devices. One tethered over a lightning cable to my Mac, the other available over the local network. You can use either option to use collect unified logs.

To use this new log argument, iOS devices must be trusted and paired to the Mac, otherwise you’ll get this error.

The following is an example of what I might use for quick iOS testing. While I can dump all the logs, to make things go quicker I use --last to control how much I want to dig through (could also do this with --size). I also don’t use the default output name of system_logs.logarchive, but use the --output option to name them appropriately. This is nice if you are doing multiple tests over and over. Also, I couldn’t even tell you how many random system_logs.logarchives files I have on my system from many different test devices!)

sudo log collect --device-udid <UDID> --last 10m --output iphone_test1.logarchive

You may also see these devices in Console.app if you have it open.

One device we see in Console.app that we didn’t see via idevice_id, is my Apple Watch. You can load up the sysdiagnose profile on the paired iPhone by following these instructions. I AirDrop this to my iPhone to install it.

This profile will be usable for three days to read Apple Watch logs in Console.app before you will have to reload it.

I feel the Apple Watch can (should?) be collected in the same way by using –device-udid, however I get an “log: failed to create archive: Device not configured (6)” error and sometimes a partial and corrupt logarchive. If anyone has any pointers for this, please let me know!

I hope this argument gives us less of an excuse to review our Unified Logs on our iOS devices, we certainly need to know more about what is stored on them and how they are similar or different to our macOS devices.

Part 2: Step-by-step iPhone Setup for iOS Research (via @bizzybarney)

This is a follow-on to the previous post showing how to setup your Mac for iOS testing. If you haven’t read over that one - this article draws assumptions that your Mac is setup in a certain way, or that you know what you’re doing otherwise. Feel free to go read that first, I’ll wait..

Alright, now that we are all on the same page, let’s tackle the second piece and get your iPhone setup for research and testing. This guide will be very similar to the last in its simplicity, with the assumption that you are not a command line expert. But before we move on, let me repeat - THIS IS FOR RESEARCH AND TESTING.  Please don’t read this and think it is a great idea to jailbreak, load binaries onto, or otherwise press a bunch of buttons on evidentiary devices in criminal cases, or devices being inspected for civil or corporate investigations. I’m not saying you can’t do it, but make sure you understand what you are doing to the device, can explain that to someone else, and understand there are certain risks involved with jailbreaking a device.

You will need to have setup your iOS device with an AppleID and general account stuff before you can start this process. The assumption for this guide is your iDevice is at the home screen where you can use it - meaning it has been setup with whatever account you intend to use. Real you, fake you, real someone else - just kidding (but seriously don’t be an a-hole).

Jailbreak Time

If you are unfamiliar with jailbreaking - read this carefully; don’t skim it. 

This is not hacking. We are gaining privileged access to the root of the file system. Apple has setup your iDevice so it’s not easy to break things. When we jailbreak using publicly available jailbreak methods, we accept a certain risk that some harm could come to the device or its data during the jailbreak process. Please don’t mistake that warning for distrust in the FREE work the amazing jailbreak teams do to support the research and security communities. Without the jailbreak folks, mobile forensic research would be significantly diminished. If the jailbreak process goes smoothly (which it will), you now have the ability to break things. There was a time where I was extremely apprehensive about jailbreaking, mostly because I had to get over the fear that by clicking the button to start the jailbreak I might brick my device. While that certainly could happen, I will tell you I have used publicly provided jailbreaks for years now on a myriad of different iDevices and I have never caused any one of those devices to be unusable. 

Before we decide to dive into jailbreaking, you need to understand one very important thing. Your iPhone is a piece of hardware, which has an operating system running on it, and for a jailbreak to be successful it must accommodate both your hardware and OS version. If you want to jailbreak a test device, you need to closely monitor which OS version is currently available vs. which OS version is able to be jailbroken for your piece of hardware. In a perfect world, you want your test device to have the latest version of iOS that is able to be jailbroken. 

A great resource I use to determine which jailbreak method I can use for the hardware and OS version I am trying to jailbreak is https://www.theiphonewiki.com/wiki/Jailbreak.

One device I have is an iPhone 11 Pro on iOS 13.5. This isn’t the ideal test device because it isn’t susceptible to the checkm8 hardware exploit, but it is the newest device available right now. So we are going to start with the more difficult process on the newest iPhone and work towards the easier method on an older iPhone X. When the checkm8 age of iOS exploitation is gone, this method via Cydia Impactor might be the way you will jailbreak - because this is the way it was done prior to checkm8. Every jailbreak is different though, so no need to commit to anything just yet. 

Using the guide from theiphonewiki.com, I scroll down until I find the table containing a row for iOS 13.5 and column for iPhone 11 Pro. I find that my device is able to be jailbroken using unc0ver version 5.2.0. If I was keeping my device’s OS perfectly updated, it would be at iOS 13.6 at the time of writing. There is no jailbreak available for 13.6 right now, so this is why you have to pay attention and only update your OS when a jailbreak is available for the version you are upgrading the device to. You have to be diligent with this to keep your device jailbroken while updating to relevant OS versions. If you are using a personal-use device for your testing, you have to realize that by not keeping your OS updated, you are potentially saying “no thank you” to relevant security patches and new features. 

In a perfect testing scenario where money is no issue, the coffee and pastries are free, and you ride a unicorn to your corner office with a perfect view, you would have an iPhone on each OS version and never upgrade them. You would have a library of all iPhone covering allOS versions, so very specific test scenarios could be achieved - but this is a very expensive approach and is certainly not something I am personally going to do.

unc0ver Jailbreak Method

How to jailbreak using unc0ver via Cydia Impactor for iPhone 11 Pro with A13 processor on iOS version 13.5 (requires Apple Developer account)

If unc0ver is the jailbreak that works for your hardware and OS, here are steps to follow to successfully jailbreak via Cydia Impactor. Note, this method requires you to have a paid Apple Developer account. A paid account costs about $100 per year, so I maintain a dev account for this reason. If you don’t want to sign up for a developer account, there are two other free options listed on the unc0ver.dev page for jailbreaking via “AltStore” or “Xcode + iOS App Signer.” 

You are going to need Cydia Impactor on your Mac for the method I use, but there are other options available. Check unc0ver’s site for other options that are free, but we are going to use Cydia Impactor for this guide. Essentially what we are doing here is side-loading an application onto your iPhone. You aren’t going to find jailbreak applications on Apple’s App Store, so we are going to use Cydia Impactor to push an application onto your test iPhone instead.

1. Go to cydiaimpactor.com and click the download link for Mac OS X. It will download a .dmg (disk image) file.

2. Double click .dmg file then drag and drop Impactor into your Applications folder. Cydia Impactor is now installed. To find it, hold ‘command+space bar’ and use Spotlight Search and type ‘Impactor’ and select the result. You may get a warning that Impactor was downloaded from the internet and could be malicious - yup, got it, thank you Apple. 

3. Download the .ipa for unc0ver - Go to unc0ver.dev and then click “Download v5.3.1” or whatever version it lists at the time you are reading this. This will download the .ipa file which is the application that ultimately jailbreaks the device.

4. With your iPhone connected via USB and Cydia Impactor running, you should see your iPhone’s friendly name and UDID in the top field. In the bottom field it probably says, “install Cydia impactor” which is not what we are doing, ignore that for now and DO NOT PRESS START!

5. Drag the unc0ver .ipa file we previously downloaded into the bottom field of Impactor and drop it there. 

6. After dropping the file, a box pops up and asks for your iTunes email login, enter your Apple Dev account email address and press OK.

7. Apple ID Password box appears:

  • If you don’t have two-factor authentication turned on for the dev account, you can enter your AppleID password here and press OK. 

  • If you enter the AppleID password, but two-factor authentication is turned on and it fails - no big deal. Keep reading, but this is the error you will get.

  • If you do have two-factor authentication turned on, you need to go to appleid.apple.com and login to your dev account. 

  • Once logged in, you will see an account dashboard. Look in the “Security” section where it says “APP-SPECIFIC PASSWORDS” and click “Generate Password…

  • Enter a label for the password you are about to generate - it doesn’t matter at all what you put here. Click “Create.”

  • An app-specific password will be generated. Copy the password and paste it into the password box in Cydia Impactor. Click OK on Cydia Impactor.

8. Cydia Impactor will run through the application installation and should complete without any errors. Once completed, it goes back to the appearance where it displayed the iDevice name, UUID, and “install Cydia Extender”.

9. Check your iPhone for the unc0ver application and Cydia.

10. Open unc0ver application.

11. Select Settings gear in top left of screen. In Settings, toggle (Re)Install Open SSH to ON. This is going to allow us to communicate between our Mac and the iPhone. Select “Done” in top right corner and return to main screen.

12. Press “Jailbreak” button. After an advertisement, you will get a pop-up that says “Jailbreak Completed. No error occurred. The device will now reboot into the jailbroken state.” Press OK and the device will reboot fairly quickly and your device is now jailbroken!

checkra1n Jailbreak Method

The checkra1n jailbreak is a semi-tethered jailbreak based on the checkm8 boot ROM exploit. The checkm8 exploit was discovered and announced in September of 2019. It unveiled a vulnerability that essentially allows jailbreak access to the iPhone 5s, iPhone 6, iPhone 6 Plus, iPhone 6s, iPhone 6s Plus, iPhone SE (1st Gen), iPhone 7, iPhone 7 Plus, iPhone 8, iPhone 8 Plus, and iPhone X - regardless of the OS version as long as it is 12.3 or higher. If you are deciding on which iPhone to purchase to dedicate to testing and research, my suggestion would be the iPhone X. Technically the iPhone 8 was released at the same time as the iPhone X, but the iPhone X includes FaceID which the majority of current iPhones employ as their unlock method. If you want to do TouchID specific testing, then perhaps the iPhone 8 or 8 Plus makes more sense. I acquired an iPhone X and an iPhone 8 Plus so I have both available if necessary. If you are buying two test devices, maybe get one of each. Essentially the oldest phones exposed by this vulnerability will be the first ones that Apple drops OS support for. The iPhone X is the “newest” older device with the vulnerable chipset, and therefore will be the last device to be aged out by Apple eventually dropping OS support for it. There are rumblings that Apple may have found a way to combat this vulnerability for iOS 14, but for research devices that you know the passcode to everything should still be fine. 

How to jailbreak using checkra1n for iPhone X with A11 processor on iOS 13.6.1

1. On your Mac, go to checkra.in in a web browser, scroll down and click “Download for macOS” and the checkra1n .dmg file will download.

2. Open your Downloads directory and double-click the checkra1n beta <version>.dmg file. After it opens the disk image, drag the checkra1n application over into the Applications folder.

3. Press “command+space bar” and use Spotlight Search and type “checkra1n” and select the application.

4. You will likely get a warning saying it cannot be opened because the developer cannot be verified. Click Cancel.

5. Click the Apple in the top left corner of your screen, then click System Preferences. Click “Security and Privacy” tab and open it. You will see a message at the bottom of the tab about checkra1n being blocked, click “Open Anyway.” Apple will show another pop-up asking if you’re really sure you want to open it, just say yes and click Open for the 12th time (just kidding). The checkra1n application is now installed on your Mac.

6. Press “command+space bar” and use Spotlight Search and type “checkra1n” again, and select it. This time the application will finally open. Typically you would want to connect your device and make sure it is supported, but for the purposes of showing off what checkra1n is capable of, I upgraded my test device to the latest version of iOS - 13.6.1 (8/21/2020). The window says it isn’t supported. If the OS version is tested and supported, you just simply click “Start” and off it goes. For an unsupported OS version on my iPhone X that is definitely susceptible to the checkm8 exploit, you can click “Options” and check the box beside “Allow untested iOS/iPad)S/tvOS versions.” Then go back to the main screen and click “Start” to make the jailbreak happen.

7. After another warning against running checkm8 on an untested OS version, it advances to a screen saying the device needs to be put into DFU mode. But first it puts the device into Recovery Mode to avoid any file system corruption.

8. The device is placed into Recovery Mode and the checkra1n application displays instructions for putting the device into DFU Mode. You need to follow the instruction in the checkra1n interface explicitly and the device should enter DFU mode. 

  • Click Start.

  • Press and hold the Side and Volume down buttons together (4 seconds)

  • Release the Side button BUT KEEP HOLDING the Volume down button (10 seconds)

9. If done correctly, the device will advance to another screen where the exploit and jailbreak occur. You can release the Volume down button once you get to this screen. The checkra1n interface will advance through a few steps without needing any actions by you. The iPhone will display a black screen with a checkra1n logo and then will boot into the operating system. The checkra1n interface will say “All Done” and you can click “Done” to return to the home screen. Unlock and open the iPhone and you should see the checkra1n application installed. Your device is now jailbroken!

Mac Setup  

iPhone Jailbroken  

Access / Research 🚧 🧰 🚧

Alright we now have a Mac setup and ready, an iPhone in a jailbroken state, and we are finally ready to gain access into the phone and it’s data. What comes next is the fruit of your labor, and what justifies to yourself that you needed to buy the new Mac and random iPhones for testing in the first place! 

Before we start, make sure these last few details are correct:

1. iPhone is connected to Mac via USB

2. iPhone is unlocked and a “Trust” pairing has been made to Mac. When you connect to Mac and unlock the iPhone, you should get a pop-up on the iPhone asking to trust the Mac or not. You must Trust the connection to the Mac.

3. iPhone display is set to never go to sleep. Settings > Display & Brightness > Auto-Lock > Never. If you are copying files from the file system and the device auto-locks, you will potentially get less data because of file permissions that change when the device is locked vs. unlocked.

Ok, let’s connect to the iPhone via Terminal on the Mac! There a few nuances to connecting to the iPhone depending on which jailbreak was used, so I will detail both. For me, I have test devices on unc0ver and checkra1n regularly, so what I am showing you is completely normal as I change between connecting to the different devices on my Mac. We are going to use iproxy to establish a TCP connection between the Mac and your iPhone. This is going to facilitate a shell into the iPhone, so you can surf the file system of your iPhone via your Mac!

1. Open a new Terminal window

2. In the Terminal window:

  • unc0ver - type iproxy 4242 22 and press return

  • checkra1n - type iproxy 4242 44 and press return

Explanation: iproxy is a utility from libimobiledevice that we are using to make a TCP (4242) connection at port #22 or #44. The unc0ver jailbreak is setup to listen on port 22 (standard SSH), and checkra1n listens on port 44.

After pressing return, your Terminal window will say “waiting for connection” with a blinking cursor.

3. Open a second Terminal window. Either right click Terminal in your Dock and select “New Window” or simply click on your first active Terminal window and press command+N to create a new window.

4. In the second Terminal window, for unc0ver and checkra1n: type ssh root@127.0.0.1 -p 4242 and press return

Explanation: ssh is the network protocol we are using to access our device, root is the username and 127.0.0.1 is our local host which is connecting to (-p) port 4242.

  • If this is your first time ever doing this, you will get an authentication message in your second terminal window asking if you are okay with the connection that is being attempted. Skip down to 4.3

  • For me, I am changing from accessing an unc0ver device to a checkra1n device. So I need to make one adjustment before I can make the connection. 

4.1 If you get the error saying there is an “Offending RSA key in /Users/<username>/.ssh/known_hosts:1”, then you need to remove the previous ssh pairing from the known_hosts file so this new device can connect. So if you get this error, it just simply means you already have an SSH known host pairing for 127.0.0.1 -p 4242. To get rid of just that specific pairing, in your second Terminal window type ssh-keygen -R “[127.0.0.1]:4242” and press return. This will save the previous known host pairing to a new file and clear the space for us to use it again. You might find a better way to manage ssh known_hosts, but this is just facilitating what we need to connect iPhones quickly without an intermission for that. (Thanks to Sarah for a non-destructive method here that is easy to follow! For this example I had to break out into a different window to make changes, so the next few photos won’t have this step in sequence.)

4.2 In second Terminal window, type ssh root@127.0.0.1 -p 4242 and press return again. (You can also press the UP arrow in the second terminal window to recall previous commands to not type the same thing again!)

4.3 In the second Terminal window, you will get a message asking if you are sure you want to continue connecting. You have to type yes and press return. You will then be presented with a screen to type a password.

5. In the password line, type alpine and press return. **The letters won’t appear as you type, you aren’t crazy. Well, not in this moment anyway.** The stock passcode to connect to iPhones in this manner is alpine and has been for some time. When I attempted this in my second terminal window, my connection unexpectedly closed. Things like this will happen, it isn’t a big problem. I simply arrowed up and ran my ssh root@127.0.0.1 -p 4242 again and then entered alpine in the password line and it worked just fine!

6. If you see something like “-bash-3.2#” or “Jane’s iPhone#” or whatever - you now have root shell access into your iPhone! Pause for celebration. 

7. In the second terminal window, which is now a shell into your iPhone, type ls -la and press return. You should see a list of the /var/root/ directory and you now have the ability to surf the file system of your iPhone via Terminal! 

This article became quite long, but I think it is important to lay some of these things out in extremely plain, easy to understand ways so that someone not overly confident in certain aspects of the process can arrive at this place. The ability to change directories on the iPhone and look at which files exist in different places, quickly viewing file contents on your screen, extracting out a single file to your Mac, and much much more - that is why we are doing this. 

If you are mildly comfortable with CLI, feel free to explore the file system of the iOS device. If you aren’t, that’s ok! You are slowly getting some exposure and will become more comfortable as we go. Our next step will take us deeper into CLI to address the file system of the iPhone.

Ending Facts: 

Once you achieve the shell into your iPhone, that first Terminal window we opened to run iproxy in essentially can be minimized and forgotten about until you need to connect a device again, or if you have connection issues while testing.

If you used checkra1n, your file system is mounted as Read Only. **If you know what you’re doing, run mount -o rw,union,update / to remount it as Read/Write.**

If you chose to jailbreak your personal device for testing, you have just softened it’s security and are accepting certain risks. You should change your default password from alpine to something of your choosing. If you are doing this, you must first turn the mount command above to mount the file system as Read/Write.  Then, you can change the password by typing passwd and pressing return in the root shell. It will ask you for a new password, then a confirmation, then you can’t forget what you chose! Repeat the process for passwd mobile.

If you want to learn more about how to load a file system monitor, find application directories, and extract specific items from the iPhone instead of doing a backup or using a forensic tool to extract data each time - check back for the next article!

Until then, “Stay classy, forensicators.”

Part 1: Step-by-step macOS Setup for iOS Research (via @bizzybarney)

CLI…WTF

Command line interface (CLI) isn’t for everyone.  Trust me; I get it.  @iamevltwin forced me out of my comfort zone a few years ago and opened my eyes to the power of Terminal (command prompt on Mac).  Now it is pinned to the Dock on every Mac I use, but I still struggle at times and that is okay!  The internet provides plenty of support to help me along when I just can’t make something work.  I use and abuse my Notes application with random commands and ways to accomplish certain tasks in Terminal that I know I will want to recall sometime in the future.  Inevitably though, I find my way back to mac4n6.com to read an article because I am cussing at an iPhone I’m struggling to jailbreak because I forget if the port is 22 or 44.  

I recently bought a new MacBook Pro and the thing is a beast, but as soon as Apple setup was completed I started installing things to set it up for mobile testing.  I figured I would write a set of current instructions on how I setup my Mac, and do so in a way that someone unfamiliar with Terminal can follow along without issues.

DISCLAIMER.  Following these instructions worked for me and will work for you too.  As with anything else, proceed at your own risk but nothing we are doing here is dangerous for your machine if done correctly.  I tried to bold exactly the text you need to type or to highlight a key combination you need to press to grab your eye as you scan this article.

1. Terminal (CLI)

What:

We are going to use it but you don’t have to understand everything we are doing to still achieve the desired outcome.  To find Terminal, hold ‘command+space bar’ and Spotlight Search will appear on your Mac’s screen.  Type ‘terminal’ and select the application from the results.  I choose to pin it in my dock because I use it every day, you might want to do the same.

How: 

  1. Hold command key and press space bar

  2. In Spotlight search type ‘terminal’ 

  3. Select Terminal application and it will open

  4. Right click Terminal in your Dock, mouse up to Options and over to ‘Keep in Dock’ and select it.

2. Xcode

What:

Xcode is Apple’s development platform, and pieces of it are used in regular forensics work on iOS and Mac data.  This takes a while depending on your download speeds, so this might be a good place to grab a drink.  

How: 

  1. Open the App Store on your Mac and search for Xcode.  Download.

3. Homebrew

What:

I am a huge fan of craft beer, so perhaps I appreciate the naming convention here more than others.  Regardless of whether you like craft beer or are yet to learn that you love craft beer 🍻 - you need to install Homebrew to install some stuff Apple doesn’t install for you. 

How: 

  1. In a web browser, go to brew.sh  (DO NOT GO TO homebrew.sh, that is a super sketchy place and is not where you want to be)

  2. When the page opens, look directly under “Install Homebrew”, and copy the entire line: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Paste that into a Terminal window and press ‘return’ key.  (If you are asked for a password, it is the user password you enter to access the machine so you need to be an admin!  Also when you type your password nothing shows up on the screen, you aren’t crazy.) 

It tells you what the script will install, and you need to press ‘return’ again to install which will take a few minutes.

4. DB Browser for SQLite

What: 

My preferred SQLite database browser for everyday database research and analysis.  As with Terminal, I keep this one in the Dock of my Mac also

How: 

  1. Simply go to sqlitebrowser.org/dl/ and download and install the appropriate version. 

OR

Homebrew Install Method: You will notice on the download page that Homebrew is listed there with a command to install the application via Homebrew.  Since we already installed Homebrew, you can take a look at how it works by using it to install DB Browser for SQLite!

If you choose to install via Homebrew:

  1. In Terminal, type the following and press ‘return’ - brew cask install db-browser-for-sqlite

5. Hex Fiend

What:

Free hex viewer, and I love it.  I drag and drop files into the application to quickly check file contents every day I’m doing research.  This one also stays in the Dock.

How

  1. Simply go to ridiculousfish.com/hexfiend and download and install.  

OR…I wonder if Homebrew can do this for me?

Homebrew Install Method: 

To check if homebrew has the ability to install a certain utility, you can just type brew search hexfiend and press return

The results tell me there is a Cask named ‘hex-fiend’ so I can install via Homebrew just like we did before.

  1. In Terminal, type the following and press ‘return’ - brew cask install hex-fiend

6. libimobiledevice

What:

We will use the “iproxy” utility, which enables TCP service access to an iDevice.  It allows us to forward ‘localhost’ to the device, thus allowing an SSH connection over USB to jailbroken devices.  If you don’t know what TCP, SSH or ‘localhost’ means - don’t quit here.  Once this is setup and your iDevice is jailbroken, you simply need to type a few things in Terminal and boom!  You’re surfing the file system of a live iDevice!

How:

  1. In Terminal, type brew search libimobiledevice

  2. The results show us ‘libimobiledevice’ is available, so type brew install libimobiledevice and press return

And with that the Mac setup is now complete!  We arranged applications in the Dock for quick access, got Xcode ready to go, setup a SQLite database browser, a hex viewer, and finally the utility we will use to communicate with our iDevice via USB.  But wait..what about my favorite <insert tool name here>?  Personal preference will drive many other installs or setup tweaks, but if you follow these instructions your Mac is ready to do iDevice testing.  

If you successfully followed the instructions above, your iOS testing progress bar is at 51% - congratulations!  Part 2 is coming soon and will visualize and simplify the jailbreak process, getting your iDevice ready for testing.  You will be setup and ready to answer your own questions about the iOS file system, how it behaves, and you can prove or disprove that hunch you have!  

Until next time, “Stay classy, forensicators.”

Follow-on to DFIR Summit Talk: Lucky (iOS) 13: Time To Press Your Bets (via @bizzybarney)

Facial Recognition in Photos

One facet of my DFIR Summit talk I want to expand upon is a look into the Photos application, and a few of the derivative pieces of that endeavor.  While trying to focus on the topic of facial recognition, it seemed prudent to include a brief progression from snapping a photo thru to a persons name being placed beside their face in the Photos application.  

When you use the Native camera and snap a photo, depending on user options, at least a few standard things occur.  It ultimately writes the newly taken photo to /private/var/mobile/Media/DCIM/1**APPLE/IMG_0001.HEIC / .JPG.  As the photo is taken, the Photos.sqlite database is updated to reflect a lot of the metadata about the photo,  which will be covered a bit later.  Additionally, the “PreviewWellImage.tiff” is created.  The “PreviewWellImage.tiff” represents the photo you see when you open your Photos application and see a preview of the most recent image, which is the photo just taken by the camera in this instance.

The beginning of the user’s photos reside in the ../100APPLE/ directory, but this directory iterates upwards (101APPLE, 102APPLE, etc) as more and more photos and videos are saved.  If iCloud syncing is turned on by the user, then several others behaviors occur - but that is for another time.

Let’s focus on the analysis and intelligence built into the Photos application.  I’m able to type text strings and my photos are immediately searched for matching objects within them.  There is a section of my Photos dedicated to “People” where a name has been associated with a face that Apple has analyzed.  

Some of the analysis pieces occurring with the Photos happens in the mediaanalysis.db file.  This file is analyzing and scoring the media files and producing results that seems to feed into other pieces of the analysis.  Some scoring results to highlight are ones that focus on Humans, Faces, and Pets.  

Path: /private/var/mobile/Media/MediaAnalysis/mediaanalysis.db

The ‘Results’ table of the mediaanalysis.db file contains the ‘assetId’ which represents a media file, a ‘resultsType’ which is the specific analytical type and score value found in that media file, and a BLOB (binary large object) which is a binary .plist (bplist).  You can see in the image below, the ‘assetId’ 3 has numerous ‘resultsType’ associated with it and the BLOB for ‘resultsType’ of 1 is selected and on the right you can see the bplist.  

That bplist can be printed to a text file by saving the bplist as a file and then using ‘plutil’ to print it to a text file. As you can see below beside the red star, the printed text is a clean presentation of that .bplist and it tells us that ‘resultsType’ of 1 is associated with Faces based on the scoring.  

I repeated that process for the remaining pieces of data and wrote a brief description of the results type for each, although my device still had a few types that did not have any results.

After running a SQL Query against this database, you can sort the results to potentially see just files that have the results type for ‘humanBounds’ and ‘humanConfidence’.  The ‘localIdentifier’ column from the “assets’ table is a UUID which matches up to the ZGENERICASSETS table of the Photos.sqlite.  

Here is the query for the mediaanalysis.db file.  It’s big and ugly but please test it out if you’re interested, but this piece just seems to build into what we will see later in the Photos.sqlite where this all comes together.

select
	a.id,
	a.localIdentifier as "Local Identifier",
	a.analysisTypes as "Analysis Types",
	datetime(a.dateModified+978307200, 'unixepoch') as "Date Modified (UTC)",
	datetime(a.dateAnalyzed+978307200, 'unixepoch') as "Date Analyzed (UTC)",
CASE
	when results.resultsType = 1 then "Face Bounds / Position / Quality"
	when results.resultsType = 2 then "Shot Type"
	when results.resultsType = 3 then "Duration / Quality / Start"
	when results.resultsType = 4 then "Duration / Quality / Start"
	when results.resultsType = 5 then "Duration / Quality / Start"
	when results.resultsType = 6 then "Duration / Flags / Start"
	when results.resultsType = 7 then "Duration / Flags / Start"
	when results.resultsType = 15 then "Duration / Quality / Start"
	when results.resultsType = 19 then "Duration / Quality / Start"
	when results.resultsType = 22 then "Duration / Quality / Start"
	when results.resultsType = 23 then "Duration / Quality / Start"
	when results.resultsType = 24 then "Duration / Quality / Start"
	when results.resultsType = 25 then "Duration / Quality / Start"
	when results.resultsType = 27 then "Duration / Quality / Start"
	when results.resultsType = 36 then "Duration / Quality / Start"
	when results.resultsType = 37 then "Duration / Quality / Start"
	when results.resultsType = 38 then "Duration / Quality / Start"
	when results.resultsType = 39 then "Duration / Quality / Start"
	when results.resultsType = 48 then "Duration / Quality / Start"
	when results.resultsType = 8 then "UNK"
	when results.resultsType = 11 then "UNK"
	when results.resultsType = 13 then "UNK"
 	when results.resultsType = 21 then "UNK” 
	when results.resultsType = 26 then "UNK"
	when results.resultsType = 31 then "UNK"
	when results.resultsType = 42 then "UNK"
	when results.resultsType = 45 then "UNK"
	when results.resultsType = 49 then "UNK"
	when results.resultsType = 9 then "Attributes - junk"
	when results.resultsType = 10 then 'Attributes - sharpness'
	when results.resultsType = 12 then "Attributes - featureVector"
	when results.resultsType = 14 then "Attributes - Data"
	when results.resultsType = 16 then "Attributes - orientation"
	when results.resultsType = 17 then 'Quality'
	when results.resultsType = 18 then "Attributes - objectBounds"
	when results.resultsType = 20 then "Saliency Bounds and Confidence"
	when results.resultsType = 28 then "Attributes - faceId / facePrint"
	when results.resultsType = 29 then "Attributes - petsBounds and Confidence"
	when results.resultsType = 30 then "Various Scoring Values"
	when results.resultsType = 32 then "Attributes - bestPlaybackCrop"
	when results.resultsType = 33 then "Attributes - keyFrameScore / keyFrameTime"
	when results.resultsType = 34 then "Attributes - underExpose"
	when results.resultsType = 35 then "Attributes - longExposureSuggestionState / loopSuggestionState"
	when results.resultsType = 40 then "Attributes - petBounds and Confidence"
	when results.resultsType = 41 then "Attributes - humanBounds and Confidence"
	when results.resultsType = 43 then "Attributes - absoluteScore/ humanScore/ relativeScore"
	when results.resultsType = 44 then "Attributes - energyValues/ peakValues"
	when results.resultsType = 46 then "Attributes - sceneprint/ EspressoModelImagePrint"
	when results.resultsType = 47 then "Attributes - flashFired, sharpness, stillTime, texture"
end as "Results Type",
	hex(results.results) as "Results BLOB"
from assets a
left join results on results.assetId=a.id

Before diving into the Photos.sqlite file, I want to first point out the file recording the text strings as an apparent result of Apple’s object analysis of the photos.  This file stores the text results which empower our ability to search text strings in the Photos application and return results.  The text strings are not necessarily a result of any specific user activity, but instead an output from analysis automatically being deployed by Apple against the user’s media files.  

Path: /private/var/mobile/Media/PhotoData/Caches/search/psi.sqlite

The ‘word_embedding’ table within psi.sqlite contains columns ‘word’ and ‘extended_word’ which are just strings stored in BLOB’s.  Using DB Browser for SQLite you can export the table to a CSV and it prints the strings from the BLOB’s pretty cleanly.  Separately there is also a table named ‘collections’ that has ‘title’ and ‘subtitle’ columns that appear to be a history of the Memories and Categories that have been used or ones that will be used.

The last table in psi.sqlite to mention for this piece is the ‘groups’ table.  Within the groups table the ‘content_string’ contains some really interesting data.  I initially set out to find just the words “Green Bay” as it was something populated in my text search for the letter “g”.  What I found was far more interesting.  I did find “Green Bay” but additionally found in one of the other BLOB’s, “Green Bay Packers vs. Miami Dolphins”.  That BLOB has a little extra flavor added by Apple for me.  Whether they simply used my geo coordinates baked into my photos from being at Lambeau Field, or analyzed the content of the photos and found the various Miami Dolphins jerseys - I’m not sure.  But a very interesting artifact that is absolutely accurate, dropped in there for me.  Thanks Apple!

Now let’s tackle Photos.sqlite, but only as it pertains to facial recognition and associating photos of people to an actual name.  Because quite honestly this singular file is nearly a full time job if someone wanted to parse every inch of it, and maintain that support.

Path: /private/var/mobile/Media/PhotoData/Photos.sqlite

My instance of Photos.sqlite is a beast, weighing in at over 300MB and containing 67 tables packed full of data about my Photos.  We are going to focus on two tables - ZDETECTEDFACE and ZPERSON.  

ZDETECTEDFACE 

This table contains values that indicate features about faces to include an estimate of age, hair color, baldness, gender, eye glasses, and facial hair.  Additionally there are indicators for if the left or right eyes were closed, and X and Y axis measurements for the left eye, right eye, mouth and center.  So the data in this table is extremely granular, and was quite fun to work through.  Who doesn’t like looking at old photos?

ZPERSON

This table contains a count for the number of times Apple has been able to identify a certain face from the media files.  So in my device, I am recognized by name for hundreds of photos, but there are also photos of me where it hasn’t associated my name with my face.   For each face identified, a UUID (Unique Identifier) is assigned.  So although the analytics piece may not be able to connect a face with a name, it can group all identified instances of the unknown faces as being the same person. 

If there is an association made between the person’s face and a saved contact, the ZCONTACTMATCHINGDICTIONARY column’s BLOB data can possibly reveal a full name and the phone number.  This again can be achieved by printing the bplist to a .txt file.

select
	zga.z_pk,
	zga.ZDIRECTORY as "Directory",
	zga.ZFILENAME as "File Name",
CASE
	when zga.ZFACEAREAPOINTS > 0 then "Yes"
	else "N/A"
	end as "Face Detected in Photo",
CASE 
	when zdf.ZAGETYPE = 1 then "Baby / Toddler"
	when zdf.ZAGETYPE = 2 then "Baby / Toddler"
	when zdf.ZAGETYPE = 3 then "Child / Young Adult"
	when zdf.ZAGETYPE = 4 then "Young Adult / Adult"
	when zdf.ZAGETYPE = 5 then "Adult"
end as "Age Type Estimate",
case
	when zdf.ZGENDERTYPE = 1 then "Male"
	when zdf.ZGENDERTYPE = 2 then "Female"
	else "UNK"
end as "Gender",
	zp.ZDISPLAYNAME as "Display Name", 
	zp.ZFULLNAME as "Full Name",
	zp.ZFACECOUNT as "Face Count",
CASE	
	when zdf.ZGLASSESTYPE = 3 then "None"
	when zdf.ZGLASSESTYPE = 2 then "Sun"
	when zdf.ZGLASSESTYPE = 1 then "Eye"
	else "UNK"
end as "Glasses Type",
CASE
	when zdf.ZFACIALHAIRTYPE = 1 then "None"
	when zdf.ZFACIALHAIRTYPE = 2 then "Beard / Mustache"
	when zdf.ZFACIALHAIRTYPE = 3 then "Goatee"
	when zdf.ZFACIALHAIRTYPE = 5 then "Stubble"
	else "UNK"
end as "Facial Hair Type",
CASE	
	when zdf.ZBALDTYPE = 2 then "Bald"
	when zdf.ZBALDTYPE = 3 then "Not Bald"
end as "Baldness",
CASE
	when zga.zlatitude = -180
	then 'N/A'
	else zga.ZLATITUDE
end as "Latitude",
CASE
	when zga.ZLONGITUDE = -180 
	then 'N/A' 
	else zga.ZLONGITUDE
end as "Longitude",
	datetime(zga.zaddeddate+978307200, 'unixepoch') as "Date Added (UTC)",
	ZMOMENT.ztitle as "Location Title"
from zgenericasset zga
left join zmoment on zmoment.Z_PK=zga.ZMOMENT
left join ZDETECTEDFACE zdf on zdf.ZASSET=zga.Z_PK
left join ZPERSON zp on zp.Z_PK=zdf.ZPERSON
where zga.ZFACEAREAPOINTS > 0

Below is a sample of the output of this analysis, paired with the photo the metadata came from.  You can see it is able to identify me and my two daughters by name, and accurately assess our genders, my sunglasses and facial hair.  

Please test, verify, and give me a shout on Twitter @bizzybarney with any questions or concerns.