使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

處理 BLE(Bluetooth Low Energy,低功耗藍牙)設備時常碰到的一個問題就是,確定有哪些信息發送給它。

使用諸如 Ubertooth 之類的藍牙嗅探器來截獲傳輸數據。這一方法有點麻煩,因為你只有1/3的機會截取到數據流。

使用 bleno 模擬設備,然後截取數據流。

逆向手機APP,然後分析出它的通信協議。

我通常使用第3種方法,通過閱讀反編譯後的安卓代碼分析出它的協議。因為對APP代碼進行混淆已經變得越來越常見了,因此使用這種方法有時候會非常痛苦。

我想,是否可以hook函數調用,直接dump對屬性進行寫操作的方法。有一些框架都能做到這一點,最終我選擇了goole搜索排名第一的 Frida 。

這個框架可以對二進制程序進行注入,支持的平臺包括Linux, Windows, iOS 和 Android。你可以用JavaScript 寫程序來替換Java的調用,但奇怪的是,使用Python來進行Hook。

使用Frida時會碰到的一個問題是,官方文檔是基於你已經會使用Frida了而寫的。幸好的是這裡 還有一些教程,但都不夠全面,因此就有了這篇文章。

安裝

這是最容易的部分,你可以像安裝Python(我使用Python 2.7)的其它包一樣使用pip來安裝。

pip install frida

因為我平常處理一些硬件上的東西都是在虛擬機上操作的,所以我起初在我的Linux虛擬機上安裝,但它會時不時的崩潰和超時,但使用Windows的時候又不會這樣。這似乎是因為我虛擬機上的adb版本太低了,所以你首先應該確保你能正常地連接上你的Android設備。

現在我們已經在對應的操作系統上安裝好Frida了,接下來需要在Android設備上安裝一個服務器。我使用的是Nexus 5,它的系統是Android 6.0.1(當然已經root了)。最好把服務器push到/data/local/tmp這個位置,這樣shell用戶就能有寫權限,且在重啟後這個文件依然存在。

C:\Users\dave>adb push frida-server /data/local/tmp

C:\Users\dave>adb shell

shell@hammerhead:/ $ su

root@hammerhead:/ # cd /data/local/tmp

root@hammerhead:/data/local/tmp # ./frida-server &

經過上述操作後,一切就準備就緒了。

安裝app

因為我不能給你看我測試的app(因為客戶端的權限問題),我使用我同事使用的Marshall amp app,我相信我們不久後就能找到一些關於它的優秀的博文。

第一步是取得它的apk安裝文件,並獲取程序的進程名。我們不需要寫程序,找到進程名的最簡單的方法就是查看它在Google Play store上的鏈接。

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

為了更方便的安裝app,最好是獲得它的apk安裝文件,然後使用pull命令把這個文件提取到電腦上。網上有一些服務可以解密Google Play的apk文件,並提供下載,但我覺得這不安全。

為了把apk文件提取出來,我們需要找到apk文件的存儲位置。它可以通過調用包管理器(pm)命令,使用 -f 參數(顯示文件列表):

D:\dave>adb shell pm list packages -f | findstr marshall

package:/data/app/air.com.marshall.gateway-1/base.apk=air.com.marshall.gateway

=號前面的部分是app的路徑,這樣我們就能使用pull命令把它提取出來了(這一步不需要root權限):

D:\dave>adb pull /data/app/air.com.marshall.gateway-1/base.apk marshall.apk

7157 KB/s (15674806 bytes in 2.138s)

我們還需要app的名稱。它一般和包名相同(com.marshall.tone),但也不一定,萬無一失的做法是查看進程列表。我們可以用adb shell ps或是frida-ps查看進程列表:(-U 表示服務器不在本機,而需要使用USB連接到Frida服務器)

D:\dave>frida-ps -U | findstr marshall

16182 air.com.marshall.gateway

接下來就可以試著hook對應的方法了,我們首先要找到我們想要hook的方法。通過查Google我們知道Android的 API 中通過BLE進行屬性的寫操作的方法是android.bluetooth.BluetoothGatt.writeCharacteristic。

我前幾次的嘗試都不成功,後來我換了個更簡單的位置進行Hook。

我使用jadx-gui來搜索反編譯代碼中writeSettingValue這個關鍵字出現的位置,在類net.transpose.igniteaneandroid.IgniteANEAndroidExt中找到了android.bluetooth.BluetoothGatt的實例。

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

從上圖可見,方法net.transpose.igniteaneandroid.IgniteANEAndroidExt.writeSettingValue

接收一個byte數組和一boolean類型的參數,返回void,通過傳進來的參數再調用writeCharacteristic。

因此,理論上來說,如果我們hook了這個方法,我們就能知道所有通過藍牙寫入的數據。

使用Frida

我們所有的操作都可以在Frida命令行中運行,但使用腳本的話更方便。

Frida控制檯基於Node會話,使用JavaScript進行編程來hook方法調用。有一個從Java API可以實現從Java到JavaScript的映射,儘管數據類型有點混亂。

接下來我碰到一個問題,每當我進行hook時,writeCharacteristic 會接收一個byte數組,然後這個數組會被轉為JavaScript對象。默認的日誌提示是[Object object],沒辦法得到更多的提示。所以我寫了個小程序進行hook並打印元數據。

function enumerateObject(obj)

{

for (key in obj)

{

console.log(key + ": " + obj[key]);

}

}

function newWriteCharacteristic(data)

{

enumerateObject(data);

this.writeCharacteristic(data);

}

function hookIt()

{

var ble=Java.use("net.transpose.igniteaneandroid.IgniteANEAndroidExt ");

ble. writeSettingValue.implementation=newWriteCharacteristic;

}

Java.perform(hookIt);

這段代碼會附加到類net.transpose.igniteaneandroid.IgniteANEAndroidExt的定義上,並用我寫的方法替換writeSettingValue 方法的實現,它會在把程序控制權傳回原來函數時枚舉傳進來的對象。

frida -U -l c:\\users\dave\desktop\marshall-write.js air.com.marshall.gateway

-l選項指定我們的腳本名,而com.marshall.tone是進程名。接下來我使用這個app進行了一次BLE屬性寫操作(通過選擇一個預設設備),控制檯輸出如下:

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

從上圖可以看到,這個對象有三個屬性。

$handle—對象實現的句柄

type—它告訴我們這是個byte數組

length—對象的長度

因為這是個byte數組,因此我們直接用索引進行遍歷,如果我們把newWriteCharacteristic(譯者注:這裡應該為writeCharacteristic,疑為作者筆誤)替換為:

function newWriteCharacteristic(data)

{

hexstr="";

for (i=0;i

{

b=(data[i]>>>0)&0xff;

n=b.toString(16);

hexstr += ("00" + n).slice(-2)+" ";

}

console.log("Output: " + hexstr);

this.writeCharacteristic(data);

}

上面這個函數應該會發送一些十六進制值。Frida有內置的十六進制輸出函數,但我使用它的時候一直不成功。

重新加載Frida,然後在app上按幾個鍵,就會顯示出它發送的消息。

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

要想實現上圖效果,設備首先需要和Marshall amp進行配對。看上圖我們的實驗似乎已經成功了。

我們可以使用gatttool把上述輸出發送給設備,看設備是否能正確的響應消息以驗證實驗是否成功。

使用 Frida 逆向分析 Android 應用與 BLE 設備的通信

最終,我們的實驗成功了,設備狀態改變了。

結論

Frida是一個強大的攔截Android app內部組件間消息傳遞的工具,它可以簡化我們的工作。

花一些時間來了解它是值得的,因為它能讓BLE的逆向工程更加簡單。

如果你想要我進行上述實驗的代碼,你可以在我們的Github賬戶。請注意,我非常不喜歡JavaScript的匿名函數嵌套。因此,如果可能的話,我會把匿名函數進行擴展以使代碼更具可讀性。因此,我的代碼相對於其他教程的代碼可能會有點長。

如果你想要看到更多的對吉他音箱的研究,可以閱讀我同事寫的博文

本文章由看雪翻譯小組 夢野間 編譯 轉載請註明來自看雪論壇

關注看雪學院公眾號:ikanxue,獲取更多幹貨!


分享到:


相關文章: