From 85c7b4830a5546bc1c64097583b9be03653a855b Mon Sep 17 00:00:00 2001 From: jawahirulwildan Date: Sun, 1 Dec 2024 13:59:25 +0700 Subject: [PATCH 1/5] Add SQLite parser plugin for Android Viber Call --- plaso/parsers/sqlite_plugins/__init__.py | 1 + .../sqlite_plugins/android_viber_call.py | 138 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 plaso/parsers/sqlite_plugins/android_viber_call.py diff --git a/plaso/parsers/sqlite_plugins/__init__.py b/plaso/parsers/sqlite_plugins/__init__.py index dfa7c0a680..685efd2009 100644 --- a/plaso/parsers/sqlite_plugins/__init__.py +++ b/plaso/parsers/sqlite_plugins/__init__.py @@ -8,6 +8,7 @@ from plaso.parsers.sqlite_plugins import android_tango from plaso.parsers.sqlite_plugins import android_turbo from plaso.parsers.sqlite_plugins import android_twitter +from plaso.parsers.sqlite_plugins import android_viber_call from plaso.parsers.sqlite_plugins import android_webview from plaso.parsers.sqlite_plugins import android_webviewcache from plaso.parsers.sqlite_plugins import chrome_autofill diff --git a/plaso/parsers/sqlite_plugins/android_viber_call.py b/plaso/parsers/sqlite_plugins/android_viber_call.py new file mode 100644 index 0000000000..f333bb176a --- /dev/null +++ b/plaso/parsers/sqlite_plugins/android_viber_call.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +"""SQLite parser plugin for Android Viber call history database files.""" + +from dfdatetime import java_time as dfdatetime_java_time + +from plaso.containers import events +from plaso.lib import definitions +from plaso.parsers import sqlite +from plaso.parsers.sqlite_plugins import interface + + +class AndroidViberCallEventData(events.EventData): + """Android Viber Call event data. + + Attributes: + number (str): phone number. + type (int): type of call, such as: Incoming, or Outgoing. + viber_call_type (int): type of call in Viber app, such as: Audio Call, or Video Call. + duration (int): number of seconds the call lasted. + start_time (dfdatetime.DateTimeValues): date and time the call was started. + end_time (dfdatetime.DateTimeValues): date and time the call was stopped. + """ + + DATA_TYPE = 'android:viber:call' + + def __init__(self): + """Initializes event data.""" + super(AndroidViberCallEventData, self).__init__(data_type=self.DATA_TYPE) + self.number = None + self.type = None + self.viber_call_type = None + self.duration = None + self.start_time = None + self.end_time = None + + +class AndroidViberCallPlugin(interface.SQLitePlugin): + """SQLite parser plugin for Android Viber call history database files. + + The Android Viber call history database file is typically stored in: + viber_data + """ + + NAME = 'android_viber_call' + DATA_FORMAT = 'Android Viber call history SQLite database (viber_data) file' + + REQUIRED_STRUCTURE = { + 'calls': frozenset(['_id', 'date', 'number', 'duration', 'type', 'viber_call_type'])} + + QUERIES = [ + ('SELECT _id AS id, date, number, duration, type, viber_call_type FROM calls', + 'ParseViberCallsRow')] + + SCHEMAS = [{ + 'blockednumbers': ( + 'CREATE TABLE blockednumbers (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'canonized_number TEXT NOT NULL, blocked_date LONG DEFAULT 0, ' + 'block_reason INTEGER DEFAULT 0, status INTEGER DEFAULT 0, ' + 'UNIQUE (canonized_number) ON CONFLICT REPLACE )'), + 'calls': ( + 'CREATE TABLE calls (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'call_id LONG NOT NULL, aggregate_hash LONG NOT NULL, ' + 'number TEXT NOT NULL, canonized_number TEXT NOT NULL, ' + 'viber_call BOOLEAN DEFAULT TRUE, viber_call_type INTEGER DEFAULT 1, ' + 'date LONG NOT NULL, duration LONG NOT NULL, type INT NOT NULL, ' + 'end_reason INT DEFAULT 0, start_reason INT DEFAULT 0, ' + 'token LONG DEFAULT 0, looked BOOLEAN DEFAULT TRUE, ' + 'conference_info TEXT, group_id LONG DEFAULT 0, ' + 'flags INTEGER DEFAULT 0)'), + 'phonebookcontact': ( + 'CREATE TABLE phonebookcontact (_id INTEGER PRIMARY KEY NOT NULL, ' + 'native_id INTEGER DEFAULT 0, display_name TEXT, phonetic_name TEXT, ' + 'phone_label TEXT, low_display_name TEXT, starred BOOLEAN, ' + 'viber BOOLEAN, contact_lookup_key TEXT, contact_hash LONG, ' + 'version INTEGER DEFAULT 0, has_number BOOLEAN, has_name BOOLEAN, ' + 'native_photo_id LONG DEFAULT 0, recently_joined_date LONG DEFAULT 0, ' + 'joined_date LONG DEFAULT 0, numbers_name TEXT DEFAULT '', ' + 'deleted BOOLEAN, flags INTEGER DEFAULT 0, ' + 'UNIQUE (_id) ON CONFLICT REPLACE)'), + 'sqlite_sequence': ( + 'CREATE TABLE sqlite_sequence(name,seq)'), + 'sync_data': ( + 'CREATE TABLE sync_data (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'canonized_phone_number TEXT NOT NULL, display_name TEXT DEFAULT '', ' + 'phonetic_name TEXT DEFAULT '',operation INTEGER DEFAULT 0)'), + 'vibernumbers': ( + 'CREATE TABLE vibernumbers (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'canonized_number TEXT NOT NULL, photo TEXT DEFAULT '', ' + 'viber_name TEXT, clear BOOLEAN, member_id TEXT NOT NULL, ' + 'encrypted_member_id TEXT NOT NULL, viber_id TEXT, ' + 'date_of_birth TEXT)'), + 'viberpay_data': ( + 'CREATE TABLE viberpay_data (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'encrypted_member_id TEXT NULL, canonized_phone_number TEXT NULL, ' + 'phone_number TEXT NULL, country_code TEXT NULL, ' + 'is_country_supported BOOLEAN NOT NULL, ' + 'default_currency_code TEXT NULL, is_viberpay_user BOOLEAN NOT NULL, ' + 'last_sync_date INTEGER NOT NULL)'), + 'walletlist': ( + 'CREATE TABLE walletlist (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'country_codes INTEGER NOT NULL)'), + 'walletnumbers': ( + 'CREATE TABLE walletnumbers (_id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'canonized_number TEXT NOT NULL, wallet_wu_status INTEGER DEFAULT 0, ' + 'UNIQUE (canonized_number) ON CONFLICT REPLACE )'), + }] + + def ParseViberCallsRow(self, parser_mediator, query, row, **unused_kwargs): + """Parses a Viber Call record row. + + Args: + parser_mediator (ParserMediator): mediates interactions between parsers + and other components, such as storage and dfVFS. + query (str): query that created the row. + row (sqlite3.Row): row. + """ + query_hash = hash(query) + + duration = self._GetRowValue(query_hash, row, 'duration') + timestamp = self._GetRowValue(query_hash, row, 'date') + + event_data = AndroidViberCallEventData() + event_data.type = self._GetRowValue(query_hash, row, 'type') + event_data.duration = duration + event_data.number = self._GetRowValue(query_hash, row, 'number') + event_data.viber_call_type = self._GetRowValue(query_hash, row, 'viber_call_type') + event_data.start_time = dfdatetime_java_time.JavaTime(timestamp=timestamp) + + if duration: + # The duration is in seconds and the date value in milliseconds. + timestamp += duration * definitions.MILLISECONDS_PER_SECOND + + event_data.end_time = dfdatetime_java_time.JavaTime(timestamp=timestamp) + + parser_mediator.ProduceEventData(event_data) + + +sqlite.SQLiteParser.RegisterPlugin(AndroidViberCallPlugin) From e91cd0b8542e879477abc9ca8a775ad5c651777c Mon Sep 17 00:00:00 2001 From: jawahirulwildan Date: Sun, 1 Dec 2024 14:01:09 +0700 Subject: [PATCH 2/5] Modify timeliner.yaml to support Android Viber Call SQLite parser plugin --- plaso/data/timeliner.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plaso/data/timeliner.yaml b/plaso/data/timeliner.yaml index 1681f33d74..0b5635d7d9 100644 --- a/plaso/data/timeliner.yaml +++ b/plaso/data/timeliner.yaml @@ -87,6 +87,14 @@ attribute_mappings: description: 'Creation Time' place_holder_event: true --- +data_type: 'android:viber:call' +attribute_mappings: +- name: 'end_time' + description: 'End Time' +- name: 'start_time' + description: 'Start Time' +place_holder_event: true +--- data_type: 'android:webview:cookie' attribute_mappings: - name: 'expiration_time' From c7a0f7af2a8283618e1e61b4e4e615c5db2bbf2e Mon Sep 17 00:00:00 2001 From: Aurelio Killian Date: Sun, 1 Dec 2024 14:46:30 +0700 Subject: [PATCH 3/5] Modify android.yaml to support Android Viber Call SQLite parser plugin --- plaso/data/formatters/android.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plaso/data/formatters/android.yaml b/plaso/data/formatters/android.yaml index bd76492cdd..6fe2c47d30 100644 --- a/plaso/data/formatters/android.yaml +++ b/plaso/data/formatters/android.yaml @@ -230,6 +230,33 @@ short_source: 'Twitter Android' source: 'Twitter Android Status' --- type: 'conditional' +data_type: 'android:viber:call' +enumeration_helpers: +- input_attribute: 'type' + output_attribute: 'type' + default_value: 'UNKNOWN' + values: + 1: 'INCOMING' + 2: 'OUTGOING' +- input_attribute: 'viber_call_type' + output_attribute: 'viber_call_type' + default_value: 'UNKNOWN' + values: + 1: 'AUDIO CALL' + 4: 'VIDEO CALL' +message: +- 'Number: {number}' +- 'Call type: {type}' +- 'Viber call type: {viber_call_type}' +- 'Duration: {duration} seconds' +short_message: +- '{number}' +- '{type}' +- '{viber_call_type}' +short_source: 'Android Viber' +source: 'Android Viber Call History' +--- +type: 'conditional' data_type: 'android:webview:cookie' message: - 'Host: {host}' From 49a1aec5837ab66d5ff27818813ed62ed8cf8831 Mon Sep 17 00:00:00 2001 From: Aurelio Killian Date: Sun, 1 Dec 2024 14:51:21 +0700 Subject: [PATCH 4/5] Add unit test for Android Viber Call SQLite parser plugin --- test_data/viber_data | Bin 0 -> 131072 bytes .../sqlite_plugins/android_viber_call.py | 46 ++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test_data/viber_data create mode 100644 tests/parsers/sqlite_plugins/android_viber_call.py diff --git a/test_data/viber_data b/test_data/viber_data new file mode 100644 index 0000000000000000000000000000000000000000..24ce4a994c064c4b282d88bffdb88c3cfd0b042e GIT binary patch literal 131072 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 N%I;oY+D!Mr{{fs+SRnua literal 0 HcmV?d00001 diff --git a/tests/parsers/sqlite_plugins/android_viber_call.py b/tests/parsers/sqlite_plugins/android_viber_call.py new file mode 100644 index 0000000000..ccd9f085cd --- /dev/null +++ b/tests/parsers/sqlite_plugins/android_viber_call.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""Tests for the Android Viber call history plugin.""" + +import unittest + +from plaso.parsers.sqlite_plugins import android_viber_call + +from tests.parsers.sqlite_plugins import test_lib + + +class AndroidViberCallSQLitePluginTest(test_lib.SQLitePluginTestCase): + """Tests for the Android Viber Call History database plugin.""" + + def testProcess(self): + """Test the Process function on an Android viber_data file.""" + plugin = android_viber_call.AndroidViberCallPlugin() + storage_writer = self._ParseDatabaseFileWithPlugin(['viber_data'], plugin) + + number_of_event_data = storage_writer.GetNumberOfAttributeContainers( + 'event_data') + self.assertEqual(number_of_event_data, 4) + + number_of_warnings = storage_writer.GetNumberOfAttributeContainers( + 'extraction_warning') + self.assertEqual(number_of_warnings, 0) + + number_of_warnings = storage_writer.GetNumberOfAttributeContainers( + 'recovery_warning') + self.assertEqual(number_of_warnings, 0) + + expected_event_values = { + 'type': 2, + 'data_type': 'android:viber:call', + 'duration': 105, + 'number': '+19198887386', + 'start_time': '2022-11-25T20:43:08.267+00:00', + 'end_time': '2022-11-25T20:44:53.267+00:00', + 'viber_call_type': 4} + + event_data = storage_writer.GetAttributeContainerByIndex('event_data', 3) + self.CheckEventData(event_data, expected_event_values) + + +if __name__ == '__main__': + unittest.main() From 75d17836f1e9af2c2c3937533b14a88fdc2daa4c Mon Sep 17 00:00:00 2001 From: Aurelio Killian Date: Tue, 3 Dec 2024 15:09:09 +0700 Subject: [PATCH 5/5] Fix linting --- plaso/parsers/sqlite_plugins/android_viber_call.py | 12 +++++++----- tests/parsers/sqlite_plugins/android_viber_call.py | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/plaso/parsers/sqlite_plugins/android_viber_call.py b/plaso/parsers/sqlite_plugins/android_viber_call.py index f333bb176a..04d75592cf 100644 --- a/plaso/parsers/sqlite_plugins/android_viber_call.py +++ b/plaso/parsers/sqlite_plugins/android_viber_call.py @@ -15,7 +15,7 @@ class AndroidViberCallEventData(events.EventData): Attributes: number (str): phone number. type (int): type of call, such as: Incoming, or Outgoing. - viber_call_type (int): type of call in Viber app, such as: Audio Call, or Video Call. + viber_call_type (int): type of call in Viber,(Audio Call, or Video Call). duration (int): number of seconds the call lasted. start_time (dfdatetime.DateTimeValues): date and time the call was started. end_time (dfdatetime.DateTimeValues): date and time the call was stopped. @@ -45,11 +45,12 @@ class AndroidViberCallPlugin(interface.SQLitePlugin): DATA_FORMAT = 'Android Viber call history SQLite database (viber_data) file' REQUIRED_STRUCTURE = { - 'calls': frozenset(['_id', 'date', 'number', 'duration', 'type', 'viber_call_type'])} + 'calls': frozenset(['_id', 'date', 'number', 'duration', 'type', + 'viber_call_type'])} QUERIES = [ - ('SELECT _id AS id, date, number, duration, type, viber_call_type FROM calls', - 'ParseViberCallsRow')] + ('SELECT _id AS id, date, number, duration, type, ' + 'viber_call_type FROM calls', 'ParseViberCallsRow')] SCHEMAS = [{ 'blockednumbers': ( @@ -123,7 +124,8 @@ def ParseViberCallsRow(self, parser_mediator, query, row, **unused_kwargs): event_data.type = self._GetRowValue(query_hash, row, 'type') event_data.duration = duration event_data.number = self._GetRowValue(query_hash, row, 'number') - event_data.viber_call_type = self._GetRowValue(query_hash, row, 'viber_call_type') + event_data.viber_call_type = ( + self._GetRowValue(query_hash, row, 'viber_call_type')) event_data.start_time = dfdatetime_java_time.JavaTime(timestamp=timestamp) if duration: diff --git a/tests/parsers/sqlite_plugins/android_viber_call.py b/tests/parsers/sqlite_plugins/android_viber_call.py index ccd9f085cd..72e62e8143 100644 --- a/tests/parsers/sqlite_plugins/android_viber_call.py +++ b/tests/parsers/sqlite_plugins/android_viber_call.py @@ -4,9 +4,8 @@ import unittest -from plaso.parsers.sqlite_plugins import android_viber_call - from tests.parsers.sqlite_plugins import test_lib +from plaso.parsers.sqlite_plugins import android_viber_call class AndroidViberCallSQLitePluginTest(test_lib.SQLitePluginTestCase):