logs

Ok Internet, Lets Test this APFS Plaintext Password Bug Properly

There has been some confusion (myself included) on what is vulnerable to this bug and what isn't. Some folks can replicate and some cannot - so I think its high time to test this properly to see what versions and scenarios are affected by this bug.

The table below is sorted by macOS version - I'm just testing 10.13.x here. (If you happen to get it to leak the password on 10.12.x please let me know.) I'm also organizing by disk formatting scenario since I believe this is where most of the confusion comes from.

APFS encrypted volumes can be created on the disk level as well as the volume level and it truly seems to make a difference. Please also test if you find (or don't find) the results in the Unified logs and/or the install.log or neither (and god forbid any other locations you might come across!). I'm also consistently using the "Erase" button versus the "Partition" button.

If I am missing a certain scenario that you think should be added please let me know. If you disagree with the current findings - also let me know (I will also expect screenshots/videos from you to be sure we're on the same page.) I have tested 10.3.3 (host system) and 10.13.4 (VM) but would love someone to sanity check me - I've been wrong in the past!) I would have done more testing on different versions but have a limited set of systems as I'm traveling right now.

I will update the spreadsheet below as necessary.

For previous related blogs see here and here.

YAY TEAMWORK!

pay attention to me cat GIF-source.gif

OMG, Seriously? - APFS Encrypted Plaintext Password found in ANOTHER (More Persistent!) macOS Log File

UPDATE: PLEASE HELP ME TEST

At some point you just need to stop looking and be blissfully ignorant...this was not one of those days. 

In and update to my previously updated blog article, I have found another instance where the plaintext password was written to system logs. This time I found it in more persistent log. This is actually a worse problem than the one I previously reported on.

The previous examples were found in the unified logs which can hang around for a few weeks, this new example stores the exact same information in the system's /var/log/install.log. I have found that the install.log will only get wiped out upon major re-installation (ie: 10.11 -> 10.12 -> 10.13), therefore these plaintext passwords will hang around for quite a bit longer than a few weeks!  I had entries dating back to when I originally installed High Sierra on this system back in November of 2017! 

Twitter user @sirkkalap, was unable to re-create what I previously reported on. I finally got some time this afternoon to re-test. As it turns out, I was unable to re-create my results from 03/24. I assumed that at some point in the past few days a silent security update was pushed out. I went to my install.log file to investigate further. As far as updates go - the only thing that has potential to be the cause of the fix is a GateKeeper ConfigData update v138 (com.apple.pkg.GatekeeperConfigData.16U1432). I have not investigated if this was the true cause. I have not updated to 10.13.4 yet, this was on 10.13.3.

During this investigations I was VERY surprised to see the same diskmanagementd logs that I had found in the unified logs. Why are they logged in the software installation log at all, I have no clue. It makes absolutely no sense to me.

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!

New macOS Sierra (10.12) Forensic Artifacts – Introducing Unified Logging

I know its been a while since I've last posted - I've been hard at work delving into macOS Sierra and iOS 10 to add new artifacts into my course. Here is something new that macOS Sierra has to offer us forensic analysts!

macOS Sierra (10.12) introduced a new logging mechanism called Unified Logging. The developer reference document  states that the same mechanism will be used for iOS 10, tvOS 10, and watchOS 3 as well.

The developer docs also state that unified logs will take the places of Apple System Logs as well as Syslog which is what rely on quite heavily for log analysis on 10.11 and older systems. As of 10.12.1, these logs still exist in /var/log so don’t discount them just yet. (Also as far as I know, Audit logs are still fair game.)

The unified logs are stored in two directories:

  • /var/db/diagnostics/
  • /var/db/uuidtext/

The first file path (/var/db/diagnostics/) contains the log files. These files are named with a timestamp filename following the pattern logdata.Persistent.YYYYMMDDTHHMMSS.tracev3. These files are binary files that we’ll have to use a new utility on macOS to parse them. This directory contains some other files as well including additional log *.tracev3 files and others that contain logging metadata. The second file path (/var/db/uuidtext/) contains files that are references in the main *.tracev3 log files.

The new utility used to interact with these log files is simply called ‘log’. The ‘log’ command can be used to do everything from collecting, removing, configuring, and reviewing logging data. The new ‘Console’ application can be used to view logs in real-time (volatile logs) but you may find it easier to use the ‘log’ command to view log historically or those that are extracted from another system.

The ‘log collect’ command can collect records from a certain timeframe, log size, or type into a *.logarchive archive bundle. *.logarchive files can be imported into the Console application.

The ‘log show’ command will parse the records from the binary log files either from a specific *.tracev3 file(s) or from a *.logarchive bundle . A user can filter on different predicates filters or time frames. It is worth noting that this command by default will not show you “info” or “debug” messages – be sure to keep that in mind. You can choose between different outputs as well including syslog or JSON styles.

Additional References:

  • https://developer.apple.com/videos/play/wwdc2016/721/