iOS

Pincodes, Passcodes, & TouchID on iOS - An Introduction to the Aggregate Dictionary Database (ADDataStore.sqlite)

Have you ever wondered how Apple can put out statistics such as “The average iPhone is unlocked 80 times a day”? How the heck do they know?

Now I do not know for sure that they use this database, however I'd consider putting some cash down on this bet. The Aggregate Dictionary database aggregates (hence the name) certain features of the iOS operation system.

This database is located on the physical device in the path below, and it is not backed up in iTunes/iCloud backups.

  • /private/var/mobile/Library/AggregateDictionary/ADDataStore.sqlitedb

It is worth mentioning here, the ‘dbbuffer’ plaintext file) in this same directory – is exactly what the filename suggests, a buffer for the database. Worth looking at for entries not yet written into the main database.

The ADDataStore.sqlitedb aggregates data on a 7-day per-day basis (first day in, first day out). You will generally see the last weeks worth of data. The day is stored in the column ‘daysSince1970’ which can be converted to human-readable time by using the SQL date function as shown below. It is worth noting this data is being stored in UTC.

I’ve known about this database for a while but have not had the chance to really dig into it. Recently, a reader emailed me about a case they were working on and wanted to know if the passcode was turned on or off on a specific day. Luckily this investigator had a physical acquisition to analyze and the specific day was in the last week of when the acquisition was created. The physical acquisition has many more of these logging databases are available for analysis too! - Want to see more about these awesome databases, check out my iOS of Sauron presentation.

The ADDataStore.sqlite database stores all sorts of seemingly odd settings in the ‘key’ column of the ‘Scalers’ table. The key that I was interested for this readers inquiry was the ‘com.apple.passcode.PasscodeType’ key which stores the passcode type. The ‘value’ column stores a numerical representation of the passcode type last used during each day (UTC time). If the user changes their passcode type throughout the day, it will store the last one configured.

I have enumerated the following passcode types. The example device show above used the 6-Digit passcode, then recently switched to a Custom Numeric passcode.

  • -1 = 6-Digit
  • 0 = No Passcode
  • 1 = 4-Digit
  • 2 = Custom Alphanumeric
  • 3 = Custom Numeric

We can take a look at how many times the device was unlocked successfully or unsuccessfully by using the keys ‘com.apple.passcode.NumPasscodeEntered’ and ‘com.apple.passcode.NumPasscodeFailed’, respectively. The user was mostly successful inputting their passcode, but put the wrong passcode in once (highlighted in pink).

Hrm. Those values look small – the user is probably using TouchID instead of manually entering their passcode. TouchID allows users to enroll up to five fingers to unlock their devices. Note: They still need a passcode to do this, but it allows the user to have a more complex passcode because they can use their enrolled fingerprints to unlock the device for convenience and general usability

Looking at the ‘com.apple.fingerprintMain.templateCount’ key we can determine how many finger “templates” have been enrolled. The example tells us that four fingerprints were enrolled.

By default the enrolled fingers are named ‘Finger 1’, ‘Finger 2’, and so on as shown below. (Nerd Note: When you are in this screen as a user of the device you can check if a finger is enrolled because it will be highlighted in gray as shown - well, I thought it was neat.).

*** WARNING - RESEARCH BELOW IS ONGOING - READ AT YOUR OWN RISK ***

...just kidding...its actually kinda interesting.

I did want to show the complexity of this database therefore I decided to post this as some readers might find it interesting, however don't take my word on this - I can be wrong. In encourage everyone to do their own testing!

This is where it becomes less clear and more research will need to be done. In the Scaler table at any given moment there are many entries that contain the keyword “fingerprint” for all sorts data. I've listed some of the more interesting keys below.

  • com.apple.fingerprintMain.enabled – Binary value – 1 = Enabled, 0 = Not enabled
  • com.apple.fingerprint.countimagesForProcessing – This appears to be the number of times that TouchID was used (whether or not it was used to unlock the device).
  • com.apple.fingerprint.match.autonomousAttempts & com.apple.fingerprint.match.attempts - Match attempts (Not entirely sure the difference as of yet – I think one may be for unlocks (autonomous) and others for other TouchID functions.)
  • com.apple.fingerprint.unlock.touchesTouchIDNotAllowed – How many times a TouchID was attempted but not allowed for some reason, perhaps fingers were the wrong ones or greasy from a hamburger! (c’mon, we’ve all been there)
  • com.apple.fingerprint.unlock.bioLockouts – I found this key to be incremented when I attempted to unlock the device with the wrong finger too many times.
  • com.apple.fingerprint.unlock.passcodeUnlocksNonMandatory – The user put in the passcode, however they were not required to do so.

Enrolling Fingerprints

  • com.apple.fingerprint.enroll.attempts – Fingerprints “enrolled”
  • com.apple.fingerprint.enroll.popup.tooLittleMoves – Apparently I didn’t move my finger enough when enrolling. 

TouchID Passes – Various keys that I’ve seen that show the specifics of how a TouchID match was passed. Many of these are hard to test to explain.

  • com.apple.fingerprint.match.autonomousPassesAfterHomeButton – Incremented when a match was made after the home button was pressed.
  • com.apple.fingerprint.match.autonomousPassesAfterPowerButton – Incremented after boot when TouchID was used (after passcode of course).
  • com.apple.fingerprint.match.autonomousPassesButtonDown – Incremented after the home button was pressed or “pressed” if you have an solid state button.
  • com.apple.fingerprint.match.autonomousPassesButtonLifting
  • com.apple.fingerprint.match.autonomousPassesButtonUp
  • com.apple.fingerprint.match.autonomousPassesButtonUpWithPressureMitigation
  • com.apple.fingerprint.match.autonomousPassesHumid – I assume this one has to do if you are a live body or not.
  • com.apple.fingerprint.match.passesButtonDown
  • com.apple.fingerprint.match.passesButtonUp

TouchID Fails – On the flip side, if a fingerprint fails – we have many keys with many reasons, many with the same characteristics as above but failed.

  • com.apple.fingerprint.match.autonomousFailsBadImageBadBlocks
  • com.apple.fingerprint.match.autonomousFailsCancels
  • com.apple.fingerprint.match.autonomousFailsFingerOffAfterHomeButton
  • com.apple.fingerprint.match.autonomousFailsNoMatchAfterHomeButton
  • com.apple.fingerprint.match.autonomousFailsNoMatchAfterPowerButton
  • com.apple.fingerprint.match.autonomousFailsNoMatchButtonDown
  • com.apple.fingerprint.match.autonomousFailsNoMatchButtonLifting
  • com.apple.fingerprint.match.autonomousFailsNoMatchButtonUp
  • com.apple.fingerprint.match.autonomousFailsNoMatchButtonUpWithPressureMitigation
  • com.apple.fingerprint.match.autonomousFailsNoMatchHumid – I guess I might have been a bit under the weather? ;)
  • com.apple.fingerprint.match.failsNoMatchButtonUp
  • com.apple.fingerprint.match.failsNoMatchHumid

Getting specific, TouchID unlocks appear to be recorded in the ‘com.apple.fingerprintMain.unlock.unlocksByFinger*’ keys.

As far as as I can tell the keys containing “unlocksByFinger” (colored below in yellow) contain the actual number of unlocks, however in the example below the total unlocks were 11, not 22. I am not sure why there are two entries – I’m sure they record different items, however I cannot find documentation to sort out each one. I would rely on the ‘com.apple.fingerprintMain.unlock.unlocksByFinger#Fail’ entries. (As an aside, it’s worth noting that if you get ‘Finger2’ entries, they have an ‘s’ appended ie: com.apple.fingerprintMain.unlock.unlocksByFinger2Fails, maybe a strange type in the code?)

The ‘fail’ in the key would seem to suggest it records “failed” attempts however my testing shows these are in the green highlighted ‘unlocksCanceled’ entries instead.

What’s the ‘QT’ stand for? I have no idea. I tried looking through Apple documentation to find out, but I’ve got nothin’. Suggestions are welcome!

You might think, “Hey, I see Finger 0, Finger 1 in there – that must be the unlocks for each enrolled fingerprint right?”. That’s what I thought, however that was not the case in my testing. In my tests no matter which finger I unlocked the phone with it would be added to the ‘Finger0’ count.

Another key that looks interesting and related are the ‘com.apple.fingerprint.sortedTemplateMatchCount#’ keys. I would have thought these would be equal to the number of times the fingerprint template was used, however it appears that is not the case. I can try two different fingers (each enrolled) and sometimes they show up under the expected number (ie: finger 1 = com.apple.fingerprint.sortedTemplateMatchCount1) and sometimes it won’t – however one of them will increment. Not sure what is going on here.

In conclusion - I’ve only barely touched one of the tables in this database. There is so much data in this database! There is also the ‘DistributionKeys’ and ‘DistributionValues’ tables which store more numerical-based stats versus the incremental/binary stats of the 'Scaler' table. Try the following SQL query on your own and see what you find!

select 
DistributionKeys.key,
date(DistributionKeys.daysSince1970*86400,'unixepoch','localtime') as daysSince1970,
DistributionValues.secondsInDayOffset,
DistributionValues.value
from DistributionKeys
left join DistributionValues on DistributionKeys.rowid = DistributionValues.distributionID
whereDistributionKeys.key like '%unlock%'

I will hopefully be putting out a few more blog entries on other data found in this database (and other databases!). I will of course post updates to this research if and when I get the chance to do it! Stay tuned!

Mac News & Updates - 08/11/16

Blogs

Papers

Presentations

Tools

Malware

My Upcoming Classes & Presentations:

I’ll be teaching my SANS FOR518 – Mac Forensic Analysis class at the following conferences, there are some bonus @Night presentations as well! I hope to see many of you at one of these conference some day!

[LINK] SANS Virginia Beach (Aug 28 – Sept 2) - This one is coming up soon! This conference is super chill and relaxed, and you get to watch fighter jets from the beach!

  • @Night – The iOS of Sauron- How iOS Tracks Everything You Do

[LINK] SANS Network Security (Sept 12 – 17 in Las Vegas, NV) - Missed Vegas for Blackhat or DEF CON? Didn't get enough of it? Join me...if you're feelin' lucky! :)

  • @Night – The iOS of Sauron- How iOS Tracks Everything You Do

[LINK] SANS DFIR Prague (Oct 3 –  8 in the Czech Republic), Stay for the Summit on the 9th!

[LINK] SANS San Francisco (Nov 27 – Dec 2) 

  • @Night – iOS Location Forensics

[LINK] SANS Cyber Defense Initiative (Dec 12 – 17 in Washington, DC)

  • @Night – The iOS of Sauron- How iOS Tracks Everything You Do

[LINK] SANS Cyber Threat Intelligence Summit (Jan 25 – 30 in Arlington, VA)

  • @Night – The iOS of Sauron- How iOS Tracks Everything You Do

BSidesNOLA Preso - The iOS of Sauron: How iOS Tracks Everything You Do

I was lucky enough to again be selected as a speaker at one of my favorite BSides conferences, BSidesNOLA (4 years running!). This one has THE BEST speaker party. Backyard tiki bar, homemade gumbo, boiled crawfish, jambalaya, bananas foster. If you want to speak at a fantastic forensics heavy security conference, I highly recommend this one!

I presented my newest presentation "The iOS of Sauron". This is a presentation that I will be continuously researching and updating so be sure to visit again to get the newest version. I hope to also write various blog articles going into more depth on some of the topics covered.

This is very much a pattern-of-life presentation - if you have a particular "pattern" you are looking for - let me know. If you think its important, I bet someone else does as well!

You can find the presentation here.

iOS Imaging on the Cheap!

Many analysts and researchers work with a very limited budget, many of us can’t get those $uper expen$ive commercial mobile acquisition and analysis tools. I’ve been asked many times, “What tools can I use to analyze iOS with $0 in the budget for tools?”

With newer iOS devices that come with newer operating systems, the ease of forensic access to iOS devices has been quite limited. Every commercial tool has the capability to provide a logical dump of the phone (give or take the caveats of access to PIN/Passcodes or the reboot/unlock status of the devices of course!). This data dump may be fine for some analysts but I have found that it doesn’t quite provide me with the data that I’m looking for. I needed to find a different way of doing things.

 

Breakin’ Jails

Whether or not you think this is “forensically sound” or whether your legal policies allow you to do so I want to at least offer this method as a potential capability.

You should absolutely discuss this with the people you need to before you use this method operationally because, among other reasons:

  • It will change the data on the phone, but of course data is always changing on mobile devices.
  • The jailbreak software can be “shady” at best.
  • You are breaking the security of the system. This is kinda the point of a jailbreak after all.
  • The jailbreak process may not go as planned, and you could destroy the data on the device (or brick the device itself!). Use this method only as final option to an exhaustive effort to get the data you need. If a logical backup gets you what you need then absolutely go with it.
  • The jailbreak can potentially void the warranty, however restoring the phone to a current, clean OS though iTunes will remove the jailbreak.

Remember - Documentation is key! Sometimes to get to the files we need we have to Jailbreak - there is really no other way around this problem.

Of course if it is for research and testing – and it’s a device you own – go nuts!

 

Jailbreak Software

Jailbreaking software is available for most iOS versions/device combinations. At the time of this writing iOS 9.1+ does not have a jailbreak available. One of my favorite sites to determine what jailbreaks are available for a specific device and iOS combination is https://www.theiphonewiki.com/wiki/Jailbreak. New jailbreaks can come out anytime from before an iOS update comes out to months afterwards - there is no guarantee that a jailbreak will even be available when you need it. Sometimes you just have to wait it out.

Popular jailbreaks for iOS 8 and 9 are TaiG and Pangu, available at the links below. Jailbreak instructions can be searched for easily and depends on the jailbreak software you are using.

In preparation for the jailbreak you will need the password for the device as some jailbreaks require you to remove this password. Also as part of jailbreak “best practices” some jailbreaks require the device to be backed up, in airplane mode, Find My iPhone turned off, and without a password. Be sure to read the directions carefully - each one works a little bit different.

A word of warning here - make sure you go to the legitimate link for the jailbreak software, otherwise you might be tricked into paying a fee. (As of this writing, most public jailbreaks are free - we can hope the iOS jailbreak creators continue this trend.)

 

Utility Install

Once jailbroken, you need to install SSH to make imaging and analysis possible.

Cydia is usually the tool of choice for this process as most jailbreak software includes and installs this application. OpenSSH is the preferred SSH utility for iDevices, find the OpenSSH application and install it. 

You may need to “Refresh” the Sources before searching for it. Go to Sources tab in Cydia and Press “Refresh”.

Dump the Device’s Data

Accessing the device is easy using SSH over WiFi, but when we copy data from the device that could be a bit slow. Instead, we are going to use a tool called iproxy to access the device over USB using the usbmuxd capability. To do this, we are going to install a package called iproxy, part of the libimobiledevice suite of utilities. This installation can be done using brew if you prefer. Please review the additional utilities available, many are very useful!

Connect the iDevice using a USB cable. iproxy creates a usbmuxd (USB) connection from an iDevice to the system by listening to SSH connections and forwarding them to another port. The iproxy usage is as follows:

iproxy LOCAL_TCP_PORT DEVICE_TCP_PORT [UDID]

In the screenshot below, I’ve connected my iPhone via USB cable to my system and ran iproxy using ‘4242’ as my local port and ’22’ as the device port (SSH can usually be found port 22).

The next step is to SSH to the iDevice. We do this using the built in SSH client on OS X, one change we need to make is to specify the port we are going to use. In this case I will use port 4242 as configured from iproxy using the ‘-p’ flag. I will be logging in as ‘root’ on 127.0.0.1. I could also login as ‘mobile’, the devices ‘user’ account – by why limit myself! I didn’t jailbreak for nothing! The default password for both ‘root’ and ‘mobile’ accounts is ‘alpine’. I highly recommend changing both passwords immediately if you are going to be using this device continuously for research (use the passwd command).

This will dump the user into their home directory, since I used ‘root’ I am in /var/root.

We could cd to “/” if we wanted to start reviewing files in the file system but we’re here to dump data. (In fact, you don’t have to SSH into the phone at all before you image – it’s really just a test to make sure everything is in working order.) Before we exit out of this SSH session, let’s look at the partitions of this device. We can do this two different ways; using the ‘mount’ command, or by viewing the /etc/fstab file.

There are always at least two partitions that are of forensic interest, a “System” and “Data” partition.

The “System” partition contains the operating system, ideally it should be read-only as shown in the /etc/fstab output (ro). However, since we jailbroke our devices we can actually write to it if we wanted. This partition is on the /dev/disk0s1s1 device and is mounted on “/”.

The “Data” or “User” partition contains the user data files, configurations, and preferences. From a forensic perspective this is our “gold mine”. This partition is on /dev/disk0s1s2 device and is mounted on “/private/var”. To get to the user’s (mobile) data in the file system in SSH and other tools we have to navigate to /private/var/mobile/.

We have a few options here to make depending on the type of data we want. We can make a full dd-style image of the whole disk (or each partition separately) OR we can get a tar bundle of files (per disk or per partition).

One item to be aware of here – encryption.

  • The “System” partition is unencrypted, whether you choose dd-style image or tar bundle is completely a personal preference.
  • The “Data” or ”User” partition does have a per-file encryption scheme (read about Data Protection here). Grabbing a dd-style image of this partition is going to be mostly useless as everything will be encrypted. (However you will get file system structure and metadata.) A tar bundle will be much more useful, even though you don’t get the unallocated space.*

*A note about unallocated space in iDevice – Due flash disks and how Data Protection works, even if you grab the unallocated space on an iDevice, there will likely not be much data available to carve or view in an unencrypted format.)

What I normally do is create a dd-style dump of System partition, and a tar bundle of the Data/User partition. 

Let’s first create a DD image of our System partition. (If you are following along, be sure to exit out of your SSH session with your device.) The command below will use SSH to connect to the device (using the specific port, in my case I chose 4242). It will ask for the device’s password, and immediately start imaging the System partition using the dd utility on the device.

We have provided it the input file (if=) /dev/rdisk0s1s1. We are using the rdisk here as we don’t have permission to access the active disk on /dev/disk0. We are using a block size (bs=) of 4k or 4096 bytes. Finally, using the pipe “|” we can output the image to our host systems ‘dd’ utility to an output file (of=) called system.dd.

ssh root@127.0.0.1 -p 4242 dd if=/dev/rdisk0s1s1 bs=4k | dd of=system.dd

This will dump the file into your current working directory. The prompt will not update, however you should be able to see that the system.dd is growing in size. This should only take a few minutes. For my iOS 9.0.2 device the System partition was just over 3G in size.

We can check to make sure we have an HFS+ image by running the following command. Using dd we are going to look at the third sector on the disk. We skipped the first two (by design, they are blank) to look at the HFS+ Volume Header in the 3rd one.

dd if=system.dd skip=2 count=1 | xxd

The “HX” in the first two bytes, followed by “HFSJ” show us that this is a Journaled HFS+ (Case sensitive) partition.

Now let’s get to the Data/User partition. We going to use nearly the same command, except we are going to change a few items. We will be using the tar command to place the logical files into a tarball. We are specifically going to grab only the files in the /private/var directory. (We could do the whole drive here from ‘/’, but we already captured the system partition using the previous command. Again, this is user preference.) Finally, we will redirect the output of this to a user.tar file on our local systems. Depending on the allocated data on the user space on the device this could take a considerable amount of time!

ssh root@127.0.0.1 -p 4242 ‘tar -cf - /private/var/' > user.tar

Once you have the data dump, you can analyze in the tool of your choice or extract the tarball into a read-only disk such as a DMG for easier analysis/transport.

For my uses I extracted the tarball into a directory using the following command. (Note: Some forensic analysis software may allow you to use this tar file as is, some do not.)

tar -xvpf user.tar -C user_untar/

Time to poke around! Have fun!