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.  

Socially Distant but Still Interacting! New and Improved Updates to macOS/iOS CoreDuet interactionC.db APOLLO Modules

The interactionC.db database certainly does not get as much as attention as its CoreDuet partner in crime, knowledgeC.db. However, I think it has quite a bit of investigative potential. I’ve written about it before in a prior blog, however I’d like to give it more attention here.

I spent this weekend updating the APOLLO modules to have more contextual support and better backwards compatibility with older iOS versions. This database was also introduced to the macOS side with 10.15. 

I’ve added a new query for this database for the ZKEYWORDS table. This tables appears to capture keywords that are contained in various Calendar (com.apple.mobilecal) events. It seems only select certain events as not all my calendar event has keywords in this table.

The main interactionsC.db query has many new updates including attachments and sender/recipient correlation. In general, this database is keeps track of “recent” contact interactions. As an example, I used this query on my iOS database that I copied off of my iPhone a few days ago and it shows ~28,000 entries going all the way back to January of this year, 6+ months! 

In the screenshot below is a Messages (com.apple.MobileSMS) conversation between Heather Mahalik and I. Items that are blurred are our phone numbers. The GUIDs are our Contact Person IDs, these can be correlated with information in the iOS Address Book database. Why some recipient information is blank, I’m not sure. I scrolled way back in our conversation history and the timestamps are spot on. The content of this conversation could (and should) be correlated with the Messages database (sms.db).

This data is not just for Messages and may include other application bundle IDs. Some that I’ve seen in my data include:

  • com.apple.InCallService – Phone Calls

  • com.apple.MobileSMS - Messages

  • com.apple.Preferences - Settings

  • com.apple.ScreenshotServicesService - Screenshots

  • com.apple.mobilecal - Calendar

  • com.apple.mobilemail - Mail

  • com.apple.mobilesafari - Safari

  • com.apple.mobileslideshow - Photos

Contact Interactions & Attachments

For another example, let’s take a look at some interactions for the Photos app (com.apple.mobileslideshow). Not every interaction will have attachments associated with them. The screenshot below contains some AirDrop activity from this device. Some images were AirDropped from the Photos app itself, while one image was AirDropped from within the Messages application as shown in the Target Bundle ID column. It also shows the contact information to whom it was sent - helpful! 

Some of these attachments have a type associates with them in the UTI column (HEIC/PNG), the other has an associated attachment ID, show in hex (0x DCCB49C2FC74461EAD90DAB0C537DBF7). This is a hex representation of the UUID for the image. It seems not every image will have this attachment ID.

This image UUID can be searched for in the Photos database, as shown below to determine which image exactly was AirDropped. 

This might be another good artifact to look for in addition to some of the unified logs I’ve highlighted previously in AirDropping some Knowledge. This is what Elwood’s Phone looks like after lots of AirDropping of various items for that blog. 

Disassociated but not Forgotten Attachments

It seems some attachments are no longer associated with those in the ZINTERACTIONS Table but are not necessarily removed from the ZATTACHMENTS Table. This has potential forensic use as well. APOLLO will not extract these as there doesn’t appear to be timestamps associated with it however, I HIGHLY recommend at least taking a brief look at this table when doing an investigation.

The example below shows may attachment files of different types were associated with a contact interaction.  

  • PDF

  • Images (PNG, HEIC, JPG)

  • Contact VCard

  • Text

  • Archives

  • Movies

  • Documents

Unfortunately, we lose the contact context here. However, we can still find useful tidbits of information like text, file types, URLs, image UUIDs, etc.

Other examples include text that was copy/pasted, or URLs like a Google search link or a YouTube video that was sent.

A Note about Accounts & Recipient Counts

One more example of Mail (com.apple.mobilemail) shows the ACCOUNT column. This GUID can be used to tie interactions to a specific email account in the Accounts databases (Accounts3.sqlite/Accounts4.sqlite).

The Recipient Count columns can be a bit misleading. The column I’ve labeled ‘Recipient Count’ is the amount of recipients on an interaction. This examples shows 2, however that does not include myself. This is an example of an email thread between Heather, Lee, Phil, and myself. I would have thought there would be at least a 3 in this column however that doesn’t appear to be the case. A good example to not make assumptions!

The incoming/outgoing sender/recipient count columns are even more misleading – I haven’t quite figured those out but I believe this might be the total amount of interactions versus the amount of “recipients” on those interactions.

InteractionsC.db can really be a useful database, especially when it is used along with all the other data that APOLLO extracts – context can be everything!

Extensive knowledgeC APOLLO Updates!

While helping some investigators out I realized that my some of my APOLLO knowledgeC modules needed a bit of updating. Naturally I thought it would be quick, but it turned into quite an extensive update. I’ve included lots of brand-new modules as well as updates to ones that I’ve had before. 

Most of the updates to the older ones provided better backwards compatibility with older versions of macOS and iOS as well as adding additional contextual items to some of the queries from ZSTRUCTUREDMETADATA. Regression testing was performed on iOS 11, 12, and 13 and macOS 10.13, 10.14, and 10.15. Of course, please let me know if you run into a knowledgeC “stream” that I’ve not created a module for, or any issues that you might come across. 

I’ve highlighted a few modules below using my iOS 13.5 device. However, they may also apply to macOS and older iOS versions as well – review the modules for more documentation.

New Modules:

  • knowledge_activity_level_feedback.txt

  • knowledge_airplay_prediction.txt

  • knowledge_calendar_event_title.txt

  • knowledge_charging_smart_topoff_checkpoint.txt

  • knowledge_dasd_battery_temperature.txt

  • knowledge_device_locked_imputed.txt

  • knowledge_discoverability_usage.txt

  • knowledge_event_tombstone.txt

  • knowledge_inferred_microlocation_visit.txt

  • knowledge_knowledge_sync_addition_window.txt

  • knowledge_photos_edit_all.txt

  • knowledge_photos_deletes_all.txt

  • knowledge_photos_deletes_recent.txt

  • knowledge_photos_engagement.txt

  • knowledge_photos_share_airdrop.txt

  • knowledge_photos_share_all.txt

  • knowledge_photos_share_extension.txt

  • knowledge_segment_monitor.txt

  • knowledge_siri_activites.txt

  • knowledge_siri_flow_activity.txt

  • knowledge_sync_addition_window.txt

  • knowledge_sync_deletion_bookmark.txt

  • knowledge_user_first_backlight_after_wakeup.txt

The knowledge_app_activity_passbook.txt module was added to conveniently look for Apple Wallet (com.apple.Passbook) activity. Shown below I’m switching between my Apple Cash card and my Apple Card (yes, I got one for “research”).

The knowledge_photos_deletes_all.txt module appears to keep track of when I deleted a photo from the Photos app. This output is fairly vague. However, it could be useful in evidence destruction cases. The output of this one is similar to the other knowledge_photos_* modules.

Want to know if a thing was AirDrop’ed, copied, searched for, or otherwise interacted with from the iOS ShareSheet? The knowledge_sharesheet_feedback.txt module will help with that! Shown below, this module is keeping track of:

  • Photo Markups (com.apple.MarkupUI.Markup.MarkupPhotoExtension) via Camera App (com.apple.camera)

  • File Copies (com.apple.UIKit.activity.CopyToPasteboard) in Photos (com.apple.mobileslideshow)

  • Sending a photo in Messages (com.apple.MobileSMS) via Photos app (com.apple.mobileslideshow)

  • Finding text in a webpage (com.apple.mobilesafari.activity.findOnPage) in Safari (com.apple.mobilesafari)

  • Airdrop Activity (com.apple.UIKit.activity.AirDrop) 

Some modules are fairly self-explanatory. The knowledge_system_airplane_mode.txt modules keeps track of whether Airplane Mode on the device is enabled or not.

The next two are associated with the iOS low power mode functionality. The first, knowledge_device_battery_saver.txt which shows that I’ve activated Low Power Mode via the Control Center and while knowledge_device_low_power_mode.txt shows that it was turned on about two seconds after.

Click for larger view.

Updated Modules:

  • knowledge_activity_level.txt

  • knowledge_app_activity.txt

  • knowledge_app_activity_calendar.txt

  • knowledge_app_activity_clock.txt

  • knowledge_app_activity_mail.txt

  • knowledge_app_activity_maps.txt

  • knowledge_app_activity_notes.txt

  • knowledge_app_activity_photos.txt

  • knowledge_app_activity_safari.txt

  • knowledge_app_activity_weather.txt

  • knowledge_app_install.txt

  • knowledge_app_intents.txt

  • knowledge_app_location_activity.txt

  • knowledge_audio_bluetooth_connected.txt

  • knowledge_audio_output_route.txt

  • knowledge_device_batterylevel.txt

  • knowledge_device_inferred_motion.txt

  • knowledge_device_is_backlit.txt

  • knowledge_device_locked.txt

  • knowledge_device_pluggedin.txt

  • knowledge_discoverability_signals.txt

  • knowledge_notification_usage.txt

  • knowledge_paired_device_nearby.txt

  • knowledge_portrait_entity.txt

  • knowledge_portrait_topic.txt

  • knowledge_app_relevantshortcuts.txt

  • knowledge_safari_browsing.txt

  • knowledge_settings_doNotDisturb.txt

  • knowledge_siri.txt

  • knowledge_standby_timer.txt

  • knowledge_widgets_viewed.txt

The module knowledge_app_inFocus.txt has added extensions context. The extensions below show a location sign-in alert (com.apple.AuthKitUI.AKLocationSignInAlert) via the Springboard (com.apple.springboard), access to the Camera (com.apple.camera) via Messages (com.apple.MobileSMS), and access to Photos (com.apple.mobileslideshow) via Messages. All the while, playing around with the Unc0ver Jailbreak (science.xnu.undecimus).

New with knowledge_app_webusage.txt are the “Digital Health” columns. These will show website visits and associated URLs on various apps (not just Safari or Chrome!). 

In this example I was using Twitter (via Safari) on a device with the macOS hardware UUID (or iOS UDID) in Device ID column - let’s say my laptop. On my iPhone, I was also on Twitter but this time the iOS application (com.atebits.Tweetie2) ordering a new t-shirt from Jailbreak Brewery

Additions to knowledge_audio_media_nowplaying.txt include:

  • Is AirPlay Video

  • Playing – Values likely for Stopped, Playing, Paused – I will test those and update those in a future update.

  • Duration

  • Elapsed

  • Identifier

  • Media Type – Audio, Music, Video, Podcast

  • Output Device IDs (Binary plist in hex)

This is only a small slice of knowledgeC examples (and a very small part of APOLLO) so I hope this gives you some incentive to give it a try!