本文詳細分析了三星Gallery3d應用中的刪除痕跡取證技術,包括SQLite數據庫結構解析、Base64編碼路徑的解碼方法、Python自動化腳本開發,以及通過逆向工程APK來理解數據編碼機制的全過程。

Mike與猴子深入挖掘三星Gallery3d應用垃圾數據

這一切始於Michael Lacombe在2021年11月初在Physical and RAW Mobile Forensics Google羣組上發佈的一個帖子。該帖子涉及一個案例,三星手機用户聲稱收到了特定圖片,但在訪問後立即被刪除。Mike被問及是否有可能確定這一點。由於不知道這個問題的直接答案,他開始分析三星Android 9設備。

Mike發現在local.db SQLite數據庫中有一些三星Gallery3d應用的刪除痕跡可見。具體來説,他在"log"表中看到了各種帶時間戳的日誌條目,這些條目與編碼字符串相關聯。在論壇成員"Tony"提示這些字符串是base64編碼後,Mike開始了更深入的研究。

在研究過程中,他發現了Cheeky4n6monkey在2016年發佈的這篇帖子。將該信息與他當前的案例數據進行比較後,他發現這些年來情況發生了很大變化,但這足以促使他進行更深入的挖掘。Mike詢問這隻猴子是否想一起參與,於是冒險開始了...

研究過程中的發現

總有新事物需要研究

三星Gallery3d應用已經存在多年,根據Google Play,它最後更新於2019年,版本為5.4.11.0。從測試設備的Gallery3d Android包(APK)中打開AndroidManifest.xml文件顯示:

android:versionCode="1020000021"
android:versionName="10.2.00.21"

根據Android開發者文檔,versionName顯示給用户,而versionCode是一個正整數,隨着每個版本發佈而增加,可用於防止降級到早期版本。

這個應用更新頻繁。在搜索測試數據時,我們發現幾乎我們查看的每個設備都包含不同版本的應用,這反過來導致應用程序文件夾和數據庫本身存儲的信息也不同。

挖掘應用痕跡可帶來當前未被解析的額外信息

據我們確定,目前沒有商業或非商業取證工具處理三星Gallery3d應用數據庫的刪除痕跡。

我們用於分析數據和APK的一些開源工具包括:

數據分析:

  • DB Browser for SQLite - 查看/導出SQLite數據庫
  • Cyberchef - base64解碼字符串
  • Base64 Decode and Encode網站 - base64解碼字符串
  • Epochconverter - 確認時間戳類型
  • Android Studio

APK逆向:

  • dex2jar - 將APK的classes.dex轉換為Java .jar
  • JD-GUI - 從.jar文件查看源代碼
  • JADX - 直接從APK文件查看源代碼

我們還編寫了自己的Python3腳本來協助批量轉換base64編碼字符串並輸出到製表符分隔變量(TSV)格式。

三星Gallery3d應用的觀察結果

這是安裝在三星設備上的庫存應用。它具有屬於三星Android框架部分的庫依賴項。因此,似乎沒有簡單的方法(如果有的話)在非三星設備上安裝該應用程序。

三星Gallery3d應用位於用户數據分區:
/data/com.sec.android.gallery3d

從應用內發送到垃圾箱的文件位於:
/media/0/Android/data/com.sec.android.gallery3d

由於應用程序每個版本的差異以及研究由Mike的案例驅動,我們決定將本博客重點放在該應用程序版本(10.2.00.21)上。

緩存目錄

/data/com.sec.android.gallery3d/cache/內有多個緩存子目錄。在這種情況下,/0文件夾包含較大的縮略圖圖像,寬度範圍225-512像素,高度範圍256-656像素,而/1文件夾有較小的縮略圖,寬度範圍51-175像素,高度範圍63-177像素。還有/2、/3和/4文件夾。/2和/3為空,/4有一個大小為320x320的單個縮略圖。

除了縮略圖本身之外,這裏似乎沒有什麼有用的東西。縮略圖的名稱似乎使用哈希算法生成。

數據庫目錄

/data/com.sec.android.gallery3d/cache/databases/中包含local.db SQLite數據庫。

此數據庫包含各種信息,包括:

  • 畫廊中的相冊("album"表)
  • 記錄與應用相關的各種操作的日誌("log"表),例如移動到垃圾箱、清空垃圾箱
  • 當前在垃圾箱中的項目("trash"表)

在後期版本中,我們注意到另一個名為"filesystem_monitor"的表。它包含時間戳、應用包名稱(例如com.sec.android.gallery3d)和base64編碼的文件路徑。但是,由於此表不在Mike的案例數據中,我們不確定是什麼觸發了這些記錄,需要進一步研究。

表觀察

"album"表

以下是"album"表模式:

CREATE TABLE album (_id INTEGER PRIMARY KEY AUTOINCREMENT, 
__bucketID INTEGER UNIQUE NOT NULL, 
__absPath TEXT, 
__Title TEXT, 
folder_id INTEGER, 
folder_name TEXT, 
default_cover_path TEXT, 
cover_path TEXT, 
cover_rect TEXT, 
album_order INTEGER, 
album_count INTEGER, 
__ishide INTEGER, 
__sefFileType INTEGER DEFAULT 0, 
__isDrm INTEGER DEFAULT 0, 
__dateModified INTEGER DEFAULT 0)

重要字段:

  • _bucketID:通過對相冊完整路徑("_abspath")調用Java hashcode算法生成
  • _abspath:相冊的路徑,例如:/storage/emulated/0/DCIM/Screenshots
  • default_cover_path:與相應相冊關聯的圖像
  • album_count:相冊中當前存儲的文件數

"log"表

以下是"log"表模式:

CREATE TABLE log (_id INTEGER PRIMARY KEY AUTOINCREMENT, 
__category INTEGER NOT NULL, 
__timestamp TEXT, 
__log TEXT)

重要字段:

  • _timestamp:特定日誌條目發生的時間戳文本字符串(格式為YYYY-MM-DD HH:MM:SS本地時間)
  • _log:專有格式文本字符串,列出執行的"操作"和相關文件的base64編碼路徑

觀察到的日誌"操作"包括:

  • MOUNTED:未知何時觸發,告知當前垃圾箱中有多少文件
  • MOVE_TO_TRASH_SINGLE:用户從時間線或畫廊視圖將單個文件移動到垃圾箱時發生
  • MOVE_TO_TRASH_MULTIPLE:用户從時間線或畫廊視圖將多個文件移動到垃圾箱時發生
  • EMPTY_SINGLE:手動清空垃圾箱且當時垃圾箱中有一個文件時發生
  • EMPTY_MULTIPLE:手動清空垃圾箱且包含多個文件時發生
  • EMPTY_EXPIRED:文件在垃圾箱中停留預定時間後自動刪除時發生

Base64編碼字符串解碼示例

原始值:

[MOVE_TO_TRASH_SINGLE][1][0][location://timeline?position=9&mediaItem=data%3A%2F%2FmediaItem%2F-575841975&from_expand=false][eTgcy4piFL3Pil4904piFb+KXj3LimIVh4pePZ2Uv4pePZeKXj2114pePbOKYhWHimIV0ZeKXj2TimIUvMOKYhS9EQ+KYhUlN4piFL1PimIVj4piFcmXil49l4pePbuKXj3Pil49ob3TimIVzL1PimIVj4piFcmXil49lbnNo4pePb3TimIVf4piFMjAxOTHimIUy4pePM+KXjzEtMeKXjznimIUyMeKXjzXil4844piFX+KXj1Nu4pePYeKYhXBjaGF0LmrimIVw4pePZw==bakWlla]

解碼過程:

  1. 複製[ ]中的base64字符串
  2. 移除最後7個字符
  3. 從字符串開頭移除3-6個字符,直到長度是4的倍數
  4. Base64解碼字符串
  5. 移除填充字符,如Black Star和Black Circle

"trash"表

以下是"trash"表模式:

CREATE TABLE trash (__absPath TEXT UNIQUE NOT NULL, 
__Title TEXT, 
__absID INTEGER, 
__mediaType INTEGER, 
__width INTEGER, 
__height INTEGER, 
__orientation INTEGER, 
__originPath TEXT, 
__originTitle TEXT, 
__deleteTime INTEGER, 
__storageType INTEGER, 
__burstGroupID INTEGER, 
__bestImage INTEGER, 
__cloudServerId TEXT, 
__cloudTP TEXT, 
__restoreExtra TEXT, 
__volumeName TEXT, 
__volumeValid INTEGER, 
__expiredPeriod INTEGER)

重要字段:

  • __absPath:已刪除文件的當前路徑和文件名
  • __Title:已刪除文件的當前文件名
  • __originPath:原始路徑和文件名
  • __originTitle:原始文件名
  • __deleteTime:UNIX毫秒時間(UTC)
  • __restoreExtra:JSON格式,包含各種元數據

腳本編寫

編寫了初步的Python 3腳本來解析"log"和"trash"表。由於觀察到不同的"__log"字段格式,為"log"表編寫了兩個版本:samsung_gallery3d_log_parser_v10.pysamsung_gallery3d_log_parser_v11.py

這些腳本提取"log"表中的各種字段,並對我們在數據中觀察到的任何編碼路徑名稱進行base64解碼。

還編寫了java-hashcode.py腳本將給定路徑轉換為"album"表中看到的"__bucketID"值。

總結

所有這些研究導致對逆向工程Android應用、新的獨特哈希碼算法和不同編碼技術的更深入理解。進一步研究可能/可能不被現有工具解析的應用數據庫仍然可以帶來新的信息、感興趣的文件夾、日誌文件等。您可能會發現Android或特定應用的新版本中引入的新數據。

對於Mike的案例,使用本文的研究和腳本顯示用户習慣於截屏或下載圖像,然後在短時間內刪除它們並清空垃圾箱。網絡瀏覽器用於訪問有問題的圖像,但刪除網絡歷史記錄也是一個頻繁的過程。恢復的截屏名稱顯示用户在特定時間使用了網絡瀏覽器。不幸的是,這些日期和時間與有問題的時間不匹配,但這確實導致了在其他解析數據中未找到的其他調查時間。

與Mike一起研究這篇文章讓猴子學到了更多關於三星Gallery應用的知識,獲得了逆向工程Android APK的進一步經驗,並保持了他的Python技能新鮮。像任何語言一樣,流利度會因缺乏使用而退化。

編寫了各種Python 3腳本來協助從三星Gallery3d應用(v10.2.00.21)解析"log"和"trash"表。這些表可能存儲有關從三星Gallery3d應用內執行的圖像刪除的信息,例如時間戳和原始文件路徑。

本文還展示了協作研究如何導致增加的輸出/新工具。例如將Mike的測試觀察與猴子的腳本編寫相結合。與具有不同知識、技能、經驗和新鮮視角的其他人合作的機會是無價的。利用這種經驗可能與參加培訓課程或網絡研討會一樣好,甚至更好。