-
-
[翻译]Android平台安全模型(The Android Platform Security Model)
-
发表于: 2021-12-19 17:51 21129
-
版权声明:本文为CSDN博主「ashimida@」翻译的文章,转载请附上出处链接和本声明。
本文链接:Android平台安全模型(The Android Platform Security Model)_ashimida-CSDN博客此文翻译自<The Android Platform Security Model>(2019),译者水平有限,如有错误之处还请指正
更多内容可关注微信公众号
摘要
Android是部署最广泛的终端用户操作系统,其覆盖的用例包括: 通信,导航,媒体消费,娱乐,财务,健康以及传感器,执行器,摄像头或麦克风,其基础安全模型需要在各种情况下解决许多实际的威胁。
Android的安全模型模型需要在终端用户的安全性,隐私性,可用性,及在资源紧张的硬件配置下保证应用开发和系统性能之间取得平衡。
虽然很多设计原则都隐含在了整个系统架构,访问控制机制和漏洞缓解技术中,但Android的安全模型之前从未正式发布过,本文的目的就是为了讨论此抽象模型。
基于威胁模型的定义和Android运营的生态环境,我们分析了过去和当前在Android中实施的不同安全措施是如何协同工作以缓解安全威胁的。
在应用此安全模型时还有一些例外的情况,本文也讨论了这些特意和安全模型有偏差的地方。
1.简介
在撰写本文时,Android是最广泛部署的终端用户操作系统。凭借每月超过20亿的激活设备数[9]以及移动互联网服务的大趋势,Android现在是全球用户与数字服务互动的最常用的系统。跨越不同的外形尺寸(包括手机,平板电脑,可穿戴设备,电视,物联网,汽车和更多特殊用途类别),Android扔存在大量且持续增长的用例,包括通信,媒体消费和 娱乐,财务,健康和物理传感器/执行器等。大部分应用程序的安全性和隐私性越来越重要,Android作为操作系统需要为用户和开发人员提供充分和适当的保证。
为了平衡用户,应用程序开发人员,内容制作者,服务提供商和雇主的不同(有时是冲突的)需求和希望,Android基本上是一个基于多方批准的模型:即一个操作只有所有的相关方都批准才能进行,任何一方不同意则此操作就要被停止或阻塞。这与传统的操作系统的安全模型不同,传统的模型中更注重于用户是否同意某请求,而没有明确考虑其他利益相关者(本文中的批准指执行某一方意图的各种技术方法,而不是法律制度中的要求或标准)。
虽然多方模型从一开始就隐式的包含在了Android平台的架构设计中,但其已经根据过去的经验进行了改进和扩展。本文的目的在于文档化Android的安全模型并系统分析其在生态环境约束和历史发展过程中的意义,本文的贡献如下:
1) 本文第一次基于安全原则和Android运营生态定义Android安全模型,本文中分析的三方批准模型从Android最早的版本期就已经隐式包含在其安全模型中了,本文只是系统化的说明了之前存在但未公开发布的知识。
2) 我们定义了Android面临的威胁模型,以及安全模型如何解决此问题,并且讨论了对应的影响和其他需要考虑的特殊情况。
3) 我们解释了AOPS(Android平台的参考实现)是如何基于多个层面上的安全措施的交互来实现此安全模型的。
4) 我们也同时提出当前系统存在的差距和未来可能的一些改进措施
本文重点介绍的是Android平台自身的安全和隐私性的保护,如在用户设备上的代码执行。而其他补充的安全服务,如GPP(Google Play Project,扫描提交到Google Play的应用,设备上的代码扫描)、Google Play政策,和其他法律框架问题则不在本文的讨论范围 [6,28,50,93]。
但这里需要明确指出的是,Google Play中有一个对安全有积极影响的政策,就是Google Play要求新开发或更新的App需要使用最新的Android API Level,这可以使得Android后续可以启用并删除已知被错误使用或有安全问题的API。
下文首先介绍Android的安全原则,Android的生态环境和威胁模型(Section 2),这些都是Android安全模型的基础。之后是中心安全模型(Section 3)和其在OS体系结构不同层面上的具体实现(Section 4),除非特殊说明,否则所有的实现都基于Android Pie(9.0)[79], 且后续的说明都是基于版本号而不是名字:4.1-4.3(Jelly Bean),4.4(KitKat),5.x(Lollipop),6.x(Marshmallow),7.x(Nougat),8.x(Oreo),最终在Section 5讨论特殊例子和Section 6讨论相关工作。
2. Android背景
2.1 生态环境
一些设计决策是需要放到生态的大背景下去考虑的,而并不是孤立存在的。一个成功的生态系统是所有合作方都会在其成长过程中收益的,但同时也需要有个最低的相互信任级别。这意味着平台必须创建默认安全的执行环境,在此环境中,主要方(终端用户,应用开发人员,操作系统)可以定义互利的参与条款。若这些方不能就某一行为达成协议,那么最安全的方法就是禁止此行为的执行(默认拒绝)。
Android是一个以终端用户为中心的操作系统,尽管力求灵活性,但主要的关注点还是终端用户,其显示的含义就是,作为一个消费者操作系统,Android必须对用户有用并吸引开发者。这就意味着在默认情况下用户界面和工作流必须是默认安全的,且对于可能危害系统安全或隐私的要求都需要被显示的提出来显示给用户,这也意味着操作系统不得将关于安全或隐私的技术细节的决定展现给没有经验的用户[5]。
Android生态系统是巨大的,不同的统计数据显示,在过去的几年中,全球大多数各种各样的用户群已经在使用移动设备访问互联网(美国为63%[1],全球为56%[2],超过68%在亚洲,印度超过80%),此外还有数以百计的OEM(Original Equipment Manufacturers, 如设备制造商 )制造了上万种不同 外形的Android设备(包括但不限于只能手机,平板电脑,手表,眼镜,相机和其他IOT设备,手持扫描仪/显示器和其他专用设备,TV,车等)。
某些OEM没有详细的技术专业知识,只依赖于ODM(Original Device Manufacturers)开发的硬件 和固件然后重新打包或简单的换个商标。由于只有集成了Google服务的设备需要固件认证,而仅仅基于AOSP的设备可以未经许可或注册的情况下制造,因此没有一个唯一的已注册OEM列表,且即使有,这个列表也是随着硬件概念的发展而不断变化的。这也就意味着,对API接口的修改会导致生态系统中巨大的改变,且大多数使用用例是需要时间来覆盖的。
但使用Android作为商标宣传的设备,就必须要通过Android的CTS兼容性测试(Compatibility Test Suite), 开发人员开发的app在不同设备执行的正确性都是要由CTS来保证的。和一些平台相比 Android是支持任意应用的安装的,这就导致了不同应用商店的出现以及不受Google Play应用商店 控制的程序的出现,同时也导致了App的长尾效应,也就是说总有一些只在特定设备上使用的旧版本的app,是一直没有更新的,故Android API的修改需要考虑到对生态中大量应用的影响。
理论上Android的App可以用任意语言编写,只要其接口使用的是Java API与Android框架层交互 即可,不论此语言是否需要运行时支持,编译或解释。Android目前并不支持非JAVA API的程序生命 周期控制,因为如果支持其他语言,则势必要支持与Java的API并行等问题,这会使得框架层变得更加复杂,且更容易出错,因此应用至少需要有一个小的Java语言wrapper来初始化启动,并与系统的服务进行交互。其重要的影响是,这种灵活性导致安全机制不能依赖编译时检查或其他编译环境假设,因此Android的安全需要基于应用程序的边界(进程)做运行时检查。
2.2 Android安全原则
Android从一开始就假设几个基本的安全和隐私原则,这些可以认为是和生态系统中其他方的一个隐式约定:
* 数据创建方拥有其创建数据的访问控制权。任何数据的创建者都被隐式的授予数据的控制权(这里指的是文件系统或内存中的数据访问权限,而不是法律上的所有权)
* 批准是在知情的情况下,并且必须是有意义的。批准任何行动的行为者必须有权根据有关行动及其影响的信息作出决定,并且必须有有意义的方式来批准或拒绝。尽管实现的技术手段是不同的,但这一条是需要同时应用于用户和开发人员的。批准不仅仅来自项目的创建者,还要包含所有其他的参与者,批准的决定必须是强制的,而不是可以自定义的。
* 设计/默认安全(Safe by design/default)。组件在设计上应该是安全的,也就是说系统组件或服 务需要始终考虑到保护安全和隐私虽然这可能导致潜在的阻碍某些使用场景。这一原则适用于模块,APIs,通信通道,通常也适用于各种接口。当需要为了灵活性而提供一些此类接口的变种时(如具有更多参数以覆盖默认行为的第二个接口方法),应确保这些接口难以被有意或无意的滥用。此原则是针对开发者的,包括设备制造商,但也隐式包含用户如何在用户界面中设计和呈现安全性。Android广泛的面向开发者并且有意降低应用开发者的门槛。让乱用API变得困难不仅可以防范恶意的对手,并且可以缓解真正的错误,如对接口定义不完全了解或缺乏安全开发经验的开发者。在纵深防御方法中,没有单一的方法可以让一个系统变成设计安全的,相反,设计安全被认为是一种指导原则,定义、更新或者必要时弃用和删除接口时候都要遵循此原则。
* 纵深防御。一个安全系统如果可以允许攻击者不需要bypass任何安全机制即可完成其所有的目标,那么这个安全系统是不够健壮的。具体来说,如果想要违反上述任何一个原则都的需要一个设备上的控制绕过。任何安全系统的主要目标都是强制执行其安全模型。对于Android这种在复杂环境运行的操作系统(可参考后面的威胁模型),这意味着即使设备不是最新的,当系统安全中的某个假设被违反了,或者攻击者发现了某个实现的漏洞,纵深防御这种方法也不会立刻失效。纵深防御的特点就是是的单个漏洞更难或不可被利用,并且使得攻击者想要完成目标必须增加漏洞数量。我们通常采用4种通用的安全策略来防止对手绕过安全模型,即:隔离和限制,利用缓解,完整性保护,补丁和更新,这些将会在Section 4更详细的讨论。
2.3 威胁模型
移动设备的威胁模型和通常用于桌面或服务器的系统的威胁模型不同,主要的原因有两个:
- 移动设备容易丢失或被盗
- 移动设备预期会连接到非授信网络
同时由于大多数移动设备都距离用户很近,其会比其他设备接触到更多类别的敏感数据,[73]介绍了一个分层的移动设备威胁模型,我们采用此文的涉及范围来讨论Android安全模型。
* 攻击者可物理接触到设备。对于所有移动和可穿戴设备,我们必须假设其可能落入攻击者手中,对于其他Android的设备如IOT,车,TV等,此情景也成立。因此我们将"Android设备可以直接被攻击者获取,或攻击者可以物理接近"作为威胁模型的一部分,这包括丢失或被盗,但也包括多个用户共享一台设备的情况(处于善意或好奇,如电视或平板电脑的共享)。由于物理接触或物理接近而确定的威胁包括:
T1: 已关机的设备受到完全物理控制(可能是由于边境管控或海关检查等)
T2: 已锁屏的设备受到完全物理控制(如攻击者此时可能会尝试从设备中抽取数据以进一步实现 身份盗取)
T3: 已屏幕解锁(或共享)的设备在已授权但非本人的用户手中(如亲密伴侣乱用,资源提交边境 管制或海关检查)
T4: 已锁屏/未锁屏的设备被攻击者物理接近(假设攻击者可以控制无线信道包括蜂窝通信,wifi, 蓝牙,GPS,NFC,FM等),如直接通过蓝牙[30]攻击。尽管由于距离太小,NFC可以认为是物理控制,但我们还是将其放到了物理接近中。
* 网络通信是不受信任的。 攻击者可完全控制网络通信基本是一个标准的威胁假设了,当然也存 在于Android设备中。包括网络通信的第一跳(如捕获wifi入口以破坏TLS链接,恶意的伪造接入点)以及其他控制点(如移动运营商网络或国家防火墙),此威胁包括相关的短距离无线电威胁(如NFC/BLE蠕虫攻击)都在Dolev-Yao的模型中[40]进行了总结。出于实际目的,我们主要考虑两种网络级威胁:
T5: 被动窃听和流量分析,包括追踪网络内部或跨网络的设备,如基于MAC地址或其他网络 标识符的追踪。
T6: 主动操纵网络流量,如基于TLS的中间人攻击
就可扩展性而言,T5/T6和T4是不同的,控制主网络的单个节点即可用来攻击大量设备,而T4中的近端无线攻击则需要物理近距离接触目标设备。
* 不受信任的代码在设备上执行。Android与其他移动操作系统的一个根本区别在于,Android特意允许(在终端用户明确批准的情况下)从任意来源安装应用代码,并且不许强制通过特定中心节点的审查。这就意味着在Android上会增加多个级别的攻击向量 (对比[73]):
T7: 恶意使用系统提供的API,如间谍软件
T8: 利用OS中的漏洞,如内核,驱动,系统服务等[36-38,90]
T9: 滥用系统设备上其他应用的API接口[89]
T10: 没有明确的用户同意的情况下执行来自网络的不授信的代码(如JavaScript)
T11: 模仿系统或其他应用界面来欺骗用户([39,81])
T12: 从系统或其他应用程序的用户界面读取数据,如屏幕截图获取其他app数据[58,63]
T13: 将输入时间注入到系统或其他用户界面[51]
* 设备处理了不受信的内容。除了直接执行非授信代码之外,设备还会处理大量非授信的数据,包括多媒体数据,这就导致了有关数据和元数据处理的威胁:
T14: 利用操作系统或app中处理处理不受信内容的代码,如media库[88]
T15: 滥用唯一标识符进行有针对性的攻击(即使在受信网络上也有可能发生),如使用电话号码或 email地址发送垃圾邮件或收集其他数据集,包括位置信息。
3. Android平台安全模型
本章描述的基本安全模型已为Android的设计提供了信息,此模型经过了改进,但没有发生根本的变化。基于上述提到的Android生态环境和一般的Android安全原则,Android的安全模型根据应用和平台自身的安全需求来平衡用户的安全、隐私需求。之前提到的威胁模型包括了对所有利益相关者的威胁,而Android平台的安全模型(Section 3)及其具体的实现(Section4)则是为了解决这些威胁。
Android平台的安全模型由5条规则非正式定义:
1)三方批准(三方准入): 除非三个主要方都批准,否则任何操作都无法执行,这三方即用户,平台和开发人员(开发人员隐式包含了内容制作者和服务提供者的利益)。任何一方都可以否决此执行。此三方批准模型涵盖了作为大多数安全模型基础的传统的二维主体客体模型[91](主体如用户和应用进程,客体如文件,套接字,IPC接口,内存,虚拟数据提供者等)。在传统的主客体模型中,文件是主要要保护的客体类型,对这些文件的默认控制依赖于其位置和是哪一方创建的:
- 共享存储(Shared Storage)的数据是由用户控制
- 私有app目录的数据和app的地址空间是由App自己控制的
- 在特定系统位置的数据是由平台控制的(如已授予的权限列表数据库)
但需要指出的是在三方批准模型下即使一方主要控制数据项,对其的操作也必须要其他两方批准才可执行。对数据的控制权不代表对数据的拥有权(拥有权是一个法律上的概念,而非技术上的,因此超出了OS安全模型的范围)
需要注意的是还会存在一些极端情况,有可能只需要两方需准(主要是对于用户只使用platform/OS服务但不引入新app的情况),或也有可能存在四方的情况(如移动设备管理控制的设备或配置,此策略也被视为批准某项行动??没看懂)。
2)开放生态系统访问(或者说系统默认是可以开放给用户使用的): 用户和开发者都是开放生态系统的一部分,而不仅仅限制于某个应用商店。不需要对开发人员进行中央审查或用户注册。这一条对于安全模型的影响较大,app-app的交互是显式允许的,app开发者可以自有定义自己的API并 提供给其他用户,而不是为每个能想到的工作流程创建特定的平台API。
3)安全是一个兼容性要求(或者说要把安全当做一个兼容性要求来测试):安全模型是Android规范的一部分,这部分定义在CDD(Compatibility Definition Document)[10]中,并由CTS、VTS和其他测试套件来强制保证。不符合CDD,没通过CTS的设备就不能称之为Android设备。在本文中,我们将rooting定义为: 修改系统以执行不受沙箱和隔离机制限制的进程,这样恶意或无意的rooting是一个典型违反CDD的不合规修改的例子。因此只有满足CDD兼容性的设备才称之为Android设备。很多设备支持解锁bootloader且可以刷新固件,如果没有安全保障,则此类修改在CDD下被视为不兼容的。验证启动(Verified boot)和硬件秘钥认证 (hardware key attestation)可以用来验证当前的固件是否处于一个已知的良好状态,进而可能影响用户和开发者是否做出批准的决定。
4)恢复出厂设置要可以将设备恢复到一个安全的状态: 在安全模型被bypass,攻击者对系统造成了永久性危害后,一个恢复出厂设置可以擦除/重新格式化可写的数据分区,将设备恢复到一个只依赖受完整性保护分区的状态。也就是说系统软件不必重装,只需要抹去data分区即可将设备恢复到默认状态。有一个需要注意的是只读设备软件可能自出厂后就已经升级了,恢复出厂设置不会将其降级。因此 更具体的说,恢复出厂设置将Android设备重置到一个只依赖于验证启动覆盖的系统代码,而不依赖于可写分区的状态。
5)应用程序是安全的主角:和在已登录用户帐户的上下文中运行应用程序的操作系统最主要的区别在于Android app不会被当做用户行为的的完全授权代理。在传统的服务器和台式机实现的模型 中甚至通常都不需要利用安全边界,因为恶意代码通常都具有主用户的全部权限,这已经足够其滥用了。有很多的例子,包括文件加密勒索[59,84](并不违背系统的安全模型,只是简单的重写当前用户账户下的所有文件)和隐私数据泄露(如浏览器token[70],历史访问记录,加密货币钱包秘钥等)。
总结: 尽管乍一看,和不适用多方批准模型的传统操作系统相比,Android安全模型向用户会授予较小的权限,但这种做法对终端用户是受益的,即如果一个应用无法以全部用户权限运行,用户就不会被欺骗,以让其访问到其他app控制的数据。也就是说要求应用程序开发同意(由平台强制执行)有助于避免用户混淆攻击,从而更好的保护私有互数据。
4. 实现
Android的安全机制实现了Section 3中提出的安全模型,并且设计上就打算解决上面提到的安全 威胁。本节中我们描述安全措施并指出其缓解了哪些威胁,同时将纵深防御和安全设计这两个体系结构的安全原则考虑到范围内。
4.1 批准
对于不同参与方,给出有意义的批准的含义是不同的,其潜在的问题和制约因素也是不同的。
4.1.1 对于开发者(Developers)
与传统的桌面操作系统不同,Android需确保可以让开发者批准其对其开发的应用或应用数据的操作。这可以防止无关应用向用户设备上的其他应用注入代码或从中偷取数据的大量滥用行为。
与用户不同,开发者的批准是通过其签名的代码和系统的执行来体现的。如一个应用提供了相应的机制来共享数据(如基于操作系统的共享方法,如内置的隐式Intent解析选择对话框[11]),则相当于其同意了共享数据给用户(或者可设置权限)。再比如调试,app自己控制分配给其的VA空间,外部进程的调制只有在app主动同意后才可执行(如在manifest中配置可调式选项)。
有意义的批准是为了确保APi和其行为是清晰的,且开发者理解其应用是如何和其他组件交互,或如何提供数据给其他组件的。此外我们还要假设开发者的技能水平不同,也许不能完全理解某些安全的细微差别,因此API必须是默认安全且很难被错误使用的,以避免意外的安全衰退。
为了确保此批准是来自开发者而不是其他参与方的,应用需要被开发者签名(或者使用秘钥轮换函数,即一个秘钥在此之前已由此应用授予了)。这防止了第三方(包括应用商店)替换或删除代码或资源以修改应用的预期行为。但在应用安装时,应用的签名秘钥是会被隐式信任的,因此在传输过程中(如侧载app,side-loading,和上传下载对应,指的是如在设备之间传输数据)的app替换或修改则不再此平台安全模型的考虑范围内,也有可能导致违反安全模型中的开发者批准。
4.1.2 对于平台
平台和开发者是一样的,都是通过代码签名来代表批准的,但二者的目的却截然不同: 平台的作 用是确保系统按照预期的行为运行,包括强制执行监管或合同要求,以及确定什么样的行为是允许的。平台的批准是通过验证启动强制执行的,用以保护系统镜像,和使用平台签名/权限的平台应用不被篡改(这一点和4.1.1中的应用的签名很像)
4.1.3 对于用户
实现有意义的用户批准是到目前为止最难和最细致的挑战事情,主要问题是如何让用户产生有意义的批准。其中的一些指导原则一直是Android的核心原则,其他的一些指导原则则是根据10年的开发经验完善的:
* 避免过度提示: 过度提示会导致用户疲劳和失明[7],每个操作都提示用户Yes/No不会导致任何有意义的批准,用户会由于规律性的出现而对其视而不见。
* 以用户可以理解的方式提示: 用户不是专家,无法理解细微的安全问题[48],给用户态的提示必须以非技术用户可以理解其做出决定的意义的方式提出。
* 尽可能使用选择器,或以事务为单位批准,而不要使用粗粒度的权限授予: 若可能,则尽量只允许具体体条目的访问,而不是整个集合的访问。如联系人选择器可以允许用户选择一个特定的联系人并分享给其他app,而不是直接给其他app一个联系人数据库的访问权限。这既可以限制数据的暴露,也可以以清晰直观的方式向用户呈现出需要选择的内容。
* 操作系统不能将一个难以做决定的事情交给用户处理: Android经常会强制拒绝某些太过危险的行为,并且可能避添加对于特权用户很有用,但对普通用户有害的功能。
* 为用户提供一个可撤销之前决定的方法: 用户可能会犯错误,即使是最重视安全且对隐私很精明的用户也有可能偶尔因为简单的按错按钮而导致犯错。用户应该可以很容易的撤销其先前做出的决定。这种撤销可能是取消之前授予的权限,也可能到最终直接删除应用。
此外,确保发出批准的用户是设备的合法用户而不是其他物理接触到设备的用户也是至关重要的([T1]-[T3]), 这直接依赖于表单中的下一个部分,即Android锁屏。Rule1(三方批准)需要依赖系统所 有层交叉实现。
我们使用两个例子来更好地描述批准方:
* 两个app之间共享数据需要:
1) 用户通过在对话框中选择一个要共享的app完成用户批准。
2) 开发人员通过在源码中实现 发起数据共享到其他app的代码来完成开发者批准。
3)(Android)平台通过仲裁据访问和确保目标应用无法访问除了此链接显式指定共享外的任何其他数据的方式(在两个app之间构建了一个临时的信任关系)来完成平台批准。
* 更改移动网络运营商(MNO, Mobile Network Operator)配置需要:
1) 通过在一个设置对话框中选择对应的选项来获取用户批准。
2) (MNO APP)开发者实现了这些可以修改配置条目的的选项则相当于获取了开发者批准 (开发者还可以在实现过程中查询策略策略)。
3) 平台验证对应国家的相关法规,且确保此配置不会导致网络不稳定后即可批准。
4.2 身份校验
身份校验是一个守门人的功能,以确保一个系统只与其所有者或合法用户交互。在移动设备上主要的身份校验是通过锁屏来实现的。需要注意的是锁屏是一个明显的安全和可用性的折中: 一方面用户每天会有大约50次(特殊情况下会到200次[45,56])的解锁是会和手机做短时间的交互的(10-250秒),而锁屏显然是与设备进行无摩擦交互的阻力[54,56]。另一方面,没有锁屏功能的设备可以直接被未授权用户打开([T1]-[T3]), 操作系统没法在没有用户认证的情况下可靠的执行用户批准。
目前的形式是,移动设备上的锁屏大多只有两种状态,要么整个手机可以访问,要么主要的功能被锁定(尤其是和安全和隐私相关的功能)。在移动设备上不建议使用长密码或伴随计划的字母数字密码(高度安全但不适用于移动设备),也不建议使用滑动解锁(不能提供安全性),因此锁屏在安全性和可用性之间取得一个合理的平衡至关重要。
为此,最近的Android版本使用了一个分层验证模型,其中基于安全知识因素的身份验证机制可以由便利性模式提供支持,这些便利性功能根据其提供的安全级别在功能上受到限制。这种模型提供的便利性有助于推动锁屏的使用,并且允许更多的用户即受益于锁屏的及时安全性优势,又受益于如基于文件的加密(依赖于用户提供的身份凭据的存在)。举例如Android 7.x开始,我们发现77%的带指纹传感器的设备启用了安全锁屏,而没有指纹的设备只有50%拥有安全锁屏。
从Android 9.0开始,分层身份验证模型将验证模式分为三层:
* 主身份验证方式仅限于只是因素,默认包含(PIN, 图案,密码),主身份验证通过可以访问手 机中所有的功能。
* 二级身份验证方式必须是强大的生物识别特征,如其欺骗和冒名顶替接受率所定义的[78]。在威胁模型中考虑显式的攻击者有助于减少使用不安全解锁方法的可能性[75]。二级身份验证在执行某些操作的时候也会被阻止,如其不能解密基于文件或全盘加密的用户数据分区(如在首次启动时),并且需要每72小时会退到一次一级身份认证。
* 三级身份认证方式是那些或是不符合可欺骗性标准的弱生物特征的方式,或是一些可被替换的方式如授信的蓝牙匹配时解锁或在受信任的位置解锁。三级身份认证受到二级身份认证的所有条件束缚,但除此之外还受到额外的限制,其不能被授予访问Keymaster auth-bound 秘钥的权限(如付款所需的秘钥),同时在任何4小时的空闲时间后都要回退到一级身份认证。
Android的锁屏目前是在内核上一层的Android系统组件实现的,尤其是Keyguard和相应的解锁方法(其中某些方法可能是OEM特有的)。安全锁屏的用户只是因素会传递到GateKeeper/Weaver,以使其和存储的模板匹配,并派生用于存储加密的秘钥。一个隐式逻辑是:内核被破坏了会导致锁屏被绕过,但这必须在用户第一次启动且输入密码之后。
4.3 隔离和限制
执行安全模型最重要的一部分是在运行时针对已经在设备上运行的潜在的恶意代码做安全增强。linux内核提供了很多Android安全模型依赖的基础能力和数据结构,进程隔离为沙箱提供了基本的安全性原语,除了少数的例外,进程的边界通常是指定和实施安全决策的地方,Android特意没有依赖于进程内的隔离,如Java的安全模型。进程的安全边界由进程边界和进程入口组成,并且执行开放生态系统访问规则,即无需对应用程序进行审查或预处理即可在沙箱中运行。此边界可以通过多种方法来加强,如:
* 访问控制: 增加权限检查,增加权限检查的粒度或切换到更安全的默认设置(如默认拒绝)
* 减少攻击面: 减少可访问的入口点,如使用最小权限原则
* 限制与隔离: 隔离和取消特权组件,尤其是处理不授信内容的组件(如media)
* 结构化分解:将特权进程切分为权限级别更低的组件,并且减少攻击面(这个实际上华为的去root就是这个原理,并没有什么可炒作的)
* 关系分离: 避免功能的重复
本节我们将介绍Android在不同层面上的各种沙箱和访问控制机制的使用,以及这些机制是如何改进整体的安全态势的。
4.3.1 权限
Android使用三种不同的权限机制来执行访问控制:
* DAC(Discretionary Access Control,自主访问控制): 进程可以通过修改对象的权限(如授予全局读取访问权限)或通过IPC将句柄传递给对象,来授予或拒绝对其拥有的资源的访问。在Android中DAC是通过UNIX风格的权限来实现的,该权限由内核和URI权限授予机制实现。以root身份运行的程序通常拥有广泛的权限来覆盖UNIX权限(取决于是否受到下面的MAC权限的限制)。URI权限授予提供了App到app之间交互的核心机制,允许应用选择性的被授予部分数据的访问权限。
* MAC(Mandatory Access Control,强制访问控制): 系统有一个安全策略来规定什么行为是 被允许的,只有被策略显式授予的操作是被允许的。在Android中使用的是SElinux[87],主要由内核来强制执行。Android在兼容性测试期间期间广泛使用SELinux来保护系统组件和声明安全模型需求。
* Android权限: 控制对敏感数据和服务的访问,此权限控制主要是在用户态通过数据/服务 privider完成的(值得注意的例外如INTERNET,是内核实现的)。权限是在app的AndroidManifest.xml [12]中静态定义的,尽管并非所有定义的权限都会被授予。Android 6.0带来了重大的变化,即不再保证在应用在安装的时候会授予所有申请的权限,这是因为意识到用户实际上并没有足够的能力在安装时决定是否应该授予权限[47,48,82,101])。
总体而言,Android权限按严重性从低到高分为五类:
1) 仅审计权限: 这些是具有"正常"保护级别的安装时权限
2) 运行时权限: 这些是在运行时必须要弹框让用户同意的权限,这些权限可以用来保护常用的敏感 用户数据,并且建议根据这个权限对应用当前功能的重要性,使用不同的请求策略[24]。
3) 特殊访问权限: 对于比运行时权限还要暴露更多风险的权限,存在一类特殊的权限,其授予的阻碍要高得多,因为应用程序运行时无法显示提示。为了使用户允许应用程序使用特殊的访问权限,用户必须进入设置并手动将权限授予该应用程序。
4) 特权权限: 这些权限是预安装特权应用的,且允许特权操作如运营商计费。
5) 签名权限: 这些权限仅适用于使用与声明该权限的组件相同的密钥签名的组件,例如:平台签名密钥,它们旨在保护内部或高度特权的操作,例如配置网络接口。
权限限可用性由它们的protectionLevel属性[13]定义,该属性分为两部分(级别本身和一些可选标志),它们可以扩展可以向哪些应用程序授予许可以及如何请求许可。
保护级别分为:
* Normal: Normal权限是那些不会带来太多隐私或安全风险并在安装时自动授予的权限,这些权限主要用于审核应用程序行为。
* dangerous: 具有此保护级别的权限是运行时权限,应用程序必须在清单中声明,并且在执行时也要用户显示的授予。为了支持审计和强制执行,这些权限的粒度设置的很细,这些权限通过使用PermissionGroup属性分组为逻辑权限。当请求运行时权限时,该组将显示为单个权限,以避免过度提示。
* signature: 必须是与定义权限的应用具有相同秘钥签名的应用才能授予此权限,对于平台的signature权限来说,只有平台秘钥签名的应用才能使用。如果允许使用,则这些权限会在安装时被授予。此外,还有许多保护标志可修改权限是否可授予,如BLUETOOTH_PRIVILEGED权限具有signature|privileged级别的保护,其中的privileged标志允许向特权应用程序授予此权限。
三种许可机制中的每一种都大致与三方之一授予同意的方式保持一致(三方批准),平台利用MAC,应用程序利用DAC,用户批准则是通过授予Android权限(需注意这里的批准指的不是法律意义上的批准,而是技术上的一种加强可审计性和控制力的措施,应由应用开发者来决定如何处理个人用户数据以满足法律上的要求)。
4.3.2 应用沙箱
Android的原始DAC应用沙箱通过为每个app提供一个唯一的UID和目录,将应用程序彼此分离并与系统分离。这种方法与传统的桌面系统使用物理用户UID运行程序的方法完全不同。这种给每个进程一个UID的独特方法简化了权限检查,并消除了灵活多变的PID检查。app被授予的权限存储在一个集中的位置(/data/system/packages.xml),以供其他服务查询。如当应用程序从位置服务请求位置时,位置服务向权限服务发起查询请求,以查看发起请求的UID是否已被授予位置权限。
UID沙箱有很多缺点,如root身份运行的进程基本上是不受沙箱限制的,并且具有操纵系统,app和app私有数据的权限。类似的,以system UID运行的进程会免于Android的权限检查,并允许执行 很多特权操作。使用DAC意味着app和系统进程可以覆盖安全默认值,并且更容易受到危险行为的影响,如符号链接可以通过IPC或fork/exec跟随或泄露文件/数据。此外DAC只能用于支持ACL(Access Controls Lists,访问控制链表)的文件系统上的文件,主要的影响是FAT系列文件系统(还广泛用于扩展存储,如[micro-]SD卡或通过USB连接的媒体)不能直接支持DAC。在Android上,每个app都在外存上有一个众所周知的目录,其路径包括应用的包名(如/sdcard/Android/data/com.example)。由于操作系统已经维护了一个从包名到UID的映射,因此其可以将UID所有权分给这些外存目录中的文件,从而在一个不支持DAC的文件系统中创建一个DAC控制。从Android 4.4 - Android 7.x,此 UID->包名的映射都是通过FUSE文件系统实现的,在Android 8.0和之后则是通过一个内核中的 sdcardfs实现的(以获得更好的性能),二者实际上都是在维护UID的映射关系以模拟DAC的实现。
尽管其存在缺陷,但UID沙箱奠定了一个基础,并且其也是隔离app的主要执行机制。事实证明应用沙箱是增加额外沙箱限制的坚实基础,其缺点在后续的版本中通过多种方式得以缓解,部分是通过添加MAC策略,但也包含其他的一些机制,如运行时权限和攻击面减少(见表1)。
根据前面的定义,rooting的意义在于可以让某些app及其进程可以以root身份打破应用沙箱的限制[57],以覆盖现有的DAC规则(但不是MAC规则,MAC的打破需要扩展root方案来消除MAC限制)。恶意程序可能会通过临时或永久的利用来应用这些rooting方法,从而绕过应用沙箱。
=4.3 |
进程隔离: App可以选择在一个只有两个binder权限,没有其他任何的android权限的进程空间中运行,如Chrome的渲染进程。 |
主要是恶意代码执行 |
5.x |
selinux: Selinux为所有用户空间程序启用,显著提高了app和系统进程之间的 隔离,应用之间的隔离主要还是通过UID沙箱实现的。selinux的一个主要优点是策略的可审计性/可测试性,随着selinux的引入,兼容性测试测试测试安全性需求的能力显著提高。 |
OS漏洞利用[T8] 不信任数据输入[T14] |
5.x |
webview移动到一个可更新的apk中,使其从完整的系统ota中独立出来 |
JS恶意代码[T10] |
6.x |
引入了运行时权限,将危险权限请求从安装移动到首次使用 |
恶意使用系统API[T7] |
6.x |
多用户支持: 为每个物理用户的app沙箱引入selinux 类别 |
已解锁的设备被非本人使用[T3] |
6.x |
为私有App数据设置更安全的默认值: 主目录由0751->0700 (基于targetsdkversion) |
滥用其他引用的API接口[T9] |
6.x |
selinux限制ioctl系统调用: 59% app可达的内核漏洞都是通过ioctl 访问的,此限制限制了用户空间->内核漏洞的可达性(减少攻击面,导致攻击攻击向量减少了) |
利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
6.x |
删除app对debugfs的访问权限(占所有应用程序可访问内核漏洞的9%) |
利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
7.x |
hidepid=2: 移除 /proc/<pid>侧信道,此侧信道可以推断出应用是 何时启动的 |
模仿系统/应用欺骗用户[T11] |
7.x |
perf-event-hardening(11%应用可访问的内核漏洞都是通过 perf_event_open实现的) |
利用OS漏洞[T8] |
7.x |
/proc/文件系统访问均有更安全的默认值 |
恶意使用系统API[T7] 模仿系统/应用欺骗用户[T11] |
7.x |
默认情况下不信任中间人CA证书(MITM CA) |
中间人攻击[T6] |
8.x |
/sys 文件系统默认更安全的访问 |
恶意使用系统API[T7] 模仿系统/应用欺骗用户[T11] |
8.x |
所有应用程序都使用seccomp过滤以减少内核攻击面 |
利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
8.x |
所有进程使用的webview都进入隔离进程 |
JS恶意代码[T10] |
8.x |
app必须手动选择进入明文网络流量 |
被动窃听、流量分析[T5] |
9.0 |
per-app Selinux沙箱,所有非特权应用必须在不同的SElinux沙箱中运行, 此种保护可以提升隔离的效果(targetSdkVersion >= 28) |
滥用其他引用的API接口[T9] 模仿系统/应用欺骗用户[T11] |
4.3.3 沙箱化系统进程
除了应用沙箱之外,Android还为系统进程推出了一组有限的UID沙箱。值得注意的是Android的架构师认识到处理不授信媒体内容的固有风险,因此将媒体框架隔离到UID AID_MEDIA中,其他被 确保通过UID隔离的进程包括电话栈,WiFi和蓝牙(参见表2)。
4.4 | SELinux: 只有四个root进程开启了SELinux强制模式,分别为 installd,netd,vold,zygote | 恶意使用系统API[T7] 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
5.x | SELinux: 所有用户app开启SELinux | 恶意使用系统API[T7] 利用OS漏洞[T8] |
6.x | SELinux: 所有进程开启SELinux | 恶意使用系统API[T7] 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
7.x | mediaserver结构分解 | |
7.x | 系统组件的ioctl限制[96]
| 恶意使用系统API[T7] 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
8.x | Treble结构分解:将HAL移动到单独的进程中、减少权限、限制对硬件驱动的访问[33, 97] | 恶意使用系统API[T7] 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
4.3.4 沙箱化内核
Android用户空间的安全加固逐渐将内核变为一个更具吸引力的提权攻击目标[95], SoC(System On Chip)供应商提供的硬件驱动的漏洞占Android内核漏洞的绝大部分[98],上面已经描述了如何 减少app/系统对驱动的访问,但对内核沙箱化的代码在各个版本中也得到了显著的增强(参见图3)。
5.x | Privileged eXecute Never(PXN)[3]:禁止内核执行用户态代码 防止ret2usr类型的攻击 | 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
6.x | 内核线程进入SELinux强制模式,从而限制内核对用户空间文件的访问。 | 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
8.x | Privileged Access Never (PAN)和模拟PAN(Domain PAN): 阻止内核直接访问用户空间,其访问必须通过copy-*-user()系列 接口[94] | 利用OS漏洞[T8] 利用操作系统处理不信任数据[T14] |
4.4 静止数据加密(Encryption of data at rest) 4.3.5 内核下层的沙箱化
除了内核外,Android设备上的可信计算基础(Trusted Computing Base,TCB)是从bootloader开始的,并且隐式的包含内核下层的几个组件,如可信计算环境(TEE),硬件驱动,用户空间初始化组件 init,ueventd,vold[25]。显然TCB所依赖的这些所有因素造成了足够的复杂性,在当前的技术水平下,我们必须假设其中一部分是存在bug的。对于一些高敏感使用场景,即使使用了上述内核和系统进程bug的缓解机制,可能也无法提供足够的针对潜在漏洞的安全保证。因此我们明确考虑到内核被破坏的情况(如通过物理访问直接攻击内核接口,如串口[T2]-[T4],或通过串联用户态多个漏洞来达到内核攻击面[T8]), 配置错误(如使用错误或过于宽松的 SELinux策略[34]),或安全绕过(如修改启动信任链,运行了未启用安全策略的内核)作为某些特定方案的威胁模型的一部分。要明确的是,如果内核受损,则Android就不再满足兼容性要求了,并且很多对用户和app安全和隐私的保证也就不再满足了,但是即使在这种假设下,Android还是可以抵御某些威胁的:
* Keymaster在TEE中实现了Android的秘钥存储功能,在内核被破坏的情况下[14],也可以保护TEE存储的秘钥或经过TEE加密的部分秘钥的明文。即使在内核完全受损的情况下,攻击者也无法读取到Keymaster中的秘钥信息。App可以明确要求将秘钥存储到Keymaster中(即与硬件绑定),只有在验证了用户身份后才可以访问(用户身份通过Gatekeeper/Weaver验证),或者请求证明证书以验证这些密钥属性[15],允许规则3(安全是一个兼容性要求)中的兼容性校验。
* Strongbox是在Android 9.0出现的,为了更好的隔离,将Android秘钥存储功能放在单独的防篡改硬件(TRH, Tamper Resistant Hardware)中,这可以缓解强 大对手的[T1],[T2]威胁,如防止冷启动内存攻击[53],硬件bug如Spectre/Meltdown[61,69], Rowhammer[32,99],及Clkscrw[92],这些漏洞都有可能从内核影响到TEE。从硬件的角度来看,主处理器(AP, Application Processor) 总是比一个专用处理器拥有更大的攻击面,单独添加一个TRH相当于在纵深防御上增加了另一层沙箱。需要注意的是,仅在TEE/TRH中存储和使用秘钥并不能完全解决内核被破坏则秘钥应该不可用的问题,如果攻击者获取了直接和keymaster/strongbox交互的接口,其可以用此接口作为原语(oracle),执行本来需要秘钥才能执行的操作。这也是为什么这些秘钥可以和用户存在检测绑定的原因。
* Gatekeeper: 是在TEE中实现的用户锁屏验证模块(还包括PIN/password/图形),并在验证成功 后将数据传递给keymaster,以允许对身份绑定的秘钥的访问[16]。Weaver是在Strongbox中实现的Gatekeeper功能。特别的,我们还在Google Pixel 2/3(Android 9.0)上添加了一个 Insider Attack Resistance(IAR)属性,在没有获得用户锁屏信息的情况下,更新Weaver/Strongbox 的代码会导致其中存储的设备根秘钥的擦除[74,102],也就是说,即使有了可以更新Weaver/Strongbox的签名秘钥,在没有用户配合的情况下也没法泄露出用户信息。
* Protected Confirmation: 也是在Android 9.0中引入的[17],其部分缓解了威胁[T11](模仿其他 程序界面欺骗用户)和[T13](将输入时间注入到系统或其他用户界面),其当前覆盖的范围内,app可以将存储在keymaster/Strongbox中的秘钥使用和用户确认绑定起来(通过按下物理按键),他们会看到屏幕上显示的信息。在用户确认之后,app会收到显示的信息的hash,这个hash可以用来远程校验用户是否确认了此消息。当app请求确认时,可以通过TEE控制屏幕的输出,即使内核被完全破坏了,在没有用户配合的情况下也无法伪造用户的确认。
当主系统内核未运行或被bypass后,则需要第二个加强安全模型的元素了(第一个是4.3中的隔离),尤其是针对rule1(三方批准)和rule3(安全是一个兼容性要求)。
全盘加密(FDE,Full Disk Encryption)使用一个凭证保护的key来加密整个用户数据分区。FDE在 Android5.0即被引入了,尽管对[T1](已关机的设备)有效,但其有很多缺点。在输入密码前,设备的核心功能是无法访问的(如紧急拨号,辅助服务和闹钟), Android 6.0引入的多用户支持在磁盘访问前仍然需要等待用户主密码。
这些缺点在Android 7.0 引入文件加密(FBE, File Based Encryption)后就得以缓解了。在具有 TEE/TRH的设备上,所有的秘钥都是从可信环境中派生的,导致用户知识因素和硬件绑定的随机数在Android 内核和组件无法访问(密钥纠缠的详细说明和分析尚需进行相关工作,目前仍在进行中。 对此细节的引用将添加到本文的更高版本中)。FBE允许将不同的文件与不同的用户绑定,在共享设备上可以单独保护每个用户的数据[T3](已解锁设备在已授权但非本人使用者手上)。支持FBE的设备同时还支持一个称谓Direct Boot的特性,此特性可以允许用户输入凭据之前访问紧急拨号,辅助服务,闹钟和接电话。静止数据加密对于rule3(安全是一个兼容性要求)的执行很有帮助,因为删除用户数据只需要删除用户主秘钥即可,并不受限于flash传输层交互的复杂性。
4.5 传输中的数据加密
Android假设所有的网络都是敌对的,可能会引起注入攻击或流量监听。为了确保网络级别的对手不会bypass app数据保护, Android的立场是所有的网络流量都进行段对端的加密,链路层的加密是不够的。这主要可以防止[T5](被动窃听和流量分析)和[T6](主动操纵网络流量)攻击。除了确保使用加密通信外,Android还着重于确保加密是否使用正确,尽管默认情况下的TLS选项是安全的,但我们发现开发人员还是很容易以错误的方式自定义TLS,从而是其受到中间人(MITM)攻击[43,44,52],表4列出了在默认情况下使网络连接变得更安全的最新改进。
6.x | manifest中的usesCleartextTraffic用来防止意外的明文连接[31]
| 被动窃听和流量分析[T5] 主动操纵网络流量[T6] |
7.x | 网络安全配置[18],用于在per-domain或app范围内声明特殊的TLS和 明文设置以自定义TLS连接。 | 被动窃听和流量分析[T5] 主动操纵网络流量[T6] |
9.0 | DNS-over-TLS[60]可减少通过明文发送的敏感数据,app要特意在网络 配置中选择使用明文才会使用明文。 | 被动窃听和流量分析[T5] 主动操纵网络流量[T6] |
4.6 利用缓解
健壮的安全系统应假定存在软件漏洞并积极防御这些漏洞。从历史上看,Android中大概有85%的安全漏洞是由不安全的内存访问导致的(参考[62, slide 54])。
注:Android在2016年在此文中提出的安全原则包括:
1) 利用缓解(Exploit Mitigation)
2) 利用遏制(Exploit Containment)
3) 最小权限(Principle of Least Privilege)
4) 结构分解(Architectural Decomposition)
5) 攻击面缩减(Attack Surface Reduction)
6) 设计安全的APIs(Safe by design APIs)
7) 纵深防御(Defense-in-depth)
尽管本节主要介绍针对内存安全问题的缓解措施,但我们需要注意的是最好的内存安全防御方法就是类似Java的内存安全语言。Android的框架大部分都是用Java写的,可以有效防御系统中大部分的安全漏洞。 Android强制使用多种缓解措施包括ALSR[29,86], W^X内存[85]和缓冲区溢出保护(如栈溢出,堆 溢出保护),Android的内核页同样使用了类似的保护机制[94]。
除了上面的缓解措施外,Android还在积极推出其他缓解措施,首先关注的就是远程可访问的代码区域(如media framework[26])或者历史上有高严重性漏洞记录的区域(如内核)。Android率先在生产设备中使用LLVM的未定义行为清理器(Undefined Behavior Sanitizer, UBSAN),以保护 media framework中的整数溢出漏洞和其他安全敏感的组件。Android还在内核和安全敏感的用户态 组件如media、Blutooth、wifi,NFC,解析器(parsers),中推出了LLVM的CFI[71]。
这些缓解方法与遏制方法协同工作,形成了多层的防御,即使一个层面失效了,其他机制也旨在阻止漏洞利用链的成功。缓解机制还有助于维持rule2(开放生态系统访问)和rule3(安全是一个兼容性要求),而不需对app的编程语言做任何假设。
4.7 系统完整性
最后系统完整性是防御攻击者获得持久立足点的重要防御措施。 自从Android KitKat以来, AOSP就一直使用Linux内核的dm-verity支持启动验证,此特性可为Android 的TCB(Trusted Computing Base, 可信计算基础)和系统组件提供强大的完整性保护以实现rule4(恢复出厂设置要 可以将设备恢复到一个安全的状态)。
启动验证[19]从Android Nougat以来就必须强制执行了(只有对AES效率不能达到50MiB/sec的 设备才能豁免),这使得boot chain上做出的修改在验证boot、TEE、或其他vender/OEM分区的时候可 以被检测到,同时也会对system分区进行检测[20]。也就是说攻击者绕过了之前的所有防御,可以直接修改内核后,也无法对TCB做永久性修改。注意,启动验证的前提是可信跟(root of trust)是完整 的,由于这一段的代码通常是在ROM中实现的简单的代码,出现严重错误的可能性较小。
此外具有硬件支持的回滚保护可防止攻击者刷入一个之前签名的旧版本的镜像(可能存在漏洞利用的镜像)。最后启动验证的状态包含在关键证书中的deviceLocked和vertifedBootState段(由Keymaster/Strongbox提供),app可以在后台验证此证书的有效,也可以将其传到后端并校验完整性。
应用程序完整性是通过APK签名校验的[22],每个应用都是被签名的,在应用更新时只有拥有相同的签名或者原始签名者委派身份的人签名时,此App才可以被更新。
在Android 9.0中,只有可更新的app没有被启动验证保护,可更新app的完整性是通过Android 的PackageManager在安装/更新时检测的。在本文中,其他CPU(包括但不限于无线芯片,GPU,触屏控制器等)的固件完整性不再Android启动验证的范围内,并且经常是由OEM的boot loader处理的。
4.8 patching
patching与其他的防御机制是正交的,在任何层发现的漏洞都需要被修复,定期漏洞修补可以被视为另一层的防御。但将更新的代码传送到多样化的Android生态环境中是一个挑战(这也是为何要使用纵深防御的原因之一)。
从2015.08月开始,Android公开发布了每月向Google汇报的安全公告和补丁程序,为了解决生态多样性问题,Android 8.0上发布了Treble项目,其目的是为了减少更新Android设备的时间/成本 [72,76]。
自2018年,Android企业推荐几乎和OEM通用协议增加了一个90天保证安全更新的要求[23]。
5. 特殊情况
存在一些特殊的case需要故意偏离抽象的安全模型以平衡不同参与方的特殊需求,本章描述其中的部分,但并不打算形成完成的列表。公开定义Android安全模型的其中一个目的就是能让研究人员通过对比AOSP的实现和我们描述的模型,发现更多潜在的差距,并就这些特殊情况进行讨论。
* 列举packages: 这个是从rule2(开放生态系统访问)派生出的,App之间相互访问受限需要app能相互发现。
* VPN应用可以监控/阻塞其他app的网络流量: 这通常是与应用沙箱隔离模型存在偏差的,因为一个app可能看到或影响另一个app的流量。由于VPN程序对用户的价值(如提高隐私和数据使用控制),以及需要明确的用户同意,所以VPN被授予赦豁免。
* 备份: 私有app的数据默认是可以备份的,应用可以在manifest中主动设置哪些数据不要备份。
* 企业: Android允许DPC(Device Policy Controller,设备策略控制)app强制执行所谓的Device Owner(DO)或Profile Owner(PO)策略。DO需要在用户的主账户中安装,PO则是在扮演工作资料的要用户上安装。工作资料(Work profiles)可以基于Andorid的多用户,在设备上将个人数据与 企业数据分开,这种隔离和app之间的隔离的原理是相同的,但对资料使用了一个更加严格的分离[8]。DPC向批准模型中引入了第四方:只有策略允许某行为(如PO控制的工作资料中),且其他三方也同意的情况下,行为才会执行。最近的版本增加了对不同用户知识因素的支持(由锁屏处理),增强了个人和工作资料的区别,这会导致FBE中使用不同的加密秘钥分别加密。需注意的是在具有PO工作资料管理,但没有DO全设备控制的情况下,个人资料的意思保护还是要在安全模型中保留的。
* 恢复出厂设置保护(Factory Reset Protection, FRP): 恢复出厂设置不存储任何之前的数据是rule4(恢复出厂设置要 可以将设备恢复到一个安全的 状态)的一个例外,故意偏离此部分是为了缓解被偷窃后的恢复出厂设置攻击[T1](已关机的设备被完全控制),[T2](已锁屏的设备被完全控制)。
6. 相关工作
传统的操作系统安全模型主要关注的是定义主体(user/groups/roles)对客体(file/其他os资源/结合权限,有时称为domain[91])的访问控制(read/write/execute或更细粒度的)。有效实现这些关系(理论上是稀疏矩阵)最常见的数据结构是ACL(访问控制列表,Access Control Lists[83])和capability列表 [100]。第一个众所周知且定义明确的模型是Bell-LaPadula提出的多级安全模型[27],该模型定义了 权限分配相关的属性,且可以当做诸如MAC/TEAC(Type Enforcement)策略实现(如SELinux)的抽象基 础。因此,Android平台的安全模型隐式的基于这些通用模型以及其最小权限原则。
一个根本的区别在于,在传统模型假设进程是用户启动的,进程是用户行为的代理人,因此应该拥有该用户拥有的所有权限,但更多现代的模型明确承认,用户启动了恶意软件是威胁中的一部分,因此现代的模型则会区分用户的行为。许多操作系统(包括之前例子中的塞班系统),都在以进程为单位区分权限,而不是用户,Android也是使用了一个类似的方法。和其他操作系统更详尽的对比不再本文的讨论范围之内,我们将参考其他的调研结果[41,64,77],以及之前对Android安全机制的分析,以及恶意软件对漏洞的利用[4,42,46,66-68,103].
7. 结论
在本文中,我们描述了Android平台安全模型以及运行它所需要的复杂威胁模型和生态系统。
其中的一个抽象规则即多方批准,这个规则和大多数OS安全模型的规则都不相同,因为其隐含的认为应用程序拥有和平台以及用户一样的否决权。从用户的角度看,这似乎是有一些限制,但这有效的限制了恶意应用可能对其他应用控制的数据的滥用的可能性。通过避免一个强大的用户账户可以无过滤的访问所有数据(就像大多数台式机和服务器那样),使得诸如文件加密勒索软件或直接数据泄露的威胁变得不切实际(主要是Android的应用沙箱完成的)。
AOSP实现了Android平台的安全模型以及通用的安全原则,即"纵深防御"和"默认安全(Safe by Default)"。不同的安全机制联合在一起形成了多层防御,更重要的是,即使存在安全相关的bug,也未必是用户代码可达的,最终也未必会导致漏洞利用。虽然当前模型和其实现已经覆盖了Android安全和隐私考虑范围内的大多数威胁模型,但在概念上简单的安全模型中还是存在一些特意的例外,未来还有工作的空间。
* 密钥库已经支持API flags/methods以请求验证绑定的或硬件的秘钥,但app需要明确的要求 使用这些方法才可从改进的如Strongbox中收益。通过支持类似TLS连接的网络安全配置的声明性使用可使app文件/目录的加密更加透明,从而使应用程序开发者更容易使用这些功能。
* 恶意软件通常会根据设备来动态加载其第二阶段的代码,以尝试利用检测到的漏洞,以及避免app store的检测。一种可行的缓解措施是要求所有的二进制代码:
a) 由相应的Android实例信任的密钥签名(如使用固件中预置秘钥签名,或由终端用户添加)
b) apk自身应不具有运行时动态加载/创建代码的特殊权限。
这样可以更好的控制代码的完整性,但还是不会对使用的语言或创建app的平台有所限制。这些措施仅限于可执行代码,解释性代码或基于服务的配置是可以绕过这些特性的(这两种应该通过逻辑或MAC限制)
* 高级攻击者可能获取到OEM或vender(供应商)的签名秘钥,即使在这种情况下,能仍然为用户保留一些安全和隐私保证是有益的。最近的一个例子是针对TRH[102]中可更新代码的IAR(Insider Attack Resistance,内部攻击抵抗)的实现,并且希望将类似的防御措施扩展到更高级 别的软件中[74]。潜在的可用方法包括可复制固件生成,记录发布固件的hash,其他还有如证书透明度[65]。
* W^X内存已经是当前大多数操作系统(包括Android)中的标准保护机制了,然而通常RX是一起的,并且这种读取访问可能导致ROP gadgets的地址泄露,潜在的改进设置XOM内存页。
* 硬件级的攻击正在变得越来越普遍,因此针对如RAM相关的攻击需要增加额外的一层软件或硬件的防御机制,尽管更多的是在性能开销之间的一个权衡。
但所有的这些未来的工作都必须考虑到其对更广泛的生态系统的影响,并且要与Android的安全原则保持一致。
致谢
我们要感谢Dianne Hackborn在Android平台安全历史的很大一部分上所做的有影响力的工 作,以及对本文早期草案的深刻见解。另外,我们还要感谢Joel Galenson,Ivan Lozano,Paul Crowley,Shawn Willden,Jeff Sharkey和Xiaowen Xin在各个部分的投入,尤其是Vishwath Mohan对Authentication部分的直接贡献。我们还要感谢众多安全研究人员(https://source.android.com/security/overview/notifications),这些年来他们对Android进行了改进,并感谢匿名审阅者为本文的早期草案提供了非常有帮助的反馈。
参考资料:
[1]. https://www.perficientdigital.com/insights/our-research/mobile-vs-desktop-usage-study //2019年移动设备和PC的使用情况统计
[2] https://gs.statcounter.com/platform-market-share/desktop-mobile-tablet //2018-2018移动设备,pc,tablet的使用情况统计
[3]. Exploit Methods/Userspace execution
[4]. SoK: Lessons Learned from Android Security Research for Appified Software Platforms, 2016
[5]. https://dl.acm.org/citation.cfm?doid=322796.322806 //用户并非你的敌人,ACM,1999
[6]. https://android-developers.googleblog.com/2018/01/how-we-fought-bad-apps-and-malicious.html //将Google如何区分恶意软件的
[7]. From Warning to Wallpaper: Why the Brain Habituates to Security Warnings and What Can Be Done About It
[8]. Android Enterprise Security White Paper
[9]. Android Security 2017 Year In Review. Mar. 2018.
[10]. https://source.android.com/compatibility/android-cdd.pdf //Android CDD
[11]. https://developer.android.com/guide/components/intents-filters //intent-filters
[12]. https://developer.android.com/guide/topics/manifest/manifest-intro
[13]. https://developer.android.com/guide/topics/manifest/permission-element //Andorid权限
[14]. https://source.android.com/security/keystore/
[15]. Android KeyGenParameterSpec
[16]. Gatekeeper
[17]. Android 受保护的确认(Android Protected Confirmation)
[18]. Android 网络安全配置
[19]. verified boot
[20]. Android Verified Boot 2.0
[22]. 应用签名
[23]. Android Enterprise Recommended 的规格要求
[24]. Android platform permissions requesting guidance //Android平台权限一览
[25]. https://source.android.com/security/overview/updates-resources#process_types
[26]. Hardening the media stack
[27]. Secure Computer System Unified Exposition and Multics Interpretation
[28]. https://android-developers.googleblog.com/2018/06/google-play-security-metadata-and.html //Google Play安全元数据和线下App发布
[29]. Address Obfuscation: An Efficient Approach to Combat a Board Range of Memory Error Exploits
[30].https://go.armis.com/hubfs/BlueBorne%20-%20Android%20Exploit%20(20171130).pdf?t=1529364695784 //Android的蓝牙漏洞BlueBorne
[31]. Introducing nogotofail — a network traffic security testing tool
[32]. Attack TrustZone with Rowhammer
[33]. SELinux in Android O: Separating Policy to Allow for Independent Updates
[34]. Analysis of SEAndroid Policies: Combining MAC and DAC in Android
[36]. CVE-2017-13177 //libhevc RCE
[37]. CVE-2017-17558: Remote code execution in media frameworks.
[38]. CVE-2018-9341: Remote code execution in media frameworks.
[39]. http://dx.doi.org/10.1145/1124772.1124861 // Why Phishing Works
[40]. https://ieeexplore.ieee.org/document/1056650 //公钥协议安全
[41]. Hackers in Your Pocket: A Survey of Smartphone Security Across Platforms, 2012
[42]. Understanding Android Security, 2009
[43]. Why Eve and Mallory Love Android: An Analysis of Android SSL (in)Security
[44]. Rethinking SSL Development in an Appified World
[45]. https://dl.acm.org/citation.cfm?doid=1814433.1814453 //Diversity in Smartphone Usage
[46]. Android Security: A Survey of Issues, Malware Penetration, and Defenses, 2015
[47]. How to Ask for Permission
[48]. Android Permissions: User Attention, Comprehension, and Behavior
[50].https://android-developers.googleblog.com/2018/04/protecting-webview-with-safe-browsing.html //通过安全浏览器保护webview
[51]. Cloak and Dagger: From Two Permissions to Complete Control of the UI Feedback Loop
[52]. The most dangerous code in the world: validating SSL certificates in non-browser software
[53]. Lest We Remember: Cold-boot Attacks on Encryption Keys
[54]. Diversity in Locked and Unlocked Mobile Device Usage //锁屏和解锁设备的多样性
[56]. A Large-Scale, Long-Term Analysis of Mobile Device Usage Characteristics //手机使用特点
[58]. https://dl.acm.org/citation.cfm?doid=2660267.2660295 // A11Y Attacks: Exploiting Accessibility in Operating Systems
[59]. Cutting the Gordian Knot: A Look Under the Hood of Ransomware Attacks
[60]. DNS over TLS support in Android P Developer Preview
[61]. Spectre Attacks: Exploiting Speculative Execution
[62]. The Art of Defense: How vulnerabilities help shape security features and mitigations in Android
[63]. On Malware Leveraging the Android Accessibility Framework
[64]. A Survey on Security for Mobile Devices, 2013
[65]. Certificate Transparency
[66]. I know what leaked in your pocket: uncovering privacy leaks on Android Apps with Static Taint Analysis, 2014
[67]. Static analysis of Android apps: A systematic literature review
[68]. ANDRUBIS – 1,000,000 Apps Later: A View on Current Android Malware Behaviors
[69]. Meltdown
[70]. OAuth 2.0 Threat Model and Security Considerations
[71]. Compiler-based security mitigations in Android P
[72]. Here comes Treble: A modular base for Android
[73]. https://onlinelibrary.wiley.com/doi/full/10.1002/sec.1028 //安全的移动操作系统体系结构
[74]. Insider Attack Resistance in the Android Ecosystem, USENIX, 2019
[74]. Insider Attack Resistance in the Android Ecosystem,2019, USENIX
[75]. Adversary Models for Mobile Device Authentication
[76]. An Empirical Study of API Stability and Adoption in the Android Ecosystem
[77]. Android vs iOS Security: A Comparative Study, 2015
[78]. Better Biometrics in Android //Android生物特征相关
[79]. https://android-developers.googleblog.com/2018/12/android-pie-la-mode-security-privacy.html //Android 9.0 安全和隐私
[81]. http://dx.doi.org/10.1007/s00779-015-0840-5 // Only play in your comfort zone: interaction methods for improving security awareness on mobile devices
[82]. User-driven access control: Rethinking permission granting in modern operating systems
[83]. Access control: principle and practice
[84]. CryptoLock (and Drop It): Stopping Ransomware Attacks on User Data
[85]. SecVisor: A Tiny Hypervisor to Provide Lifetime Kernel Code Integrity for Commodity OSes
[86]. On the Effectiveness of Address-space Randomization
[87]. Security Enhanced (SE) Android: Bringing Flexible MAC to Android
[88]. https://www.kb.cert.org/vuls/id/924951 // Stagefright Vulnerability Report. 2015.
[89]. SVE-2018-11599: Theft of arbitrary files leading to emails and email accounts takeover.
[90]. SVE-2018-11633: Buffer Overflow in Trustlet //三星TA栈溢出
[91]. Modern Operating Systems. 4th. Prentice Hall Press, 2014. isbn: 013359162X, 9780133591620
[91]. Modern Operating Systems
[92]. CLKSCREW: Exposing the Perils of Security-Oblivious Energy Management // ARM电源管理方面的漏洞,可以远程攻击窃取数据,好像还能加载模块,2017 USENIX Security Symposium的议题
[93]. https://android-developers.googleblog.com/2018/05/keeping-2-billion-android-devices-safe.html //通过机器学习确保20亿Android设备的安全
[94]. Hardening the Kernel in Android Oreo
[94]. Hardening the Kernel in Android Oreo
[95]. Android: Protecting the Kernel. LSS 2016
[96]. ioctl command whitelisting in SELinux
[97].Android isolate HAL
[98]. Year in Review: Android Kernel Security. LSS 2018
[99]. Drammer: Deterministic Rowhammer Attacks on Mobile Platforms
[100]. New approaches to operatng system security extensibility
[101]. Android Permissions Remystified: A Field Study on Contextual Integrity
[102]. Insider Attack Resistance
[102]. Insider Attack Resistance 2018
[103]. Vetting Undesirable Behaviors in Android Apps with Permission Use Analysis
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创] AArch64中va_list/va_start/va_arg/...的实现 19744
- [原创] AArch64函数栈的分配,指令生成与GCC实现(上) 19432
- [原创] 内核模块的加载流程 55003
- [原创] linux中的信号处理与SROP 26106
- [原创] AARCH64平台的栈回溯 30142