三星Rubin与数字健康功能交互揭秘:解锁事件与延迟写入的取证观察

本文深入探讨了三星Android设备上“Rubin定制服务”与“数字健康”功能共同作用时的取证特性。核心发现包括解锁事件从DWB数据库转移至Rubin、记录延迟写入现象,以及“启动完成”事件与设备首次解锁状态的关联。这些行为可能导致取证工具遗漏关键数据。

(并非)奇怪的搭档——三星的Rubin与数字健康功能

或者说,并非如此。

又一个夏天飞逝而过。假期、法庭(是的!)、课程(也是,是的!)以及当然还有今年的各种会议(现在依然如此)都进行得如火如荼。事情稍微放缓了一点,我终于有机会敲打键盘,写一些我一直在研究的事情。如今,要找到时间坐下来写作变得越来越困难。不过,我希望这种趋势会改变。

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

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

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

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

锁定与解锁——相辅相成

标题已经说明了一切。如果取证人员遇到一部同时使用Rubin和DWB的手机,为了最清晰地了解设备上发生的情况,需要将这两者放在一起检查。原因在于,传统上由DWB保存的一项信息——设备解锁事件——在启用Rubin时,会被转移到Rubin中。参见图1。

图1. dwbCommon中没有一个解锁事件。

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

图2. 屏幕解锁和锁定。

inferenceengine_logging.db中的screen_state_log表包含了设备解锁和锁定的信息。为了确定哪些记录代表哪个动作,需要同时使用screen_state、user_present、use_keyguard和time(我喜欢用UTC时间)或time_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文件)中。然而有趣的是,一些锁定事件(eventType=17)被记录在usageEvents(dwbCommon.db)中,但并非全部,而且它们与screen_state_log(inferenceengine_logging.db)中记录的相应动作时间大致接近。

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

延迟写入与“已完成的启动”

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

图3. 已完成的启动以及Logging表中的最后条目。

图4. usageEvents表中的最后记录。

图3和图4真正揭示了这种奇怪的行为,因为我在测试过程中多次遇到这种情况。图3显示了Logging表中的最后两条记录,其中有两条“BOOT_COMPLETED”条目。这些条目的有趣之处在于它们与usageEvents表中最后四条记录的关系:它们的时间戳比后者晚了超过12小时!这很有趣,因为在这段时间内手机上有活动,本应在usageEvents中记录信息,包括两次启动动作,但它们并不在usageEvents中。然而,几个小时后又进行了几次提取,这些记录终于出现了。

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

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

图5. 两次重启。

上面有两次重启事件。第一次发生在2025-08-04 09:26(UTC -0400),但手机直到09:27(UTC -0400)才被解锁。第二次重启发生在2025-08-04 19:20(UTC -0400),但手机直到2025-08-05 08:29(UTC -0400)才被解锁。如上所示,BOOT_COMPLETED条目与手机首次解锁的时间一致。为了确认我所看到的,我查看了文件eRR.p(USERDATA/system/users/service/data/)。下面的图6显示了相关的时间范围,对应的重启事件用各自的颜色进行了编码。

图6. eRR.p中的重启事件。

那么,发生了什么(或正在发生)?当S22在重启后首次被解锁时,在我输入PIN码后,屏幕显示“正在启动手机…”。在此之前,手机处于BFU状态;它可以执行一些操作,但无法执行全部操作。一旦我输入了PIN码,手机就“完成”了其启动过程,并进入了AFU状态。似乎,就DWB而言,启动过程直到手机进入AFU状态才算完成。

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

没有Rubin?没问题。

到目前为止,讨论都围绕着Rubin和DWB共存在手机上的情况。但如果用户不使用Rubin会发生什么?为了测试这一点,我重置了S22,但没有登录我的三星账户。我要提前说明一下,我仍然观察到记录以与之前相同的方式延迟写入数据库。不过,就DWB而言,情况略有不同。参见图7。

图7. 这看起来好多了。

在没有启用Rubin的情况下,解锁事件(eventType=18)重新出现在了usageEvents表中。而且,和以前一样,设备启动记录(eventType=27)仍然指示着手机在启动/重启后首次被解锁的时间。图8显示了Logging表,其中一条BOOT_COMPLETED记录被高亮显示。注意其时间与图7中记录855(DEVICE_STARTUP)的时间大致接近。

图8. BOOT_COMPLETED(没有Rubin的情况)。

非常简短

虽然这是我有史以来最短的文章……但我认为单独强调这一点很重要。Rubin+DWB的组合设置不仅会导致问题,还可能导致取证工具遗漏重要数据。这是过去五年来取证人员一直依赖的数据。此外,这种不立即写入记录的习惯可能会让取证人员在并非所有内容都已写入时产生错误的安全感。记录可能正在等待写入而尚未可用(我仍然认为这些东西在磁盘的某个地方——我会继续寻找),取证人员可能会因为缺乏数据而得出错误的结论,因此理解这种行为的存在非常重要。

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