使用 Frida 逆向分析 Android 應用與 BLE 裝置的通訊

Editor發表於2018-03-13

處理 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<data.length;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的匿名函式巢狀。因此,如果可能的話,我會把匿名函式進行擴充套件以使程式碼更具可讀性。因此,我的程式碼相對於其他教程的程式碼可能會有點長。


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


本文章由看雪翻譯小組 夢野間 編譯
原文連結:https://www.pentestpartners.com/security-blog/reverse-engineering-ble-from-android-apps-with-frida/

相關文章