What iOS SDK fingerprinting features are unique per device? - ios

There is a lot of interest in digital "fingerprinting" for mobile devices. Given some recent moves from Apple: http://techcrunch.com/2014/02/07/openidfa-a-solution-to-idfa-related-app-store-rejections-debuts/ there is some increased interest.
One can do this by combining features that make the device somewhat unique. This fingerprint does not need to be totally unique or 100% stable, just unique and stable enough to match a click to an app launch within a small period (say 1 week).
Here is a closed source version:
https://github.com/ylechelle/OpenIDFA
And an open source one (from me):
https://github.com/mcorner/ActuallyOpenIDFA/
There are a number of features used here:
https://github.com/mcorner/ActuallyOpenIDFA/blob/master/aoi/aoi.m
Some obvious features are not usable without user permission (location, contacts) and therefore can't be used with advertising. Others are not usable across apps (like the vendorID), thus aren't usable from connecting a click in one app to a launch of another. Others are not particularly stable (like IP).
What other features of iOS might be useable?

There are several different approaches on how to generate a unique fingerprint of an ios device. The UUID+Keychain approach mentioned by davbryn is one of them, but not the strongest.
You may have a look at the app belonging to my research project at the University of Erlangen-Nuremberg in Germany, which's aim is to identify an ios device uniquely:
https://itunes.apple.com/us/app/unique/id835879646?mt=8
In our research project we follow the approach called "device fingerprinting". The app explains in detail, what it does in order to identify your device.
After i have finished my master thesis, there will be a paper about this topic.

Best I've managed is to create a UUID and store it in keychain. Works well enough to track a user, but you can't track after an OS reinstall etc

Related

Is DeviceCheck or indentifierForVendor safe?

I am planning on using DeviceCheckor indentifierForVendor to ensure that the same device is not being used to redeem multiple times the same gift (free money for example sake) offered to new users. I am wondering however, if it is possible to trick this system on a jailbroken device? Or using a custom simulator or a botnet (do iOS botnets exist?)?
I haven't tried it myself, but I think it is possible to change the bundle identifier, resign the app and side load it to your device.
This will change the change the identifier for both DeviceCheck and indentifierForVendor.
Now, for this to really affect you, the user needs to get a hold of the ipa. Which is getting increasingly difficult with the newer versions of iOS.
If you are interested in trying what I've discussed, refer to this link.
https://coderwall.com/p/qwqpnw/resign-ipa-with-new-cfbundleidentifier-and-certificate
And probably AirSign (much easier). Its a paid app for the Mac. https://www.macupdate.com/app/mac/51845/airsign

Block app install from AppStore and app delete using Swift

I am aware that we can block safari content using swift code. I am interested in finding out if we can restrict install of certain apps from AppStore using similar approach ?
Also, is it possible if we can restrict a user from deleting the app from device (not from phone settings but from code) ? Even if Apple does not allow that to publish such app, I am looking for a solution as a part of research.
There are two things you mentioned.
First, can restrict install of certain apps from AppStore
Using Swift code I feel there are no Public API provided by Apple for the developer till now but there is a similar way that is called Device Enrollment Program.
The Device Enrollment Program (DEP) is part of the Apple Deployment
Programs (ADP), which help businesses and educational institutions
easily deploy and configure iOS and OS X devices. DEP provides a fast,
streamlined way to deploy institutionally owned iPad and iPhone
devices and Mac computers that are purchased directly from Apple or
participating Apple Authorized Resellers or carriers.
For more visit this developer guide.
Second: restrict a user from deleting the app from device
Same response for that, till now no Developer API, but lets say if we see this as a part of research and we develop some POC still, it does not make sense for me at all (It's my device and I install the app for making my life easy and better if I don't want to use it anymore, I need an option to delete it) and I don't think so this will be possible in future as well because the USP for iOS device is user experience and we can't make this like that.
I also want to hear something from others and if possible give the use case why you are looking a solution like that.
I hope this will help.

How do I accurately detect the presence and/or absence of a jailbreak in iOS?

After I attended a programming class, one of my friends showed me an app that would not allow him get past the first screen due to his jailbroken iPhone.
Since then I have been intrigued as to how the app was able to detect the jailbreak without being blocked by apple and, being the anti-jailbreak advocate that I am, I kept fruitlessly trying to find a reliable way to detect a jailbroken iOS device to prevent people from cheating if I ever decided to release a game on the App Store.
Does anyone know of a reliable method(s) to detect a device's jailbreak status that cannot be easily bypassed by said jailbroken device?
EDIT: based on recent comments, I would just like to clarify that the intention of this post is to share the knowledge I gained from finding that article, and to provide a place where other users can contribute their methods of jailbreak detection.
The other day I stumbled across an article containing the exact answer I was looking for.
From https://www.theiphonewiki.com/wiki/Bypassing_Jailbreak_Detection
While there are countless ways apps can implement checks for jailbroken devices, they typically boil down to the following:
Existence of directories - Check your file system for paths like /Applications/Cydia.app/ and /private/var/stash, amongst a handful of others. Most often, these are checked using the -(BOOL)fileExistsAtPath:(NSString*)path method in NSFileManager, but more sneaky apps like to use lower-level C functions like fopen(), stat(), or access().
Directory permissions - Check the Unix file permissions of specific files and directories using NSFileManager methods as well as C functions like statfs(). Far more directories have write access on a jailbroken device than on one still in jail.
Process forking - sandboxd does not deny App Store applications the ability to use fork(), popen(), or any other C functions to create child processes on non-jailbroken devices. sandboxd explicitly denies process forking on devices in jail. if you check the returned pid on fork(), your app can tell if it has successfully forked or not, at which point it can determine a device's jailbreak status.
SSH loopback connections* - Due to the large portion of jailbroken devices that have OpenSSH installed, some apps will attempt to connect to 127.0.0.1 on port 22. If the connection succeeds, it means OpenSSH is installed and running on the device, therefore it is jailbroken.
system() - Calling the system() function with a NULL argument on a device in jail will return 0; doing the same on a jailbroken device will return 1. This is since the function will check whether /bin/sh exists, and this is only the case on jailbroken devices.[1]
dyld functions - By far the hardest to get around. Calling functions like _dyld_image_count() and _dyld_get_image_name() to see which dylibs are currently loaded. Very difficult to patch, as patches are themselves part of dylibs.
*Only a very small number of applications implement this (as it is not nearly as effective as the others)
the above passage was edited for brevity
I figured I'd post this here as a knowledge-share for those app developers wondering how that one app was able to successfully implement jailbreak detection when all other attempts at detecting jailbreak get rejected by Apple.
Blocking all jailbroken users probably wouldn't help you fight app piracy if you released a game on the App Store because it would force them to get a pirated version of the game to be able to play (instead of giving them the possibility to pay to play the game).
What you'd want is to check if the game is a legit version off the App Store. But even that could be potentially patched by the guys who crack games to release them...
You can check if the currently running executable is encrypted, which is a good way to know if the app has been pirated by looking at this answer.
Otherwise if it's a free game with in-app purchase, doing receipt validation helps block out most tweaks that get around paying for in-app purchases.
But there's definitely no way to absolutely block out app piracy.
You could always mention how had you worked on that game within the game... That could convince a few persons to pay for the legit version of the game.

iOS 8 How to get Serialnumber

In our applications the user autentications is based on the serial number.It seems that in ios 8 it is not possible to get the serialnumber.Is any other way?
Thanks in advance.
Apple deprecated access to a unique-per-device UUID (known as uniqueIdentifier as of iOS 6. As of iOS 7, they also blocked access to MAC querying the address, and other sorts of unique identifiers. Sometime between iOS 6 and today, they started rejecting any application that accesses this property.
There are two replacement APIs that might help: on UIDevice, there is identifierForVendor, that is consistent across your apps. And there is also an entire framework, AdSupport, who's job is to provide an identifier that can be used for advertising networks. This identifier has the limitation of people can change it whenever they want, so you cannot rely on it being consistent across multiple launches.
The hint Apple is trying to pass on here is "you cannot consistently, uniquely identify people per device across multiple apps that are not your own".
In addition to zadr excellent explanation I would like to not iCloud as another possible solution:
Simply store a value (as file or key-value) in iCloud. Only disadvantage of this approach is, that you will have to add the iCloud entitlement to your app if your app does not use iCloud yet. On the other hand there are some advantages
Very little / none additional effort necessary if your app already uses iCloud
No additional Frameworsk like AdSupport necessary
The saved value will be consistent between devices and app re-install
More than one app can share the ID by using the same iCloud (ubiquity container)
Of course in some cases this might be a little overdone but in other this can be a handy solution.
I would recommend using uniqueIdentifier as suggested above but saving in keychain. This way its reliably available to you all the time, and can be used to track the user.

Installed App Sizes Vs Appstore app sizes

Here is a question that had been bothering me. The other day I checked my wife's phone and pinterest app was eating up 2 GB of space while the actual app in the appstore is 26.8 MB. I know there must be user / log / crash data that is dumped in its apps document directory but that got me thinking how many other apps on her phone had large amount of user data stored compared to what the app size is in appstore.
So here are my questions of how to do all this using objectiveC
Sample Xcode iHasApp display's all the available apps installed on a device. Is there a way I check how much space they are taking in GB/MB etc?
Is there a way I can go query that app build size in appstore and tell the user hey its only X MB in appstore?
I know I can get to all the app installed on a device is there a way I can check when was an app last launched or used by a user?
Can I check how much space photo / video and music is taking up?
What I am trying do in the end is to see if I can make an app that shows user what they got installed on their device and make some informed decisions themselves.
So far all I am able to find is how to check total used and free space on a device and get a list of all apps installed.
Sample Xcode iHasApp display's all the available apps installed on a device. Is there a way I check how much space they are taking in GB/MB etc?
No. The APIs being used by iHasApp can only be used to check whether selected applications are present -- basically, all you get to ask "is ThisApp installed?", and you can build up a partial list of installed applications by running that check for a large number of common applications.
There is no way to get launch or disk usage information for other applications. I'm not sure last launch is even tracked at all by the device.
With this in mind, most of your other questions are irrelevant. It is not possible to do what you're after from an iOS application.

Resources