mvt/mvt/ios/modules/mixed/locationd.py

124 lines
4.7 KiB
Python
Raw Normal View History

2021-07-16 06:05:01 +00:00
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2022 Claudio Guarnieri.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
2021-07-16 06:05:01 +00:00
import plistlib
2021-07-16 06:05:01 +00:00
from mvt.common.utils import convert_mactime_to_unix, convert_timestamp_to_iso
2021-08-15 11:14:18 +00:00
from ..base import IOSExtraction
2021-07-16 06:05:01 +00:00
LOCATIOND_BACKUP_IDS = [
"a690d7769cce8904ca2b67320b107c8fe5f79412",
]
LOCATIOND_ROOT_PATHS = [
"private/var/mobile/Library/Caches/locationd/clients.plist",
2021-09-07 13:18:00 +00:00
"private/var/root/Library/Caches/locationd/clients.plist"
2021-07-16 06:05:01 +00:00
]
2021-11-19 14:27:51 +00:00
2021-07-16 06:05:01 +00:00
class LocationdClients(IOSExtraction):
2021-09-07 13:06:19 +00:00
"""Extract information from apps who used geolocation."""
2021-07-16 06:05:01 +00:00
def __init__(self, file_path=None, base_folder=None, output_folder=None,
fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder,
output_folder=output_folder, fast_mode=fast_mode,
log=log, results=results)
2021-08-16 08:50:35 +00:00
2021-07-16 06:05:01 +00:00
self.timestamps = [
"ConsumptionPeriodBegin",
"ReceivingLocationInformationTimeStopped",
"VisitTimeStopped",
"LocationTimeStopped",
"BackgroundLocationTimeStopped",
"SignificantTimeStopped",
"NonPersistentSignificantTimeStopped",
"FenceTimeStopped",
"BeaconRegionTimeStopped",
]
def serialize(self, record):
records = []
for timestamp in self.timestamps:
if timestamp in record.keys():
2021-07-16 06:05:01 +00:00
records.append({
"timestamp": record[timestamp],
2021-07-16 06:05:01 +00:00
"module": self.__class__.__name__,
"event": timestamp,
"data": f"{timestamp} from {record['package']}"
2021-07-16 06:05:01 +00:00
})
return records
2021-09-07 13:06:19 +00:00
def check_indicators(self):
if not self.indicators:
return
2021-09-07 13:06:19 +00:00
for result in self.results:
parts = result["package"].split("/")
proc_name = parts[len(parts)-1]
2022-01-23 14:01:49 +00:00
ioc = self.indicators.check_process(proc_name)
if ioc:
self.log.warning("Found a suspicious process name in LocationD entry %s",
result["package"])
2022-01-23 14:01:49 +00:00
result["matched_indicator"] = ioc
2021-09-07 13:06:19 +00:00
self.detected.append(result)
continue
if "BundlePath" in result:
2022-01-23 14:01:49 +00:00
ioc = self.indicators.check_file_path(result["BundlePath"])
if ioc:
self.log.warning("Found a suspicious file path in Location D: %s",
result["BundlePath"])
2022-01-23 14:01:49 +00:00
result["matched_indicator"] = ioc
self.detected.append(result)
continue
if "Executable" in result:
2022-01-23 14:01:49 +00:00
ioc = self.indicators.check_file_path(result["Executable"])
if ioc:
self.log.warning("Found a suspicious file path in Location D: %s",
result["Executable"])
2022-01-23 14:01:49 +00:00
result["matched_indicator"] = ioc
self.detected.append(result)
continue
if "Registered" in result:
2022-01-23 14:01:49 +00:00
ioc = self.indicators.check_file_path(result["Registered"])
if ioc:
self.log.warning("Found a suspicious file path in Location D: %s",
result["Registered"])
2022-01-23 14:01:49 +00:00
result["matched_indicator"] = ioc
self.detected.append(result)
continue
2021-09-07 13:06:19 +00:00
2021-09-14 12:29:04 +00:00
def _extract_locationd_entries(self, file_path):
with open(file_path, "rb") as handle:
file_plist = plistlib.load(handle)
2021-07-16 06:05:01 +00:00
2021-09-07 13:06:19 +00:00
for key, values in file_plist.items():
result = file_plist[key]
result["package"] = key
for ts in self.timestamps:
if ts in result.keys():
result[ts] = convert_timestamp_to_iso(convert_mactime_to_unix(result[ts]))
2021-07-16 06:05:01 +00:00
2021-09-07 13:06:19 +00:00
self.results.append(result)
2021-07-16 06:05:01 +00:00
2021-09-13 18:02:48 +00:00
def run(self):
if self.is_backup:
self._find_ios_database(backup_ids=LOCATIOND_BACKUP_IDS)
self.log.info("Found Locationd Clients plist at path: %s", self.file_path)
2021-09-14 12:29:04 +00:00
self._extract_locationd_entries(self.file_path)
2021-09-13 18:02:48 +00:00
elif self.is_fs_dump:
for locationd_path in self._get_fs_files_from_patterns(LOCATIOND_ROOT_PATHS):
self.file_path = locationd_path
self.log.info("Found Locationd Clients plist at path: %s", self.file_path)
2021-09-14 12:29:04 +00:00
self._extract_locationd_entries(self.file_path)
2021-09-13 18:02:48 +00:00
2021-07-16 06:05:01 +00:00
self.log.info("Extracted a total of %d Locationd Clients entries", len(self.results))