首页
社区
课程
招聘
[翻译]使用 Frida 逆向分析 Android 应用与 BLE 设备的通信
发表于: 2018-3-3 20:53 7920

[翻译]使用 Frida 逆向分析 Android 应用与 BLE 设备的通信

2018-3-3 20:53
7920

处理 BLE(Bluetooth Low Energy,低功耗蓝牙)设备时常碰到的一个问题就是,确定有哪些信息发送给它。

我通常使用第3种方法,通过阅读反编译后的安卓代码分析出它的协议。因为对APP代码进行混淆已经变得越来越常见了,因此使用这种方法有时候会非常痛苦。
我想,是否可以hook函数调用,直接dump对属性进行写操作的方法。有一些框架都能做到这一点,最终我选择了goole搜索排名第一的 Frida
这个框架可以对二进制程序进行注入,支持的平台包括Linux, Windows, iOS 和 Android。你可以用JavaScript 写程序来替换Java的调用,但奇怪的是,使用Python来进行Hook。
使用Frida时会碰到的一个问题是,官方文档是基于你已经会使用Frida了而写的。幸好的是这里 还有一些教程,但都不够全面,因此就有了这篇文章。

这是最容易的部分,你可以像安装Python(我使用Python 2.7)的其它包一样使用pip来安装。

因为我平常处理一些硬件上的东西都是在虚拟机上操作的,所以我起初在我的Linux虚拟机上安装,但它会时不时的崩溃和超时,但使用Windows的时候又不会这样。这似乎是因为我虚拟机上的adb版本太低了,所以你首先应该确保你能正常地连接上你的Android设备。
现在我们已经在对应的操作系统上安装好Frida了,接下来需要在Android设备上安装一个服务器。我使用的是Nexus 5,它的系统是Android 6.0.1(当然已经root了)。最好把服务器push到/data/local/tmp这个位置,这样shell用户就能有写权限,且在重启后这个文件依然存在。

经过上述操作后,一切就准备就绪了。

因为我不能给你看我测试的app(因为客户端的权限问题),我使用我同事使用的Marshall amp app,我相信我们不久后就能找到一些关于它的优秀的博文。
第一步是取得它的apk安装文件,并获取程序的进程名。我们不需要写程序,找到进程名的最简单的方法就是查看它在Google Play store上的链接。
图片描述
为了更方便的安装app,最好是获得它的apk安装文件,然后使用pull命令把这个文件提取到电脑上。网上有一些服务可以解密Google Play的apk文件,并提供下载,但我觉得这不安全。
为了把apk文件提取出来,我们需要找到apk文件的存储位置。它可以通过调用包管理器(pm)命令,使用 -f 参数(显示文件列表):

=号前面的部分是app的路径,这样我们就能使用pull命令把它提取出来了(这一步不需要root权限):

我们还需要app的名称。它一般和包名相同(com.marshall.tone),但也不一定,万无一失的做法是查看进程列表。我们可以用 adb shell ps或是frida-ps查看进程列表:(-U 表示服务器不在本机,而需要使用USB连接到Frida服务器)

接下来就可以试着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控制台基于Node会话,使用JavaScript进行编程来hook方法调用。有一个从Java API可以实现从Java到JavaScript的映射,尽管数据类型有点混乱。
接下来我碰到一个问题,每当我进行hook 时,writeCharacteristic 会接收一个byte数组,然后这个数组会被转为JavaScript对象。默认的日志提示是[Object object],没办法得到更多的提示。所以我写了个小程序进行hook并打印元数据。

这段代码会附加到类net.transpose.igniteaneandroid.IgniteANEAndroidExt的定义上,并用我写的方法替换writeSettingValue 方法的实现,它会在把程序控制权传回原来函数时枚举传进来的对象。

-l选项指定我们的脚本名,而com.marshall.tone是进程名。接下来我使用这个app进行了一次BLE属性写操作(通过选择一个预设设备),控制台输出如下:
图片描述
从上图可以看到,这个对象有三个属性。

因为这是个byte数组,因此我们直接用索引进行遍历,如果我们把newWriteCharacteristic(译者注:这里应该为writeCharacteristic,疑为作者笔误)替换为:

上面这个函数应该会发送一些十六进制值。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/

 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-3-3 20:53 被梦野间编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (4)
雪    币: 24
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
“如果我们把newWriteCharacteristic(译者注:这里应该为writeCharacteristic,疑为作者笔误)替换为“
其实  人家原文没有问题,是小编你理解错了。
ble.  writeSettingValue.implementation=newWriteCharacteristic;
作者已经将封装的函数重新命名为  newWriteCharacteristic了。
2018-3-14 10:11
0
雪    币: 3757
活跃值: (1757)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
3
Stanleyboy “如果我们把newWriteCharacteristic(译者注:这里应该为writeCharacteristic,疑为作者笔误)替换为“ 其实 人家原文没有问题,是小编你理解错了。 ble. w ...
writeCharacteristic是系统内置函数
作者用自己写的newWriteCharacteristic对其进行替换
所以说才是把writeCharacteristic替换为newWriteCharacteristic
2018-3-23 11:35
0
雪    币: 2122
活跃值: (3854)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
4
如果要分析蓝牙设备的通讯的话除了BLE以外还有可能走的SPP的私有协议
2018-4-4 00:07
0
雪    币: 24
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
梦野间 writeCharacteristic是系统内置函数 作者用自己写的newWriteCharacteristic对其进行替换 所以说才是把writeCharacteristic替换为newWrit ...
所以说  原作者没有笔误
2018-5-10 09:06
0
游客
登录 | 注册 方可回帖
返回
//