예제 #1
0
class SpotlightPlugin(interface.PlistPlugin):
  """Plist parser plugin for Spotlight searched terms plist files.

  Further information about extracted fields:
    name of the item:
      search term.

    PATH:
      path of the program associated to the term.

    LAST_USED:
      last time when it was executed.

    DISPLAY_NAME:
      the display name of the program associated.
  """

  NAME = 'spotlight'
  DATA_FORMAT = 'Spotlight plist file'

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

  PLIST_KEYS = frozenset(['UserShortcuts'])

  # pylint: disable=arguments-differ
  def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
    """Extracts relevant Spotlight 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.
    """
    shortcuts = match.get('UserShortcuts', {})
    for search_text, data in shortcuts.items():
      datetime_value = data.get('LAST_USED', None)
      if not datetime_value:
        continue

      display_name = data.get('DISPLAY_NAME', '<DISPLAY_NAME>')
      path = data.get('PATH', '<PATH>')

      event_data = plist_event.PlistTimeEventData()
      event_data.desc = (
          'Spotlight term searched "{0:s}" associate to {1:s} ({2:s})').format(
              search_text, display_name, path)
      event_data.key = search_text
      event_data.root = '/UserShortcuts'

      date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
      date_time.CopyFromDatetime(datetime_value)

      event = time_events.DateTimeValuesEvent(
          date_time, definitions.TIME_DESCRIPTION_WRITTEN)
      parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #2
0
class InstallHistoryPlugin(interface.PlistPlugin):
    """Plist parser plugin for MacOS install history plist files."""

    NAME = 'macosx_install_history'
    DATA_FORMAT = 'MacOS installation history plist file'

    PLIST_PATH_FILTERS = frozenset(
        [interface.PlistPathFilter('InstallHistory.plist')])

    PLIST_KEYS = frozenset([
        'date', 'displayName', 'displayVersion', 'processName',
        'packageIdentifiers'
    ])

    # pylint: disable=arguments-differ
    def GetEntries(self, parser_mediator, top_level=None, **unused_kwargs):
        """Extracts relevant install history entries.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      top_level (Optional[dict[str, object]]): plist top-level item.
    """
        for entry in top_level:
            datetime_value = entry.get('date', None)
            package_identifiers = entry.get('packageIdentifiers', [])

            if not datetime_value or not package_identifiers:
                continue

            display_name = entry.get('displayName', '<UNKNOWN>')
            display_version = entry.get('displayVersion', '<DISPLAY_VERSION>')
            process_name = entry.get('processName', '<PROCESS_NAME>')
            package_identifiers = ', '.join(package_identifiers)

            event_data = plist_event.PlistTimeEventData()
            event_data.desc = (
                'Installation of [{0:s} {1:s}] using [{2:s}]. Packages: '
                '{3:s}.').format(display_name, display_version, process_name,
                                 package_identifiers)
            event_data.key = ''
            event_data.root = '/item'

            date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
            date_time.CopyFromDatetime(datetime_value)

            event = time_events.DateTimeValuesEvent(
                date_time, definitions.TIME_DESCRIPTION_WRITTEN)
            parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #3
0
class AirportPlugin(interface.PlistPlugin):
    """Plist parser plugin for Airport plist files."""

    NAME = 'airport'
    DATA_FORMAT = 'Airport plist file'

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

    PLIST_KEYS = frozenset(['RememberedNetworks'])

    # pylint: disable=arguments-differ
    def _ParsePlist(self, parser_mediator, match=None, **unused_kwargs):
        """Extracts relevant Airport 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.
    """
        if 'RememberedNetworks' not in match:
            return

        for wifi in match['RememberedNetworks']:
            ssid = wifi.get('SSIDString', 'UNKNOWN_SSID')
            security_type = wifi.get('SecurityType', 'UNKNOWN_SECURITY_TYPE')

            event_data = plist_event.PlistTimeEventData()
            event_data.desc = (
                '[WiFi] Connected to network: <{0:s}> using security {1:s}'
            ).format(ssid, security_type)
            event_data.key = 'item'
            event_data.root = '/RememberedNetworks'

            datetime_value = wifi.get('LastConnected', None)
            if datetime_value:
                date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                )
                date_time.CopyFromDatetime(datetime_value)
            else:
                date_time = dfdatetime_semantic_time.NotSet()

            event = time_events.DateTimeValuesEvent(
                date_time, definitions.TIME_DESCRIPTION_WRITTEN)
            parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #4
0
파일: ipod.py 프로젝트: tomchop/plaso
class IPodPlugin(interface.PlistPlugin):
  """Plist parser plugin for iPod, iPad and iPhone storage plist files."""

  NAME = 'ipod_device'
  DATA_FORMAT = 'iPod, iPad and iPhone plist file'

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

  PLIST_KEYS = frozenset(['Devices'])

  # pylint: disable=arguments-differ
  def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
    """Extract device information from the iPod plist.

    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.
    """
    devices = match.get('Devices', {})
    for device_identifier, device_information in devices.items():
      datetime_value = device_information.get('Connected', None)
      if not datetime_value:
        continue

      event_data = IPodPlistEventData()
      event_data.device_id = device_identifier

      # TODO: refactor.
      for key, value in device_information.items():
        if key == 'Connected':
          continue

        attribute_name = key.lower().replace(' ', '_')
        setattr(event_data, attribute_name, value)

      date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
      date_time.CopyFromDatetime(datetime_value)

      event = time_events.DateTimeValuesEvent(
          date_time, definitions.TIME_DESCRIPTION_LAST_CONNECTED)
      parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #5
0
class SpotlightVolumePlugin(interface.PlistPlugin):
  """Plist parser plugin for Spotlight volume configuration plist files."""

  NAME = 'spotlight_volume'
  DATA_FORMAT = 'Spotlight volume configuration plist file'

  PLIST_PATH_FILTERS = frozenset([
      interface.PlistPathFilter('VolumeConfiguration.plist')])

  PLIST_KEYS = frozenset(['Stores'])

  # pylint: disable=arguments-differ
  def _ParsePlist(self, parser_mediator, match=None, **unused_kwargs):
    """Extracts relevant Volume Configuration Spotlight 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.
    """
    stores = match.get('Stores', {})
    for volume_name, volume in stores.items():
      datetime_value = volume.get('CreationDate', None)
      if not datetime_value:
        continue

      partial_path = volume['PartialPath']

      event_data = plist_event.PlistTimeEventData()
      event_data.desc = 'Spotlight Volume {0:s} ({1:s}) activated.'.format(
          volume_name, partial_path)
      event_data.key = ''
      event_data.root = '/Stores'

      date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
      date_time.CopyFromDatetime(datetime_value)

      event = time_events.DateTimeValuesEvent(
          date_time, definitions.TIME_DESCRIPTION_WRITTEN)
      parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #6
0
class TimeMachinePlugin(dtfabric_plugin.DtFabricBasePlistPlugin):
    """Plist parser plugin for TimeMachine plist files.

  Further details about the extracted fields:
    DestinationID:
      remote UUID hard disk where the backup is done.

    BackupAlias:
      structure that contains the extra information from the destinationID.

    SnapshotDates:
      list of the backup dates.
  """

    NAME = 'time_machine'
    DATA_FORMAT = 'TimeMachine plist file'

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

    PLIST_KEYS = frozenset(['Destinations', 'RootVolumeUUID'])

    _DEFINITION_FILE = 'timemachine.yaml'

    # pylint: disable=arguments-differ
    def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
        """Extracts relevant TimeMachine 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.
    """
        backup_alias_map = self._GetDataTypeMap('timemachine_backup_alias')

        destinations = match.get('Destinations', [])
        for destination in destinations:
            backup_alias_data = destination.get('BackupAlias', b'')
            try:
                backup_alias = self._ReadStructureFromByteStream(
                    backup_alias_data, 0, backup_alias_map)
                alias = backup_alias.string

            except (ValueError, errors.ParseError) as exception:
                parser_mediator.ProduceExtractionWarning(
                    'unable to parse backup alias value with error: {0!s}'.
                    format(exception))
                alias = 'Unknown alias'

            destination_identifier = (destination.get('DestinationID', None)
                                      or 'Unknown device')

            event_data = plist_event.PlistTimeEventData()
            event_data.desc = 'TimeMachine Backup in {0:s} ({1:s})'.format(
                alias, destination_identifier)
            event_data.key = 'item/SnapshotDates'
            event_data.root = '/Destinations'

            snapshot_dates = destination.get('SnapshotDates', [])
            for datetime_value in snapshot_dates:
                date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                )
                date_time.CopyFromDatetime(datetime_value)

                event = time_events.DateTimeValuesEvent(
                    date_time, definitions.TIME_DESCRIPTION_WRITTEN)
                parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #7
0
class SafariHistoryPlugin(interface.PlistPlugin):
    """Plist parser plugin for Safari history plist files."""

    NAME = 'safari_history'
    DATA_FORMAT = 'Safari history plist file'

    PLIST_PATH_FILTERS = frozenset(
        [interface.PlistPathFilter('History.plist')])

    PLIST_KEYS = frozenset(['WebHistoryDates', 'WebHistoryFileVersion'])

    # pylint: disable=arguments-differ
    def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
        """Extracts Safari history items.

    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.
    """
        format_version = match.get('WebHistoryFileVersion', None)
        if format_version != 1:
            parser_mediator.ProduceExtractionWarning(
                'unsupported Safari history version: {0!s}'.format(
                    format_version))
            return

        if 'WebHistoryDates' not in match:
            return

        for history_entry in match.get('WebHistoryDates', {}):
            last_visited_date = history_entry.get('lastVisitedDate', None)
            if last_visited_date is None:
                parser_mediator.ProduceExtractionWarning(
                    'missing last visited date')
                continue

            try:
                # Last visited date is a string containing a floating point value.
                timestamp = float(last_visited_date)
            except (TypeError, ValueError):
                parser_mediator.ProduceExtractionWarning(
                    'unable to convert last visited date {0:s}'.format(
                        last_visited_date))
                continue

            display_title = history_entry.get('displayTitle', None)

            event_data = SafariHistoryEventData()
            if display_title != event_data.title:
                event_data.display_title = display_title
            event_data.title = history_entry.get('title', None)
            event_data.url = history_entry.get('', None)
            event_data.visit_count = history_entry.get('visitCount', None)
            event_data.was_http_non_get = history_entry.get(
                'lastVisitWasHTTPNonGet', None)

            # Convert the floating point value to an integer.
            # TODO: add support for the fractional part of the floating point value.
            timestamp = int(timestamp)
            date_time = dfdatetime_cocoa_time.CocoaTime(timestamp=timestamp)
            event = time_events.DateTimeValuesEvent(
                date_time, definitions.TIME_DESCRIPTION_LAST_VISITED)
            parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #8
0
class SoftwareUpdatePlugin(interface.PlistPlugin):
    """Plist parser plugin for MacOS software update plist files.

  Further details about the extracted fields:
    LastFullSuccessfulDate:
      timestamp when MacOS was full update.
    LastSuccessfulDate:
      timestamp when MacOS was partially update.
  """

    NAME = 'macos_software_update'
    DATA_FORMAT = 'MacOS software update plist file'

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

    PLIST_KEYS = frozenset([
        'LastFullSuccessfulDate', 'LastSuccessfulDate',
        'LastAttemptSystemVersion', 'LastUpdatesAvailable',
        'LastRecommendedUpdatesAvailable', 'RecommendedUpdates'
    ])

    # pylint: disable=arguments-differ
    def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
        """Extracts relevant MacOS update 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.
    """
        version = match.get('LastAttemptSystemVersion', 'N/A')
        pending = match.get('LastUpdatesAvailable', None)

        event_data = plist_event.PlistTimeEventData()
        event_data.desc = 'Last MacOS {0:s} full update.'.format(version)
        event_data.key = ''
        event_data.root = '/'

        datetime_value = match.get('LastFullSuccessfulDate', None)
        if datetime_value:
            date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
            date_time.CopyFromDatetime(datetime_value)

            event = time_events.DateTimeValuesEvent(
                date_time, definitions.TIME_DESCRIPTION_WRITTEN)
            parser_mediator.ProduceEventWithEventData(event, event_data)

        datetime_value = match.get('LastSuccessfulDate', None)
        if datetime_value and pending:
            software = []
            for update in match.get('RecommendedUpdates', []):
                identifier = update.get('Identifier', '<IDENTIFIER>')
                product_key = update.get('Product Key', '<PRODUCT_KEY>')

                software.append('{0:s}({1:s})'.format(identifier, product_key))

            if not software:
                return

            software = ','.join(software)
            event_data.desc = (
                'Last Mac OS {0!s} partially update, pending {1!s}: '
                '{2:s}.').format(version, pending, software)

            date_time = dfdatetime_time_elements.TimeElementsInMicroseconds()
            date_time.CopyFromDatetime(datetime_value)

            event = time_events.DateTimeValuesEvent(
                date_time, definitions.TIME_DESCRIPTION_WRITTEN)
            parser_mediator.ProduceEventWithEventData(event, event_data)
예제 #9
0
class BluetoothPlugin(interface.PlistPlugin):
    """Plist parser plugin for Bluetooth plist files.

  Additional details about the fields.

  LastInquiryUpdate:
    Device connected via Bluetooth Discovery. Updated
    when a device is detected in discovery mode. E.g. BT headphone power
    on. Pairing is not required for a device to be discovered and cached.

  LastNameUpdate:
    When the human name was last set. Usually done only once during
    initial setup.

  LastServicesUpdate:
    Time set when device was polled to determine what it is. Usually
    done at setup or manually requested via advanced menu.
  """

    NAME = 'macosx_bluetooth'
    DATA_FORMAT = 'Bluetooth plist file'

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

    PLIST_KEYS = frozenset(['DeviceCache', 'PairedDevices'])

    # pylint: disable=arguments-differ
    def GetEntries(self, parser_mediator, match=None, **unused_kwargs):
        """Extracts relevant BT 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.
    """
        device_cache = match.get('DeviceCache', {})
        for device, value in device_cache.items():
            name = value.get('Name', '')
            if name:
                name = ''.join(('Name:', name))

            event_data = plist_event.PlistTimeEventData()
            event_data.root = '/DeviceCache'

            datetime_value = value.get('LastInquiryUpdate', None)
            if datetime_value:
                event_data.desc = ' '.join(
                    filter(None, ('Bluetooth Discovery', name)))
                event_data.key = '{0:s}/LastInquiryUpdate'.format(device)

                date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                )
                date_time.CopyFromDatetime(datetime_value)

                event = time_events.DateTimeValuesEvent(
                    date_time, definitions.TIME_DESCRIPTION_WRITTEN)
                parser_mediator.ProduceEventWithEventData(event, event_data)

                if device in match.get('PairedDevices', []):
                    event_data.desc = 'Paired:True {0:s}'.format(name)
                    event_data.key = device

                    date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                    )
                    date_time.CopyFromDatetime(datetime_value)

                    event = time_events.DateTimeValuesEvent(
                        date_time, definitions.TIME_DESCRIPTION_WRITTEN)
                    parser_mediator.ProduceEventWithEventData(
                        event, event_data)

            datetime_value = value.get('LastNameUpdate', None)
            if datetime_value:
                event_data.desc = ' '.join(
                    filter(None, ('Device Name Set', name)))
                event_data.key = '{0:s}/LastNameUpdate'.format(device)

                date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                )
                date_time.CopyFromDatetime(datetime_value)

                event = time_events.DateTimeValuesEvent(
                    date_time, definitions.TIME_DESCRIPTION_WRITTEN)
                parser_mediator.ProduceEventWithEventData(event, event_data)

            datetime_value = value.get('LastServicesUpdate', None)
            if datetime_value:
                event_data.desc = ' '.join(
                    filter(None, ('Services Updated', name)))
                event_data.key = '{0:s}/LastServicesUpdate'.format(device)

                date_time = dfdatetime_time_elements.TimeElementsInMicroseconds(
                )
                date_time.CopyFromDatetime(datetime_value)

                event = time_events.DateTimeValuesEvent(
                    date_time, definitions.TIME_DESCRIPTION_WRITTEN)
                parser_mediator.ProduceEventWithEventData(event, event_data)