Exploring Local Storage in iOS: iStorageEnumV2.0

Shibin B Shaji
5 min readAug 14, 2024

--

A tool to easily analyze the Local Storage of an iOS Application to find juicy information. Skip to the section iStorageEnumV2 to jump directly into the tool usage.

Introduction

iOS Pentesting is an area which is rarely touched, mostly because of the initial investment required. You need to have a physical device, that too one which could be Jailbroken. This is a really hard combination to get. You’d have to go out and purchase devices that are running outdated iOS versions.

iPhone Pentesting

The ideal device, at the time of writing this article, is iPhone 6 series and iPhone 7 series because the last update for them is iOS 15. iOS 15 could be jailbroken with Palera1n, although the steps would be a bit different than from checkra1n and the chances of falling into a boot loop are high.

iOS applications tend to store sensitive information in the local storage which we have to manually ssh into the device and inspect, or use a file explorer like Filza to do the same.

Some of the common issues that I have come across while inspecting local storage are:

  • Tokens stored in plain text.
  • Passwords stored in plain text.
  • SQLite files which contain sensitive information.
  • PDF files in local storage which contain PII data.
  • Images which contain sensitive data.

These are a few. Some of the data still persisted in the device even after a logged in user logs out of the application.

While some of the issues might sound to be less severe, they could possibly used by an attacker to gather information.

The first iteration

I was really lazy to manually inspect the files in terminal or via Filza. I wanted the files to be displayed neatly so that I can quickly find out all the files and view only the necessary ones. And that’s exactly what the first iteration did. It printed the structure like a tree and with the help of some find commands, I was able to list out some files like “.plist”, “.json”, “*.sqlite” etc. so that I can go ahead and download them, or inspect them in Filza.

The output of the first iteration looked something like this:

Navigating to Application files
File structure
.
|-Documents
| |-ABLoaderError.log
|-.com.apple.mobile_container_manager.metadata.plist
|-Library
| |-Caches
| | |-com.crashlytics.data
| | | |-com.xxxxxxxxxx.xxxxxxxx
| | | | | |-settings
| | | | | | |-settings.json
| | | | | |-reports
| | | | | | |-prepared
| | | | | | |-processing
| | |-google-sdks-events
| | | |-GDTCORFlatFileStorage
| | | | |-gdt_library_data
| | | | | |-GDTCORFlatFileStorageBatchIDCounter
| | | | |-gdt_batch_data
| | |-xxxxxxxxxxxxxxxxxxxxx
| | | |-com.xxxxxxxxxxxxxxxxxxxxx
| | | | |-libraries.list
| | | | |-functions.data
| | | | |-functions.list
| | | | |-libraries.data
| | | |-xxxxxxxxxxxxxxxxxxxxx
| | | |-CacheStorage
| | | |-OfflineWebApplicationCache
| | |-xxxxxxxxxxxxxxxxxxxxx
| | | |-HSTS.plist
| |-Saved Application State
| | |-com.xxxxxxxxxx.xxxxxx
| | | |-restorationInfo.plist
| | | |-KnownSceneSessions
| | | | |-data.data
| | | |-data.data
|-SystemData
| |-com.xxxxxxxxxxxxxxxxxxxxx
| | |-Library
| | | |-WebKit
| | | | |-WebsiteData
|-tmp
| |-CFNetworkDownload_devtpH.tmp
| |-WebKit
| | |-MediaCache

=================================================================================

[+] Interesting files:
\tJSON Files:
./Library/Caches/xxxxxxxxxxxxxxxxxxxxx/settings.json
./Library/Caches/xxxxxxxxxxxxxxxxxxxxx/settings/cache-key.json
./Library/Caches/flutter_callback_cache.json

---------------------------------------------------------------------------------

PList Files
[ Plist files are convenient to use and can be used to store standard data types, such as integer, strings, and so on. Many times a developer makes the mistake of saving sensitive information in plist. Many top companies' iOS app had mistakenly stored users' credentials/pin in the plist files in their earlier versions. ]

Tip: Use cat to view the files and hunt for Sensitive data.

./Library/Application Support/xxxxxxxxxxxxxxxxxxxxx/g-checkin.plist

---------------------------------------------------------------------------------

SQLite Files
[ Tip: Use sftp to download the files to local system and take advantage of sqlite3, or any other SQL viewers to browse the files. ]

./Library/Application Support/xxxxxxxxxxxxxxxxxxxxx/rmq2.sqlite

---------------------------------------------------------------------------------

SQL Files
[ Tip: Use sftp to download the files to local system and take advantage of SQL browsers to examine the files. ]

./Library/xxxxxxxxxxxxxxxxxxxxx/google-app-measurement.sql

---------------------------------------------------------------------------------

Image files:
Developers mistakenly store images which expose sensitive data. Use sftp to download the image to local machine to view the images

./Library/SplashBoard/Snapshots/sceneIDxxxxxxxxxxxxxxxxxxxxx/8403xxxxxxxxxxxxxxxxxxxxx63CCDD@2x.jpeg

---------------------------------------------------------------------------------

PDF Files:
Developers mistakenly store PDF files of a currently or previously logged in user which might expose sensitive data. Use sftp to download the pdf file to local machine to view the files.


---------------------------------------------------------------------------------

Other files


---------------------------------------------------------------------------------

The problem was that we had to manually download each file using sftp. Wouldn’t it be easier if all these files would be automatically downloaded to our system with few steps?

iStorageEnumV2

The above problem gave me the idea (and the need) to upgrade the tool. Also, I found myself searching for sensitive strings in the files to find some interesting things like passwords, tokens etc.

Installation:

Just clone the repository:

git clone https://github.com/shibinbshaji/iStorageEnumV2.git

Usage:

Requirement: APP_ID

This can be fetched using objection.

objection -g <App Name / Bundle Name> explore

After objection fires up the application, use env command to find out the environment, ie. the storage location the application writes to. A long gibberish which looks like a hash with upper case characters is the thing we are looking for.

Using objection to get the UUID

Permissions for the script

Give necessary write permissions to the script by running the command:

chmod +x iStorageEnumv2.sh

Running the script

Then, run the script using:

./iStorageEnumv2.sh

You would be asked to provide the following:

  • IP address of the iOS device
  • SSH username of the iOS device
  • Binary File name (UUID)
Screenshot of iStorageEnumV2.0

Optional feature:

Typing the IP address and SSH username each time the script runs could be a bit tiresome. To tackle this, the script first checks for the presence of these information from the environment variable. It can be set by:

  • IP Address: export IPHONE_IP=192.xxx.xxx.xxx
  • SSH Username: export IPHONE_USER=user

Hit me up on X (formerly known as Twitter) to give feedback on the tool: shibinbshaji06.

--

--