Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

Security Analysis of Android Factory Resets

论文下载:http://www.cl.cam.ac.uk/~rja14/Papers/fr_most15.pdf

最近传出一则新闻《Android手机恢复出厂设置后,数据依然可恢复》,炒得沸沸扬扬,虽然这则新闻来自于剑桥大学研究人员在2015年MoST安全会议上发表的论文Security Analysis of Android Factory Resets,但是新闻的编辑显然对Android数据擦除和论文所讨论的内容理解上存在一定的偏差,因此我们有必要重新审视这篇论文,并对真实情况下的Android数据擦除进行探究。

1 背景

首先要澄清的一点是,这篇论文的作者并没有像新闻中所说“发现超过五亿Android手机在恢复出厂设置后并没有完全擦除手机数据”,他们只是对26台相关的手机进行了分析,然后推测出类似的手机存在安全问题。但是对于研究人员而言,我们想要深入了解到底这样的安全问题的根源是什么?这也是我们今天论文阅读要深入讨论的主题。

关注数据擦除问题,首先要理解数据擦除的三个层次,在本文中作者也介绍了这三个层次分别是:

  1. analog sanitisation,在模拟电路层面的擦除,真正意义上的“data purging”;
  2. digital sanitisation,在数字电路层面的清除,若在此层面上清除的数据,用任何设备本身提供的接口方式去读取(绕过操作系统访问控制)都无法读取到数据;
  3. ogical sanitisation,通过存储介质提供的操作接口进行的数据删除,通过这种清除方式删除的数据无法通过同一类型的接口进行数据读取。对于移动电话和PDA,NIST 800-88 对于数据删除定义为“clearing” level,建议先删除数据,然后执行Factory Reset.

我们想要在这里一并推荐两篇相关论文:第一篇论文Reliably Erasing Data From Flash-Based Solid State Drives来自FAST 2011,这篇论文主要阐述了三个观点:第一,存储介质的 built-in commands 通常能提供有效的数据擦除功能,但是并不能保证这些命令总是被制造商正确地实现;第二,将SSD的所有数据全部覆盖两次(在大部分情况下)能够有效地清除数据;第三,对于单个文件删除而言,当前的SSD都存在不足之处(这个我们在后面会展开讨论)。第二篇论文User-Level Secure Deletion on Log-structured File Systems来自AsiaCCS 2012,介绍了对于Log-structured File Systems(例如ext4这种)日志化文件系统的用户级别安全删除,当然,这篇文章发表的时间较早,因此只讨论了早期Android版本常用的 YAFFS 文件系统,作者认为只要进行特定的加密或者反复写操作,就能够有效地防止数据恢复攻击。

为了更好理解上述结论,我们简单介绍一下一些数据擦除的相关知识,首先,回到Android设备上,我们知道Android设备通常使用的存储介质是eMMC(Embedded Multi Media Card),主要是针对手机或平板电脑等产品的内嵌式存储器标准规格。这一类存储介质的特点是提供了一系列的操作COMMAND指令,而Android通过kernel的 ioctl system call 来接收上层应用发出的数据删除请求,并相应的执行不同的eMMC COMMAND来进行数据删除。例如 BLKDISCARDBLKSECDISCARD 指令,前者往往会被kernel更换为 DISCARD 或者 TRIM 指令,而后者能够确保数据安全的删除,但是这两种操作都仅仅是logical sanitisation,如果需要执行digital sanitisation.,可以使用 SECURE TRIM , SECURE ERASESANITIZE 指令。

其次,我们需要介绍一下自从 Android 4.3 开始正式支持的TRIM特性,TRIM实际上是一个存储介质引入的ATA指令,由操作系统发送给SSD主控制器,告诉它哪些数据占的地址是需要清理的。传统的情况下,当一个文件被删除的时候,操作系统并不会真正的去删除它。操作系统只是把这个文件的地址标记为空,让它可以被再次使用,这表示这个文件所占的地址已经无效。而由于SSD的特性,这种操作就会出问题:SSD写入数据要以一整页的粒度写入(大小通常为4至8千字节),而写入需要先擦除这整一页才能再次写入数据,为了保证这一页上的有效数据不被擦除,SSD必须先复制这一页到新的空白页上,然后才能擦除这个旧的页。如果没有TRIM,传统的SSD主控制器在对一个页上某些数据进行擦除之后,要等到操作系统要求覆盖数据进去之时,才会执行上述的复制-写操作。这样一来会让写入速度变慢,二来造成了数据残留。TRIM指令的引入,相当于在硬件控制器层面上引入了一个隐式的自动化磁盘碎片整理和数据擦除机制,这样就能从某种程度上减轻数据残留的风险。当然,这个特性必须由硬件本身支持来完成,操作系统仅仅是发送了这样一个信息给硬件控制器,至于硬件什么时候去进行数据的删除和重整理工作,上层是一无所知的。

可以看出,Android上数据残留问题有着非常复杂的现实制约因素(硬件和软件层面),实际上,无论是论文Security Analysis of Android Factory Resets还是这则《Android手机恢复出厂设置后,数据依然可恢复》的新闻,都只关注了不同版本、不同设备上执行 Factory Reset 之后数据的残留问题,但是却没有对这些问题的本质进行总结,我们于是进行了深入的分析和总结,并给出了我们的相关结论:

2 Factory Reset 何时安全(或不安全)?

我们在2013-2014年间同样开展了大量的数据删除和数据恢复实验工作,我们发现,Factory Reset 对数据的有效清理,决定于两个因素:

A. 是否正确地调用了数据清除接口

我们发现,Android平台上全磁盘数据清除一般发生在两种情况下:第一,当用户手工触发了操作系统或Recovery提供的Factory Reset,注意到不管是操作系统执行Factory Reset还是Recovery执行Factory Reset,实际上都是需要重启进入Recovery来完成这个工作的,Android本身并不负责进行这个工作(绝大多数情况下,手机的官方Recovery都不提供用户操作的界面,当然也不排除少数手机自带可操作的Recovery)。如前所述,SSD控制器通常会提供一些特殊的COMMAND来帮助数据清除,例如 BLKSECDISCARD,按照正常的情况,Recovery会去调用这个指令来安全的擦除磁盘,我们的测试表明在大部分手机上这个功能是安全可靠的(相关分区所有可读数据块完全被置为0,凭借普通的恢复技术得不到任何有用数据);第二,很多手机提供了所谓“Bootloader解锁”功能,在解锁的同时就会强制触发一个全磁盘清理(通常这个清理会处理/data和/sdcard两个分区),根据我们的测试这也是一个比较安全的数据清除过程。

但是,这个过程存在一些变数,有一个非常著名的例子即三星字库门事件 ( http://wiki.cyanogenmod.org/w/EMMC_Bugs ),就是因为eMMC芯片上对erase命令支持有问题,一旦执行了相关操作有很高概率导致设备变砖,因此后续的补丁释出时就在kernel上patch了MMC_CAP_ERASE flag 来强行屏蔽各类erase命令。在这种情况下,Factory Reset自然就会变成不安全的。

事实上,论文Security Analysis of Android Factory Resets对于上层数据删除对应的底层命令给出了一个非常好的总结表格:

Fig

B. 是否为了兼容性使用了不安全的清除方式

Android设备上有一个比较著名的“刷机”特性。当用户为了绕过官方的签名限制刷入新的rom包时,往往会给系统先刷入一个第三方的Recovery,比较著名的第三方Recovery包括CWM和TWRP。我们发现,在这种情况下,第三方Recovery为了兼容性往往会引入不安全的Factory Reset,这个兼容性问题来自于现在诸多Android设备都将SD卡内置入手机中(用户使用的外置SD卡的品质无法保证,干脆全部屏蔽了),实际上就是将/data分区下的一个目录虚拟为/sdcard,这样导致了一个问题,如果清理/data分区就会把/sdcard分区全部清理掉,实际上Android默认是不希望清理掉SD Card上的数据的,于是第三方Recovery就自作聪明的去用rm -rf命令来逐一清理/data下的各个目录(除了/sdcard),这种方法根本无法保证数据的清除,会导致极为严重的数据残留。实际上,我们认为这是Android Factory Reset导致数据残留里面,最根本性的问题。

3 还有哪些导致数据残留的问题?

我们进一步发现,不仅仅是“恢复出厂设置”这个机制背后隐藏了大量的数据残留问题,在Android平台上同样存在很多平时不为人注意的操作会导致数据残留问题。

3.1 APP的 “清理数据” 功能

在Andorid系统中,有一个针对各个应用的“清理数据”功能,能够把每个应用所在/data/分区下私有的文件进行清理,这个过程实际上触发了:

initiateClearUserData()->
... ->
    clearUserData()->
        do_rm_user_data()->
            delete_user_data()->
                delete_dir_contents()->
                    unlinkat()

最后的unlinkat,在SSD上去触发文件删除功能。由于SSD是一个Block Device,而文件的大小是不确定的,在SSD上对文件的删除无法使用 BLKDISCARDBLKSECDISCARD 来处理,因此这里必然带来了数据残留的风险。

3.2 APP 卸载过程

同“清理数据”功能一样,APP的卸载功能,过程为

deletePackage()->
    deletePackageAsUser()->
        deletePackageX()->
            deletePackageLI()->
                removePackageDataLI()->
                    removeDataDirsLI()->
                        remove()->
                            uninstall()->
                                _delete_dir_contents()

最后还是落到文件删除过程上去,也存在着数据残留的风险。

由于这两个过程本身是由Android系统来控制的(用户本身无法随意访问到/data/分区下的文件),因此这两个过程不仅造成了数据残留,同时还屏蔽了用户可能的后续操作(例如覆写或者加密相关文件)。会带来很多隐患。例如root过的手机可以读取/data分区恢复某个app删除前的数据,如果这个app是诸如支付类或者IM类,可能会导致登陆凭证或隐私信息的泄漏。

4 总结

今天介绍的这篇Security Analysis of Android Factory Resets论文还是很好地揭示了Android上数据残留的问题,当然,我们进一步的分析表明,大部分手机(特别是自Android 4.3之后)的Factory Reset都使用了 BLKSECDISCARD 指令,应该是比较安全的。需要提醒的是那些使用第三方Recovery的用户。此外,如果担心app保存的数据无法彻底清理的问题,一方面用户需要开启全磁盘加密并使用复杂密码,另一方面,定期的执行安全的Factory Reset也不失为一种办法吧。