Skip to content

Commit

Permalink
Create plist parser plugins to read com.apple.MobileMBackup.plist
Browse files Browse the repository at this point in the history
  • Loading branch information
= committed Oct 16, 2024
1 parent df00bfe commit 28678ab
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 0 deletions.
9 changes: 9 additions & 0 deletions plaso/data/formatters/ios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,12 @@ short_message:
- 'Message: {text}'
short_source: 'Twitter iOS'
source: 'Twitter iOS Status'
---
type: 'conditional'
data_type: 'ios:mobile:backup:entry'
message:
- 'Activity description: {activity_description}'
short_message:
- 'Activity description: {activity_description}'
short_source: 'PLIST'
source: 'Apple iOS Mobile Backup application plist'
6 changes: 6 additions & 0 deletions plaso/data/timeliner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1795,3 +1795,9 @@ attribute_mappings:
- name: 'recorded_time'
description: 'Recorded Time'
place_holder_event: true
---
data_type: 'ios:mobile:backup:entry'
attribute_mappings:
- name: 'activity_time'
description: 'Activity Time'
place_holder_event: false
1 change: 1 addition & 0 deletions plaso/parsers/plist_plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from plaso.parsers.plist_plugins import install_history
from plaso.parsers.plist_plugins import ios_carplay
from plaso.parsers.plist_plugins import ios_identityservices
from plaso.parsers.plist_plugins import ios_mobilebackup
from plaso.parsers.plist_plugins import ipod
from plaso.parsers.plist_plugins import launchd
from plaso.parsers.plist_plugins import macos_background_items
Expand Down
77 changes: 77 additions & 0 deletions plaso/parsers/plist_plugins/ios_mobilebackup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
"""Plist parser plugin for Apple iOS Mobile Backup plist files.
The plist contains history of opened applications in the Mobile Backup.
"""

from dfdatetime import posix_time as dfdatetime_posix_time
import datetime

from plaso.containers import events
from plaso.lib import definitions
from plaso.parsers import plist
from plaso.parsers.plist_plugins import interface


class IOSMobileBackupEventData(events.EventData):
"""Apple iOS Mobile Backup history event data.
Attributes:
activity_description (str): activity description.
activity_time (dfdatetime.DateTimeValues): activity last run date and
time.
"""

DATA_TYPE = 'ios:mobile:backup:entry'

def __init__(self):
"""Initializes event data."""
super(IOSMobileBackupEventData, self).__init__(data_type=self.DATA_TYPE)
self.activity_description = None
self.activity_time = None


class IOSMobileBackupPlistPlugin(interface.PlistPlugin):
"""Plist parser plugin for Apple iOS Mobile Backup plist files."""

NAME = 'ios_mobilebackup'
DATA_FORMAT = 'Apple iOS Mobile Backup plist file'

PLIST_PATH_FILTERS = frozenset([
interface.PlistPathFilter('com.apple.MobileBackup.plist')])

PLIST_KEYS = frozenset(['AccountEnabledDate','BackupStateInfo'])

def _getEventData(self, description, datetime_value):
event_data = IOSMobileBackupEventData()
event_data.activity_description = description
timestamp = datetime.datetime.timestamp(datetime_value)
timestamp = int(timestamp * definitions.NANOSECONDS_PER_SECOND)
event_data.activity_time = dfdatetime_posix_time.PosixTimeInNanoseconds(
timestamp=timestamp)

return event_data

# pylint: disable=arguments-differ
def _ParsePlist(self, parser_mediator, match=None, **unused_kwargs):
"""Extract Mobile Backup history entries.
Args:
parser_mediator (ParserMediator): mediates interactions between parsers
and other components, such as storage and dfVFS.
match (Optional[dict[str: object]]): keys extracted from PLIST_KEYS.
"""

datetime_value = match.get('AccountEnabledDate', {})
parser_mediator.ProduceEventData(self._getEventData("AccountEnabledDate", datetime_value))

plist_key = match.get('BackupStateInfo', {})
for key, value in plist_key.items():
if key == "date":
parser_mediator.ProduceEventData(self._getEventData(f"BackupStateInfo - date", value))

elif key == "errors":
for val in value:
parser_mediator.ProduceEventData(self._getEventData(f"BackupStateInfo - {val['localizedDescription']}", val['date']))

plist.PlistParser.RegisterPlugin(IOSMobileBackupPlistPlugin)
Binary file added test_data/com.apple.MobileBackup.plist
Binary file not shown.
1 change: 1 addition & 0 deletions tests/cli/pinfo_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ def testPrintStorageInformationAsText(self):
'plist/airport',
'plist/apple_id',
'plist/ios_carplay',
'plist/ios_mobilebackup',
'plist/ipod_device',
'plist/launchd_plist',
'plist/macos_bluetooth',
Expand Down
45 changes: 45 additions & 0 deletions tests/parsers/plist_plugins/ios_mobilebackup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Tests for the Apple iOS Car Play application plist plugin."""

import unittest

from plaso.parsers.plist_plugins import ios_mobilebackup

from tests.parsers.plist_plugins import test_lib


class IOSMobileBackupPlistPluginTest(test_lib.PlistPluginTestCase):
"""Tests for the Apple iOS Car Play application plist plugin."""

def testProcess(self):
"""Tests the Process function."""
plist_name = 'com.apple.MobileBackup.plist'

plugin = ios_mobilebackup.IOSMobileBackupPlistPlugin()
storage_writer = self._ParsePlistFileWithPlugin(
plugin, [plist_name], plist_name)

number_of_event_data = storage_writer.GetNumberOfAttributeContainers(
'event_data')
self.assertEqual(number_of_event_data, 12)

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 = {
'activity_description': 'AccountEnabledDate',
'data_type': 'ios:mobile:backup:entry',
'activity_time': '2023-04-15T13:58:42.481633792+00:00'}

event_data = storage_writer.GetAttributeContainerByIndex('event_data', 0)
self.CheckEventData(event_data, expected_event_values)


if __name__ == '__main__':
unittest.main()

0 comments on commit 28678ab

Please sign in to comment.