A Forensic Gold Mine II: Forensic Analysis of Signal Messenger on Windows 10

Over the past months, I was looking at the forensic artefacts that the Signal messenger leaves on a Windows Desktop. While a lot of work out there focuses on the forensic analysis of the mobile apps, I rather wanted to have a look at the traces that the desktop versions leave. My goal was to find out what messages, media, and metadata could be recovered. After looking at Viber by Rakuten in my previous post, I’ll today be focusing on Signal Messenger by the Signal Technology Foundation. With over 50 million downloads on the Google Play Store it is among the top messaging applications worldwide. From a DFIR perspective, this application is an extremely valuable source of information. Let’s check out why!

Info
I have conducted this research on Signal v5.4.1 for Windows Desktop, which was the latest version at the time of writing this post. You can download the client from the official signal.org website.

Signal’s Directory Structure

Like most instant messaging applications these days, Signal installs itself into the %appdata% directory. While the program installer is located within the Local directory, resides the user content within the Roaming directory. As you can see, from the listing below, Signal follows the setup of a traditional Electron Application, by having a Cache folder, a GPU Cache, an Indexed DB and so on. However, one folder that stands out, is the sql folder within AppData\Roaming.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
C:\USERS\<user>\APPDATA\LOCAL\SIGNAL-Desktop-Updater
└───temp
C:\USERS\<user>\APPDATA\ROAMING\SIGNAL
├───attachments.noindex
│   ├───..
├───blob_storage
│   └───..
├───Cache
├───Code Cache
│   ├───js
│   │   └───index-dir
│   └───wasm
│       └───index-dir
├───databases
├───Dictionaries
├───drafts.noindex
│   ├───..
├───GPUCache
├───IndexedDB
│   └───file__0.indexeddb.leveldb
├───Local Storage
│   └───leveldb
├───logs
├───Session Storage
├───sql
├───stickers.noindex
│   ├───..
└───temp
    └───..

Locating the Allmighty db.sqlite Database

The forensic investigation of this messaging application is extremely straightforward, as all the information are stored in a single SQLite database named db.sqlite.

This file is located under AppData Roaming on Windows. The full path will follow this structure:

1
C:\Users\<user>\AppData\Roaming\Signal\sql\db.sqlite

If you are analysing a Linux, system then you will find the database under:

1
~/.config/Signal/sql/db.sqlite

Under MacOS, it will be located within the Application Support directory under:

1
~/Library/Application Support/Signal/sql/db.sqlite

It should be noted that this database is encrypted using sqlcipher, but don’t worry, the encryption key is conveniently located in the adjacent config.json file. For browsing the database under Windows I recommend using a recent version of DB Browser for SQLite, but pretty much any software that supports sqlcipher would do. Use whatever floats your boat.

Simply fire up DB Browser for SQLite, navigate to the db.sqliteand you’ll be prompted to specify a password (see image below). At this step it is important to put the toggle right of the password field to raw key and set the encryption settings to SQLCipher 4 defaults. As a key, you will have to specify 0x prefix + the key specified in the JSON dictionary located in the config.json und %appdata%\Signal\. If your config.json looks like this, then the raw key, would be 0xb....40

Signal Messenger config.json

DB Browser for SQLite

The Database Structure

In the current version, the database consists out of 24 tables. From a digital forensics perspective, the most interesting ones are undoubtedly the messages tables as these might hold some potential evidence about the case you are inspecting.

Extracting the Exchanged Chat Messages

Let us look at a common scenario and try to extract the message body, format the timestamp neatly, include the direction of the message flow and list the sender phone number.

1
2
3
4
5
6
SELECT strftime('%Y-%m-%d %H:%M:%S',(received_at/1000),'unixepoch') AS Time,  
source AS Contact, 
 CASE sourceDevice WHEN 1 THEN 'received' ELSE 'sent' END AS Direction, 
 body AS Message
 FROM messages
ORDER BY Time DESC;

The resulting table would look somewhat like this:

Signal Messages queried in DB Browser for SQLite

Feel free to browse the remaining tables yourself and let me know of any other queries you had found!

Other Artefacts of Interest

  • The Attachments folder contains thumbnails and previews of the exchanged attachments. These can be viewed through a standard browser, like Google Chrome.
  • Configuration details, such as device names, are available from the database, which might be useful, for locating additional evidence.
  • Call Histories, message reactions, pinned messages…

Conclusion 🎇

This was a really fun little project, as it allowed me to play around with one of my favourite messengers and do some forensic investigation on it. Seeing that all messages can be retrieved without major issues shows that this makes Signal for Desktop an extremely interesting target for any forensic investigation and that disk encryption is indispensable. Even though this post could only scratch the surface of the data stored in the SQLite database, due to the limited time which I could spend on this project, it should be enough to get your own investigation started. I hope this post is also useful for your own forensic investigation.

Posts in this series