在 2012 OSSLab在台灣駭客年會分享過 數位鑑識與資料救援前瞻性研究 主題
那時候已有遇到各種IM加密狀況, 像Whatsapp是固定AES密鑰,但無法破解微信Sqlite資料庫加密. 就沒辦法分析提取對話資料..

直到2015時候 網路上有人分享 其解密原理.

Wechat 是用手機的IMEI值和微信UIN值的組合來對數據進行加密   MD5 左側加密(SIM值+uin值) 取前七位為 Sqlite decrypt key
其後我們在資料恢復應用跟分享給刑事單位這些技術與資訊.解決了很多問題 
但是我們一直不理解其反組譯思路.
最近翻到這篇文章 才恍然大悟..

Android中靜態方式破解微信獲取聊天記錄和通訊錄信息  
原作:jiangwei212
http://www.52pojie.cn/thread-544808-1-1.html
(以下為轉載)

一猜想數據存放路徑

微信現在是老少皆宜,大街小巷都在使用,已經替代了傳統的短信聊天方式了,只要涉及到聊天就肯定有隱私消息,那麼本文就來講解如何獲取微信的聊天記錄以及通訊錄信息。

首先我們在沒有網絡的時候,打開微信同樣可以查看聊天記錄,說明微信會把聊天記錄保存到本地,那麼這麼多信息肯定會保存在數據庫中,所以我們可以去查看微信的databases目錄看看內容:

可惜的是,我們在這個裡面並沒有發現一些有用的數據,所以這時候就瞭解到了微信因為把重要信息的數據庫存在其他目錄下面,我們可以直接把微信的整個沙盒數據全部導出來,然後查找db文件:

在這個目錄中找到了一些db文件:

看到這個目錄下有很多db文件,我們可以一個一個進行查看,這裡可以直接使用SQLite Expert可視化工具進行查看:

可惜的是,這裡打開失敗了,看到提示消息應該瞭解了,這個數據庫文件被加密了。這也更讓我們相信這個數據庫存放的是非常重要的信息,而且從安全角度來說,加密操作也是很正常的。

二、靜態方式破解微信分析

好了到這裡,看來得去看代碼了,因為數據庫加密了,既然是加密肯定有解密的過程,我們去分析代碼獲取其密碼即可。

首先我們可以使用apktool工具進行反編譯,這裡不演示了,微信本身沒有加固操作,所以反編譯沒有報錯的:

注意:

這裡的命令中加上了-d的參數了,是為了反編譯之後生成的是Java文件,而不是smali文件。便於後面能夠導入Eclipse中

反編譯之後,接下來咋們就開始把文件導入Eclipse中,關於如何導入的話,這裡不介紹了,不瞭解的同學可以轉戰這裡:Eclipse中動態調試smali源碼 我們成功導入之後:

這裡看到有些報錯,但是這個不用太關心,我們分析源碼就可以了,其實到這裡有的同學可能想到的是速度調試:

借助之前說到的mprop工具來修改系統的調試屬性ro.debuggable屬性值,不瞭解這個工具的同學可以看這篇文章:如何脫掉360加固的殼 ,如果不想用這個工具就有點費事了,修改反編譯之後的AndroidManifest.xml中打開調試屬性,然後在回編譯,不過可惜的是,在這個過程中我嘗試過失敗了幾次,所以我最後採用了mprop工具來進行操作的。修改系統調試屬性之後可以看到:

微信出於debug模式了,我們這時候只要按照之前說到的Eclipse中動態調試samli源碼的步驟來即可。但是這裡有一個問題,就是在調試的過程中會被卡死的,我嘗試了很多次結果都失敗了,所以這裡就放棄了動態方式破解微信了,而是採用靜態方式去破解微信獲取密碼。

三、破解步驟

之前在說到使用靜態方式破解的時候第一點,一定要找到關鍵點,我們現在的問題是知道了數據庫,但是這個是加密的,我們需要密碼,那麼在Android中如果使用數據庫的話,肯定會涉及到一個類:SQLiteDatabase,我們可以在Eclipse中先去全局搜一下這個類:

因為微信工程代碼非常大,所以在搜索的過程中需要等一段時間:

在samli中找到了com.tencent.kingkong.database.SQLiteDatabase類的定義了,因為smali語法看起來還是比較費勁的,所以我們使用Jadx工具進行可視化操作,之前一篇文章中介紹了:Android中反編譯利器分析 這裡講解了apktool和jadx工具的原理,為什麼說jadx好用呢?主要是他是開源的,而且用Java編寫的,同時還支持方法的跟蹤,這個對於混淆代碼的跟蹤非常有用。

這裡需要注意個問題,因為微信的apk太大了,所以得分開查看,因為微信有多個dex文件,而剛剛看到SQLiteDatabase類是在第一個dex中的,我們使用jadx查看第一個dex文件即可:

這樣看起來就方便很多了,我們找到這個類,首先肯定看看他的openDatabase方法,不過這裡會發現有很多重載方法,不過最終都要調用的是這個openDatabase方法:

內部接著調用了open方法,繼續跟進:

內部又調用了openInner方法,接著跟進:

調用了SQLiteConnectionPool的open方法,再跟進去:

哈哈,終於找到核心的地方了,這裡看到果然有一個密碼的字段,那麼這個值就是SQLiteDatabase中的openDatabase方法的第二個參數,那麼現在我們就去分析哪裡調用了SQLiteDatabase的openDatabase方法,因為SQLiteDatabase的openDatabase的重載方法太多了,所以一個一個找很費勁,所以可以直接搜SQLiteDatabase被調用的地方,可以直接使用Jadx的查找跟蹤功能:

查找結果:

這裡會發現,很多地方都調用了,看起來非常麻煩,所以這裡得想個辦法縮減查找範圍,我們剛剛看到SQLiteDatabase類中的open方法都是static的,所以在調用的時候肯定是這麼使用的:Lcom/tencent/kingkong/database/SQLiteDatabase; 這個是標準的smali語法調用形式,所以這時候我們在去Eclipse中全局搜索這個字符串內容:

最終看到在com.tencent.mm.bb.e這個類中,有多個地方都調用了,咋們再去看看這個類:

果然在d方法中調用了數據庫的open方法,而且傳入的str2就是密碼,在跟蹤d方法在哪裡被調用了:

點擊進入查看:

這裡的this.Ee就是密碼,看他的賦值,是先調用j方法構造一個字符串出來,然後取前7個字符即可,再看看j方法:

這個方法看起來就眼熟了,計算字符串的MD5值的,這裡需要注意的是,MD5的值是小寫的,好了,到這裡我們就瞭解了:密碼其實是一個字符串的MD5值的前7位字符串,那麼接下來的問題在繼續跟蹤是哪個字符串來計算MD5的:

在繼續跟蹤a方法在哪裡被調用了:

找到之後點擊進入:

繼續查找這個a方法又在哪裡被調用了,這裡調用的比較深,所以需要多次進行查找跟蹤,耐心點即可:

最終到了這個類的方法中,我們看到,mY值是通過mY方法獲取的,j2值是上面的i值轉化過來的:

查看mY方法的實現,很簡單,獲取設備的IMEI值,而i值在前面進行賦值了:

看到了,是一個uin值,再看看這個uin值在哪裡進行賦值操作的:

看到這裡就放心了,原來這個uin值存放在SharedPreferences中的,那麼就簡單了,我們在開始的時候把沙盒數據全部導出來了,可以全局搜一下uin字符串的值:

哈哈,在這裡找到了這個值。

總結:

到這裡我們就分析完了微信中數據庫加密的密碼獲取流程了,下面來總結一下:

1、首先我們全局查找SQLiteDatabase類,因為這個類是操作數據庫的核心類,他是突破口。

2、找到這個類的定義之後,再次查看他的open系列方法,因為要操作數據庫肯定有open之類的方法。

3、再去全局查找SQLiteDatabase的open方法的調用地方,這裡調用的地方比較多,所以大家需要耐心的查找,而且為了縮小查找範圍,我們可以根據smali語法調用格式的字符串內容來進行查找。

4、找到了這個方法的被盜用的地方,下面就開始一步一步的往下跟蹤,到了一個核心的方法中瞭解到了,密碼是一個字符串計算MD5之後取前7個字符串的值。

5、繼續跟蹤,找到這個被計算MD5的字符串內容,最後跟蹤到這個字符串其實是設備的IMEI加上用戶的uin值,而這個uin值是保存在SharedPreferences中的。

上面雖然找到了密碼,但是我們知道是如何進行數據加密的呢?這裡就要借助經驗了,因為現在主流的Sqlite數據加密技術就是sqlitecipher,不瞭解的同學可以去看看,這個數據庫加密需要用到so文件,我們去微信的libs下面查看:

這裡沒有找到那個sqlitecipher.so文件,但是我們看到了這個libkkdb.so文件,他貌似就是操作數據庫的,使用IDA打開進行查看內容:

看到了,這裡的的sqlite操作都是在native層進行的,所以我們如果要查看數據庫的話,需要用sqlcipher軟件來進行查看,這個軟件網上的下載地址很多,專門用來查看sqlitecipher加密的數據庫信息的。

四、數據庫密碼構造

首先獲取設備的IMEI,可以直接撥打:*#06#即可查看;然後查看他的uin值,直接讀取SharedPreferences中的值即可,然後拼接到一起,用txt文件檔保存一下,在使用HashTab工具進行查看屬性即可得到MD5的值,關於HashTab工具:

這個工具還是很有用的,可以很方便的右鍵文件屬性,即可查看文件的MD5值了:

這裡看到前七位就是:748B34D,注意字符小寫=》748b34d:

輸入密碼之後,就可以查看數據庫中的各個表格信息了:

可以發現這個數據庫中存了很多表格內容,但是這裡我們最關心的就是通訊錄信息表和聊天記錄表:

看到了,聊天記錄表格是message,通訊錄表格是recontact:

而且這裡有一個好玩的東東,就是你以前刪除的好友,都會存在的,這個是微信會把你的通訊錄保存到服務端,及時你本地刪除了聯繫人,但是服務端並不會刪除,所以如果你想找到你以前刪除的好友,可以在次查找重新加上好友。

概要總結:

到這裡我們就用靜態方式去破解微信,知道了數據庫加密的密碼,然後看到他是使用的主流的數據庫加密框架:sqlitecipher,而且現在很多app都用這個框架,比如一些小說類的app,這裡就不指定說是誰了,我之前反編譯過幾個小說類的app,有兩個都是用的這個框架進行加密的。

五、破解流程總結

1、猜想信息是保存在本地數據庫

想得到聊天記錄和通訊錄信息,我們的想法是這些信息在設備沒有連接網絡的時候也是可以查看的,所以我們猜想這些信息是保存在本地的數據庫中的。

2、使用sqlite工具查看信息報錯

我們把微信的沙盒數據全部導出到本地,然後查找db文件,找到了EnMicroMsg.db文件,使用sqlite expert工具進行查看報錯,提示數據庫被加密了。

3、根據數據庫的常規使用流程找到入口

我們在Android中使用數據庫的時候都會用到SQLiteDatabase類,所以可以全局搜索這個類,找到這個類的定義,然後再找到他的一些open方法,看看這些方法的調用地方。

4、通過數據庫的入口方法進行代碼跟蹤

知道了open系列方法的調用地方,就開始使用Jadx工具進行代碼跟蹤,最後跟蹤到了有利信息,就是密碼是用戶設備的IMEI+uin值計算MD5值,注意是小寫字符,然後在取MD5的前7位字符構成的密碼。

5、獲取密碼流程

這裡知道了密碼的構成,獲取就比較簡單了,使用*#06#撥號直接獲取IMEI值,然後在去查看SharedPreferences中的auth_info_key_prefs.xml文件中的_auth_uin值就是用戶的uin值,然後進行拼接,使用HashTab計算出MD5值,獲取前7位字符串。

6、使用sqlcipher工具查看數據庫

得到密碼之後,使用sqlcipher工具進行數據庫的查看,可以找到通訊錄表格recontact和聊天記錄表格message。

概要:微信的核心數據庫是EnMicroMsg.db,但是是加密操作的,而加密的密碼是設備的IMEI+用戶的UIN值(在SP中保存了),計算MD5(字符是小寫),取出前7位字符即可。

六、延展

1、微信的通訊錄信息和聊天記錄信息對於一個用戶來說是非常重要的隱私,所以這也是微信對數據庫進行加密的原因,但是不管最後怎麼加密,都會需要解密的,所以這就是我們破解的關鍵,只要解密操作在本地進行,密碼肯定能夠獲取到。

2、關於微信的這個密碼獲取的規則不會發生改變的,有的同學會想微信會改掉數據庫加密的密碼獲取算法嗎?答案是不會的,原因很簡單,如果密碼算法改了,就會影響到老用戶,比如新版本中密碼改了,老用戶更新之後,在讀取數據庫的時候進行解密,那麼加密的數據庫是老的,新的加密算法是解密失敗的,這個用戶體驗會瘋的,那有的同學又說了,對數據庫進行升級處理,但是這裡的升級一定要保證老的數據不能丟失,那麼這裡就存在一個老數據遷移的工作,這個工作是巨大的,因為現在很多微信使用的過程中如果不去主動的清除數據,聊天信息非常多,那個數據庫也會非常的大,幾十M很正常的,那麼在數據遷移的時候風險是非常巨大的,所以這樣一來,微信短期內是不會改變密碼算法規則的,其實我已經嘗試了很多老版本的反編譯,發現的確這個算法一直都是這樣的。所以一定要記住微信的數據庫加密算法是:MD5(IMEI+UNI)=>前7個字符。

3、這裡為什麼使用靜態方式去分析呢?原因是微信的包太大了,如果動態調試的話總是出現死機情況,沒辦法後續操作了,所以使用了靜態方式去破解。

七、安全性

通過本文之後,大家應該都知道如何破解微信的聊天記錄信息和通訊錄信息了,只要獲取到加密的數據庫,得到密碼即可,但是這兩步卻不是那麼容易獲取的,首先如何獲取加密的數據庫,這些信息都是保存在微信的沙盒數據中的,所以得設備root之後獲取,設備的imei信息就簡單了,那麼問題就來了,如果一個用戶的設備root了,那麼惡意程序就可以開始盜取信息了。而且在之前的一篇文章中:Android中allowBackup屬性引發的安全問題 介紹了微信在5.1之前的版本allowBackup屬性默認值是true,也就是說沒有root的情況下,可以獲取到微信的沙盒數據,那麼這個安全性就太暴露了。現在也有很多微信通訊錄備份的工具,其實就是把這個數據庫信息同步一下。以後只要有了微信的這個數據庫,那麼破解也是很簡單的,因為密碼是規定的。

八、用途

1、如果你想看周邊的人微信信息,那麼這裡就是給你提供了最好的方案,特別是你最愛的人,比如媳婦總是不讓你看她微信,但是自己又很想看,那麼機會來了。

2、對於root之後的設備可以在後台竊取用戶的微信信息把imei一起上傳到服務端,然後在人工分析獲取聊天記錄中重要信息。

3、當我們的設備中誤刪除了聊天記錄,這時候可以通過導出本地數據庫,然後使用sqlcipher工具進行查看既可以找到之前數據

本文的重點和意圖是:如何使用靜態方式破解apk的思路,而對於微信來說,這個不算是漏洞也不算是問題,因為我們上面介紹中涉及到的數據都是微信的沙盒中的,所以一般情況下是無法獲取到的,所以對於攻擊者來說沒有太多的意義。所以本文的意圖很簡單就是講解靜態方式破解apk的一種思路。

九、總結

上面分析了微信數據庫的加密操作的原因,以及數據庫的密碼構造算法,同時也分析了,這個算法短期內是不可能更改的,從安全性來說,對於新版本的微信,如果設備root了,那麼對惡意程序來說就有了盜取的入口,而微信中的聊天記錄信息相當於用戶的隱私,同時會涉及到一些利益相關的,所以微信今後對這個數據庫操作希望能夠盡快的進行改善操作

留言

留言