Android FRP功能分析(Factory Reset Protection)

简介

最近在对华为P10刷机时,发现解锁bootloader需要关闭“查找我的手机“功能,此外,解锁bootloader后刷recovery时,仍然需要关闭“查找我的手机”才能进行,这种现象表明了Android主系统可以操作bootloader和recovery分区,一番查找后,发现这个功能叫做FRP(Factory Reset Protection),自Android 5.0后引入,为了防止手机被盗后被刷机而引入的一种保护机制。

FRP工作机制

我们假设手机被盗取后的几个场景来分析:

一、手机有锁屏密码,盗取者无法进入主系统

方案1:
盗取者为了使用该设备,此时,很容易想到进入recovery模式去恢复出厂设置,即使这样,原机主的设备在reset后数据被清除,但重启后再次进入系统前,FRP保护开始工作,要求输入原设备绑定的账号解锁。如下是在华为手机上做的实验:

upload successful

方案2:
既然原设备的recovery有检查,那盗取者可以刷第三方的recovery,此时便需要解锁bootloader。然而,随着很多手机厂商都不提供解锁bootloader服务,仅仅是解锁bootloader就很困难了,我们再假设盗取者有解锁bootloader的能力,然而FRP又发挥了作用,在bootloader中设置了一个标记位,只有这个标记位置零时才允许解锁bootloader。同样道理,即使完成了解锁bootloader这一关,刷第三方recovery时依然受到FRP保护。

两种方案都失败了,对于盗取者来说,只能眼睁睁看着设备卖废铁了,所以FRP作用还是挺大的。

二、无锁屏密码或被破解,盗取者可以进入主系统

这个时候就比较尴尬了,失主的数据当然一览无余,但盗取者可能有三种操作:

  1. 关闭FRP保护
  2. 添加一个自己的账户或删除原机主账户
  3. 在设置中恢复出厂设置
    这三种操作无论哪一个,都需要输入原账户的口令进行验证。

当然,如果知道原账户的账号,我可以重置密码,毕竟能进主系统就可以收验证码。但google的账户要求在重置72小时后才能关闭FRP,这期间失主可以对手机进行远程擦除或锁定。国内的其他厂商应该也有一些保护机制,但不代表可以万无一失,不过由此看来设置锁屏密码还是非常重要的。

根据上述两个场景,总结FRP的功能如下:

  • 只要有google账户(第三方厂商也可以),有网络,就可以远程通过Android Device Manager(ADM)锁屏
  • frp打开后,如下操作会提示密码:在主用户上添加google账户;删除最后一个google账户
  • frp打开后,只有在Settings下做factory reset才会清除reset token,重新打开setup wizard(设置向导)时才不需要密码 (trusted factory reset)
  • frp打开后,bootloader下或者ADM下做factory reset不会清除reset token,重新打开setup wizard时会提示输入密码。 (untrusted factory reset), 只要输入的账户/密码符合之前任意一个google账户即可。

代码分析

Android中FRP实现主要在以下几个文件中:

当创建有一个账户时,FRP会创建一个重置的标志位和key保存在这个block里面,可以用通过其他的android设备登陆你的google账户定位或者锁定,远程清空手机,回复出场设置等。

FRP在bootloader分区的最后一个字节用于信号标记,如果字节为0,OEM-UNLOCK位DISABLE。即,当此字节设置为0,fastboot oem unlock应该失败。enable/disbale OEM-UNLOCK只能通过PersistentDataBlockManager这个API来更改(相当于更改分区最后1个byte)。

FRP对应一个Account Data Blocks用来存放key,其实就是一个独立的存储分区(500kb - 2M),通过系统中的ro.frp.pst来指定该分区的路径:

1
2
ro.frp.pst=/dev/block/platform/sdhci-tegra.3/by-name/PST
ro.frp.pst=/dev/block/platform/msm_sdcc.1/by-name/frp

对其的读写操作是通过API——android.service.persistentdata.PersistentDataBlockManager来操作的,当然操作需要特殊的权限,具体在代码中有解释。

这部分代码的核心其实就是读写操作,例如PersistentDataBlockService#wipe(),实际上就是ioctl(fd, BLKSECDISCARD, &range)。

FRP漏洞

  1. Nexus 6 重置后利用设置向导的漏洞进入系统
    https://www.androidauthority.com/factory-reset-protection-bypass-nexus-marshmallow-680580/
  2. Huawei安全公告上一个FRP绕过(未公开)
    https://www.huawei.com/en/psirt/security-advisories/huawei-sa-20170524-01-frp-en

事实上,我在一部root的手机上am broadcast -a “com.huawei.remotecontrol.OFF_REMOTE”就可以关闭FRP,无需输入账号验证,因此这里可能存在什么问题,后续待研究。

参考资料

  1. Help prevent others from using your device without permission
  2. https://blog.csdn.net/woshing123456/article/details/44524051
  3. https://www.androidpolice.com/2015/03/12/guide-what-is-android-5-1s-antitheft-device-protection-feature-and-how-do-i-use-it/
  4. http://cfig.github.io/2017/12/20/Android-Factory-Reset-Protection-FRP/