(并非)奇怪的搭档——三星Rubin与数字健康功能
引言
又一个夏天飞逝而过。假期、法庭(是的!)、课程(同样,是的!)以及当然还有会议巡回,今年都在全面进行中。事情稍微缓和下来,我终于有机会动手写下一些一直在进行的工作。如今,坐下来写作的时间越来越难找。不过,我希望这种趋势会改变。
首先是三星。具体来说,是三星定制服务(又名Rubin)和数字健康(DWB)。有很多人直接或通过工作联系我,询问关于这两者以及它们表现出的一些奇怪行为,我认为“奇怪”可能是最好的描述方式。毕竟这是三星,在Android方面,他们喜欢以自己独特的方式做事。这让检查人员保持警惕,并为Android增添了一些多样性。因为Android取证缺乏多样性,对吧?
在测试过程中,我必须应对三星的SPL和常规更新,这使得获取提取变得棘手和令人沮丧。有时我能获得Rubin所需的关键材料,有时则不能。这完全取决于我进行提取时的具体情况。无论如何,S22得到了很好的锻炼。它运行的是Android 15(OneUI 7),带有2024年12月和2025年4月的SPL。我知道有7月的SPL,但由于手机已经让我很头疼,我选择保持现状。
如果你没有阅读过三星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小时!这很有趣,因为这部手机上有活动,本应在8月4日记录信息到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设置会导致问题,而且它可能导致取证工具遗漏重要数据。这些数据是检查人员在过去五年中逐渐依赖的。此外,这种不立即写入记录的习惯可能会在并非所有内容都已写入时给检查人员一种错误的安全感。记录可能等待写入而不可用(我仍然认为这些东西在磁盘上的某个地方——我会继续寻找),检查人员可能由于缺乏数据而得出错误的结论,因此理解这种行为的存在非常重要。