diff --git a/scripts/artifacts/chromeDIPS.py b/scripts/artifacts/chromeDIPS.py index b93e7f2c..6be17bcd 100644 --- a/scripts/artifacts/chromeDIPS.py +++ b/scripts/artifacts/chromeDIPS.py @@ -6,12 +6,11 @@ # Thanks to Ryan Benson for awareness https://github.com/obsidianforensics/hindsight/pull/146/commits/015ee189c97c0a4e48deb59568dfe4f536ace8aa import os -import sqlite3 from scripts.artifact_report import ArtifactHtmlReport -from scripts.ilapfuncs import logfunc, tsv, timeline, is_platform_windows, get_next_unused_name, open_sqlite_db_readonly +from scripts.ilapfuncs import logfunc, tsv, timeline, get_next_unused_name, open_sqlite_db_readonly from scripts.artifacts.chrome import get_browser_name -def get_chromeDIPS(files_found, report_folder, seeker, wrap_text): +def get_chromeDIPS(files_found, report_folder): for file_found in files_found: file_found = str(file_found) @@ -29,34 +28,31 @@ def get_chromeDIPS(files_found, report_folder, seeker, wrap_text): columns = [i[1] for i in cursor.execute('PRAGMA table_info(bounces)')] - if 'first_stateless_bounce_time' not in columns: - cursor.execute(''' - select - site, - case first_site_storage_time - when 0 then '' - else datetime((first_site_storage_time/1000000)-11644473600,'unixepoch') - end, - case last_site_storage_time - when 0 then '' - else datetime((last_site_storage_time/1000000)-11644473600,'unixepoch') - end, - case first_user_interaction_time - when 0 then '' - else datetime((first_user_interaction_time/1000000)-11644473600,'unixepoch') - end, - case last_user_interaction_time - when 0 then '' - else datetime((last_user_interaction_time/1000000)-11644473600,'unixepoch') - end, - case first_stateful_bounce_time + stateless = 'first_stateless_bounce_time' in columns + + if 'first_user_interaction_time' in columns: + first_user_col = 'first_user_interaction_time' + else: + first_user_col = 'first_user_activation_time' + + if 'last_user_interaction_time' in columns: + last_user_col = 'last_user_interaction_time' + else: + last_user_col = 'last_user_activation_time' + + if stateless: + last_bounce_expr = """ + case first_stateless_bounce_time when 0 then '' - else datetime((first_stateful_bounce_time/1000000)-11644473600,'unixepoch') + else datetime((first_stateless_bounce_time/1000000)-11644473600,'unixepoch') end, - case last_stateful_bounce_time + case last_stateless_bounce_time when 0 then '' - else datetime((last_stateful_bounce_time/1000000)-11644473600,'unixepoch') - end, + else datetime((last_stateless_bounce_time/1000000)-11644473600,'unixepoch') + end + """ + else: + last_bounce_expr = """ case first_bounce_time when 0 then '' else datetime((first_bounce_time/1000000)-11644473600,'unixepoch') @@ -65,41 +61,9 @@ def get_chromeDIPS(files_found, report_folder, seeker, wrap_text): when 0 then '' else datetime((last_bounce_time/1000000)-11644473600,'unixepoch') end - from bounces - ''') - - all_rows = cursor.fetchall() - usageentries = len(all_rows) - if usageentries > 0: - description = 'DIPS - Incidental parties are sites without meaningful user interactions, such as bounce trackers' - report = ArtifactHtmlReport(f'{browser_name} - Detect Incidental Party State') - #check for existing and get next name for report file, so report from another file does not get overwritten - report_path = os.path.join(report_folder, f'{browser_name} - Detect Incidental Party State.temphtml') - report_path = get_next_unused_name(report_path)[:-9] # remove .temphtml - report.start_artifact_report(report_folder, os.path.basename(report_path), description) - report.add_script() - data_headers = ('Site','First Site Storage Timestamp','Last Site Storage Timestamp','First User Interaction Timestamp','Last User Interaction Timestamp','First Stateful Bounce Timestamp','Last Stateful Bounce Timestamp','First Stateless Bounce Timestamp','Last Stateless Bounce Timestamp') # Don't remove the comma, that is required to make this a tuple as there is only 1 element - tl_data_headers = ('First Site Storage Timestamp','Site','Last Site Storage Timestamp','First User Interaction Timestamp','Last User Interaction Timestamp','First Stateful Bounce Timestamp','Last Stateful Bounce Timestamp','First Bounce Timestamp','Last Bounce Timestamp') - data_list = [] - tl_data_list = [] - for row in all_rows: - data_list.append((row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8])) - - tl_data_list.append((row[1],row[0],row[2],row[3],row[4],row[5],row[6],row[7],row[8])) + """ - report.write_artifact_data_table(data_headers, data_list, file_found) - report.end_artifact_report() - - tsvname = f'{browser_name} - Detect Incidental Party State' - tsv(report_folder, data_headers, data_list, tsvname) - - tlactivity = f'{browser_name} - Detect Incidental Party State' - timeline(report_folder, tlactivity, tl_data_list, tl_data_headers) - else: - logfunc(f'No {browser_name} - Detect Incidental Party State data available') - - else: - cursor.execute(''' + sql = f''' select site, case first_site_storage_time @@ -110,13 +74,13 @@ def get_chromeDIPS(files_found, report_folder, seeker, wrap_text): when 0 then '' else datetime((last_site_storage_time/1000000)-11644473600,'unixepoch') end, - case first_user_interaction_time + case {first_user_col} when 0 then '' - else datetime((first_user_interaction_time/1000000)-11644473600,'unixepoch') + else datetime(({first_user_col}/1000000)-11644473600,'unixepoch') end, - case last_user_interaction_time + case {last_user_col} when 0 then '' - else datetime((last_user_interaction_time/1000000)-11644473600,'unixepoch') + else datetime(({last_user_col}/1000000)-11644473600,'unixepoch') end, case first_stateful_bounce_time when 0 then '' @@ -126,47 +90,63 @@ def get_chromeDIPS(files_found, report_folder, seeker, wrap_text): when 0 then '' else datetime((last_stateful_bounce_time/1000000)-11644473600,'unixepoch') end, - case first_stateless_bounce_time - when 0 then '' - else datetime((first_stateless_bounce_time/1000000)-11644473600,'unixepoch') - end, - case last_stateless_bounce_time - when 0 then '' - else datetime((last_stateless_bounce_time/1000000)-11644473600,'unixepoch') - end + {last_bounce_expr} from bounces - ''') - - all_rows = cursor.fetchall() - usageentries = len(all_rows) - if usageentries > 0: - description = 'DIPS - Incidental parties are sites without meaningful user interactions, such as bounce trackers' - report = ArtifactHtmlReport(f'{browser_name} - Detect Incidental Party State') - #check for existing and get next name for report file, so report from another file does not get overwritten - report_path = os.path.join(report_folder, f'{browser_name} - Detect Incidental Party State.temphtml') - report_path = get_next_unused_name(report_path)[:-9] # remove .temphtml - report.start_artifact_report(report_folder, os.path.basename(report_path), description) - report.add_script() - data_headers = ('Site','First Site Storage Timestamp','Last Site Storage Timestamp','First User Interaction Timestamp','Last User Interaction Timestamp','First Stateful Bounce Timestamp','Last Stateful Bounce Timestamp','First Stateless Bounce Timestamp','Last Stateless Bounce Timestamp') # Don't remove the comma, that is required to make this a tuple as there is only 1 element - tl_data_headers = ('First Site Storage Timestamp','Site','Last Site Storage Timestamp','First User Interaction Timestamp','Last User Interaction Timestamp','First Stateful Bounce Timestamp','Last Stateful Bounce Timestamp','First Stateless Bounce Timestamp','Last Stateless Bounce Timestamp') - data_list = [] - tl_data_list = [] - for row in all_rows: - data_list.append((row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8])) - - tl_data_list.append((row[1],row[0],row[2],row[3],row[4],row[5],row[6],row[7],row[8])) + ''' - report.write_artifact_data_table(data_headers, data_list, file_found) - report.end_artifact_report() - - tsvname = f'{browser_name} - Detect Incidental Party State' - tsv(report_folder, data_headers, data_list, tsvname) - - tlactivity = f'{browser_name} - Detect Incidental Party State' - timeline(report_folder, tlactivity, tl_data_list, tl_data_headers) + cursor.execute(sql) + all_rows = cursor.fetchall() + usageentries = len(all_rows) + if usageentries > 0: + description = 'DIPS - Incidental parties are sites without meaningful user interactions, such as bounce trackers' + report = ArtifactHtmlReport(f'{browser_name} - Detect Incidental Party State') + report_path = os.path.join(report_folder, f'{browser_name} - Detect Incidental Party State.temphtml') + report_path = get_next_unused_name(report_path)[:-9] + report.start_artifact_report(report_folder, os.path.basename(report_path), description) + report.add_script() + data_headers = ( + 'Site', + 'First Site Storage Timestamp', + 'Last Site Storage Timestamp', + 'First User Interaction Timestamp', + 'Last User Interaction Timestamp', + 'First Stateful Bounce Timestamp', + 'Last Stateful Bounce Timestamp', + 'First Stateless Bounce Timestamp', + 'Last Stateless Bounce Timestamp' + ) + if stateless: + tl_last = ('First Stateless Bounce Timestamp', 'Last Stateless Bounce Timestamp') else: - logfunc(f'No {browser_name} - Detect Incidental Party State data available') - + tl_last = ('First Bounce Timestamp', 'Last Bounce Timestamp') + tl_data_headers = ( + 'First Site Storage Timestamp', + 'Site', + 'Last Site Storage Timestamp', + 'First User Interaction Timestamp', + 'Last User Interaction Timestamp', + 'First Stateful Bounce Timestamp', + 'Last Stateful Bounce Timestamp', + tl_last[0], + tl_last[1] + ) + data_list = [] + tl_data_list = [] + for row in all_rows: + data_list.append((row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])) + tl_data_list.append((row[1], row[0], row[2], row[3], row[4], row[5], row[6], row[7], row[8])) + + report.write_artifact_data_table(data_headers, data_list, file_found) + report.end_artifact_report() + + tsvname = f'{browser_name} - Detect Incidental Party State' + tsv(report_folder, data_headers, data_list, tsvname) + + tlactivity = f'{browser_name} - Detect Incidental Party State' + timeline(report_folder, tlactivity, tl_data_list, tl_data_headers) + else: + logfunc(f'No {browser_name} - Detect Incidental Party State data available') + db.close() __artifacts__ = {