Skip to content
Draft
106 changes: 66 additions & 40 deletions scripts/artifacts/appleMapsSearchHistory.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@
)

def longbase64proto(longstuff, longtypes):
longstuff = longstuff.split('placeRequest=')[1]
longstuff, _ = blackboxprotobuf.decode_message(base64.b64decode(longstuff), longtypes)
return longstuff
try:
longstuff = longstuff.split('placeRequest=')[1]
# Add padding if needed for base64 decoding
missing_padding = len(longstuff) % 4
if missing_padding:
longstuff += '=' * (4 - missing_padding)
longstuff, _ = blackboxprotobuf.decode_message(base64.b64decode(longstuff), longtypes)
return longstuff
except (ValueError, IndexError, KeyError, Exception) as e:
return None

def shortbase64proto(shortstuff, shorttypes):
shortstuff = shortstuff.split('=')[1]
shortstuff, _ = blackboxprotobuf.decode_message(base64.b64decode(shortstuff), shorttypes)
return shortstuff
try:
shortstuff = shortstuff.split('=')[1]
# Add padding if needed for base64 decoding
missing_padding = len(shortstuff) % 4
if missing_padding:
shortstuff += '=' * (4 - missing_padding)
shortstuff, _ = blackboxprotobuf.decode_message(base64.b64decode(shortstuff), shorttypes)
return shortstuff
except (ValueError, IndexError, KeyError, Exception) as e:
return None

@artifact_processor
def get_appleMapsSearchHistory(context):
Expand Down Expand Up @@ -94,9 +108,10 @@ def get_appleMapsSearchHistory(context):
pass
try:
if protostuff.get('8'):
if (protostuff['8']['2']['1'].get('201')):
usersearchnotinproto = (protostuff['8']['2']['1']['201']['2']['2']['1'].decode())
except (KeyError, AttributeError, UnicodeDecodeError):
nested = protostuff.get('8', {}).get('2', {}).get('1', {}).get('201', {}).get('2', {}).get('2', {}).get('1')
if nested is not None:
usersearchnotinproto = nested.decode() if isinstance(nested, bytes) else str(nested)
except (KeyError, AttributeError, UnicodeDecodeError, TypeError):
#pass
try:
for mira in (protostuff['8']['2']['1']['4']):
Expand All @@ -105,25 +120,26 @@ def get_appleMapsSearchHistory(context):
if mira['11']['2'].startswith(b'pl'):
try:
longstuff = longbase64proto(mira['11']['2'].decode(), longtypes)
app = longstuff['1']['1'].decode()
location = longstuff['8']['1']['3'].decode()
geo1 = longstuff['8']['1']['4']['1']['5']
geo2 = longstuff['8']['1']['4']['1']['6']
geo3 = longstuff['8']['1']['4']['1']['7']
geo4 = longstuff['8']['1']['4']['1']['8']
usersearch1 = longstuff['8']['1']['7']['12']['1'].decode()
usersearch2 = longstuff['8']['1']['7']['10000'].decode()
geo5 = longstuff['8']['1']['7']['5']['1']['1']
geo6 = longstuff['8']['1']['7']['5']['1']['2']
if longstuff:
app = longstuff['1']['1'].decode() if isinstance(longstuff['1']['1'], bytes) else str(longstuff['1']['1'])
location = longstuff['8']['1']['3'].decode() if isinstance(longstuff['8']['1']['3'], bytes) else str(longstuff['8']['1']['3'])
geo1 = longstuff['8']['1']['4']['1']['5']
geo2 = longstuff['8']['1']['4']['1']['6']
geo3 = longstuff['8']['1']['4']['1']['7']
geo4 = longstuff['8']['1']['4']['1']['8']
usersearch1 = longstuff['8']['1']['7']['12']['1'].decode() if isinstance(longstuff['8']['1']['7']['12']['1'], bytes) else str(longstuff['8']['1']['7']['12']['1'])
usersearch2 = longstuff['8']['1']['7']['10000'].decode() if isinstance(longstuff['8']['1']['7']['10000'], bytes) else str(longstuff['8']['1']['7']['10000'])
geo5 = longstuff['8']['1']['7']['5']['1']['1']
geo6 = longstuff['8']['1']['7']['5']['1']['2']
except (KeyError, AttributeError, UnicodeDecodeError, TypeError):
pass

try:

shortstuff = shortbase64proto(mira['11']['2'].decode(), shorttypes)

shortlat = (shortstuff['8']['4']['4']['1']['1'])
shortlon = (shortstuff['8']['4']['4']['1']['2'])
if shortstuff:
shortlat = (shortstuff['8']['4']['4']['1']['1'])
shortlon = (shortstuff['8']['4']['4']['1']['2'])


except (KeyError, AttributeError, UnicodeDecodeError, TypeError):
Expand All @@ -137,18 +153,21 @@ def get_appleMapsSearchHistory(context):
try:
if protostuff.get('7'):
shortstuff = shortbase64proto(protostuff.get('7')['1']['1'][0]['2']['1']['4'][8]['11']['2'].decode(), shorttypes)
app = shortstuff['1']['1'].decode()
location = (shortstuff['8']['1']['3'].decode())
shortlat = (shortstuff['8']['4']['4']['1']['1'])
shortlon = (shortstuff['8']['4']['4']['1']['2'])
if shortstuff:
app = shortstuff['1']['1'].decode() if isinstance(shortstuff['1']['1'], bytes) else str(shortstuff['1']['1'])
location = shortstuff['8']['1']['3'].decode() if isinstance(shortstuff['8']['1']['3'], bytes) else str(shortstuff['8']['1']['3'])
shortlat = (shortstuff['8']['4']['4']['1']['1'])
shortlon = (shortstuff['8']['4']['4']['1']['2'])

if (protostuff.get('7')['1']['1'][1]['1'].get('2')):

#pp.pprint(protostuff.get('7')['1']['1'][1]['1'].get('2')['4']) #address
pname = (protostuff.get('7')['1']['1'][1]['1'].get('2')['5'].decode()) #place name
pname_val = protostuff.get('7')['1']['1'][1]['1'].get('2')['5']
pname = pname_val.decode() if isinstance(pname_val, bytes) else str(pname_val) #place name
shortadd = ''
for parts in (protostuff.get('7')['1']['1'][1]['1'].get('2')['6']):
shortadd = shortadd + parts.decode() + ', '
part_str = parts.decode() if isinstance(parts, bytes) else str(parts)
shortadd = shortadd + part_str + ', '
shortadd = (shortadd[:-2])
except (KeyError, IndexError, AttributeError, UnicodeDecodeError, TypeError):
#pass
Expand All @@ -167,25 +186,32 @@ def get_appleMapsSearchHistory(context):
if mira['11']['2'].startswith(b'pl'):
try:
longstuff = longbase64proto(mira['11']['2'].decode(), longtypes)
app = longstuff['1']['1'].decode()
location = longstuff['8']['1']['3'].decode()
geo1 = longstuff['8']['1']['4']['1']['5']
geo2 = longstuff['8']['1']['4']['1']['6']
geo3 = longstuff['8']['1']['4']['1']['7']
geo4 = longstuff['8']['1']['4']['1']['8']
usersearch1 = longstuff['8']['1']['7']['12']['1'].decode()
usersearch2 = longstuff['8']['1']['7']['10000'].decode()
geo5 = longstuff['8']['1']['7']['5']['1']['1']
geo6 = longstuff['8']['1']['7']['5']['1']['2']
if longstuff:
app = longstuff['1']['1'].decode() if isinstance(longstuff['1']['1'], bytes) else str(longstuff['1']['1'])
location = longstuff['8']['1']['3'].decode() if isinstance(longstuff['8']['1']['3'], bytes) else str(longstuff['8']['1']['3'])
geo1 = longstuff['8']['1']['4']['1']['5']
geo2 = longstuff['8']['1']['4']['1']['6']
geo3 = longstuff['8']['1']['4']['1']['7']
geo4 = longstuff['8']['1']['4']['1']['8']
usersearch1 = longstuff['8']['1']['7']['12']['1'].decode() if isinstance(longstuff['8']['1']['7']['12']['1'], bytes) else str(longstuff['8']['1']['7']['12']['1'])
usersearch2 = longstuff['8']['1']['7']['10000'].decode() if isinstance(longstuff['8']['1']['7']['10000'], bytes) else str(longstuff['8']['1']['7']['10000'])
geo5 = longstuff['8']['1']['7']['5']['1']['1']
geo6 = longstuff['8']['1']['7']['5']['1']['2']
except (KeyError, AttributeError, UnicodeDecodeError, TypeError):
pass
except (KeyError, IndexError, AttributeError, TypeError):
pp = pprint.PrettyPrinter(indent = 0)
items = pp.pformat(protostuff['7']['1']['1'][0]['2']['1']['4'])

# Convert items to string if it's bytes or dict to ensure JSON serialization
if isinstance(items, bytes):
items = items.decode('utf-8', errors='replace')
elif isinstance(items, dict):
items = str(items)

data_list.append((modificationdate,app,location,shortadd,pname,shortlat,shortlon,usersearchnotinproto,usersearch1, usersearch2,geo1,geo2,geo3,geo4,geo5,geo6,guid,currentlocation,items, file_found ))
modificationdate = app = location = shortadd = pname = shortlat = shortlon = usersearch1 = usersearch2 = geo1 = geo2 = geo3 = geo4 = geo5 = geo6 = guid = items = currentlocation = ''

data_headers = (('Timestamp', 'datetime'),'App','Location','Short Address','Place Name','Latitude','Longitude','Search Not in Protobuf','Search Term','Search Term','Lat1','Lon1','Lat2','Lon2','Lat2','Lon3','Record GUID','Current Location','Items', 'Source File')
data_headers = (('Timestamp', 'datetime'),'App','Location','Short Address','Place Name','Latitude','Longitude','Search Not in Protobuf','Search Term 1','Search Term 2','Lat1','Lon1','Lat2','Lon2','Lat3','Lon3','Record GUID','Current Location','Items', 'Source File')

return data_list, data_headers, 'see Source File for more info'
return data_headers, data_list, 'see Source File for more info'
6 changes: 3 additions & 3 deletions scripts/artifacts/applePodcasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def get_applePodcastsShows(context):
'Author','Title',
'Feed URL',
'Description',
'Web Page URL'
'Web Page URL',
'Source File']

for file_found in context.get_files_found():
Expand Down Expand Up @@ -74,7 +74,7 @@ def get_applePodcastsShows(context):

data_list.append((timestampadded,timestampdateplayed,timestampdupdate,timestampdowndate,row[4],row[5],row[6],row[7],row[8], file_found))

return data_list, data_headers, 'see Source File for more info'
return data_headers, data_list, 'see Source File for more info'

@artifact_processor
def get_applePodcastsEpisodes(context):
Expand Down Expand Up @@ -139,4 +139,4 @@ def get_applePodcastsEpisodes(context):

data_list.append((timestampimport,timestampmeta,timestamplastplay,timestamplastmod,timestampdowndate,row[5],row[6],row[7],row[8],row[9],row[10],row[11],row[12],row[13], file_found))

return data_list, data_headers, 'see Source File for more info'
return data_headers, data_list, 'see Source File for more info'
4 changes: 2 additions & 2 deletions scripts/artifacts/bluetoothPairedReg.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import plistlib
import datetime

from scripts.ilapfuncs import artifact_processor, convert_unix_ts_to_str
from scripts.ilapfuncs import artifact_processor, convert_unix_ts_to_utc


@artifact_processor
Expand All @@ -31,7 +31,7 @@ def get_bluetoothPairedReg(files_found, report_folder, seeker, wrap_text, timezo
for x in plist.items():
macaddress = x[0]
if 'LastSeenTime' in x[1]:
lastseen = convert_unix_ts_to_str(x[1]['LastSeenTime'])
lastseen = convert_unix_ts_to_utc(x[1]['LastSeenTime'])
else:
lastseen = ''
if 'UserNameKey' in x[1]:
Expand Down
1 change: 1 addition & 0 deletions scripts/artifacts/deviceActivator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def deviceActivator(files_found, report_folder, seeker, wrap_text, timezone_offs
data_list = []
file_found = str(files_found[0])

alllines = ''
with open(file_found, 'r') as f_in:
for line in f_in:
line = line.strip()
Expand Down
1 change: 1 addition & 0 deletions scripts/artifacts/health.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ def health_workouts(context):
CASE workouts.activity_type''' + activity_types + '''
ELSE "Unknown" || "-" || workouts.activity_type
END AS 'Type',
NULL AS 'Location Type',
strftime('%H:%M:%S', samples.end_date - samples.start_date, 'unixepoch') AS 'Total Time Duration',
strftime('%H:%M:%S', workouts.duration, 'unixepoch') AS 'Duration',
''' + distance_and_goals + '''
Expand Down
23 changes: 17 additions & 6 deletions scripts/artifacts/netusage.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,19 @@ def get_netusage(files_found, report_folder, seeker, wrap_text, timezone_offset)
for row in all_rows:
if row[0] is None:
lastconnected = ''
else:
lastconnected = convert_utc_human_to_timezone(convert_ts_human_to_utc(row[0]),timezone_offset)
else:
ts_result = convert_ts_human_to_utc(row[0])
lastconnected = convert_utc_human_to_timezone(ts_result, timezone_offset) if ts_result else ''
if row[1] is None:
firstused = ''
else:
firstused = convert_utc_human_to_timezone(convert_ts_human_to_utc(row[1]),timezone_offset)
ts_result = convert_ts_human_to_utc(row[1])
firstused = convert_utc_human_to_timezone(ts_result, timezone_offset) if ts_result else ''
if row[2] is None:
lastused = ''
else:
lastused = convert_utc_human_to_timezone(convert_ts_human_to_utc(row[2]),timezone_offset)
ts_result = convert_ts_human_to_utc(row[2])
lastused = convert_utc_human_to_timezone(ts_result, timezone_offset) if ts_result else ''

data_list.append((lastconnected,firstused,lastused,row[3],row[4],row[5],row[6],row[7],row[8],row[9],row[10],row[11]))

Expand Down Expand Up @@ -101,8 +104,16 @@ def get_netusage(files_found, report_folder, seeker, wrap_text, timezone_offset)
data_headers = ('First Connection Timestamp','Last Connection Timestamp','Network Name','Cell Tower ID/Wifi MAC','Network Type','Bytes In','Bytes Out','Connection Attempts','Connection Successes','Packets In','Packets Out') # Don't remove the comma, that is required to make this a tuple as there is only 1 element
data_list = []
for row in all_rows:
firstconncted = convert_utc_human_to_timezone(convert_ts_human_to_utc(row[0]),timezone_offset)
lastconnected = convert_utc_human_to_timezone(convert_ts_human_to_utc(row[1]),timezone_offset)
if row[0] is None:
firstconncted = ''
else:
ts_result = convert_ts_human_to_utc(row[0])
firstconncted = convert_utc_human_to_timezone(ts_result, timezone_offset) if ts_result else ''
if row[1] is None:
lastconnected = ''
else:
ts_result = convert_ts_human_to_utc(row[1])
lastconnected = convert_utc_human_to_timezone(ts_result, timezone_offset) if ts_result else ''

if row[2] == None:
data_list.append((firstconncted,lastconnected,'','',row[3],row[4],row[5],row[6],row[7],row[8],row[9]))
Expand Down
Loading