A Forensic Gold Mine I: Forensic Analysis of Viber Messenger on Windows 10

Over the past weeks, I was looking at the forensic artefacts that the desktop versions of instant messenger leave. 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. The first candidate I had looked at was Viber developed by Rakuten. With over a billion user it is among the top six messengers worldwide. From a DFIR perspective this application is an extremely valuable source of information. Let’s check out why!

Info
In order to avoid changing artefacts this work should be carried out on a forensic copy of the target machine. There will be no need to spin up the machine all work can be done from a forensics software such as Autopsy or Encase.

Locating the Allmighty Viber.Db Database

The forensic investigation of this messaging application is extremely straight forward, as all the information are stored in a single SQLite database named viber.db along with other db and config files. This file is located under AppData Roaming on Windows. The full path will follow this structure:

1
C:\Users\<user>\AppData\Roaming\ViberPC\<phonenumber>

Please note that the phone number neither includes a + nor 00 for the country code, for the US this would be just 1. Once located, the file can easily be loaded into a SQL lite browser of your choice. I was using DB Browser for SQLite, but pretty much any software such as DBeaver or HeidiSQL would do.

The Database Structure

In the current version (14.6.0), the database consists out of 15 tables, which are most interlinked through an events table (click on the image to make it bigger or open in a new tab). From a digital forensics perspective, the most interesting ones are undoubtedly the messages, calls and the contact tables as these might hold some potential evidence about the case you are inspecting. viber.db Database Structure

Extracting the Exchanged Chat Messages

Let’s look at a common scenario, if for example the exchanged messages and the participants should be extracted, then the contact and messages have to be joined to through the events table using a simple inner join. This join is necessary, as the messages table itself does not indicate who sent the message. In this example, I’ve also converted the epoch time into a bit more readable format.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
SELECT strftime('%Y-%m-%d %H:%M:%S',(Events.TimeStamp/1000),'unixepoch') AS Time,  
 Contact.Name AS Name, 
 Contact.ClientName AS ContactName, 
 Contact.Number As Cellphone, 
 CASE Direction WHEN 0 THEN 'received' ELSE 'sent' END AS Direction, 
 Messages.Body AS Message 
FROM Events  
 INNER JOIN Contact ON Events.ContactID = Contact.ContactID 
 INNER JOIN Messages ON Events.EventID = Messages.EventID 
ORDER BY Time;

The resulting table would look somewhat like this:

TimeNameContactNameCellphoneDirectionMessage
2021-01-28 13:33:45Own NumberIM Forensics+49-redactedsentA sent test message.
2021-01-28 13:34:16name redacted+49-redactedreceivedA received test message. 😂

Extracting the Phone Calls

In a similar fashion, the phone calls can be joined through the events to the contacts in order to see which phone calls were issued or received.

1
2
3
4
5
6
7
8
9
SELECT strftime('%Y-%m-%d %H:%M:%S',(Events.TimeStamp/1000),'unixepoch') AS Time,  
 Contact.Name AS Name, 
 Contact.ClientName AS ContactName, 
 Contact.Number As Cellphone,
 CASE Calls.Type WHEN 0 THEN 'voice' ELSE 'video' END AS Calltype
FROM Events  
 INNER JOIN Contact ON Events.ContactID = Contact.ContactID 
 INNER JOIN Calls ON Events.EventID = Calls.EventID 
ORDER BY Time;

I tried it with two unanswered call and that gave me the following result:

TimeNameContactNameCellphoneCalltype
2021-02-03 11:34:25Own NumberIM Forensics+49-redactedvoice
2021-02-03 11:37:10Own NumberIM Forensics+49-redactedvoice

Other Artifacts of Interest

Besides the previous two examples, there is an abundance of information available within the viber.db.

  • You might also want to have a look at the contact tables, as this is basically a whole sync of the users address book and includes even those contacts, which are not using Viber.
  • It’s possible to see which files were downloaded and where they were stored. Conveniently for us, Viber even includes an MD5 hash and the payload path. Therefore, we could, with a certain degree, reproduce how illicit content got onto the machine.
  • The events and messageinfo table includes longitude and latitude geo coordinates. I am not completely sure, under which circumstances these would be populated, but might be worth a look.
  • If a message gets deleted, the record in the messages table would be nulled out, which makes it fairly hard to recover. Common approaches such as undark do only work if the entry has been removed. If you know a way to recover altered records, please let me know!

Conclusion 🎇

This was a really fun little project, as it allowed me to play around with a previously unknown messenger and do some investigative work. Seeing that all messages can be synced in there entirety and stored in an unencrypted format, makes it an extremely interesting target for any forensic investigation. Even though this post could only scratch the surface of the data stored in the SQLite database, due 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