Skip to main content

Hard-Coded Data / On-Device

An iOS app can be configured in many different places. Typically, these are kept in Property List (PLIST), SQLite Databases, JSON, or XML files.

Get app Environment Information

When you install an app, it is placed into a newly generated Globally Unique Identifier (GUID) directory for both the "Bundle" portion of the app, and the "Data" portion. These two directories make up the app sandbox! There is a third directory if the app uses an "App Group" to share information.

NameDirectory
Bundle/private/var/containers/Bundle/Application/(GUID)
Data/private/var/mobile/Containers/Data/Application/(GUID)
App Group Shared/private/var/mobile/Containers/Shared/(GUID)

If you remove an app and then reinstall it, it will be installed in new GUID created directories. It will not use the previous GUID. To get the current environment information:

objection -g 'App Name' run env

Example:

% objection -g com.godaddy.goapp.dev run env
Using USB device `iPhone`
Agent injected and responds ok!
Determining environment...
Running command... `env`

Name Path
----------------- -------------------------------------------------------------------------------------------
BundlePath /private/var/containers/Bundle/Application/8EE061EB-9AC1-488B-B525-3D6B0F25032D/Polaris.app
CachesDirectory /var/mobile/Containers/Data/Application/A1362F7B-A6E2-431E-B1FD-BA6EEAB709CA/Library/Caches
DocumentDirectory /var/mobile/Containers/Data/Application/A1362F7B-A6E2-431E-B1FD-BA6EEAB709CA/Documents
LibraryDirectory /var/mobile/Containers/Data/Application/A1362F7B-A6E2-431E-B1FD-BA6EEAB709CA/Library
Asking jobs to stop...
Unloading objection agent...

The BundlePath directory is where the executable, Info.plist, and library files are stored on the device.

You infer the "Data" directory from the remaining paths listed. The Data path contains the Documents, Library, & Caches directories. In the example above the Data directory would be:

/var/mobile/Containers/Data/Application/A1362F7B-A6E2-431E-B1FD-BA6EEAB709CA/

Note: For simplicity, I will refer to the Bundle directory as $APP, and the Data directory as $DATA, in the steps below (and other documents).

Review Info.plist

The Info.plist file is the main application configuration. It contains things like permissions, URL schemes, applicable devices, etc.

To review the Info.plist file on the device:

cd $APP                                                           
plutil Info.plist

Apple documentation for iOS Info.plist Keys:

https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1

Check for Other PLIST Files

To search for other PLIST files on the device:

cd $APP
find . -type f -exec grep -ali plist {} \;

cd $DATA
find . -type f -exec grep -ali plist {} \;

It is not uncommon to find a PLIST file embedded in a PLIST file. This is typically done using the NSKeyedArchiver APIs for serialization of data. It will look like a bunch of hex strings, because that is exactly what it is. See the next section to decode this information.

Decode NSKeyedArchiver Data

This API is used to serialize data which is then stored in the PLIST file as hex. If you encounter this type of data, you can easily decode it:

. . .
LastUserIdentity = <62706c69 73743030 d4010203 04050607 0a582476
65727369 6f6e5924 61726368 69766572 5424746f 7058246f 626a6563 74731200
0186a05f 100f4e53 4b657965 64417263 68697665 72d10809 5f10104c 61737455
73657249 64656e74 69747980 01a50b0c 13141555 246e756c 6cd30d0e 0f101112
59757365 7249644b 6579586f 72674964 4b657956 24636c61 73738002 80038004
5f100f30 30357130 30303030 30364f42 7a535f10 12303044 71303030 30303030
45416943 454157d2 16171819 5a24636c 6173736e 616d6558 24636c61 73736573
5f101553 46557365 72416363 6f756e74 4964656e 74697479 a21a1b5f 10155346
55736572 4163636f 756e7449 64656e74 69747958 4e534f62 6a656374 00080011
001a0024 00290032 00370049 004c005f 00610067 006d0074 007e0087 008e0090
00920094 00a600bb 00c000cb 00d400ec 00ef0107 00000000 00000201 00000000
0000001c 00000000 00000000 00000000 00000110>;
. . .

Simply copy out the hex data between the "<" & the ">" and pipe it into a tool that can reverse the hex -- such as xxd.

echo "{ 62706c69 . . . 00000110 }" \| xxd -r -p                       
bplist00?
X$versionY$archiverT$topX$objects??_NSKeyedArchiver?
_LastUserIdentity??

YuserIdKeyXorgIdKeyV$class???_005q0000006OBzS_00Dq0000000EAiCEAW?
Z$classnameX$classes_SFUserAccountIdentity?SFUserAccountIdentityXNSObjec$)
27IL_agmt~????????????

While this is not especially helpful, we can see from the beginning of the output (bplist00?) that it is another property list file embedded into a property list file. So, we can further extend our command to automatically decode the binary PLIST data using plutil.

echo “{ 62706c69 . . . 00000110 }” | xxd -r -p | plutil -p -

{
"$archiver" => "NSKeyedArchiver"
"$objects" => [
0 => "$null"
1 => {
"$class" => <CFKeyedArchiverUID 0x7fefc1e08ab0 [0x7fff8b4988c0]>{value = 4}
"orgIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a90 [0x7fff8b4988c0]>{value = 3}
"userIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a70 [0x7fff8b4988c0]>{value = 2}
}
2 => "005q0000006OBzS"
3 => "00Dq0000000EAiCEAW"
4 => {
"$classes" => [
0 => "SFUserAccountIdentity"
1 => "NSObject"
]
"$classname" => "SFUserAccountIdentity"
}
]
"$top" => {
"LastUserIdentity" => <CFKeyedArchiverUID 0x7fefc1e089b0 [0x7fff8b4988c0]>{value = 1}
}
"$version" => 100000
}

This data is much better for us to review for sensitive information.

As the name NSKeyedArchiver implies, the data is listed as a key value pair. For instance, the data below is an entry for the "orgIdKey".

"orgIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a90 [0x7fff8b4988c0\]>{value = 3}

It is linked to the value listed as "3" in the data block. We can see that the value of 3 is:

3 => "00Dq0000000EAiCEAW"

So, in this case the orgIdKey is 00Dq0000000EAiCEAW.

Decoding this data can quickly become tedious, but it will frequently reveal username's, passwords, tokens, keys, etc.

Search for Databases

To search for database files:

# Bundle directory:
find $APP -type f -exec grep -ali sqlite {} \;
find $APP -type f -exec grep -ali data {} \;
find $APP -iname \*.db
find $APP -iname \*.sqlite
find $APP -iname \*.sqlite3
find $APP -iname \*.realm\*
find $APP -iname \*.mx
find $APP -iname \*.pflock
find $APP -iname \*.cblite
find $APP -iname \*.cblite2

# Data directory:
find $DATA -type f -exec grep -ali sqlite {} \;
find $DATA -type f -exec grep -ali data {} \;
find $DATA -iname \*.db
find $DATA -iname \*.sqlite
find $DATA -iname \*.sqlite3
find $DATA -iname \*.realm\*
find $DATA -iname \*.mx
find $DATA -iname \*.pflock
find $DATA -iname \*.cblite
find $DATA -iname \*.cblite2

To open an SQLite database for review:

sqlite3 filename.db

To list the tables in the database:

  > .tables

To review the data in a table:

  > select * from tablename;

To exit the database:

  > .exit

Search for JSON/XML/Text/Certificates/Other Files

To search for these files:

# Bundle directory: 
find $APP -iname \*.txt
find $APP -iname \*.xml
find $APP -iname \*.json
find $APP -iname \*.cer
find $APP -iname \*.pem
find $APP -iname \*.cert
find $APP -iname \*.crt
find $APP -iname \*.pub
find $APP -iname \*.key
find $APP -iname \*.pfx
find $APP -iname \*.p12
find $APP -iname \*.pkcs7
find $APP -iname \*.html
find $APP -iname \*.md
find $APP -iname \*.js
find $APP -iname \*.m
find $APP -iname \*.h
find $APP -iname \*.swift
find $APP -iname \*.log

# Data directory:
find $DATA -iname \*.txt
find $DATA -iname \*.xml
find $DATA -iname \*.json
find $DATA -iname \*.cer
find $DATA -iname \*.pem
find $DATA -iname \*.cert
find $DATA -iname \*.crt
find $DATA -iname \*.pub
find $DATA -iname \*.key
find $DATA -iname \*.pfx
find $DATA -iname \*.p12
find $DATA -iname \*.pkcs7
find $DATA -iname \*.html
find $DATA -iname \*.md
find $DATA -iname \*.js
find $DATA -iname \*.m
find $DATA -iname \*.h
find $DATA -iname \*.swift
find $DATA -iname \*.log