處理 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上的連結。
為了更方便的安裝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的例項。
從上圖可見,方法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屬性寫操作(通過選擇一個預設裝置),控制檯輸出如下:
從上圖可以看到,這個物件有三個屬性。
$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上按幾個鍵,就會顯示出它傳送的訊息。
要想實現上圖效果,裝置首先需要和Marshall amp進行配對。看上圖我們的實驗似乎已經成功了。
我們可以使用gatttool把上述輸出傳送給裝置,看裝置是否能正確的響應訊息以驗證實驗是否成功。
最終,我們的實驗成功了,裝置狀態改變了。
結論
Frida是一個強大的攔截Android app內部元件間訊息傳遞的工具,它可以簡化我們的工作。
花一些時間來了解它是值得的,因為它能讓BLE的逆向工程更加簡單。
如果你想要我進行上述實驗的程式碼,你可以在我們的Github賬戶。請注意,我非常不喜歡JavaScript的匿名函式巢狀。因此,如果可能的話,我會把匿名函式進行擴充套件以使程式碼更具可讀性。因此,我的程式碼相對於其他教程的程式碼可能會有點長。
如果你想要看到更多的對吉他音響的研究,可以閱讀我同事寫的博文
本文章由看雪翻譯小組 夢野間 編譯
原文連結:https://www.pentestpartners.com/security-blog/reverse-engineering-ble-from-android-apps-with-frida/