Categories
General

App Research: Granting Permissions on iOS

When analysing the privacy properties of apps, one often wants to grant all permissions to apps by default. This makes the subsequent analysis of apps easier, especially when done at scale.

On Android, it is super easy to install an app and automatically grant all app permissions. All is that is needed is the following command:

adb install -g [path to apk]

On iOS, no publicly documented method exists, which makes automated app analysis a lot harder.

This is especially true when large-scale analysis of iOS apps, as my colleagues and I at Oxford did in our recent paper on comparing Android and iOS (forthcoming at PETS).

In the following, I’d like to present a method to automatically grant all permissions to iOS apps. This will require a jailbroken iOS device with full shell and file system access.

A script can be found at on GitHub.

Most permissions (except location, notifications, access to local network and some others I may have missed) on iOS are handled by the TCC (Transparency, Consent, and Control) system. Calls to permissions are handled through the daemon at

/System/Library/PrivateFrameworks/TCC.framework/tccd

This daemon manages an SQLite database that’s located at

/private/var/mobile/Library/TCC/TCC.db

This database, in turn, saves all permissions to an access table:

SCC, the system that handles most permissions on iOS.

Keith Johnson provides great detail about the TCC on the Rainforest Engineering blog, but only did so for the case of macOS. However, iOS is similar as I found out.

On iOS, the column service contains the granted permission. The codes for all possible permissions can be found in

/System/Library/PrivateFrameworks/TCC.framework/en.lproj/Localizable.strings

On iOS 14.8, we have:

kTCCServiceExposureNotification
kTCCServiceFallDetection
kTCCServiceGameCenterFriends
kTCCServicePhotos
kTCCServiceSensorKitBedSensingWriting
kTCCServiceUserTracking
kTCCServiceSiri
kTCCServiceSpeechRecognition
kTCCServiceAddressBook
kTCCServiceBluetoothAlways
kTCCServiceBluetoothPeripheral
kTCCServiceBluetoothWhileInUse
kTCCServiceCalendar
kTCCServiceCalls
kTCCServiceCamera
kTCCServiceContactsFull
kTCCServiceContactsLimited
kTCCServiceMediaLibrary
kTCCServiceMicrophone
kTCCServiceMotion
kTCCServicePhotosAdd
kTCCServiceReminders
kTCCServiceWillow

The column client contains the bundleId of the app. In my case (see image above), the only non-system app on my iPhone was com.vonbruno.micfree, a microphone app that has both requested the microphone and tracking permission.

An auth_code of 2 indicates User Consent. An auth_value of 2 means acceptance. This should do for most use cases.

With the above, TCC’s database can be easily modified, and even at runtime:

sqlite3 /private/var/mobile/Library/TCC/TCC.db "INSERT INTO access VALUES('kTCCServiceMicrophone','com.vonbruno.micfree',0,2,2,1,NULL,NULL,NULL,'UNUSED',NULL,0,1643473845);"

Core Location on iOS

A script can be found at on GitHub.

SCC does not manage the location permission. Instead, the location manager on iOS is called Core Location. Before making edits, you should ensure to stop the associated service as follows:

launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist

Online material from the SANS institute shows where the Core Location service saves its settings:

/private/var/root/Library/Caches/locationd/clients.plist

This is nothing more than a binary plist file that can easily be modified. For example, the Wetherspoon app can be granted location access by changing the existing entry for this app to the following:

<key>com.jdwetherspoon.jdwetherspoon</key>
    <dict>
        <key>Authorization</key>
        <integer>2</integer>
        <key>BundleId</key>
        <string>com.jdwetherspoon.jdwetherspoon</string>
        <key>Executable</key>
        <string>/private/var/containers/Bundle/Application/16B5D594-5E91-4118-B943-89D415B52E1E/Wetherspoon.app/Wetherspoon</string>
        <key>Registered</key>
        <string>/private/var/containers/Bundle/Application/16B5D594-5E91-4118-B943-89D415B52E1E/Wetherspoon.app/Wetherspoon</string>
        <key>SupportedAuthorizationMask</key>
        <integer>7</integer>
        <key>Whitelisted</key>
        <false/>
    </dict>

Having made all necessary changed, we can restart the location service:

launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

More information on how to edit the location settings can be found here.

Concluding Notes

While most permissions are addressed by this guide, the notifications and access to the local network need further work. These should, however, not be essential for observing apps’ data flows.

UPDATE: The notification permission has been addressed here now.

UPDATE 2: The notifications permission has been addressed here now.

UPDATE 3: The local network permission has been addressed here now.

I’d also like to thank Aniketh Girish who motivated me to look into this problem again, after it had been plaguing me for a long time in my research..

This has been my first technical article on this blog. Let me know if you enjoyed it, and if you’d like to see more such articles in the future. Contact details below.