三星Rubin与数字健康功能在移动取证中的数据交互与延迟写入机制解析

本文深入分析了三星定制服务Rubin与数字健康功能共存时,设备解锁事件记录的位置迁移与数据延迟写入现象,揭示了取证工具可能遗漏关键数据的技术细节,并对Android取证实践具有重要参考价值。

(并非)陌生的伙伴——三星的Rubin与数字健康功能

另一个夏天飞逝而过。今年,假期、法庭事务、课程以及当然还有各种会议都在如火如荼地进行着。事情稍稍平息下来,我终于有机会动笔写下一些酝酿已久的内容。如今,找时间坐下来写作变得越来越困难。不过,我希望这种趋势能有所改变。

首先要谈的是三星。具体来说,是三星定制服务(又名Rubin)和数字健康功能。有不少人直接或通过工作联系我,询问关于这两者以及它们表现出来的一些奇怪行为——我认为“奇怪”可能是最贴切的形容。毕竟,这是三星,而且在Android方面,他们喜欢以自己独特的方式行事。这让取证人员时刻保持警惕,也给Android带来了一些多样性。因为Android取证太缺乏多样性了,对吧?

在测试过程中,我不得不应对三星的安全补丁级别和常规更新,这使得数据提取变得棘手且令人沮丧。有时我能获取到Rubin所需的关键数据,有时则不能。这完全取决于我提取数据时的“风向”。无论如何,这台S22经历了充分的“锻炼”。它运行的是Android 15和OneUI 7,并安装了2024年12月和2025年4月的安全补丁。我知道有7月的补丁,但鉴于这部手机已经让我很头疼,我决定保持现状。

如果你还没读过三星DWB的实现,可以在这里了解。如果你不熟悉三星Rubin,Cellebrite有一些资源,都可以在这里找到。

这无疑将是我迄今为止最短的一篇文章,但它很重要,因为它关系到可能被遗漏的数据。

锁屏与解锁——相辅相成

标题说明了一切。如果取证人员遇到同时使用Rubin和DWB的手机,为了最全面地了解设备上发生的情况,需要将这两者放在一起检查。原因是,当启用Rubin时,传统上由DWB记录的一项信息被转移到了Rubin:设备解锁事件。见图1。

图1. dwbCommon中没有一个解锁事件。 以上是dwbCommon.db中usageEvents表的摘录。截屏所覆盖的时间段本应有两个解锁事件,但实际没有。为了再次确认,我手动检查了usageEvents表,根本没有找到eventType=18的记录。这就引出了一个问题:手机怎么知道我在这个时间段内解锁了两次?事实证明,Rubin保存了这些数据。见图2。

图2. 屏幕解锁和锁屏事件。 inferenceengine_logging.db中的screen_state_log表包含了设备解锁和锁屏的信息。为了确定哪些记录代表哪个动作,需要结合使用screen_stateuser_presentuse_keyguard以及timetime_string列。此表还会告诉你屏幕何时被点亮。我观察到以下组合:

  • 解锁(生物识别或密码)screen_state = 1 user_present = 1 use_keyguard = 0
  • 通过侧边按钮锁定screen_state = 0 user_present = 0 use_keyguard = 1
  • 达到屏幕超时阈值锁定screen_state = 0 user_present = 0 use_keyguard = 0
  • 屏幕点亮,但未解锁screen_state = 1 user_present = 0 use_keyguard = 1

再次强调,这些解锁事件并未记录在dwbCommon.db或其-WAL文件中。但有趣的是,一些锁屏事件记录在usageEvents表中,不过不是全部,而且它们与screen_state_log中记录的同一动作时间相近。

这里还有一个额外的说明:即使用户关闭了Rubin,上述行为仍然适用。解锁事件仍会记录到Rubin,而不会出现在DWB中。

延迟写入与完成的启动

三星决定实现他们自己的DWB版本,这在谷歌的移动服务合同中是允许的。因此,他们在dwbCommon.db中实现并使用了一个名为Logging的表。顾名思义,这个表记录了一些事情,其中几项从取证人员的角度来看可能很有用。第一项是设备启动。虽然我们一开始就能在usageEvents表中看到这个信息,但这次探索性研究让我们对什么才真正构成“启动”有了更清晰的理解。正是在这里,我发现了一些奇怪的行为。见图3和图4。

图3. 完成的启动以及Logging表中的最后条目。 图4. usageEvents表中的最后几条记录。 图3和图4真正揭示了这种奇怪的行为,因为我在测试期间多次遇到这种情况。图3显示了Logging表中的最后两条记录,其中有两条“BOOT_COMPLETED”条目。有趣的是,这些条目与usageEvents表中最后四条记录的时间关系:它们比后者晚了超过12小时!这很有趣,因为在此期间手机上有活动,包括两次启动动作,它们本应记录在usageEvents表中,但实际上却没有。然而,几个小时后进行了几次额外的提取,这些记录终于出现了。

我们这里遇到的是一个延迟写入的实例。我的意思是,这些使用数据既没有出现在主数据库中,也没有出现在相关的-WAL文件中,并且在很长一段时间内都没有被记录到其中。在测试中,我多次观察到这种行为,其他联系我的从业者也描述了同样的情况。我看到记录需要1小时到超过12小时不等的延迟才会写入数据库或-WAL文件。我仔细检查了S22的提取数据,但找不到这些数据在被记录之前被保存在哪里。我最初怀疑是RAM,但重启设备似乎并没有强制写入。触发写入的机制对我来说仍然是个谜,但取证人员应该知道,可能存在尚未写入的记录,特别是当他们检查Logging表并看到像图3中那样的条目,其日期远远晚于usageEvents表中最后一条记录时。

这一发现还揭示了另一件事:Logging表中的“BOOT_COMPLETED”条目并不像看上去那样清晰明了。在测试期间,S22重启了多次,但有时与BOOT_COMPLETED记录相关的时间戳远晚于设备实际重启的时间。试想一下:用户重启了手机,但没有立即解锁,而是让它静置了一段时间。最终,用户解锁手机开始使用。图5展示了一个例子。

图5. 两次重启。 上图有两次重启事件。第一次发生在2025-08-04 09:26,但直到09:27才解锁手机。第二次重启发生在2025-08-04 19:20,但直到2025-08-05 08:29才解锁手机。如上所示,BOOT_COMPLETED条目与手机首次解锁的时间相吻合。为了确认我所看到的,我查看了文件eRR.p。图6显示了相关的时间范围,相应的重启事件用各自的颜色编码标出。

图6. eRR.p中的重启事件。 那么,到底发生了什么?当S22在重启后首次被解锁时,在我输入PIN码后,屏幕显示“Phone is starting…”。在此之前,手机处于BFU状态;它可以做一些事情,但不是全部。一旦我输入了PIN码,手机就“完成”了它的启动过程,进入了AFU状态。看来,就DWB而言,启动过程直到手机进入AFU状态才算完成。

请注意,手机在上次提取过程中崩溃了,这解释了图6第292行中看到的KP事件。

没有Rubin?没问题。

到目前为止,我们的讨论都围绕着Rubin和DWB共存于手机上的情况。但如果用户不使用Rubin呢?为了测试这一点,我重置了S22,但没有登录我的三星账户。我首先要说明,我仍然观察到记录以同样的方式延迟写入数据库。然而,就DWB而言,情况略有不同。见图7。

图7. 这看起来好多了。 在未启用Rubin的情况下,解锁事件回到了usageEvents表中。而且和以前一样,设备启动记录仍然指示着手机在启动/重启后首次被解锁的时间。图8显示了Logging表,其中一条BOOT_COMPLETED记录被高亮显示。请注意,其时间与图7中记录855大致相符。

图8. 无Rubin时的BOOT_COMPLETED记录。

快速收尾

虽然这是我史上最短的文章……但我认为单独强调这一点很重要。Rubin和DWB的共存设置不仅会带来问题,还可能导致取证工具遗漏重要的数据。这些是取证人员在过去五年中一直依赖的数据。此外,这种不立即写入记录的习惯,在并非所有内容都已写入时,会给取证人员一种错误的安全感。记录可能处于待写入状态而无法获取,取证人员可能由于缺乏数据而得出错误的结论。因此,理解这种行为的存在至关重要。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计