Decrypting and extracting juicy data, Snap !

Matthieu Regnery
4 min readFeb 26, 2021

Snapchat is the instant messaging app that introduced ephemeral images or short videos (Wikipedia can tell you more). It has been used at the beginning mainly for sexting but is now very popular for anything.

How is that data protected in reality ? Several ressources already exist, mainly dealing with the Android app (see Josh Hickmann’s blog). I also found this approach (James Duffy) of forensics on the iOS app. They are good starting point but do not give me everything we could recover on a iDevice.

Indeed, even in airplane mode, Snapchat shows some data, so it has to be stored on the device! As I do not rely on commercial tools and like to understand where the data come from, I took few hours to look deeper at Snapchat on iOS. You’ll find all the code in my notebook on GitHub.

*** I won’t cover ChatConversationStore.plist as it has already been in DoubleBak’s post. This file can contain a lot of conversations traces.***

The data

All the user data of Snapchat is located in the /private/var/mobile/Containers/Data/Application/<app-guid>

Few directory or files are of interest :

  • Library/Caches/tmp : contains plain text media, just watch !
  • Documents/user_scoped/arroyo/arroyo.db :
  • Documents/gallery_data_object/<digit>/<uid>/scdb-27.sqlite3 : main database of Snapchat
  • Documents/gallery_encrypted_db/<digit>/<uid>/gallery.encrypteddb : contains sensitive data such as decryption keys or location data
  • Documents/user_scoped/<uid>/DocObjects/primary.docobjects
  • Documents/user_scoped/<uid>/contentmanagerV3/contentManagerDb.db
  • Documents/user_scoped/<uid> : encrypted files sitting there
  • Documents/gallery/<digit>/<uid>/cloudfs : encrypted files sitting there too!

Let’s start with arroyo.db (BFU accessible)

This database contains tables with nice names. Well, the tables are not always populated… So no juicy data here in my example.

scdb-27.sqlite (BFU accessible)

This database contains several tables with 2 of special interest :

  • ZGALLERYSNAP : contains snaps metadata, especially times
  • ZGALLERYSNAPMINITHUMBNAIL : contains encrypted thumbnails of snaps. These are really really small…

In the ZGALLERYSNAP we found the ZHASLOCATION column… seems interesting but where is the location data?

After looking at every blob of this database and finding nothing close to a coordinate, I bet this would be encrypted.
Time to access gallery.encrypteddb !

gallery.encrypteddb (AFU accessible)

As it names do not say, this one is SQLCipher encrypted. Luckily, we already implemented SQLCipher decryption for the Signal app (this notebook). Few adjustments later and BOOM !

Decrypted gallery.encrypteddb snippet

******** Technical part for those interested *********

SQLCipher is encrypting page by page the database with an AES 256 CBC. The key is stored in the iOS Keychain and the IV is randomly generated for each page and stored at the bottom of it. There are some integrity protection with HMAC but we do not need that for simple decryption. Therefore the key parameters we need are:

  1. the page size
  2. the key from iOS Keychain (we cheated here as it is already public — Thanks Magnet Forensics)
  3. location of IV (which is determined by salt size and HMAC function)

First attempt at decrypting with default parameters gave good results (lots of zeros, which is sign of plain text data) but not quite a readable result. Indeed page size is only 0x400 for Snapchat database and the header to skip is 0x10.

Here is the final code to decrypt this database:

********* End of technical part on SQLCipher *********

As expected, the database contains juicy data:

  • snap_location_table table: contains latitude and longitude for a snap_id
  • snap_key_iv table : contains key and iv for a snap_id

That last one is picking my curiousity. Whats could they encrypt (so many possibilities…)? We’ll see that in next section

contentManagerDb.db (AFU accessible)

This table contains two tables

  • GLOBAL_CONFIG_V2_TABLE
  • CONTENT_OBJECT_TABLE

The latter is of interest as it seems to have a lot of interesting data:

CONTENT_OBJECT_TABLE content

The KEY column appears to be a media identifier and the two other one are protobuf BLOBs

Where having a look at CONTENT_DEFINITION, I found several base64 encoded strings which looked like key and iv… Humm! So I drafted a quick protobuf schema to parse this field :

And got a bunch of (key, iv) couples again !

Snaps ?

Well, as suspected they are encrypted…

Two main locations contains encrypted files:

  • Documents/gallery
  • Documents/user_scoped/<uid>

Looking at the Documents/gallery directory, we find encrypted files in a weird tree :

Documents
|--gallery/
|----1/
|------b0c7c4151c4f3f5ab9417a52b8f1...6890cc0ca3fff4/
|--------cloudfs/
|----------87578b/
|----------21bf1f/
|----------07faf9/
|------------98ee117f270ae2c6...fae2122ab5030/
|--------------b8939aafbe2cd93b16bc2a52d90a...f0a92743ba983
|----------af5552/
|------------034c0878f3f14f13391b...0db23d9e30cd73f417/
|--------------b8939aafbe2cd93b16bc2a52d90a...0a92743ba983
|----------6213d7/
|----------07c94b/
|------------95fc490...0741342a1e84d399b/
|--------------b8939aafb...a92743ba983
|----------d14a3b/
|------------138446073aab724c...ddda2a63ba6ac/
|--------------b8939aafbe2cd93b16bc2a52d90afc...43ba983
|----------390cbc/

Directories in this tree are indeed formatted as:

sha256(ZSAVERUSERID)/
|--sha256(ZSNAPID)[:3]/
|----sha256(ZSNAPID)[3:]/
|------someconstantsha256

And my little finger tells me we have the material to decrypt them :-D Let’s try the (key, iv) couple found earlier in gallery.encrypteddb. BOOM again! Using AES 256 CBC cipher, we are able to recover these media and link them to snaps thanks to SNAPID encoded tree.

The second directory containing encrypted files is Documents/user_scoped/<uid>. The tree is much simplier and with files named after a GUID. I couldn’t link these GUID to any ID found in the explored databases. So I tried to bruteforce decryption with all couples of (key, iv) found. No luck… for now.

So What?

Some commercial tools are able to decrypt and recover data. However, when I ran some comparison, I was able to recover more records. But most important, no tool is showing where the data is coming from and how then accessed it.

--

--

Matthieu Regnery
Matthieu Regnery

Written by Matthieu Regnery

I enjoy digital forensics, breaking things to understand how they work, reversing and desoldering. Keeping learning (PhD student at Lausanne University)

No responses yet