Skip to content

Commit

Permalink
Changes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Dec 26, 2024
1 parent ed0ad12 commit 0daf932
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 63 deletions.
27 changes: 18 additions & 9 deletions plaso/data/formatters/ios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@ short_source: 'LOG'
source: 'iOS lockdown daemon log'
---
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'
---
type: 'conditional'
data_type: 'ios:mobile_backup:state'
message:
- 'Description: {description}'
short_message:
- 'Description: {description}'
short_source: 'PLIST'
source: 'Apple iOS Mobile Backup application plist'
---
type: 'conditional'
data_type: 'ios:netusage:route'
enumeration_helpers:
- input_attribute: 'network_type'
Expand Down Expand Up @@ -233,12 +251,3 @@ 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'
20 changes: 14 additions & 6 deletions plaso/data/timeliner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,20 @@ attribute_mappings:
description: 'Content Modification Time'
place_holder_event: false
---
data_type: 'ios:mobile_backup:entry'
attribute_mappings:
- name: 'account_enabled_time'
description: 'Account Enabled Time'
- name: 'backup_state_time'
description: 'Backup State Time'
place_holder_event: false
---
data_type: 'ios:mobile_backup:state'
attribute_mappings:
- name: 'backup_time'
description: 'Backup Time'
place_holder_event: false
---
data_type: 'ios:netusage:process'
attribute_mappings:
- name: 'start_time'
Expand Down Expand Up @@ -1795,9 +1809,3 @@ 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
101 changes: 57 additions & 44 deletions plaso/parsers/plist_plugins/ios_mobilebackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,95 @@
The plist contains history of opened applications in the Mobile Backup.
"""

import datetime
from dfdatetime import posix_time as dfdatetime_posix_time

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.
"""Apple iOS Mobile Backup event data.
Attributes:
activity_description (str): activity description.
activity_time (dfdatetime.DateTimeValues): activity last run date and
time.
account_enabled_time (dfdatetime.DateTimeValues): date and time the mobile
backup account was enabled.
backup_state_time (dfdatetime.DateTimeValues): date and time if the backup
state.
backup_state (int): backup state.
"""

DATA_TYPE = 'ios:mobile:backup:entry'
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
self.account_enabled_time = None
self.backup_state = None
self.backup_state_time = None


class IOSMobileBackupStateEventData(events.EventData):
"""Apple iOS Mobile Backup state event data.
Attributes:
backup_time (dfdatetime.DateTimeValues): date and time of the backup.
description (str): localized description of the backup state.
"""

DATA_TYPE = 'ios:mobile_backup:state'

def __init__(self):
"""Initializes event data."""
super(IOSMobileBackupStateEventData, self).__init__(
data_type=self.DATA_TYPE)
self.backup_time = None
self.description = None


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

NAME = 'ios_mobilebackup'
NAME = 'ios_mobile_backup'
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
PLIST_KEYS = frozenset(['AccountEnabledDate', 'BackupStateInfo'])

# pylint: disable=arguments-differ
def _ParsePlist(self, parser_mediator, match=None, **unused_kwargs):
def _ParsePlist(self, parser_mediator, top_level=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.
top_level (Optional[dict[str, object]]): plist top-level item.
"""
event_data = IOSMobileBackupEventData()
event_data.account_enabled_time = self._GetDateTimeValueFromPlistKey(
top_level, 'AccountEnabledDate')

# TODO: add support for LastOnConditionEvents
# TODO: add support for RemoteConfigurationExpiration

backup_state_info = top_level.get('BackupStateInfo')
if backup_state_info:
event_data.backup_state = backup_state_info.get('state')
# TODO: determine what this time represents.
event_data.backup_state_time = self._GetDateTimeValueFromPlistKey(
backup_state_info, 'date')

parser_mediator.ProduceEventData(event_data)

if backup_state_info:
for error in backup_state_info.get('errors', []):
event_data = IOSMobileBackupStateEventData()
event_data.description = error.get('localizedDescription')
# TODO: determine if this is the start or end time of the backup.
event_data.backup_time = self._GetDateTimeValueFromPlistKey(
error, 'date')

parser_mediator.ProduceEventData(event_data)

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("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)
17 changes: 13 additions & 4 deletions tests/parsers/plist_plugins/ios_mobilebackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def testProcess(self):

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

number_of_warnings = storage_writer.GetNumberOfAttributeContainers(
'extraction_warning')
Expand All @@ -33,13 +33,22 @@ def testProcess(self):
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'}
'account_enabled_time': '2023-04-15T13:58:42.481634+00:00',
'backup_state': 4,
'backup_state_time': '2023-04-15T14:08:21.008032+00:00',
'data_type': 'ios:mobile_backup:entry'}

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

expected_event_values = {
'backup_time': '2023-05-03T01:11:53.195466+00:00',
'data_type': 'ios:mobile_backup:state',
'description': 'Backup succeeded'}

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


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

0 comments on commit 0daf932

Please sign in to comment.