Monday 19 September 2022

iOS 16 - "Paul unsent a message." ... OR DID HE?!

 With the release of iOS 16, there have been a lot of people talking about Apple's decision to allow for iMessage users to either unsend or edit a message. There are a lot of potential nefarious uses for this data, but what does all of this mean for forensics? 

This post won't be breaking down a lot of the standard database storage for unsent and edited messages as I have already covered that over on the Magnet Forensics (my day job) blog which can be found here. I'll give you some TL;DR information about the features below as well: 

  • Unsending and Editing messages are time locked. 
    • Unsending a message must be done within 2 minutes from its sent date.
    • Editing a message must be done within 15 minutes from its sent date. 
  • You can only unsend or edit a message you send.
  • It's only for iMessages (sorry Android users)
  • Both unsent and edited messages blank out the text column of the messages table in the sms.db.
  • Both unsent and edited messages have a unique timestamp to show when they were modified. 
  • Edited messages keep a "version history" with each edit having its own timestamp. 

We can track the edited messages within the database no matter how many times they edit the message. This is great! But unfortunately tracking the unsent messages are more difficult. Luckily, we have some more recent finds within the iOS file system world that can help us locate these "unsent" messages. 

Messages that are "unsent" are supposed to be deleted from databases on any device that is part of the conversation running iOS 16. It's also known that messages that are "unsent" are not impacted on devices that are not running iOS 16 or macOS 13. 

So where can we look for the contents of these unsent messages? It goes back to our favorite words in forensics "it depends" but here's a short list: 
  • sms.db-wal
  • KnowledgeC.db
  • Biome/AppIntents
  • Notification Events
Here's my test. I worked on two devices running iOS 16 and then did some "unsent" messages between the two. One of the unsent messages contained a specific keyword "Madison." When doing a byte-level search for the word I uncovered it in a couple of places. 

SMS.db-wal
Results: Unsuccessful
The easiest get is probably not as easy as one might think. Since the row itself isn't deleted when a message is unsent, and there's such a short timeframe unsend the message, the amount of time the change will live inside the -wal file is small. It's going to be unlikely that the data will get stuck in the main database after being unsent as well considering you can't go back and unsend a message hours/days/weeks later once the data has been fully committed. 

KnowledgeC.db
Results: Parsing - Unsuccessful // Carving - Successful
The KnowledgeC.db can store text messages as part of the AppIntents that are tracked within. However, one thing that was found is that when a message is unsent, it will reach back into the KnowledgeC.db file and purge that record relating to the AppIntent. 
A key word search against the database did show that the original message was present at one time within it. 

Biome/AppIntents
Results: Successful
The path /private/var/mobile/Library/Biome/streams/public/AppIntent/local path stores a 'SEGB' file as it's been called. This file stores protobuf records that can store data relating to Apple's application intents tracking even if they have been removed from the KnowledgeC database. This information makes it a prime location for recovering deleted SMS messages, as well apparently as unsent messages. By parsing the protobuf data (or using a tool that can do it for you), you can recover the date and time of the message, its content, and its sender/recipient. 



Notification Events
Results: Successful
Another 'SEGB' file found within /private/var/mobile/Library/DuetExpertCenter/streams/UserNotificationEvents/local/ also stores notification events for the operating system. This is another location to look for potential messages that have been delivered (as long as the content of the notification is cached). The problem with the notification data here is that the timestamps won't always line up with the original "unsent" message in the database. While this can be good for finding the CONTENT of these messages, its not great for corroboration.

So based on the information above, how do we figure out that a message was unsent and track the content? 

Here's the original message parsed from the database. As you can see, there's no message content for the record.

Here's that SAME record, only parsed from the AppIntent information. 


The time and dates match, and within the AppIntent data you have the actual content. 


 What about edited messages? Edited messages can be tracked within the same categories as the above. The content of the message in the database is still blanked and the data stored within the attributedBody or message_summary_info columns depending on how many edits you're trying to track. Each individual edit becomes a separate message as far as the Application Intents or Notification Events are tracked so expect to find each individual edited message in either of these two sections. Since the messages are not flagged to be deleted, the edited messages will still be tracked within the KnowledgeC.db unlike the unsent messages. 

As a reminder, "deleted" or should I say "recently deleted" messages are still within the main database until they are either deleted a second time or hit their 30 day period to be deleted. Further testing will continue to search for these messages after they are truly purged to see if they stay in their other areas as mentioned above. 

As iOS 16 continues to roll out and more people talk about the unsent/edited issue, it's going to be crucial to keep our fingers on the pulse of this information to figure out what we can do forensically. My mindset is that if you ever get a message and you are worried it might disappear, screenshot it and MAKE SURE the time is visible. At least then you have some sort of proof to help match with the database records. 


No comments:

Post a Comment