From a495dad6e5fdd9942ccd98e7eb0d5dbcf40cc759 Mon Sep 17 00:00:00 2001 From: CopasAlpha26 Date: Sat, 23 Nov 2024 09:38:20 +0700 Subject: [PATCH 1/3] improvements to plugin functionality --- plaso/data/formatters/ios_wifi.yaml | 13 +++ plaso/data/timeliner.yaml | 14 +++ plaso/parsers/plist_plugins/__init__.py | 1 + .../plist_plugins/ios_wifi_known_networks.py | 90 ++++++++++++++++++ test_data/com.apple.wifi.known-networks.plist | Bin 0 -> 1650 bytes .../plist_plugins/ios_wifi_known_networks.py | 48 ++++++++++ 6 files changed, 166 insertions(+) create mode 100644 plaso/data/formatters/ios_wifi.yaml create mode 100644 plaso/parsers/plist_plugins/ios_wifi_known_networks.py create mode 100755 test_data/com.apple.wifi.known-networks.plist create mode 100644 tests/parsers/plist_plugins/ios_wifi_known_networks.py diff --git a/plaso/data/formatters/ios_wifi.yaml b/plaso/data/formatters/ios_wifi.yaml new file mode 100644 index 0000000000..2d41da8a8c --- /dev/null +++ b/plaso/data/formatters/ios_wifi.yaml @@ -0,0 +1,13 @@ +type: 'conditional' +data_type: 'ios:wifi:known_networks:knowing' +message: + - 'SSID={ssid}' + - 'BSSID={bssid}' + - 'Channel={channel}' + - 'Added At={added_at_time_str}' + - 'Last Associated={last_associated_time_str}' +short_message: + - 'SSID={ssid}' +short_source: 'PLIST' +source: 'Apple iOS WiFi Known Networks plist file' + diff --git a/plaso/data/timeliner.yaml b/plaso/data/timeliner.yaml index 1681f33d74..793594c7bb 100644 --- a/plaso/data/timeliner.yaml +++ b/plaso/data/timeliner.yaml @@ -581,6 +581,20 @@ attribute_mappings: description: 'Content Modification Time' place_holder_event: true --- +data_type: 'ios:wifi:known_networks:knowing' +attribute_mappings: + - name: 'added_at' + description: 'Time network was added' + - name: 'last_associated' + description: 'Last associated time' + - name: 'ssid' + description: 'SSID of the network' + - name: 'bssid' + description: 'BSSID of the network' + - name: 'channel' + description: 'Channel of the network' +place_holder_event: true +--- data_type: 'ipod:device:entry' attribute_mappings: - name: 'last_connected_time' diff --git a/plaso/parsers/plist_plugins/__init__.py b/plaso/parsers/plist_plugins/__init__.py index a3292555b6..f0a0f5ee12 100644 --- a/plaso/parsers/plist_plugins/__init__.py +++ b/plaso/parsers/plist_plugins/__init__.py @@ -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_wifi_known_networks from plaso.parsers.plist_plugins import ipod from plaso.parsers.plist_plugins import launchd from plaso.parsers.plist_plugins import macos_background_items diff --git a/plaso/parsers/plist_plugins/ios_wifi_known_networks.py b/plaso/parsers/plist_plugins/ios_wifi_known_networks.py new file mode 100644 index 0000000000..46e9657eac --- /dev/null +++ b/plaso/parsers/plist_plugins/ios_wifi_known_networks.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +"""Plist parser plugin for Apple iOS WiFi Known Networks plist files. + +The plist contains information about WiFi networks the device has connected to. +""" + +from dfdatetime import posix_time as dfdatetime_posix_time +from plaso.containers import events +from plaso.parsers import plist +from plaso.parsers.plist_plugins import interface + + +class IOSWiFiKnownNetworksEventData(events.EventData): + """Apple iOS WiFi Known Networks event data. + + Attributes: + ssid (str): SSID of the WiFi network. + added_at (dfdatetime.DateTimeValues): date the network was added. + last_associated (dfdatetime.DateTimeValues): date the network was last associated. + bssid (str): BSSID of the WiFi network. + channel (int): Channel used by the WiFi network. + """ + + DATA_TYPE = 'ios:wifi:known_networks:knowing' + + def __init__(self): + """Initializes event data.""" + super(IOSWiFiKnownNetworksEventData, self).__init__(data_type=self.DATA_TYPE) + self.ssid = None + self.added_at = None + self.last_associated = None + self.bssid = None + self.channel = None + + +class IOSWiFiKnownNetworksPlistPlugin(interface.PlistPlugin): + """Plist parser plugin for Apple iOS WiFi Known Networks plist files.""" + + NAME = 'ios_wifi_known_networks' + DATA_FORMAT = 'Apple iOS WiFi Known Networks plist file' + + PLIST_PATH_FILTERS = frozenset([ + interface.PlistPathFilter('com.apple.wifi.known-networks.plist')]) + + PLIST_KEYS = frozenset([]) + + + def _ParsePlist(self, parser_mediator, match=None, top_level=None, **unused_kwargs): + print(f"Top-level keys in plist: {list(top_level.keys())}") + """Extract WiFi known network 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]]): entire plist file. + """ + for ssid_key, ssid_data in top_level.items(): + added_at = ssid_data.get('AddedAt') + bssid_list = ssid_data.get('BSSList', []) + + + for bssid_data in bssid_list: + event_data = IOSWiFiKnownNetworksEventData() + event_data.ssid = ssid_key + + if added_at: + added_at_obj = dfdatetime_posix_time.PosixTime( + timestamp=added_at.timestamp()) + event_data.added_at = added_at_obj + event_data.added_at_time_str = added_at_obj.CopyToDateTimeString() + + event_data.bssid = bssid_data.get('BSSID') + event_data.channel = bssid_data.get('Channel') + + + last_associated = bssid_data.get('LastAssociatedAt') + if last_associated: + last_associated_obj = dfdatetime_posix_time.PosixTime( + timestamp=last_associated.timestamp()) + event_data.last_associated = last_associated_obj + event_data.last_associated_time_str = last_associated_obj.CopyToDateTimeString() + + print(f"Debug Event: SSID={event_data.ssid}, Added At={event_data.added_at_time_str}, Last Associated={event_data.last_associated_time_str}") + + parser_mediator.ProduceEventData(event_data) + + + +plist.PlistParser.RegisterPlugin(IOSWiFiKnownNetworksPlistPlugin) diff --git a/test_data/com.apple.wifi.known-networks.plist b/test_data/com.apple.wifi.known-networks.plist new file mode 100755 index 0000000000000000000000000000000000000000..37218a0f653c70f40450163c5ddfb35cf1f5b0a6 GIT binary patch literal 1650 zcmbtTT}&KR6uxus-MT;}ccHBUt*!#CRG_e1c40KpfnEOGKbc)tD(vmBb9Xysnc40P z;QFF9@dr&bF@33NYy4~LgGL{G(PAY*TN4x0Xw?K78)J^}bBz zobPs$LV1*bO+n!qV!Y)icFQ!~b?sj$L&x-*$UleZ%%0ciic|>+Z&; z=AGe4H1_bwc)9z8E@c@dwNt7#r4+ePc_PP64m* zX(g;*Jf1aCK8g2uc&~@=>E<(gc{$_46%K$DK0oWxV9IY40y-c6<1}U3`~03qL>U<-MJD^1=Tz)Whs#pp^9a)(^6j z92^?HNw#ix*_PgmR9VCL@LcKZCIhH zS3hG^5Z^oXuy8ka zPO41Yrp2nxv+vk^2d8o-Zo|sRQH!tn+vmxM&8LPn6SrYO7RsFA4< z7OG~~M@>)LnoSYIikMR#Z?Pk@bB|edYwu|7R*_Z Date: Tue, 26 Nov 2024 19:20:11 +0700 Subject: [PATCH 2/3] update ios.yml --- plaso/data/formatters/ios.yaml | 13 +++++++++++++ plaso/data/formatters/ios_wifi.yaml | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 plaso/data/formatters/ios_wifi.yaml diff --git a/plaso/data/formatters/ios.yaml b/plaso/data/formatters/ios.yaml index bd3c3b005c..4a4adcab57 100644 --- a/plaso/data/formatters/ios.yaml +++ b/plaso/data/formatters/ios.yaml @@ -1,6 +1,19 @@ # Plaso iOS related event formatters. --- type: 'conditional' +data_type: 'ios:wifi:known_networks:knowing' +message: + - 'SSID={ssid}' + - 'BSSID={bssid}' + - 'Channel={channel}' + - 'Added At={added_at_time_str}' + - 'Last Associated={last_associated_time_str}' +short_message: + - 'SSID={ssid}' +short_source: 'PLIST' +source: 'Apple iOS WiFi Known Networks plist file' +--- +type: 'conditional' data_type: 'ios:app_privacy:access' message: - 'Accessor Identifier: {accessor_identifier}' diff --git a/plaso/data/formatters/ios_wifi.yaml b/plaso/data/formatters/ios_wifi.yaml deleted file mode 100644 index 2d41da8a8c..0000000000 --- a/plaso/data/formatters/ios_wifi.yaml +++ /dev/null @@ -1,13 +0,0 @@ -type: 'conditional' -data_type: 'ios:wifi:known_networks:knowing' -message: - - 'SSID={ssid}' - - 'BSSID={bssid}' - - 'Channel={channel}' - - 'Added At={added_at_time_str}' - - 'Last Associated={last_associated_time_str}' -short_message: - - 'SSID={ssid}' -short_source: 'PLIST' -source: 'Apple iOS WiFi Known Networks plist file' - From 98cbea3d2e850f50ff6d5e0c086ab877dd75b54d Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Fri, 27 Dec 2024 08:16:17 +0100 Subject: [PATCH 3/3] Changes after review --- plaso/data/formatters/ios.yaml | 32 +++-- plaso/data/timeliner.yaml | 18 +-- .../plist_plugins/ios_wifi_known_networks.py | 123 ++++++++---------- .../plist_plugins/ios_wifi_known_networks.py | 52 ++++---- 4 files changed, 103 insertions(+), 122 deletions(-) diff --git a/plaso/data/formatters/ios.yaml b/plaso/data/formatters/ios.yaml index 4a4adcab57..902ae683b6 100644 --- a/plaso/data/formatters/ios.yaml +++ b/plaso/data/formatters/ios.yaml @@ -1,19 +1,6 @@ # Plaso iOS related event formatters. --- type: 'conditional' -data_type: 'ios:wifi:known_networks:knowing' -message: - - 'SSID={ssid}' - - 'BSSID={bssid}' - - 'Channel={channel}' - - 'Added At={added_at_time_str}' - - 'Last Associated={last_associated_time_str}' -short_message: - - 'SSID={ssid}' -short_source: 'PLIST' -source: 'Apple iOS WiFi Known Networks plist file' ---- -type: 'conditional' data_type: 'ios:app_privacy:access' message: - 'Accessor Identifier: {accessor_identifier}' @@ -60,8 +47,8 @@ data_type: 'ios:datausage:event' message: - 'Bundle Identifier: {bundle_identifier}' - 'Process Name: {process_name}' -- 'Wifi In: {wifi_in}' -- 'Wifi Out: {wifi_out}' +- 'WiFi In: {wifi_in}' +- 'WiFi Out: {wifi_out}' - 'Wireless Wan In: {wireless_wan_in}' - 'Wireless Wan Out: {wireless_wan_out}' short_message: @@ -141,8 +128,8 @@ type: 'conditional' data_type: 'ios:netusage:process' message: - 'Process Name: {process_name}' -- 'Wifi In: {wifi_in}' -- 'Wifi Out: {wifi_out}' +- 'WiFi In: {wifi_in}' +- 'WiFi Out: {wifi_out}' - 'Wired In: {wired_in}' - 'Wired Out: {wired_out}' - 'Wireless Wan In: {wireless_wan_in}' @@ -246,3 +233,14 @@ short_message: - 'Message: {text}' short_source: 'Twitter iOS' source: 'Twitter iOS Status' +--- +type: 'conditional' +data_type: 'ios:wifi:known_networks:entry' +message: +- 'SSID: {ssid}' +- 'BSSID: {bssid}' +- 'Channel: {channel}' +short_message: +- 'SSID: {ssid}' +short_source: 'PLIST' +source: 'Apple iOS WiFi Known Networks plist file' diff --git a/plaso/data/timeliner.yaml b/plaso/data/timeliner.yaml index 793594c7bb..0ef14bf9ca 100644 --- a/plaso/data/timeliner.yaml +++ b/plaso/data/timeliner.yaml @@ -581,18 +581,12 @@ attribute_mappings: description: 'Content Modification Time' place_holder_event: true --- -data_type: 'ios:wifi:known_networks:knowing' -attribute_mappings: - - name: 'added_at' - description: 'Time network was added' - - name: 'last_associated' - description: 'Last associated time' - - name: 'ssid' - description: 'SSID of the network' - - name: 'bssid' - description: 'BSSID of the network' - - name: 'channel' - description: 'Channel of the network' +data_type: 'ios:wifi:known_networks:entry' +attribute_mappings: +- name: 'added_time' + description: 'Time network was added' +- name: 'last_associated_time' + description: 'Last associated time' place_holder_event: true --- data_type: 'ipod:device:entry' diff --git a/plaso/parsers/plist_plugins/ios_wifi_known_networks.py b/plaso/parsers/plist_plugins/ios_wifi_known_networks.py index 46e9657eac..c22b64e3d1 100644 --- a/plaso/parsers/plist_plugins/ios_wifi_known_networks.py +++ b/plaso/parsers/plist_plugins/ios_wifi_known_networks.py @@ -4,87 +4,76 @@ The plist contains information about WiFi networks the device has connected to. """ -from dfdatetime import posix_time as dfdatetime_posix_time from plaso.containers import events from plaso.parsers import plist from plaso.parsers.plist_plugins import interface class IOSWiFiKnownNetworksEventData(events.EventData): - """Apple iOS WiFi Known Networks event data. - - Attributes: - ssid (str): SSID of the WiFi network. - added_at (dfdatetime.DateTimeValues): date the network was added. - last_associated (dfdatetime.DateTimeValues): date the network was last associated. - bssid (str): BSSID of the WiFi network. - channel (int): Channel used by the WiFi network. - """ - - DATA_TYPE = 'ios:wifi:known_networks:knowing' - - def __init__(self): - """Initializes event data.""" - super(IOSWiFiKnownNetworksEventData, self).__init__(data_type=self.DATA_TYPE) - self.ssid = None - self.added_at = None - self.last_associated = None - self.bssid = None - self.channel = None + """Apple iOS WiFi Known Networks event data. + + Attributes: + added_time (dfdatetime.DateTimeValues): date the network was added. + bssid (str): BSSID of the WiFi network. + channel (int): Channel used by the WiFi network. + last_associated_time (dfdatetime.DateTimeValues): date the network was last + associated. + ssid (str): SSID of the WiFi network. + """ + + DATA_TYPE = 'ios:wifi:known_networks:entry' + + def __init__(self): + """Initializes event data.""" + super(IOSWiFiKnownNetworksEventData, self).__init__( + data_type=self.DATA_TYPE) + self.added_time = None + self.bssid = None + self.channel = None + self.last_associated_time = None + self.ssid = None class IOSWiFiKnownNetworksPlistPlugin(interface.PlistPlugin): - """Plist parser plugin for Apple iOS WiFi Known Networks plist files.""" - - NAME = 'ios_wifi_known_networks' - DATA_FORMAT = 'Apple iOS WiFi Known Networks plist file' - - PLIST_PATH_FILTERS = frozenset([ - interface.PlistPathFilter('com.apple.wifi.known-networks.plist')]) - - PLIST_KEYS = frozenset([]) - + """Plist parser plugin for Apple iOS WiFi Known Networks plist files.""" - def _ParsePlist(self, parser_mediator, match=None, top_level=None, **unused_kwargs): - print(f"Top-level keys in plist: {list(top_level.keys())}") - """Extract WiFi known network entries. + NAME = 'ios_wifi_known_networks' + DATA_FORMAT = 'Apple iOS WiFi Known Networks plist file' - 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]]): entire plist file. - """ - for ssid_key, ssid_data in top_level.items(): - added_at = ssid_data.get('AddedAt') - bssid_list = ssid_data.get('BSSList', []) + PLIST_PATH_FILTERS = frozenset([ + interface.PlistPathFilter('com.apple.wifi.known-networks.plist')]) + PLIST_KEYS = frozenset([]) - for bssid_data in bssid_list: - event_data = IOSWiFiKnownNetworksEventData() - event_data.ssid = ssid_key - - if added_at: - added_at_obj = dfdatetime_posix_time.PosixTime( - timestamp=added_at.timestamp()) - event_data.added_at = added_at_obj - event_data.added_at_time_str = added_at_obj.CopyToDateTimeString() - - event_data.bssid = bssid_data.get('BSSID') - event_data.channel = bssid_data.get('Channel') - - - last_associated = bssid_data.get('LastAssociatedAt') - if last_associated: - last_associated_obj = dfdatetime_posix_time.PosixTime( - timestamp=last_associated.timestamp()) - event_data.last_associated = last_associated_obj - event_data.last_associated_time_str = last_associated_obj.CopyToDateTimeString() - - print(f"Debug Event: SSID={event_data.ssid}, Added At={event_data.added_at_time_str}, Last Associated={event_data.last_associated_time_str}") - - parser_mediator.ProduceEventData(event_data) + def _ParsePlist( + self, parser_mediator, match=None, top_level=None, **unused_kwargs): + """Extract WiFi known network 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]]): entire plist file. + """ + for network_values in top_level.values(): + event_data = IOSWiFiKnownNetworksEventData() + event_data.added_time = self._GetDateTimeValueFromPlistKey( + network_values, 'AddedAt') + # TODO: add support for JoinedByUserAt + # TODO: add support for JoinedBySystemAt + # TODO: add support for UpdatedAt + event_data.ssid = network_values.get('SSID').decode('utf8') + + for bssid_data in network_values.get('BSSList', []): + event_data.bssid = bssid_data.get('BSSID') + event_data.channel = bssid_data.get('Channel') + event_data.last_associated_time = self._GetDateTimeValueFromPlistKey( + bssid_data, 'LastAssociatedAt') + + parser_mediator.ProduceEventData(event_data) + + # TODO: add support for __OSSpecific__ knownBSSUpdatedDate, + # prevJoined and WiFiNetworkPasswordModificationDate plist.PlistParser.RegisterPlugin(IOSWiFiKnownNetworksPlistPlugin) diff --git a/tests/parsers/plist_plugins/ios_wifi_known_networks.py b/tests/parsers/plist_plugins/ios_wifi_known_networks.py index 05d4a12e1d..5558470e97 100644 --- a/tests/parsers/plist_plugins/ios_wifi_known_networks.py +++ b/tests/parsers/plist_plugins/ios_wifi_known_networks.py @@ -10,39 +10,39 @@ class IOSWiFiKnownNetworksPlistPluginTest(test_lib.PlistPluginTestCase): - """Tests for the Apple iOS WiFi Known Networks plist plugin.""" + """Tests for the Apple iOS WiFi Known Networks plist plugin.""" - def testProcess(self): - """Tests the Process function.""" - plist_name = 'com.apple.wifi.known-networks.plist' + def testProcess(self): + """Tests the Process function.""" + plist_name = 'com.apple.wifi.known-networks.plist' - plugin = ios_wifi_known_networks.IOSWiFiKnownNetworksPlistPlugin() - storage_writer = self._ParsePlistFileWithPlugin( - plugin, [plist_name], plist_name) + plugin = ios_wifi_known_networks.IOSWiFiKnownNetworksPlistPlugin() + storage_writer = self._ParsePlistFileWithPlugin( + plugin, [plist_name], plist_name) - number_of_event_data = storage_writer.GetNumberOfAttributeContainers( - 'event_data') - self.assertEqual(number_of_event_data, 9) + number_of_event_data = storage_writer.GetNumberOfAttributeContainers( + 'event_data') + self.assertEqual(number_of_event_data, 9) - number_of_warnings = storage_writer.GetNumberOfAttributeContainers( - 'extraction_warning') - self.assertEqual(number_of_warnings, 0) + number_of_warnings = storage_writer.GetNumberOfAttributeContainers( + 'extraction_warning') + self.assertEqual(number_of_warnings, 0) - number_of_recovery_warnings = storage_writer.GetNumberOfAttributeContainers( - 'recovery_warning') - self.assertEqual(number_of_recovery_warnings, 0) + number_of_recovery_warnings = storage_writer.GetNumberOfAttributeContainers( + 'recovery_warning') + self.assertEqual(number_of_recovery_warnings, 0) - expected_event_values = { - 'ssid': 'wifi.network.ssid.Matt_Foley', - 'bssid': '76:a7:41:e7:7c:9d', - 'data_type': 'ios:wifi:known_networks:knowing', - 'channel': 1, - 'added_at': '2023-04-15T13:53:47+00:00', - 'last_associated': '2023-05-14T01:15:45+00:00'} + expected_event_values = { + 'added_time': '2023-04-15T13:53:47.476017+00:00', + 'bssid': '76:a7:41:e7:7c:9d', + 'channel': 1, + 'data_type': 'ios:wifi:known_networks:entry', + 'last_associated_time': '2023-05-14T01:15:45.013600+00:00', + 'ssid': 'Matt_Foley'} - event_data = storage_writer.GetAttributeContainerByIndex('event_data', 0) - self.CheckEventData(event_data, expected_event_values) + event_data = storage_writer.GetAttributeContainerByIndex('event_data', 0) + self.CheckEventData(event_data, expected_event_values) if __name__ == '__main__': - unittest.main() + unittest.main()