Friday, 18 June 2021

Android - Tracking Device Migration

 In this multi-part series of blogs on tracking device migration, we're going to take a look at some of the core artifacts one might be able to track on Android devices. Android devices will likely not have local backups restored from computers like iOS, however, device-to-device and Gdrive/Cloud backups will allow users to transition data from one device to another. This doesn't just include Android to Android but can include iOS to Android too!

While multiple Android device manufacturers have created their own switch over applications like Samsung's Smart Switch, Android has its own. Android users can restore information from Google Drive down to their device or by hooking up a cable and backing up the data device-to-device. There are several relevant artifacts that get left behind. Unfortunately, most of these artifacts will require a file system level image. Some of the information will be left in the /media/0 directory which can help provide some context at least, and available in quick style images. 

In the case of a standard Android device migration, users should locate the folder /data/data/ Within this folder there will be several relevant .xml files. 

The DeviceOrigin.xml file will list out where the original source data came from. In the case of both iOS an Android devices, this information will be here and will reflect the manufacturer and model. 

If the DeviceOrigin.xml file doesn't list out a device, it could be a cloud backup from GDrive in play. Within the same directory, a file SetupWizardCredentialProtectedPrefs.xml, will list out what Google Account was backed up. This file may exist if the device was a device-to-device or a cloud backup, but only if the account was passed over. 

The Phenotype.xml file in this directory can also contain the google account used and passed over. This information may also be available with the accounts_de.db or accounts_ce.db database files responsible for storing the accounts saved to the android device. 

Data gets moved over fairly seamlessly in Android device-to-device or GDrive backups in the case of the /media/0 (emulated SD) area. However, in iOS device-to-device to Android, the data gets stored in a folder called "Restored from iPhone." 

Android devices may also have their own migration packages. Since our target device in this case was a Pixel there is a package that can reveal some additional information. 

Within the data/data/ directory another shared_prefs directory has some interesting files. 

In the case of iOS to Android, users can find a file called ios_preferences.xml which will list out the UDID of the original source iOS device as well as a created date/time which can help show when the migration took place. 

In the case of Android to Android, users won't find a file here unforunately. But in the case of device-to-device (and cloud restores) a xml file called can help show what was transferred from the source device. 

For the cloud restores from GDrive, a file called cloudrestore.component.CloudRestoreFlowActivity.xml will be in this directory. An Android_ID value within this file can be used as a keyword search against a target device to see if this was the original source device. It also contains a "restore_started" value which will reflect that the cloud backup was started. 

Unlike the iOS counterpart (which can be found at this link), it's not quite as descriptive or readily available. Still the information can be beneficial when tracking the movement of data across devices. 

Wednesday, 16 June 2021

iOS - Tracking Device Migration

Sometimes I get the privilege of helping someone with a case and it really puts me down a rabbit hole of research. This is that situation. A brief overview: I get contacted for assistance in tracking device migration because a "bad file" (let's leave it at that) is found on a phone. However, the phone it's found on doesn't match the EXIF data of the file. Now, the argument is that the file was "planted" on the target device without the user's knowledge and that it didn't originate from the user. While this is harder to prove, one of the things I was asked was how to determine if the device was restored from another source. 

While the plist file "" has been around a while and had some good information, it's also been a bit limited. So let's dig a little deeper and see what else we can find. 

Within iOS, there's a great plist file that can help talk about device backups. This is the "data_ark.plist" that can be found within a file system image of an iOS device at the path /private/var/root/Library/Lockdown. 

This file has several important keys.

[0] - FirstPurpleBuddyCompletion - This is a Unix millisecond epoch value which can help show the first time the "Purple Buddy" or Apple's setup assistant was completed. The main PurpleBuddy plist (anyone else always think of "bonzai buddy" when they hear purple buddy?) has its own timestamp value but other things can update it including system updates between certain iOS versions. 

[4] - 
[5] -

This will show information about how the device was setup and/or restored. It will contain information relating to one of (at least) three values. 

RestoredFromDevice - A Device-To-Device setup
RestoredFromiTunesBackup - Pushing a device backup from iTunes
RestoredFromiCloudBackup - Pushing a device backup from iCloud

This file can also show the computer name of where an iTunes backup has been stored from a target device. This makes tracking both source and target devices easier. 

I'm one for additional validation. Also, I've found that the data_ark.plist hasn't always been so forthcoming on information. If we navigate over to private/var/mobile/Library/Preferences and locate the file we can find some additional information. 

The key "SetupState" will show one of two values: 

SetupUsingAssistant - This is the same for device to device and local backup to device. 
RestoredFromCloudBackup - When restored from an iCloud backup. 

The "SetupLastExit" key can also help to show when Purple Buddy was exited and can be compared to the value in data_ark.plist if available. 

In this same directory (private/var/mobile/Library/Preferences) there is another very informative plist file called 

This plist file has some awesome data for tracking migration!

By reviewing the above records, it's possible to see how the device backup was restored either from device-to-device, iTunes backup, or iCloud backup! It will also list out the build version of the software it was restored FROM which can help show a pattern of upgrades/restores. The RestoredBackupProductType key also gives the model ID of the source device. 

A word of warning about the "BackupDeviceUUID" value. I'm still trying to track where this value comes from but it's not the UDID in all cases that we have come to know. It would make a great keyword value on a target device though!

The Reason key is also incredibly informative and maybe my favorite. This value will show the TARGET device's UDID (which we likely already know because it's the device we're analyzing) but does show the date and time of the restore! Woo!

Now in the case of any of these backup restorations, who is going to have data on what devices are part of the Apple account? Hint, they're a fruit company and I'm not talking about Banana Republic. Obviously it's Apple.

There are several values that you can use to send off to Apple to find out some more information if you have search warrant or subpoena powers. Within the database Accounts3.sqlite (found within /private/var/mobile/Library/Accounts), a key referencing the "appleid-authentication" type will reveal the email address of the Apple ID. However, users can change their Apple ID email address over time. There's actually a better value. 

The DSID or Directory Services Identifier is the numerical backing to the Apple ID used by Apple to track the account. This value can be found in a variety of places depending on which iCloud services are being utilized by the user. One of the easiest places to find this is within the plist files or If you don't have access to these legal routes, getting access to a user's "Download Your Data" results from Apple can also have most of this same information to track devices users have migrated between. 

That is going to wrap up the part of this multi-part series. For the first part, please see this link on device migration artifacts form iOS to a Samsung device. Up next will be tracking device migration on generic Android. 

Friday, 28 May 2021

iOS / macOS - Tracking Downloads from Safari Without Downloads

This week I got some huge news! This blog was nominated for a 4:cast award for Blog of the Year! I'm incredibly honored for this nomination! It also spurred me to remember I had a bunch of posts I wanted to work on but the last few weeks have been packed with teaching and work. Today I'm going to talk about a methodology for how to track files that have been downloaded from the Safari browser on iOS or macOS. 

Safari is an interesting beast when it comes to its storage. Apple lauds the browser as "Safe and Secure" and this default browser on the macOS and iOS ecosystem can cause examiners some headaches due to how long it chooses to keep its data. For more information on preferences for macOS and how this is controlled, see this post I did previously,

While the methods to track data in macOS and iOS are similar, there will be a slight difference depending on what you're working with and looking for. Let's start with macOS. 


First things first. macOS will only keep Safari downloads for 24 hours by default. This is obviously problematic. In addition, it only tracks the last 20 files so if your user has downloaded more than 20 in the last 24 hours, again, harder to track. The Downloads.plist file found within the path: ~/Library/Safari/ will store this information. 

When a file is downloaded in Private Browsing mode, the Downloads.plist is still used, but stores a value within it called "DownloadEntryRemoveWhenDoneKey" which will be flagged as True. This means that files that are downloaded will immediately be cleared even if within the last 24 hours. 

Again by default (set within the Safari preferences), the downloads will land in the ~/Downloads/ directory. So looking here is a good place to start. However, before we just jump here, we might want to also consider what happens to a file when it's downloaded. Essentially, downloading a file on macOS/iOS works like this: 

1. Container is created. Container is named the name of the downloaded file with ".download" at the end of it. Container will live in the directory where the file is supposed to be downloaded.
2. Info.plist file created within the container containing matching information from the Downloads.plist file. 
3. File data streamed into the ".download" container. 
4. Upon completion, data moved from .download container (folder) into appropriate directory. 
5. macOS's GateKeeper will quarantine the file and scan it creating an entry in the quarantine database. 

Based upon the above logic, there are a couple of things we can now start looking for. 

Quarantine Data

Using the "" database found within ~/Library/Preferences, information can be tracked to find what files landed on the system that were scanned by GateKeeper. Examiners should look for the package name containing "" because depending on HOW the file was downloaded the data under application name may reference either "Safari" or others including "" The information can store the original download URL as well as the displayed URL and when it was "Quarantined" which will be extremely close to the finished date of the download. 

To be honest, this can be hit or miss. I find that if a user is actively opening files they download it may get cleared from the Quarantined events, but not always. It does, however, last longer than the standard 24 hours of the Downloads.plist file in many cases. 

A note about files downloaded in Private Browsing mode. Files downloaded within this mode will still be checked by GateKeeper, however, it will not store the download URL of the file. It will however still store its "Quarantined File Identifier" which is going to be important in tracking what file that was. 

File System Events

Since examiners now know the process of the file, we can actually use the File System Events tracked by both iOS and macOS to find out some information. It's handy when you have a starting date and time, so using an event like Quarantine Events to gather when a file was downloaded (even if you can't see what the file was or where it came from like in a private browsing record), you can use this as your launch point. 

Filtering your file system events from that start point, you may see files created in the same timeframe on the system, but remember, files are downloaded into a container that ends in .download. 

By reviewing these records, examiners can see how the file system events are tracking the flow of the downloaded file originally listed above. The "Important" folder is created, the .zip and .plist file created inside, then when complete, the .zip is moved out, and the .plist is destroyed as well as the .download container. [NOTE: These events can happen quickly in small files and creation/deletion may happen within the same recorded event]

Files that were not completed will have a similar structure but without the final removal events. 

These events can also help to show when a file was moved from the downloads directory to a new location. Now that we can track that a download occurred a couple of different ways, can we match up records in the Quarantine Events to the file that was downloaded? In some cases, yes!

Extended Attributes

macOS will record extended attributes to files downloaded. This will include in many cases what browser was used to download the file as well as in many cases the URL that the file was downloaded from. A Quarantine Event GUID is also embedded into the Extended Attributes metadata. Now this information can also be tracked with Spotlight Metadata as well, however, files that are downloaded in Private Browsing mode will not have that spotlight metadata. 

Let's compare two files from the downloads directory. The first was downloaded with Safari NOT in private browsing mode. Here's one from my local system where I downloaded the file with Safari without using private browsing mode. By looking at this, you can actually see the value kMDItemWhereFroms which lists where this file was downloaded from: "" 

The extended attributes of the same file can store this information as well. If the data is living in a directory where indexing is not done, this can still reveal the information. However, the information in the extended attributes can also store the quarantine information. While we may not be able to track where the information was downloaded from (not tracked in files downloaded from private browsing mode), we can use the quarantine information to help show it came from Safari and that it was private browsing. 

For a file that is downloaded within private browsing, spotlight metadata may not show as much. However, we can still track the information that shows that this file, "Important" was downloaded from the Safari browser and it has a GUID. This can be matched to the Quarantine Events artifact to see its match (if it is still there)!

macOS WrapUp: 

So to summarize, when tracking downloads, a good methodology is to check in the following locations: 

  • ~/Library/Safari/Downloads.plist
  • Check the Safari Preferences to see where the downloads are default going to. 
  • Use File System events looking for ".download" records to find data relating to files downloaded from Safari. 
  • Use quarantine events to find that files are downloaded using Safari
  • Use extended attributes metadata to look for the events with Safari.


Now iOS can be a slightly different beast. It still has some of the same functionality we can apply if we know where to look. When downloading files, the Downloads.plist file is still going to be used but users can't control as many preferences. The Downloads.plist file is going to be found within the Safari's app directory (not the Library/Safari directory as the browser history is). 

The same information is stored but note the Saved to Path. This is the default storage location that will send the data to the "iCloud Drive" area of iOS. Which, honestly, is interesting. It takes your download and then tries to send it back to its own cloud storage. 

Now these downloads are also not tracked forever. There is also not any way to have preferences to change how long these are going to be kept. 

File System Events:

In a similar manner to the macOS Safari downloads, when a file is downloaded in iOS/iPadOS, the file is stored within a .download container (folder). This folder is not contained within download target directory like in macOS, but is stored within a folder within the Downloads folder (that the plist lives in). 

This folder is named with a GUID which will match the "Download Identifier" in the Downloads.plist file. The data gets placed into a [Filename].[ext].download folder within a folder named the download GUID then moved to the final directory on successful download. 

No info.plist file here unfortunately. 

Files that are incomplete downloads will still live in this directory. Now the interesting thing is that a user can choose to store them within the iCloud Drive directory, but also can choose to store them on the "On My iPad" setting which puts them into a different directory. By looking at the file system events using the target filename, we can see where the file moved to. This time it didn't move to the Mobile Documents directory but to part of the data that tracks back to the iOS Files app. [For more info on the Files App, check out this post here]

The ID of this folder tracks pack to the "local storage" manager used by the Files app. which can be seen in the "" within the root of this storage container. 

iOS WrapUp: 

So as you can see there's not as MUCH to track through with the downloads from Safari but may also be less common to find. Even when you don't find any Downloads.plist entries, by checking both paths: 
  • /private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Downloads
  • /private/var/mobile/Containers/Shared/AppGroup/B00E5705-4543-4123-9309-0F6D70BE27C6/File Provider Storage/Downloads

By then working backwards to confirm these were downloads, using File System Events may help to track that they started in the Safari/Downloads/ directory. 

Final Wrap-up: 

Whew! That was longer than I originally intended. Once again the big thing is that just because the "Downloads.plist" file is empty doesn't mean you can't track the data in other ways at times. Hopefully these methodologies of where to turn can be useful to anyone reading! Again, big thanks for anyone reading this who nominated me for a 4:cast award and if you feel it's deserved, I'd love to earn your vote again for the award itself! If you're so inclined you can go vote here:

Thursday, 4 March 2021

Android - Samsung Smart Switch // iOS Transfer Artifacts

 Recently I was trying to set up an Android device to run some testing on and I just happened to pick a Samsung this time around. I needed some sample data on it but I didn't have a lot of time to generate information. Luckily, Android has a way you can restore information from one device to another, even if that device isn't an Android. 

If you happen to be transferring over to a Google Pixel phone, Android will allow you to use the USB-C adapter to connect a USB-A to Lightning cable that has an iOS device running on the other side. I thought this was a pretty slick process and will likely be checking into it more in time to see what happens on the Pixel side. 

Since Samsung is one of the most popular device manufacturers it shouldn't surprise anyone that they are copying this functionality on their device line. In order to do this, Samsung has the user download the Samsung Smart Switch application which can also be found on the Google Play store. (Link) Samsung isn't alone on this, with OnePlus, LG, and 3rd party groups using this same functionality, but Samsung is the one we'll focus on today. 

After grabbing my iPhone test device I plugged it into the S20 I was testing out and followed the step by step process that the device had displayed on the screen. 

Samsung allowed me to select quite a bit of information including SMS/MMS, Contacts, Photos/Videos, and even Application data. So after this process, what is left behind by the Smart Switch application that could be relevant to our investigations? 

The application uses the bundleID of Looking for that in the file system, there weren't many databases that appeared there at first. Within the shared_prefs folder, there was a "smartswitch_prefs.xml" file that had some great information in it including: 

  • Source Device Type
  • Target Device Type
  • Google Account Sign-In

Within the "files" folder of the application directory, there was a LOT of interesting files left behind. First off there is a folder: data\data\\files\iosotgmanagerv2\
Within this folder, a Plist file can be found identifying the source device the data came from. This is the lockdown plist file that is used as part of the Trust Pairing process of iOS. 

There is a folder called SmartSwitch which also has some great data. An "iosApps.json" file will store information about iOS applications detected from the source device. 

A "requestedApps.json" is a JSON file keeping a log of the matching Android versions that will be requested from the Play Store as well as version. 

The "BrokenRestoreInfo" directory of my device had some additional interesting JSON files. The DevInfo.json file contained UDID information, model number, OS versions, Display Name, and what was asked to be backed up. 

The JobItems.JSON will let the examiner know what was able to be downloaded from the source device. 

A PHOTO folder will contain additional JSON files that contain metadata about recovered photographs from the source device. 

Another folder, SmartSwitchLog contains several log files about the transfer process. This folder also contains the most important piece of the application as well. In this source image, a DATA_0 folder was found containing the bulk of the transferred information. This folder contains a multitude of ZIP files that have the information backed up from the Source device. These files within the zips may be named in some cases the same SHA1-named structure as the files would be from within the original iOS device's iTunes-style backup. Several examples will be linked below: 

 BACKUP DATA: --> Contains the Manifest.db for the iTunes-style backup which will give you a listing of every file included in a backup on the source device as well as helping to decipher the SHA1 names in the recovered files. 

ALARMS: --> Contains the file cc723e4537a6d5120fb720dda7dd18b10f3f4a97 which is the Library/Preferences/ from the iOS device. --> Converted.xml: The converted version of the above Plist file. 

BOOKMARKS --> Contains the file d1f062e2da26192a6625d968274bfda8d07821e4 which is the Bookmarks.db from Safari. Also contains BookMark.xml which is the converted version of this database. 

CONTACTS --> Contains the file 31bb7ba8914766d4ba40d6dfb6113c8b614be442 which is the AddressBook.sqlitedb from the iOS device. --> Converted VCard (.vcf) data from the above database. 

MEMO / NOTES --> Contains the file ca3bc056d4da0bbf88b5fb3be254f3b7147e639c which is the notes.sqlite and the file 4f98687d8ab0d6d1a371110e6b7300f6e465bef2 which is the NoteStore.sqlite database. --> Contains a which has a JSON file inside it which is the converted notes data of the two above databases. 

MESSAGES --> Contains the file 3d0d7e5fb2ce288813306e4d4636395e047a3d28 which is the sms.db from the iOS device. --> Contains several relevant files including: 
sms_restore.json - All of the SMS messages from the above database converted into a JSON file. 
mms_restore.json - All of the MMS messages from the above database converted into a JSON file. 
NOTE: iMessages are organized into the appropriate JSON above for their type either SMS/MMS. 
PART_files - Attachments recovered from the SMS/MMS/iMessage attachments. 

The PHOTO folder contains information about the photographs and videos extracted from the source iOS device, but not the media itself. 

But what if you don't have a full filesystem of the device and you're stuck with just a Quick image of the data? In that case, examiners should turn to the media/0 (or emulated sdcard) directory to find the SmartSwitch directory. Within this directory under "tmp" an ENTIRE copy of the iTunes-Style backup was recovered!

Within the SmartSwitch/tmp directory there were several folders to support the transferred data. Unfortunately, not all of these kept the JSON files that were available from the data's stored information from within /data/data. Some of these folders did, such as the message_json folder containing all of the same JSON values from earlier. 

The photos/videos transferred from the source iOS device were also discovered within a folder in the emulated sdcard directory called iPhoneData. This directory contained all of the recovered documents and media items transferred over. The names from the source device were not kept in this directory and the previously discussed photo logs keep the information about how the files are renamed. 

Android is well known for duplicating data across multiple areas of the filesystem. If the SmartSwitch application is found on a subject's device, several directories should be checked for this previous device's transferred data. Some of these areas are more available to the end user than others so each directory may or may not still have data within it. 

As a wrap up and reminder, the directories that should be checked are: 

/data/data/ --> Look for the iosotgmanagerv2, SmartSwitch, and SmartSwitchLog files. Search for any DATA_0 folders for the stored .zip files containing both original source information and converted JSON data. 

/data/media/0/iPhoneData --> Contains the recovered documents and media from the iOS device (original source names NOT kept). 

/data/media/0/SmartSwitch/tmp --> Look for the original backup of the iOS device as well as the converted JSON data within the appropriately named folder. 

And that's it for this post! In the future, I definitely want to explore the same data but for an Android to Android transfer as well as exploring the Pixel version and other manufacturer's version of the same processes. 

Tuesday, 26 January 2021

Android - Roles and Permissions (Android 10/11)

 Well it's a bit since I've been able to update, so I thought I'd change that. I've been working on some new research for a class I'm building and it's been giving me a chance to deep dive into some fun stuff for both iOS and Android.  I'm usually very interested to figure out preferences, permissions, and default applications on platforms as it can help shape the user's behavioral patterns. Because of this, I want to talk about where you can go look for this information in Android as it's been shaken up a bit thanks to Android 10 and 11. 

Once place to go look for installed applications on Android is the packages.xml and packages.list files that can be found within an Android's /data/system/ directory. Using the packages.list file can allow an examiner to see what applications are installed, where the data is stored within the file system, what SDK API the application is using, and some version number information. It should be noted that when a path references /data/user/0/[package name] they're referencing the /data/data/[package name] directory as Android sets up a symbolic link between the two for the default user. Additional users will be listed out there with their own user paths.

 The packages.xml file will list out all of the packages but also the permissions that each package is using. In addition to this, it will also store some good information about where the application is being stored (the apk file) as well as the installing package. If the package is then it came from the Google Play store. However, applications that are side loaded by another method such as ADB or downloading from the web will have a different "installer" and "installInitiator" value. 

App Installed from Google Play: 

App Installed via ADB: 

You can see above that the installer for Snapchat was while the Magisk Manager was installed by 

The packages.xml file also shows which permissions have been granted by the user and requested by the application. This can help an examiner determine what functions an application may have. In addition to the package information here, there are other files which track permissions referred to as runtime permissions. For more information on the runtime-permissions.xml file and what gets stored in there I'm going to refer you over to Josh Hickman's blog on it here: Josh was awesome in helping me test some stuff out with this. Definitely go read Josh's post on the runtime-permissions file as these are dangerous permissions that are very crucial to an investigation. 

In addition to the runtime-permissions.xml file there is also a roles.xml file. The roles.xml file is part of the Role Manager that Android added with version 10. This allows you as an examiner to figure out what the default set application is for specific functions in Android. Previously this was divided out into the settings_global, setttings_secure, and settings_system.xml files within the /data/system/users/#/ directory. The roles.xml file can be crucial in determining what application has been set by the user (or system) to perform a function, thus telling an examiner where to go look for data. Here's an example from a Samsung phone running Android 10. This file can be found in /data/system/users/0/

You can see above that most of the Samsung default applications have replaced some of the core Android functions for tasks like SMS, Dialer, Launcher, and Browser. So on this device, in addition to looking for SMS data in the standard mmssms.db file, we would need to look in the /data/data/ directory for information. 

In Android 11, the path of the roles.xml and runtime-permissions.xml have moved. Now, they can be found in the /data/misc_de/0/apexdata/ If a device ran Android 10 and was then upgraded to 11, files will be present in both locations but the new location will be used for changes made after the shift to 11. By comparing the two, examiners may be able to learn historical information.


Curious, why ever would a calculator application need access to Camera and to write to external storage? Yeah, I think we all know the answer here. The crucial takeaway is that these permissions are NOT stored as part of the packages.xml file. 

Because these files are stored in the directories they are, they should be available even in BFU style images where only the DE (device encrypted) containers have been decrypted. 

Understanding permissions and preferences can be crucial to learning how a target behaved on their device as well trying to key in on other places where data may be duplicated. Understanding the permissions applications request can help an examiner find things that might seem out of the ordinary. In addition, anyone doing Malware investigations on Android devices should pay special attention to several of the files mentioned here to figure out where applications came from, what permissions they requested, and if they've taken over functions of the device for the user. 

Big thanks to both Josh Hickman @josh_hickman1 and Kevin Pagano @KevinPagano3 for helping me test this stuff!

Monday, 28 September 2020

iOS - Tracking Bundle IDs for Containers, Shared Containers, and Plugins

 In iOS, one of the more vexing things I've found when working through data or helping a student with questions usually comes back to tracking what application is responsible for putting data in a specific place. With some of the fantastic work done by others including Alexis Brignoni (link here) on the ApplicationState.db as part of the FrontBoard directory, it has always become one of my first go-to spots to build a "treasure map" of applications to deal with those annoying AppGUIDs that Apple assigns each app on a device. These annoying things I speak of can be found when you're looking for data in: 


Luckily, most tools will parse out the ApplicationState.db and map each one of these unique IDs to the application which is stored within. 

Great! So much easier to go and figure out what apps are living where. However sometimes you stumble upon a file of interest within a folder and you're left with the task of matching the directory path to this database. Maybe you're in a situation where you're working with just the raw image and limited access to tools as well. How can we find the app's bundleID from within a directory already? 

Within the application data path, at the root there should be a file "" which seems to be same name in each application directory. This information will contain keys that contain the bundleID of the application which is great if you're in a pinch and don't want to jump back and forth. 

The more interesting thing is what happens when you do a search for this file across your iOS device. If you do, you'll see that the file appears in a lot of places including: 

  • /private/var/containers/Bundle/Application/APPGUID/
  • /private/var/containers/Shared/SystemGroup/APPGUID/
  • /private/var/containers/Data/System/APPGUID/
  • /private/var/mobile/Containers/Shared/AppGroup/APPGUID/
  • /private/var/mobile/Containers/Data/Application/APPGUID [duh]
  • /private/var/mobile/Containers/Data/InternalDaemon/APPGUID/
  • /private/var/mobile/Containers/Data/PluginKitPlugin/APPGUID/

Whoa. That's a lot more places for us to explore to make our treasure map. So what is this file anyway? First, let's talk about Sandboxing. Apple heavily utilities sandboxing in iOS. This is to prevent applications from getting access to data they're not supposed to have access to. Each application is given its own sandbox to play in and only that area to play in. This plist file allows us to see what sandbox we're in and who owns that sandbox from an application perspective. Using this information, we can break down a little bit more of this path information above to figure out why certain apps may be keeping data in a location. 


This directory is where the .app lives on the device. There's some additional data we can track here about the application itself and who downloaded it onto the device. Along with the .app, there's an iTunesMetadata and BundleMetadata plist file that can list out information such as when the application was downloaded, what version of the app was downloaded, and what AppleID actually downloaded it. 


This directory is similar to the one above, but speaks to core applications of the iOS device. There's less information in here but still a .plist file that can reveal what system application is responsible for the container. 


Again, similar to the directory above, but these seemed to be system apps that didn't want to share information between core applications. Again, less relevant information except for the bundleID who owns the container. 


Now this is where the REAL fun begins! I mentioned sandboxing earlier. Apple says that applications are not allowed to share information without requesting it through official channels first. In order to share information, application developers can assign a "group" to their application. According to Apple's developer information, these groups can then share data between each other. You may have also seen these in backup-style images that are listed as "AppDomainGroup-group.bundleID" instead of the "AppDomain-com.bundle.ID" structure. I have often used this path when I couldn't find the data I was looking for in the main Application Data path. 

Now for the downside. The ApplicationState.db doesn't contain information about this path. The upside? Each application's "Shared/AppGroup" directory will have one of our files! Woohoo! To make it even better, Alexis Brignoni has built support into iLeapp in order to list out out all of these files from this directory allowing us to match the contents of the file to the path it lives in. [Get iLeapp here]

An application may also have more than one folder in this path. A couple of examples would be the Dropbox application that over 4 different containers here and the Spark email app which had 2. More importantly, some applications may keep all of their relevant data here instead of the /private/var/mobile/Containers/Application/Data/ directory. An example of this would be the Spark email application (iTunes web link) which chooses to store all of its relevant databases within the /private/var/mobile/Containers/Shared/AppGroup/ directory structure instead of the more common /private/var/mobile/Containers/Application/Data/ directory structure. [Other notable examples of this include WhatsApp and Signal]


The place where we're supposed to look for app data. Well understood and documented. Just, not where we always end up wanting to look after all. 


In my test devices these appeared to be Apple services (or internal daemons, obviously) that could be tracked using the same files. 


I've had two situations recently that I've been assisting students with to understand where crucial data to their cases has wound up within this area. Populating exact matching data here is difficult but a few situations arose in which I was able to track a good bit of information. Because Apple is allowing applications to use plugins to tie together (think of the Giphy keyboard, my personal favorite), these plugins can keep data within this directory structure. One test case was to figure out why a bunch of illicit videos were showing up within a specific directory. By using the file, the analyst was able to figure out what plugin was helping to put data in this directory and what bundleID the plugin belonged to. In this case, it was tied to's PhotoMessagesApp.

Note: is the Photos application on iOS. 

Now that we know what plugin and what application the directory belongs to, we can then go out and try to generate data to prove how this information gets in here. In my example, I used the photo picker plugin within iMessage and then modified the video directly within that plugin without launching the original application. Using KnowledgeC, you can see in the following screenshots that when these files were created within the PluginKitPlugin/APPGUID/ directory structure that the MobileSMS application and other plugins overlap. 

Other plugins such as '' have come up in other investigations but sometimes it's difficult to populate these directories without KnowledgeC or PowerLog to go on. By at least understanding the owning BundleID, we can start to understand possibilities for how data got where it is. 

Now we have a better way to build out our own treasure maps as well as now knowing that files are typically going to provide the "X" that marks the spot. 

Wednesday, 23 September 2020

iOS 14 - Tracking App Clips in iOS 14

 iOS 14 brought a couple of new features I've been wanting to test. In past years I've evaluated Android's "Instant Apps" feature and of course when Apple added this with iOS 14's App Clips I had to see what was being stored. 

So what are App Clips anyway? For that I'll direct you over to Apple's website here. Apple's App Clips are mini-versions of applications that a user can quickly download and interact with without installing the full version of the app. These App Clips can be distributed to users in several ways from being embedded into web pages, NFC tags, QR codes, or even by using apps like Messages or Maps. 

When a user gets a notification they can download an App Clip it'll open up on their device after a brief download screen. From there they can interact with a minimal version of the application. Depending on the app, you'll get access to features the developers want you to have with obviously a big and constant incentive to download the full version of the application. Below are some screenshots of the process of finding an available App Clip (one via the Maps app and one via Safari), installing them, and using them. 

Hm, Panera sounds good for dinner, but I don't have the app. So instead, I can just use the Maps app to direct me to the Panera App Clip instead. 

The App Clip will appear as though it's running. It will generate its own KTX snapshots and be a running process within the device. 

However, you won't find the app listed on the Home Screen or iOS 14's new App Library either. Even if you accidentally close it you can't just use Spotlight to launch it again. 

Here's the Kontax Cam app. You can launch it directly from the website. 

All tested App Clip downloads look just like this. A blurry background and the text will slowly fill up with white as a progress bar. 

Most App Clips will constantly display a notification encouraging you to get the full version of the app. Here, you can see the app would allow me to take a photo but not actually save or do anything with it until I did. App Clips will transition your information to the full version of the app if you download it. 

So where can we find out what App Clips are even installed? There's some forensic artifacts to discuss but on a live-running device we can go to the Settings -> App Clips page to see the clips that are currently installed on our device. You can also click on each app clip to see the permissions that have been granted to that specific App Clip as well like Camera access or Geolocation access. You can also use the "Remove All App Clips" to get rid of them from your device. 

NOTE: According to Apple's statement under that "Learn More..." they say that data associated with the app clip is deleted after 10 days of non-use. Clips are automatically deleted after 30 days of non-use. 

One More Note: The above graphics were from my iPhone, while the screenshots and research below were done on a separate iPad device running iOS14/iPadOS14. Mostly because this is currently the only iOS14 device in which I can get a full filesystem image at the time of this writing. 

From a forensic image perspective, what can we track for these applications? It's going to depend on your level of access, as always. I noticed that from within my testing that NONE of the App Clips I tested (there were about 4 in this device as the number of apps using these are still limited) kept data within an iTunes-style backup. I was able to track that certain clips were used by using both iTunes-style backups and SysDiagnoseLog data, but not the data itself. 

Tracking the Data -  Installation and Storage

The first step in tracking these app clips is to see what the user has installed. Because of the way iOS tracks installed applications depending on your image type, we have to look in multiple placed. 

Info.plist / Manifest.plist - In a quick image, both the info.plist and manifest.plist file did not have any App Clips listed. 

ApplicationState.db - In both the quick and full image, the ApplicationState.db file tracked the clips being installed as well as their "true" path. In my testing, none of the App Clips data or bundles were in the iTunes-style backup. 

Each App Clip had the same bundle ID of the full application only with .clip added to the end of it. 

mobile_installation.log.0 - Full image or found within the sysdiganoselogs. These logs can show the applications that are installed and could go to show App Clips that are used and then deleted over time.

 Tracking the Data - Usage

Outside of tracking what App Clips are actually installed, the same methodology we would apply for regular apps seem to apply. The ApplicationState.db and mobile_instalation_log.0 data points gave us the right directories for finding anything that's stored. This will obviously change from app to app, but should at least point us in the right direction. Other standard artifacts that would be used to map when the apps are used like KnowledgeC and PowerLog are tracking these App Clips just the same. 

I did notice that right before the App Clip was triggered in KnowledgeC the service "" would pop right before while the App Clip is being loaded. 

Tracking information for the "ClipServices" led me down to a new path found only in full filesystem image: private\var\mobile\Library\\. The ClipData.db database found here stores information about the App Clips installed and permissions approved by the end user. 

A quick and easy SQLite query for parsing this information is: 
SELECT "bundle_id", 
datetime('2001-01-01', "last_user_notification_request_time" || ' seconds') AS Last_Notification_Request_Time,
datetime('2001-01-01', "last_version_check_time" || ' seconds') AS Last_Version_Check_Time,
datetime('2001-01-01', "last_install_time" || ' seconds') AS Last_Install_Time,
from app_clips; 

App Clips can ask special permissions that may extend beyond the standard TCC.db. This may prove to be another prime location to find this data. 

As more applications release their App Clip variants, I expect this database to grow in importance. I would expect that using KnowledgeC and PowerLog can help show how these app clips are getting onto the device. Only time will tell how important these clips are to investigations, but at least we have a good way of tracking them on the device!