Tuesday, December 24, 2019

iLEAPP: iOS Logs, Events, And Properties Parser

Introducing a Python 3 scripts that merges all my previous iOS digital forensics and incident response scripts (DFIR) into one.

iLEAPP
Many thanks goes to Jessica Hyde (@B1N2H3X) for suggesting I start merging my standalone scripts into a unified tool during OSDFcon. You are the best Jess. Also tons of thanks to Phill Moore (@phillmoore) for helping me with coding one of the artifacts. I'm really grateful for Christopher Vance (@cScottVance) and Geraldine Blay (@i_am_the_gia) for allowing me to create scripts based on their areas of iOS research. Last but never least my respect and appreciation to Sarah Edwards (@iamevltwin)for her trailblazing work in iOS DFIR and for showing me the existence of the Mobile Installation logs.

Name:
    iLEAPP: iOS Logs, Events, And Properties Parser

Download:
    https://github.com/abrignoni/iLEAPP

Purpose:
  1. Create a central point for iOS scripts made by the writer.
  2. Serve as a open source tool (OST) option to validate commercial DFIR tools.
  3. Be a zero cost option to forensic examiners that are tasked with iOS mobile forensics but lack the budget to acquire a full suite of commercial DFIR tools.
  4. Enable me to work on my Python coding skills as related to DFIR. 
Features:
  • Python 3 script
  • Coded and tested in macOS Catalina.
  • Script can parse an iOS full file system directory directly from a .tar file or it's decompressed contents. 
Current parsing capabilities:
Development:
    The scripts utilized are fully open source and can be used and modified by others. Looking forward to sharing and merging these with other OST DFIR tools.

    I hope to be able to add the following in the near future:
  1. Graphical user interface for point-and-click selection of source tar file or extraction directory.
  2. Progress bar or indicator of parsing activity to the user.
  3. Additional artifacts like applicationState.db query results, KTX snapshot extraction, and all sorts of plists.
Usage:
ileapp.py [-h] -o {fs,tar} pathtodir 
iLEAPP: iOS Logs, Events, and Preferences Parser. 

positional arguments: 
pathtodir Path to directory

optional arguments: -h, --help show this help message and exit -o {fs,tar} Directory path or TAR filename and path(required).

Internals:

    The script has 3 key components.
  1. ileapp.py
  2. search_files.py
  3. ilapfuncs.py
The ileapp.py script has a python dictionary list where the keys represent the parsing function names and the values are the search patterns to be executed. Here is an example the contents of the dictionary.


The flow is fairly simple. 
  • The values portion is used to traverse the tar file or logical file system for a match per the saerch_files.py script. If traversing a .tar file a temporary folder is created in the reports folder and the matching file/s are exported and stored there for parsing by the ilapfuncs.py script per the key function name. For a logical file system search no temporary file creation is needed since the file/s are already in a ready for parsing state. 
  • The ilapfuncs.py functions perform the analysis and write the proper reports.
  • The temporary folder is deleted after parsing. I am still debating if the temporary folder should be left in place for easy report validation.
Any of the key:value pairs can be deleted and/or new ones added. Any new key value pairs will be called by ileapp.py as a function that should be defined in ilapfuncs.py.

CAVEAT:
Some of the artifacts are dependent on knowing which iOS version is being worked on. The ileapp.py scripts depends on the iOS version output from the lastbuild function. If this key is removed from the dictionary of items it will break both the knowledgeC and iOS Notifications functions. It is suggested (to the point of requirement) that the lastbuild key remains in the dictionary and it that precedes all the aforementioned ones.

Conclusion:
Some, if not the majority, of the artifacts these scripts will eventually parse will not be of my discovery or making. One of the reasons I code things others have done, and even done better, is that it enables me to be grow by having something to compare my development with. Many times we think that the way to excellence is to come up with things no one has seen before, to imagine something never thought of. It is my experience that the only way to be better at what we do is to understand that which has already been done. Only then will the unknown be apparent to us. To depend and take advantage of the works of others that have come both before us or are currently with us on our DFIR journey and to contribute in any way we can is the way to successfully work our cases faster, more efficiently, to give justice to those who need it, and to feel joy while doing it. 

To that end, as always, I can be reached on twitter @AlexisBrignoni and email 4n6[at]abrignoni[dot]com.



   

Saturday, December 14, 2019

iOS Imgur app - A Realm database example

Short version:

The Imgur app keeps user generated post data in the following Realm database:
/*app folder GUID*/Documents/default.realm
All images accessed via the app, from images posted by the user to those seen as one navigates through the content the app presents, are found in the following location:
 /*app folder GUID*/Library/Caches/com.hackemist.SDImageCache/default
 App screen snapshot can be found at:
/*app folder GUID*/Library/Caches/Snapshots/imgurmobile/*.@3x.ktx
For details on Real databases and how to approach their examinations see here: https://abrignoni.blogspot.com/2019/11/realm-database-storage-primer-for.html
It is of note that Cellebrite Physical Analyzer has a database browser that is compatible with Realm databases.

For details on iOS snapshots and how to visualize them see here:
https://abrignoni.blogspot.com/2019/09/ios-snapshots-triage-parser-working.html
It is of note that Magnet Axiom has the capability of displaying .ktx images natively.

For details on how to access a full file system of an iOS device see following:
  1. Checkra1n jailbreak: https://checkra.in/
  2. Install OpenSSH via Cydia. See the acqusition section for SSH here: https://abrignoni.blogspot.com/2018/08/finding-discord-chats-in-ios.html
I will update the post with a Checkra1n step-by-step guide that is being prepared by colleage soon.
It is of note that Magnet Acquire, a free tool, allows the creation of a full file system .tar file from a Checkra1n jailbroken device.

Long version

The Imgur iOS app is one of the growing number of software development project that have moved from using SQLite databases to the Real database NoSQL data storage type. For details on how to approach Realm databases see my previous post on the topic here: https://abrignoni.blogspot.com/2019/11/realm-database-storage-primer-for.html

This post is not an exhaustive study of the Imgur iOS app. I use it as an example of the type of app that is used by millions of people that might come across your case work and your tools might not have the default capabilities to address at this moment.

In order to locate a particular application folder, in our case the one for Imgur, within our full file system extraction see Nike iOS app example here: https://abrignoni.blogspot.com/2018/08/ios-nike-run-app-geolocation-self-join.html

After locating the application directory we can exported from the device or from the tar file for analysis. So far these are the steps:

Jailbreak the device using Checkra1n.

macOS only for now.

Install OpenSSH via Cydia.

Open the checkra1n app and install Cydia. then open Cydia and install OpenSSH.
Locate the applicationstate.db file in order to identify where the Imgur user generated data resides. See previous links for steps required.

Connected from macOS to the phone via SSH. Cyberduck app. Username root and password alpine.

Export the application directory.

To figure out which one you want see the applicationstate.db entry for the app you want.

Open the application directory for analysis.

The bottom window shows the application directory folders.

Imgur analysis

The Realm database we are looking for will be located in the Documents directory. As seen in the next image my macOS computer identifies the datastore with a red and bluish icon. This is due to having already installed Realm Studio. This application allows us to access the contents of Realm databases. It can be downloaded here: https://realm.io/products/realm-studio/

Get the default.real file.
Open the file with Realm Studio.

Data
The data seen in the previous image corresponds to me making a post to Imgur using the app. The post includes an image. The left column identifies the objects and the right pane has the corresponding properties. This database separates the data in the post form the image that goes in the post. The image post has an entry in the DraftImage object at the top. This screen shows the post tile and some metadata about the post.

remoteidentifier

The DrafPost object contains two important properties, the remoteidentifieer and the accounintidentifier. The remoteidentifier is the post number used by Imgur in the website URL. The accountindentifier is self explanatory. It is tied to the user.


The DraftImage object has the name of the image in the remoteidentifier field. To confirm one can go to the post and right-click save the image. The name provided will be the same as the one found in the database. The DraftImage object also contains additional metadata as image width and height.

As you can imagine the analysis of a database made of object can get really difficult pretty fast as more objects are created and stored. One technique is to export the data as a JSON file and use Python or other tools to create a report of the contents.

Export file to JSON.
The following is a screenshot of the output of my JSON-to-HTML Python script for the exported JSON data.

Easier to visualize
I find it easier to visualize the data in a nested columns and rows format. The script can be found here: https://github.com/abrignoni/JSON-to-HTML-and-XLS.

One last artifact I wanted to highlight are the application snapshots. These are screenshots of what the app was showing on screen when the user places the app in the background in order to have a different app in the foreground. Be aware that the ktx snapshot is not compatible with regular image viewers outside or macOS and Magnet Axiom.

Snapshot
For details on snapshots see @iam_the_gia's blog post here: https://gforce4n6.blogspot.com/2019/09/a-quick-look-into-ios-snapshots.html

For details on how to identify ktx files and how to convert them to png see the blog post here: https://abrignoni.blogspot.com/2019/09/ios-snapshots-triage-parser-working.html

Conclusions

By generating more test data we can surely identify additional objects and artifacts of interest. The main takeaway from this exercise is the existence of app datastores that go beyond the usual SQLite we are used to. The same thing can be said of JSON and protobuff data stores. The only permanent thing in the digital forensics field is the fact that there will always be change. It is upon us to discover, test, and publicize new changes. Only then our tools will be updated, evidence won't be overlooked, and justice will be served.

As always remember to validate all findings and be aware I can be reached on twitter @AlexisBrignoni and via email 4n6[at]abrignoni[dot]com.

Wednesday, November 20, 2019

Realm database storage primer for digital forensic examiners

Realm databases are non-relational storage structures that are being used in place of the traditional SQLite stores in many newer/updated mobile apps. As examiners we are faced with locating and parsing these newer data stores. As expected there is always a lag between newer technological applications and commercial forensic third party support. The purpose of this small primer is to enable you to find these Realm databases and access their contents.

Analysis Tools


What is a Realm database?

Some time ago I was made aware of a popular app that all of a sudden was not being properly supported by our usual forensic tools. When one of my colleagues told me that the data was contained within a Realm database I had no idea what he was talking about. A quick Google search lead me to the developer's webpage, realm.io.

Alternative to SQLite. Interesting...
Realm is an alternative to the commonly used relational SQLite databases we are used to. In this model, called NoSQL, data is saved as objects. Imagine a database cell where you can store and manipulate not only values but a list of values. The way the Realm databases accesses these values makes apps that use this model faster than traditional SQLite stores. For an more detailed explanation of Realm capabilities, like zero copy, live objects, MVCC, and ACID, see here. Like all things in life there are pros and cons to everything. I leave the reader to Google search why a developer would decide to build an app store on Realm or SQLite if interested. For our purposes we just want to find these databases and be able to see their contents.

Sample app that uses a Realm database

Usually I work on apps from the Google Play store to illustrate the extraction and parsing of data. In this case I used a simple Android project whose only purpose is to illustrate the input and output of data from a Realm database. Sadly the generation and extraction of sample data using a fully working app takes time and effort that I currently don't have. Using this simple project and an Android virtual machine I could do the generation an extraction of data in minutes for illustration purposes.

The Android project was made by Dheeraj Andra and it is a simple app that takes as input a name and age. These values are shown to the user on screen after being saved in the realm database. Links to the project are included above. To generate the APK needed to run the app in my Genymotion virtual machine I used Android Studio. With the APK in hand I ran it on my virtual machine. The following is an image of the app in use:

Sample Realm app
At the top the user enters values and these are shown back at the bottom part of the app.

Storage location

As any Android app the data of relevance is contained within the application directory. With SQLite databases the data is usually contained in the databases directory. By contrast this Realm app, as well as others I have come across lately, has no databases directory.

Where is the databases folder?
The data we seek resides in the files folder and the file type we need to extract are the ones that end in the .realm extension.

Get the .realm file!
As explained in some of the links above Realm databases have no need for write ahead logs or rollback journal files. In this example extracting the default.realm file has all the data we seek.

How to view Realm database contents

What do we do with the file after extracted? The database developers have a free tool called Realm Studio. Open the .real file with Realm Studio and you will be able to browse the contents.

Values
As the app has more classes and more data it can be useful to export the contents in JSON format for further analysis. It goes without saying that when an examiner does transformations of the data for parsing and analysis great care has to be taken to validate every single piece of resulting data. The farther we move away from the original format the closer we have to make direct links back to it.

In the previous image the bottom part of the screen shows the contents of the sample realm database while the upper part is the same data in JSON format.

Recently (November 19, 2019) Cellebrite announced that their Database viewer tool product had Realm database support.
I expect other vendors in the space to follow suit. This is important because I forsee Realm databases, as well as JSON and protobuf, to be common in the near future as mobile app data stores.

Last but not least remember that having multiple ways of looking at a data set is important for validation purposes.

As always I can be reached on twitter @AlexisBrignoni and via email 4n6[at]abrignoni[dot]com.



Monday, October 28, 2019

Recreate Android apps, folders, and widget screen positions from a forensic extraction.

Short version

Android 9 uses the launcher.db sqlite database to keep track of where on the device screens are the app, folders, and widget shortcuts located. For stock Android the database can be found in the following directories depending on the available launcher:
/data/data/com.android.launcher3/databases/ - Quickstep Launcher
/com.google.android.apps.nexuslauncher/ - Pixel Launcher  
The relevant forensic data in the table named favorites is as follows:

  • Type of shortcut - Icon, folder, widget, etc...
  • Unique ID - Integer value
  • Name
  • Modified time - Epoch timestamp in milliseconds
  • Icon image blob - PNG file

Android home screens can be recreated using the following python3 Android Launcher DB parser script:
https://github.com/abrignoni/Android-LauncherDB-Parser/
Here are the shortcuts as viewed via the device's screen:

Android screen + shortcuts
Here are the shortcut positions and metadata as recreated via the use of the script:

Upper screen

Lower screen

It is of note that not all icons are contained within the launcher.db file. Additional details in the long version of the blog post.

Testing and analysis platform

Macbook Pro 14.1
Genymotion Android VM - Pixel 3 XL Stock Android (Quickstep & Nexus launchers)
SQLite Browser
Python 3 - Numpy + Pandas

Long version 

A few weeks ago I participated in a capture the flag that included an Android device as part of the exercise. One of the questions wanted us to identify the name of a shortcut in a precise screen location within the Android image. As I looked for the answer that made me think on practical uses for this information. Why would anyone care where and on what screen/s are the shortcuts for apps, folders, and widgets on a mobile device? What could that tells us about our case that we would need? What forensic purpose could there be?

On many Windows OS cases showing what directories, LNKs, and files were located on the desktop painted a clear picture of what the user deemed important enough to have easy access to. It speaks of usage, convenience, and to how the user decides to aggregate data. Can the same be said of Android home screens? I believe so. Consider that folders on Android home screens are created by the user long pressing an icon/shortcut and dropping it on top of another shortcut. The name of the folder is user generated if it is not Unnamed Folder. A lot of user activity to place the items where they are. Same thing with widgets. There is a lot of user interaction to generate a widget and place it on the screen. What if these interactions were timestamped?

As stated in the short version at the top the data resides in the /data/data/com.android.launcher3/databases/ and /com.google.android.apps.nexuslauncher/ directories on stock Android devices. The control of how these screens operate is the responsibility of launcher software.

Google Play Store - Launcher Apps
As seen in the previous image, stock Android launchers are not the only game in town. This blogpost limits itself to two the stock types but the device you might be looking into could use any of these other ones. Further research is needed to verify how these other launchers keep its data. My assumption is that to be compatible with Android the databases will most likely be the same as the stock versions. This is something that would need follow up.

Launcher.db

Within the path the database of interest is a sqlite database named launcher.db. The favorites table has all the relevant data in regards to position of items on screen as well as when these items were placed in their locations.

The following image will show the most pertinent fields in the table.

Relevant launcher.db fields
To better understand the data the following image shows the main divisions of an Android screen:


Blue area = Home screen. User can swipe left or right to access more screens.
Red area = Home bar. Persisten on all screens. Only has 5 spaces available.

Purpose of storage data per field:

  • _id - Unique identifier for each app, widget, and folder. Integer value.
  • title - Name of the app shortcut or folder. Widgets do not keep a name in this field.
  • container - Number identifies the type of screen. 
    • -101 - Home bar. Bottom row that does not change as the home screens change when you swipe left or right.
    • -100 - Home screen container number. If you have more than one screen that will be identified by the value in the screen field.
    • Positive integer values - These map to the _id number in the previous field. This is important because it shows the items in question reside in a folder with the corresponding _id number.
  • screen - Identifies the homescreen where the apps will be shown. Everytime a new screen is made the number increments by one. The exception is the home bar (container -101.) Apps in the home bar are limited to 5 and each position will be identified with a 'screen' number.
  • cellX and cellY - Used to identify the location of the item to be place on screen. It is a 5x5 grid on the home screen and 1x5 for the home bar.
  • spanX and spanY - Used to determine the ending location of the item on screen. If it is a widget that covers a 3x3 space the combination of cellX and cellY for the starting point and the spanX and SpanY as the end points will allow the mapping of items that span more than one space of the screen.
  • itemType - Used to determine what type of item is on screen. So far I've identified the following:
    • 0 - App
    • 2 - Directory / Folder
    • 4 - Widget that spans more than 1x1 space
    • 6 - Widget spans a 1x1 space
  • icon - Data blob that contains a PNG of the item to be displayed. Be aware some items, like folder and some widgets, might not have data in this field.
  • appWidgetProvider - Widgets do not have values in the title field. This one indicates the bundle id for the app that populates the widget data.
  • modified - Timestamp in epoch milliseconds that tells you when the placement of the icon on screen last occurred. If the user moves the location of an item the modified time changes to reflect when the move happened.
By understanding these relationships we can recreate the mapping of all items. For this purpose I created a python 3 script that can be located here:
https://github.com/abrignoni/Android-LauncherDB-Parser/

Python 3 Script

The script usage is very simple.

1- Extract the launcher.db file from the indicated path.
2- Place it in the same directory as the script

Just place the launcher.db file in the same directory as the script.
3- Run the script by typing: python launcher.py

EZ PZ
4- A timestamped named directory will be created for each run of the script. Within it you will find html representations of all screens and folders. Be aware that folders can be mapped to their corresponding home screens by the matching of their id numbers.

Notice the timestamp for the run
5- At a minimum you will see the icons directory (contains all the extracted PNG files from the db), the Bottom_Bar.html and MainScreen0.html files. In the following image you can see these html files but also additional ones that correspond to folder screens / content. Notice that these are named ScreenDirectory followed the corresponding id value that will be used to map the report to the folder location on the screen.

All the screens + all the folders/directories
Every relevant data point is included in the report to include the icon if available.


The script will do the necessary time conversions as well.

Conclusion

As always further testing and validation are never out of place. Although my script manages unknown item types it will be really useful to identify additional ones so a proper type descriptor can be included. Hopefully this type of reconstruction can give the examiner a window unto how the user managed the device,  how some might have been group in folders, and maybe which app were of most interest to the user by the fact of being in the home screens and home bar.

As always I can be reached on twitter @AlexisBrignoni and via email 4n6[at]abrignoni[dot]com.

Sunday, September 29, 2019

iOS Snapshots Triage Parser & working with KTX files

Short version

Collection of scripts that assist with parsing iOS snapshot bplists in the applicationState.db data store. Snapshot images show what was last on screen for a particular app before the app is closed or sent to the background. The research behind this artifact was conducted by Geraldine Blay (@iam_the_gia). For details on the meaning and importance of these files read her awesome write up here:
https://gforce4n6.blogspot.com/2019/09/a-quick-look-into-ios-snapshots.html
Script download:
https://github.com/abrignoni/iOS-Snapshot-Triage-Parser
Script purpose and workflow:
  1. Run SnapshotImageFinder.py to identify iOS snapshot images and extract them from a targeted iOS file system extraction directory. These files end with @3.ktx or @2.ktx.
  2. Extract the macOS Automator quick action from the ktx_quick.zip file. With it convert all the .ktx files extracted in step #1 to .png format.
  3. Run SnapshotTriage.py to extract, parse and match the images with the snapshot metadata contained in the extracted bplists from the applicationState.db datastore. This script accepts 2 parameters, the directory where the applicationState.db is located and the directory where the .png files are located.
  4. After execution of the previews steps a triage report directory will be created containing the extracted bplists and iOS snapshot reports in HTML per app. 
Full details with screenshots are below in the long version section of the blog.

Results:

The following image is of a iOS Snapshot report generated SnapshotTraige.py for the Uber app. It is of note that these snapshots can contain chats, images, maps, anything the app was doing at the time it was taken out of focus and/or sent to the background.

iOS snapshot for the Uber app.

Long version


The importance on being able to recover what was on screen when an app was last used is pretty clear. But beyond the evidentiary value of the images and when where they generated this speaks to the pressing need to teach our first responders to limit interactions with a suspect/target device. By manipulating the device on scene this data might reflect the first responder's fingering around instead of data of value for the case.

The functionality that enables the creation of such screenshots in iOS devices is called Snapshots. Android has the same functionality and it is called Recent Tasks. I made a script to parse these, it is located here:
https://github.com/abrignoni/Android-Recent-Tasks-XML-Parser
I became aware fully of the snapshot functionality in iOS by my dear friend and colleage Geraldine Blay. You can and should follow her on Twitter here:
@i_am_the_gia
Her research can be found on her blog post here:
ddsdfdf
I have made a script that automates the extraction of these snapshots and their timestamps. In her blog post you can find the paths and structures needed to validate by hand the automated output from my script.

The script to parse the iOS snapshots is located here:
https://github.com/abrignoni/iOS-Snapshot-Triage-Parser
Script prerequisites:

To parse the iOS snapshots one needs to be working with an iOS full file system extraction. For details on iOS file system extractions see the acquisition section of the following blog post:
https://abrignoni.blogspot.com/2018/08/finding-discord-chats-in-ios.html
Since the app images are in ktx format from Apple, a macOS computer will be needed. After much searching and asking around I have yet to find a python library or CLI tool that can convert ktx images to png. This is necessary since ktx files are not a widely supported image format. Our script output will produce a more universal form of output, png images in html. To do the ktx to png conversion we will use an Automator Quick Action in macOS.

The scripts and detailed workflow:

1. SnapshotImageFinder.py
Used to extract snapshot ktx files from the iOS file system extraction. Usage is really simple:

usage: SnapshotKtxFinder.py [-h] data_dir_to_analyze

This script will recursively go through and pull out all the relevant ktx files. It will place them in the FoundSnapshotImages directory. Here is the CLI output for some sample data I provided to it:


Searching for iOS Snapshot images.Please wait...
Snapshot ktx files moved to: /Users/abrignoni/Desktop/iOS-Snapshot-Triage-Parser-master/FoundSnapshotImages
Snapshot ktx files moved total: 485

2. ktx_quick.zip

This zip file contains a macOS Automate Quick Action that will convert the ktx files to png files automatically.

First unzip the file on your macOS computer and click the unzipped file. When asked if you want to install say yes. If this gives you the heebie-jeebies use Automate to create the conversion file. After install you will see the following:

Installed ktx_quick 
By installing we have the ability to right click on any directory and from the context menu execute our quick action. For our purposes we will do so on the FoundSnapshotImages directory previously mentioned.

Notice the option in blue.
As the action is being run you will see a progress gear on the right side of the top side screen bar.

Progress
When done the converted_snapshots directory will be created on your desktop. Take that directory and place it in the same directory where the python scripts are located.

From here:

At the desktop.
To here:

Inside the directory for the scripts
3. ccl_bplist.py

This module is used to deserialize NSKeyedArchiver bplists. Thanks to Alex Caithness who came up with this module. It saves us a lot of headaches. I added his module to my repo for convenience. It can be downloaded directly from the source here: https://github.com/cclgroupltd/ccl-bplist.

4. SnapshotTriage.py

All output from this script will be created in a timestamped named folder. This allows us to run the script multiple times with any overwriting issues. Thanks to Phill Moore (@phillmoore)for the idea.

All script output directories will be in these.
The script will first locate the applicationState.db file. The following query will be used to identify the blob fields that contain the iOS snapshots bplists.

SELECT
application_identifier_tab.id,
application_identifier_tab.application_identifier,
kvs.value
FROM kvs, application_identifier_tab, key_tab
WHERE application_identifier_tab.id = kvs.application_identifier
and key_tab.key = 'XBApplicationSnapshotManifest'
and key_tab.id = kvs.key

The bplists will have the image filename, bundle id name, and the timestamps of the images. With the filename it is easy to connect the exported images to the corresponding app name/ bundle id and timestamps. As mentioned in previous blog posts bplists sometimes can be incepted. This means a bplist is inside another bplist. This case is one of those. The script will extract the bplist from the database and save the incetpted bplist in the ExtracteBplistFirstLevel directory. After doing so it will extract the internal bplist and save those in the ExtractedBplistSecondLevel directory. The idea of doing so is that it will allow the examiner to validate the whole process step by step as well as provide a way to execute third party tools over the extracted data.

A third folder will be created named Reports. In this folder there will be an HTML for every app on the device that had snapshot data. As stated previously these directories are inside the SnapshotTriageReports_timestamp named directories.

SnapshotTriage.py created directories
When the script runs one can see the bplists per bundle id being processed.

Script running.

The usage for the script is as follows:

Alexiss-MBP:iOS-Snapshot-Triage-Parser-master abrignoni$ python3 SnapshotTriage.py -h
usage: SnapTriage.py [-h] data_dir_snaps data_dir_appState

iOS Snapshot KTX Traige Parser
 Parse iOS snapshot plists and matching ktx files.
positional arguments:  data_dir_snaps     Path  to the Snapshot images Directory  data_dir_appState  Path to the applicationState.db Directory.
optional arguments:  -h, --help         show this help message and exit


The first positional argument is the directory where the png files are located, the converted_snapshots directory. The second positional argument is the directory for the full file system extraction or a directory that has the pertinent applicationState.db file. After the script is done running it shows how many snapshots were processed.

Total apps with snapshots.
Reports

The reports directory has HTML for all the apps with snapshots.
Reports
The reports contain all the images and timestamps found in the processed bplists.
The images the HTMLs reference are copied inside the reports directory within the images folder. This lets us copy or move the reports directory and view the images anywhere.

Hve images, will travel.
Sample report

The type data these screenshots records can include text messages, maps, documents, chats, anything that an app can show the user.

iOS snapshot for the calculator app.

The report allows the user to click on the images to view them full screen in a new tab. This is good since some of the images are downscaled or of horizontal orientation.

Super important: The fist timestamp under each image is the ktx file creation time. Some of the images have 2 timestamps per ktx image. We are currently trying to figure out where that 2nd time comes from. I have added it to the report in the name of completeness. In order to validate these timestamps, taken from inside the bplist, the examiner can go to the original ktx files and look at the creation times directly for each image of interest.

Conclusion

Thanks again to Geraldine Blay for her research. These artifacts can give context to what the user of the device was doing or seeing shortly before the time of seizure/examination. Also note that not knowing of a scripted or direct way of dealing with ktx files does not mean there is nothing that can be done. With a little but of creativity and help we can achieve our goals.


As always I can be reached on twitter @AlexisBrignoni and email 4n6[at]abrignoni[dot]com.