从Microsoft Band以及 Hello Sense 设备中提取自己的历史数据
2021-06-18 11:00:00 Author: www.4hou.com(查看原文) 阅读量:97 收藏

许多消费者个人跟踪设备的保质期似乎只有几年,因此,如果你想要长期记录你的进程,你就必须弄清楚如何绕过他们的应用从他们的服务器取回你自己的数据。否则,一旦他们的应用或服务器停止工作,你的数据就会消失。

我使用过两个跟踪设备,它们不容易导出数据,Microsoft Band(一款健康追踪可穿戴设备,2019年5月关闭)和Hello Sense(睡眠追踪器,2017年6月关闭,但从未发送过他们即将发布的数据导出说明),因此,我正在记录检索自己数据的过程,希望这对其他试图在其他设备上做同样事情的人有用。

Microsoft Band(2014年12月的记录)

当Microsoft Band发布时,我激动地发现这是第一款既配有心率传感器又配有全球定位系统(GPS)的腕带设备。通过分析,这款手环也遭遇了困扰许多有发展前景的可穿戴设备的同样问题,即无法导出我自己的每分钟数据。

1.jpeg

Microsoft Band可以同步到自己的智能手机应用“微软健康”(Microsoft Health)上,但在网上进行了一番搜索后发现,没有人知道有什么方法可以将他们的数据发布出去。我问微软研究院Microsoft Band的设计人员,他是否知道从Band中获取数据的方法,设计人员表示这种数据是不能公开的。

数据在哪里?

于是我从手机应用程序中提取数据,以找出这些数据是如何存储的。通过设法导出了一些文件,但在挖掘之后,我发现了具有每日摘要的缓存数据,而不是我所知道的存储在某个地方的每分钟的原始值,因为Microsoft Health应用中的睡眠图表显示了更细粒度的数据(见下图)。

2.png

我决定进一步挖掘并反编译应用程序,以通过读取应用程序代码来了解数据的去向。我在手机上使用了一个名为ES File Explorer的应用程序,以将应用程序包(apk文件)从手机下载到计算机上(右图)。

apk只是一个zip文件,下面是Microsoft Health apk文件解压缩后的样子。

3.png

该应用程序的主要代码位于一个名为classes.dex的文件中,该文件是Dalvik可执行文件,基本上是一个已编译的Java二进制文件。文件格式定义得很好,我很幸运找到了一个名为jadx的开源工具来反编译源代码。

在编译完classes.dex文件后,我浏览了几个文件夹,在“microsoft/”文件夹中找到了该文件夹,该文件夹似乎是Microsoft Health应用程序的根目录。

4.png

每个文件夹里都有数百个文件,所以我搜索了像“sleep”这样的关键字,然后发现“sleeppevents”是一个经常出现的词。

当我在/src/com/microsoft/krestsdk/services/KRestServiceV1.java中遇到这个getsleeppevents函数时,我感到很惊讶。

5.png

显然,为了获取睡眠事件,应用程序正在构造一个REST调用。所以Band必须与手机上的应用程序同步,而应用程序则与微软拥有的一些服务器同步。这解释了为什么我无法在应用的文件转储中找到原始数据,因为只有缓存的数据是本地存储的。

拦截消息

我的下一个直觉是尝试拦截我手机上的应用程序和微软服务器之间的数据,看看正在传输什么。通常,这是通过在应用程序中使用代理来完成的,因此我首先尝试在Android手机上启用代理(下面的左侧屏幕截图)。

6.png

经过一些测试,很明显,Android中的代理功能仅影响Web浏览器,而不影响Microsoft Health应用程序。因此,我尝试了另一种技巧:将手机wifi的网关(即路由器)设置为我的计算机,而不是使用DHCP,以便将所有网络数据发送到我的计算机。我编辑了此设置(上面的右侧屏幕截图)并启用了IP转发,因此网络数据包仍然可以到达互联网,而不是打到我的计算机上而丢失。

7.png

接下来,我检查了一下手机上的浏览器是否还在运行,结果证明这是个好兆头。然后是棘手的部分。我设置了一个数据包筛选器,以将传入的数据包转发到计算机上的其他端口。在一个新的.conf文件中:

8.png

然后运行以下pfctl(数据包过滤实用程序):

9.png

然后我安装了一个流量检查器(一个名为mitmproxy的开源工具),研究这些标志,直到我弄明白如何激活透明代理模式。

10.png

这基本上模拟了中间人攻击来拦截数据,注意,这只是捕获我的手机发送和接收的数据,所以这不是通常意义上的真正攻击,而只是我查看我的手机正在处理的数据的一种方式。

当我访问网站时,我可以放心看到流量通过mitmproxy控制台路由。但是,当我启动Microsoft Health应用程序时,它根本不会启动(下面的左侧屏幕截图)。

11.png

最终,我发现它使用的是HTTPS,该HTTPS在另一个端口上运行。所以我做了一些改变。首先,我在手机上安装了SSL证书,以便手机可以信任拦截消息的计算机(上面的右侧屏幕截图)。然后,我在数据包过滤器中添加了一行,以通过在.conf文件下面添加额外的一行并重新运行pfctl命令来也在HTTPS端口上转发数据包。

12.png

基本上,不是通过Microsoft Health应用程序通过HTTPS与Microsoft服务器进行通信,而是通过我的计算机路由所有通信。 mitmproxy工具拦截SSL密钥并注入自己的密钥,因此它可以解密和重新加密通过它的消息。

最后,我能够看到来自Microsoft Health应用程序的流量。幸运的是,这些请求很容易弄清楚,数据也很容易理解。

13.png

注意,为了请求数据,手机会向一个URL(如https://prodphseus.dns-cargo.com/v1/Events(eventId='1234567890')?$expand=Sequences)发出一个REST GET请求,如果你只对一个事件的数据感兴趣(比如昨晚的睡眠),那么此时你就会感到满意,因此你可以保存来自Microsoft prodphseus.dns-cargo.com服务器的响应并感到高兴。为了获得更多的事件,你可以简单地点击每次睡眠(左图),运动(右图),或其他类型的事件,直到你的手机(和你的电脑拦截信息)接收到所有的数据。然后将它们保存到一个文件中,你可以在你喜欢的文本编辑器中查看它,并使用脚本处理它。

14.png

获得完整的导出

但是如果你不想手动检查你手机上的每一个入口来让它传输数据呢?基本上,当你有Band而不是单个事件的时候,你可以获得整个时间的数据。然后回想一下本文开头的反编译Java代码,其中包含:

15.png

它提供了一个线索,可以检索完整的数据集而不必选择手机上的每个条目,你可以将URL编辑为:

16.png

简单地将URL粘贴到浏览器中是行不通的,因为你必须重用Microsoft Health应用正在使用的身份验证令牌,但编辑先前的请求应该可以让你检索整个原始数据流,而不必逐个检索每个事件。

总的来说,Band的工作原理是,一些数据被缓存在手机上,而其他数据则存储在微软的“云”服务器上。通过拦截手机应用程序对服务器的请求,你可以下载正在发送的原始数据,或检索你的整个历史数据,如心率、gps、步数等每分钟的数据。

Hello Sense(2017年1月的记录)

我非常喜欢用Hello Sense,这是一个颇受欢迎的Kickstarter项目,其口号是“了解更多,睡得更好”。这是一个设计精美的仪器,里面装有传感器,可以告诉你你的睡眠环境,还有一个枕头上的运动跟踪夹子。通过研究,我知道了这个设备是如何测量的。

17.png

用了几个月,我却发现无法从传感器获取数据,再次令人失望。相反,我只能查看它生成的图表,且只能看到Hello Sense应用允许我看到的内容。更令人气愤的是,Kickstarter的页面上承诺说:“我们正在开发工具,让你可以导出、使用或删除你的数据。”Hello Sense会同步到自己的智能手机应用程序Sense,但很显然,没有实际办法导出此数据。实际上,在寻找解决方案之后,我所能找到的只是其他用户对缺乏数据导出性的抱怨。

拦截消息

我将此作为一个挑战,并希望尝试与Microsoft Band相同的程序来拦截消息。许多应用程序将使用REST调用来请求数据的特定部分,因此知道如何这样做可以让你与保存数据的服务器进行对话。基本上,我会拦截Sense应用程序和它的服务器之间的消息,看他们如何验证并将我的数据传输到应用程序,以制作图表。然后我可以学习“语言”,模仿应用程序,从服务器请求我自己的数据。

和以前一样,我第一次在我的Android手机上启用代理(左下方截图),我的Macbook被设置为网关。然后再设置一个数据包过滤器,将传入的数据包转发到计算机上的其他端口。在新的.conf文件中:

18.png

然后像以前一样运行pfctl,并以透明代理模式启动mitmproxy来拦截数据。

19.png

最后,我在我的手机上安装了一个来自http://mitm.it的SSL证书,这样它就可以拦截通过https(端口443)发送的消息。

当访问网站时,流量通过我的mitmproxy控制台被正确地路由(见右上方的截图,可以看出我窃听了手机的Chrome浏览器导航)。然而,当我启动我的Hello Sense应用程序时,它没有正确连接到服务器,因为安全地连接到服务器时出现问题。

20.png

反汇编程序

我想更好地了解是什么在应用程序中导致错误出现,这次我使用Android Debug Bridge从我的手机中提取了apk文件。与Microsoft Ban应用程序一样,主代码位于apk中的一个名为classes.dex的文件中。

仔细检查代码后,很明显该应用程序使用了一个名为OkHttp的库,该库可以进行某种类型的证书固定。基本上,其中存在用于检查SSL证书是否正确的代码,如果不是,则会引发异常。此时,有两种选择:我可以反汇编该应用程序(请注意,反编译后的Java不能简单地重新编译为一个应用程序,因此需要将其反汇编为smali并进行编辑)并删除证书固定检查。

但是,当我在查看源代码时,我遇到了一个名为ApiService.java的文件,它显示了应用程序为从服务器检索数据而进行的REST API查询。因此,从理论上讲,我要做的就是发出与应用程序相同的查询,然后服务器会将原始数据发送回去!

21.png

注意,为了请求数据,手机使用了/v2/timeline/{date}/events/{type}/{timestamp}等链接。这个时间轴实际上就是我想要得到的在一个特定日期的晚上睡眠中发生的所有事件。

但是在我发送自己的REST查询之前,服务器会要求使用OAuth协议进行身份验证。 OAuth身份验证使用客户端ID和secret进行。因此,我在源代码树中搜索了此消息,并幸运地在一个简单的配置文件中找到了它。

22.png

我突出显示了指定客户端ID和secret的两行,这个文件还告诉我REST服务器的基本URL,它是https://api.hello.is,因此我现在有了所需的所有内容:REST服务的主机名,请求的格式以及客户端ID和secret。注意,还有几行被涂黑了,我认为这是不应该公开的秘密密钥。

发送POST请求

在任何web浏览器中发送GET请求都很容易,只需输入正确的URL即可。但制作一个POST请求,这是我需要做的,需要使用像curl这样的命令行工具或寻找一个应用程序来处理烦人的部分。我用的是邮差,它是免费的,设计简单(而且我喜欢双关语的应用程序名称)。

因此,我在POST请求中输入了适当的字段,使用了非常标准的OAuth格式。根据我在源代码中找到的内容,URL是https://api.hello.is/v1/oauth2/token。

让我有点惊讶的是,请求中的Content-Type标头需要设置为“application/x-www-form-urlencoded”,否则请求将被拒绝。一旦设置了该参数,POST请求的结果就是access_token,它使我能够访问可以使用其他查询获取的其余数据。在下面的屏幕截图中,我介绍了部分访问令牌,以防止人们窥探我的睡眠数据。

23.png

有趣的是,我在标头中将访问令牌用作“授权”字段(需要在其前面加上单词“Bearer”,以表明它是Bearer令牌类型)。现在,我可以将URL更改为所需的URL,在本例中为http://api.hello.is/v1/room/current,可以从任何地方查看我当前的房间状况。

24.png

如果你真的想对你的数据做些什么,你可以编写自己的脚本来自动验证,然后获取几天的数据,例如创建一个在线仪表板或向自己发送睡眠建议。

可能Hello Sense存储的最详细的数据是它如何对我在晚上的时间进行分类,分为醒着、中等睡眠、良好睡眠等。这是在应用程序中以条形图的形式显示的时间轴,但现在我可以访问实际数据来生成我自己的可视化效果,或进行比较和分析。一夜之间发生了很多事情,但情况是这样的。

25.png

好消息是,Hello Sense已经有了一个用于数据导出的API。我花了一些时间才弄清楚如何访问这些数据,但是我想他们还没有公开发布此信息,因为他们想为API提供更好的接口。

本文翻译自:https://jeffhuang.com/extracting_data_from_tracking_devices/如若转载,请注明原文地址


文章来源: https://www.4hou.com/posts/m899
如有侵权请联系:admin#unsafe.sh