Recently, I was asked a question that had been raised about an unusual entry in iOS Messages. It was a great question, and, as usual with these types of one-off questions, I did not know the answer. So, as is the case many times when I do not the answer to something, I set out to test it and hopefully find an answer.
I like getting stumped like this. It gives me an opportunity to really deep-dive into something, generate test data, test theories, generate more test data, test more theories, and share what I find. It also helps when it comes to generating public images as I know I can include that particular thing in a future image.
Like more recent posts, this one is shorter than usual.
The question involved the iOS Messages database, sms.db. Another examiner was seeing entries in the messages table that had timestamps, but no text associated with the entries. If you have done iOS forensics before, you know this is not unusual. What was unusual was that the entries had item_type column values of four (4), something the examiner nor I recalled seeing before.
A quick check of my public iOS images found that these values existed in the iOS 13 images and when I checked the documentation I found the values were related to location sharing in the Messages app.
A few notes. First, to test this I used four phones: an iPhone 12 Pro and iPhone XS both running iOS 14.8, a first generation iPhone SE running iOS 14.3, and an iPhone 8 running iOS 15. Second, this applies to iMessages only. And finally, I thought it would be great to take a look at location sharing, in general, in in iMessages, so this article will encompass both types of location sharing.
As a side note, I discovered a hint about these messages in my Twitter history….back in July…from Sarah Edwards.
Not All Sharing is Equal
One thing I learned from testing is that not all location sharing in Messages looks the same in sms.db. There are differences between non-continuous, one-time location sharing and continuous, real-time location sharing, and the venue in which location is shared. So, this post will focus on the various situations in which a user could send or receive location data.
In Messages there are two types of location sharing: Send My Current Location (MCL) and Share My Location (SML). The former is a one-time transmission of a user’s location and the latter is the real-time, continuous transmission of a user’s location for a certain period of time determined by the user (one hour, until end of day, or indefinitely). See Figures 1 & 2.
For a user, sending & receiving a MCL looks just like messages being sent and received. When a user chooses to send MCL, the recipient (or recipients if it’s a group chat) gets a message. See Figure 3.
Forensically, it almost looks the same as receiving a message. See Figure 4 for the entries in sms.db.
The red box in Figure 4 encompasses the entirety of what is seen in Figure 3. The red arrows highlight the entries for the two MCLs in Figure 3. Scrolling over in the database finds the area in Figure 5.
The red box in Figure 5 highlights the same rows as those in Figure 4. Additionally, the column cache_has_attachments values are highlighted by the red arrows. A value of 1 indicates there was an attachment present. Now, see Figure 6.
The table mesage_attachment_join indicates that messages 98 and 100 (red box in Figures 4 & 5) have attachments that are documented in ROWIDs 5 and 6 on the attachment table. See Figure 7.
The path for the attachments (file name CL.locl.vcf – maybe “CL” stands for “Current Location”) indicate the files are Virtual Contact Files (.vcf), which are typically used to store and transmit contact information; however Apple is using them to transmit location data. As an example, I sent a MCL from my iPhone 8 running iOS 15 to my first generation iPhone SE running iOS 14.3. Figure 8 shows the contents of the .vcf file.
The nice thing about .vcf files is that they are human-readable, so they can be opened with any text editor/viewer. The green arrow points to the iOS version that created the file, and the purple arrow highlights the “name” (Current Location). The blue box contains a URL, that, when opened, will bring up the GPS coordinates that were used to populate the MCL (presumably the coordinates of the phone at the time the MCL was sent) in Apple Maps. The URL contains the actual GPS coordinates, so I’ve redacted the them here. Additionally, an examiner may find more data in the .vcf file than what is shown here.
That is the basics of MCL. Note that my testing found things were the same regardless if MCL was shared with an individual or within a group chat.
What about SML? Well, it looks a little different. See Figure 9 for how it looks to a user.
Figure 9 is from the iPhone 8 running iOS 15. The red box highlights the iPhone 8 receiving SML from an iPhone XS (different user), and the green box highlights the iPhone 8 sending SML to the iPhone XS. Note the system messages at 3:51 pm, 4:01 PM, and 4:06 PM (all times UTC -0400). Also note that in the red box, there is only a system message for SML stopping. Figure 10 shows how it looks in sms.db.
There is a lot going on here. The red box in Figure 10 highlights the same material as the red box seen in Figure 9. Note that there are two entries after the message 89 (“Copy. I’ll go first. Here comes a dynamic location”). The first entry represents when the iPhone XS started sharing SML with the iPhone 8, and the second entry represents when the iPhone XS stopped sharing SML. Note the value 2 (red arrow) in column handle_id represents the contact in the handle table (not pictured).
The green box contains the same same information as the green box in Figure 9. Just like the data in the red box, the two NULL values after after message 93 (“Alright. I’m going to share dynamic location.”) represent when the iPhone 8 started and stopped sharing SML, respectively. Note here that the handle_id value here is 0.
Also note the NULL values in the text coulmn. 🙂 Thank you Sarah for the clue!
Now see Figure 11.
Figure 11 contains the timestamps for the entries in the date column. The first line in the green box represents the message (“Alright. I’m going to share dynamic location.”), the second line represents the start of the SML action, and the third line represents the stopping of the SML action. In the red box we have the same thing (message, SML start and SML stop), but note that there was only one system message in the red box in Figure 9 (when SML was stopped). So, just be aware that while the system messages may not appear in the UI, the timestamps will still be present in the messages table.
Figure 11-A shows two more columns, share_status (blue box) and share_direction (purple box). A value of 0 in the share_status column indicates the SML was started and a value of 1 (red and green arrows) indicate it was stopped. A value of 0 in the share_direction column indicate the sharing was outgoing (shared with another party) and a value of 1 (purple arrow) indicates SML was incoming (shared by another party). See Figure 11-A.
Direction of sharing can also be determined from other columns, which will be discussed shortly.
Figure 12 highlights something important. Regardless of whether SML is shared or received, the value in the is_from_me column was always 0 in my testing (purple box and arrows in Figure 12). Same goes for the values in the is_sent column.
Figure 13 is the last part of the database entry.
Here the item_type values of 4 are seen and represent SML actions. I was able to replicate this value multiple times, and across iOS 14 and 15. Their presence in my testing and in my public image indicate these values will appear iOS 13, 14, and 15.0 when SML happens.
Determining the SML share direction relies on the columns share_direction (previously mentioned and discussed), other_handle (blue box in Figure 13) and handle_id (see green and red arrows in Figure 10). The entries where SML was sent the handle_id values are 0 and the other_handle column contains the handle identifier for the party to whom the SML was sent (green arrow in Figure 13). If SML is received, the handle_id column will contain the handle identifier for the party who sent the SML and the other_handle value will be 0.
One important note for SML: in my testing, SML actions within group chats did not have individual entries as discussed here, which were one-on-one chats.
I am not completely sure how popular sending locations in iMessages is, but it is available to users so it is good to understand how it works and how it looks forensically. It helps an examiner get a more complete picture of what was transpiring during a chat, and should clue the examiner to look for additional data on the device. It also helps build a list of things that can contribute to NULL messages in sms.db.