目录:
1.移动平台中的主流签名作用
- 1.1自签名的完整性鉴别
- 1.2信任模式
- 1.3限制安装/运行
- 1.4权限的作用
- 1.5权限的安全性保护
- 1.6Android的签名作用
- 1.7Android APK之METAINF
2.Android中的权限
- 2.1Android的权限作用
- 2.2Android的权限类别
- 2.3Android的权限定义方式
- 2.4Android的运行时权限控制方式
- 2.5Android的Permission与UID/GID的mapping
3.Android中的组件的安全机制
- 3.1组件的权限分配(Demo)
- 3.1.1 Activity
- 3.1.2 Service
- 3.1.3 ContentProvide
- 3.1.4 BroadcastReceiver
- 3.1组件的权限分配(Demo)
4.Android应用安装
- 4.1应用安装的安全性考虑和调用方式
- 4.2应用安装流程之UID/GID的分配
- 4.3应用安装流程之工作目录的创建和权限设置
5.Android中系统Service的安全
- 5.1Binder的安全
- 5.2ServiceManager Add Service的安全限制
- 5.3Zygote的Process Fork
- 5.4Zygote的Socket安全检查
6.Android中的ContentProvider以及基于URI的安全
- 6.1ContentProvider的作用
- 6.2权限临时继承的需求
- 6.3配置ContentProvider允许临时委派权限
- 6.4基于URI的权限临时委派
7.Android的Policy模式和多设备绑定
- 7.1Android的Policy模式
- 7.2MR2开始的AppOps(安卓4.3开始)
- 7.3AppOps对开发者的影响
- 7.4设备绑定
- 7.5跨设备使用
8.应用内计费和App2SDCard
- 8.1应用内计费
- 8.2SD卡安装应用的安全策略
9.Android中的多用户安全
- 9.1需求场景
- 9.2UserManagerService
- 9.3对开发者的影响
10.Android Superuser机制讲解
- 10.1ROOT的作用
- 10.2ROOT的第一步:寻找漏洞并安装特权文件
- 10.3SU的sUID的特性
- 10.4SU的核心代码分析
- 10.5MR2后的方案:SU Deamon Service
11.SEAndroid
- 11.1DAC和MAC
- 11.2基于Label的MAC
- 11.3推荐读物
1.移动平台中的主流签名作用
1.1 自签名的完整性鉴别
证书的签名者和证书拥有者是同一个实体---自签名
作为信任链的根证书.
完整性鉴别
1.2 信任模式
签名了?
签名是可信的?
可信任和普通应用的权利差异
人为的把一些操作归类
某类操作对于可信任应用和普通应用的表现不一样.
1.3 限制安装/运行
应用安装时
是否包含签名?-->没有?禁止安装
提取证书进行验证-->证书是有效且可信任的吗?-->不是?禁止安装
基于证书的公钥对签名进行验证-->签名正确吗?-->不正确?禁止安装
应用运行时
是否包含签名?-->没有?禁止运行
提取证书进行验证-->证书是有效且可信任的吗?-->不是?禁止运行
基于证书的公钥对签名进行验证-->签名正确吗?-->不正确?禁止运行
1.4 权限的作用
细粒度的特权管理
权限是一个ID或者一个字符串
权限用来细分权利(类似Capability)
通常一个权限与一类操作绑定
权限首先需要申请
但申请后是否被批准由平台策略决定
1.5 权限的安全性保护
通过签名
权限的完整性保护:防篡改
权限的授权安全策略:防Escalate
1.6 Android的签名作用
1.6.1.完整性鉴别
支持自签名用于完整性鉴别
不做信任模式
不做安装和运行时的限制
1.6.2.Signature Permision和ShareUID
Signature Protection Level Permision
用于特权Permission
只有特定签名的Apk才被授权
例如:
|
|
Share Process UID
|
|
Process间Share UID的目的是共享资源等 (如:/data/data/A包名/目录下面)
Android中两个APK Share相同的UID必须其签名所用的Private Key一样.
1.6.3.身份ID和升级的匹配
Android中的自签名只是代表了身份,但不代表身份是否可信任
Android的应用的标识符是Package Name
Package Name不一样,相互不影响,允许同时存在(安装)
Package Name一样,只能存在一个,允许做升级处理.
升级的安全性考虑
必须签名的证书一致(防假冒,防侵入隐私)
如果不一致,则用户要么放弃新的应用,要么先卸载旧的,再安装新的.但这属于安装,不属于升级
正常的升级将不擦除应用的工作目录数据,以保证历史数据的持续性.
1.7Android APK之METAINF
APK结构
META INF的组成
签名流程
|
|
这条命令的意思是:通过signapk.jar这个可执行jar包,以“testkey.x509.pem”这个公钥文件
和“testkey.pk8”这个私钥文件对“update.apk”进行签名,签名后的文件保存为“update_signed.apk”
详情可阅:[Android APK 签名比对](http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html)
MANIFEST.MF文件 (第一重保护,本文本里面包含apk的资源文件的每个文件的SHA1值)
CERT.SF文件 (第二重保护,本文本里面包含MANIFEST.MF里的所有内容,并包含有MANIFEST.MF的SHA1-Digest-Manifest)
CERT.RSA (第三重保护,此文件是一个PKCS#7格式的文件,
里面包含证书信息,以及基于私钥的签名信息,
签名信息是由整个CERT.SF文件的做一个基于sha1(160bit)+rsa(testkey.pk8,publicKey)生成)
2.Android中的权限
2.1 Android的权限作用
细粒度特权管理
权限与操作关联
应用需要显式申请权限
用户对权限可知(不可控) (也可通过LBE,腾讯管家,360等可进行权限控制)
对特权权限单独控制
2.2 Android的权限类别
Normal 没那么敏感
Dangerous 比较敏感的,安装时会被列举出来.
Signature 基于特殊权限的权限(申请权限的apk它的签名的私钥必须要跟定义这个权限的私钥一致)
SignatureOrSystem 申请权限的apk它的签名的私钥必须要跟定义这个权限的私钥一致或者apk是系统应用
2.3 Android的权限定义方式
|
|
源代码frameworks/base/core/res/AndroidManifest.xml
2.4 Android的运行时权限控制方式
通过PM的CheckPermission
Android独有的Service(底层平台不具有)
所以需要在Android本身Framework中控制
主流的Service一般都基于Binder IPC或者其他IPC提供服务
所以在最底层控制(Service所在的Server中)以避免逃逸控制
绕开应用函数直接调用远程服务
例子:(mContext.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED)
映射为OS的特定属性
非Android特有的Service(底层平台已经提供,如File访问,TCPIP数据收发等)
多个入口访问ndroidAPI,Java API NDK C API , Shell , et:Ac
底层控制准则,会聚口在底层,所以在底层(OS层面)统一控制,这样可以避免逃逸控制
所以复用OS的一些安全控制特性,比如GID
所以需要把Android空间的Permission Mapping到OS的GID
|
|
|
|
|
|
|
|
|
|
2.5 Android的Permission与UID/GID的mapping
语法:
UID assigning permission:
< assign-permission name="permission_name" uid="target_uid" />
GIDs Mapping:
<permission name="permission_nema" >
<group gid="assigned gid" />
<group gid="assigned gid" />
.....
</permission>
发生时刻:安装时
etc/permissions
任何符合以上语法的在system/etc/permissions下面的xml文件,都会被系统读取来parse并进行UID/GID的mapping.
比如Platform.xml(check代码)
frameworks/base/data/etc/platform.xml
安全性
任何应用都可以为自己的permission assign GID?
当然不行! 只有Root用户才允许新增或者改写.
并且对于ROOT用户组的用户也只有r权限
如下为手机system/etc/permissions目录下的文件权限
|
|
3.Android中的组件的安全机制
Android的4大组件及组件间的通信
组件的public和private
组件的权限分配
3.1 组件的权限分配(demo)
3.1.1.Activity
服务端增加相应的权限:
|
|
客户端必须申请许可:
否则会抛出:
java.lang.SecurityException: Permission Denial: starting Intent {
act=com.tu.test.diyPermission.NewPageActivity cmp=com.tu.test.
diyPermission/.NewPageActivity (has extras) } from ProcessRecord
{41efe3e8 8642:com.tu.test.diyPermission.client/u0a204} (pid=8642,
uid=10204) requires com.tu.test.diyPermission.DIYPERMISSION
|
|
3.1.2.service
服务端增加相应的权限:
|
|
客户端必须申请许可:
否则会抛出:
Caused by: java.lang.SecurityException:
Not allowed to bind to service Intent { act=com.tu.test.diyPermission.SERVICE_ACTION }
|
|
3.1.3.ContentProvide
服务端增加相应的权限:
读,写,访问权限.
|
|
客户端必须申请许可:
否则会抛出:
Caused by: java.lang.SecurityException: Permission Denial: opening provider
com.tu.test.diyPermission.provider.NewContentProvider from ProcessRecord{4236abd0
22086:com.tu.test.diyPermission.client/u0a204} (pid=22086, uid=10204) requires
com.tu.test.diyPermission.DIYPERMISSION_CONTENTPROVIDER_READ or com.tu.test.
diyPermission.DIYPERMISSION_CONTENTPROVIDER_WRITE
|
|
3.1.4.BroadcastReceiver
服务端增加权限:
|
|
客户端必须申请许可:
否则服务端周日接收不到信息
|
|
4.应用安装
4.1.应用安装的安全性考虑和调用方式
应用安装是一个高特权/风险操作,所以必须是可知/可控,主流实现方式:客户只能委派而不能直接操作.
调用安装传统模式: 发送Intent给系统的Package Install app
|
|
特权安装模式:系统的Package Install App内部会调用PackageManagerService的Install Package,
该操作与android.permission.INSTALL_PACKAGES 绑定,且该peimission的protection level是 signature|system
所谓的静默安装方式只存在Root手机上,开发者可以选择:
基于pm cmd : pm install -r
4.2.应用安装流程之UID/GID的分配
基于Android4.3原代码目录
frameworks/base/services/java/com/android/srver/pm/PackageManagerService.java
|
|
fameworks/base/services/java/com/android/server/pm/Settings.java
|
|
4.3.应用安装流程之工作目录的创建和权限设置
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
|
|
frameworks/base/services/java/com/anddroid/server/pm/Installer.java
|
|
frameworks/native/cmds/installd/installd.c
|
|
framework/native/cmds/installd/commands.c
|
|
5.Android中系统Service的安全
5.1 Binder的安全
Binder的作用:实现以IPC的RPC,完成远程业务范围.
Android进程间通信(IPC)机制Binder简要介绍和学习计划
5.2 ServiceManager Add Service的安全限制
Service Manager Process的作用: Naming Resolver,用于RPC框架中 AddService GetSetvice
5.3 Zygote的Process Fork
5.4 Zygote的Socket安全检查
6.Android中的ContentProvider以及基于URI的安全
6.1.ContentProvider的作用
6.1.1.软件设计更优美(官方)
屏蔽内部数据存储操作的差异性
对外提供一致的数据操作方式
抽象/共性---->都是数据操作
6.1.2.进程间数据共享
Proxy| Binder | Content Provider
client Process ------------------------------- > Service Process
6.2.权限临时继承的需求
临时委派使得委托者的权限临时提升(类似Root-setUID模式)
6.3.配置ContentProvider允许临时委派权限
|
|
6.4.基于URI的权限临时委派
6.4.1 基于API
|
|
6.4.2 基于Intent
|
|
权限的生命周期: Activity Start --> Destro即Activity的生命周期
7.Android的Policy模式和多设备绑定
7.1.Android的Policy模式
一个移动平台它解决用户隐私,相当的一系列控制或者说是跟用户的交互模式.
安装时安全提问
列出所有权限,提示用户是否安装.
All or Nothing
None Runtime Control
None Recallable
Disable untrust source by default
7.2.MR2开始的AppOps(安卓4.3开始)
如 LBE 等安全卫士控制权限
>基于AppOps Service
>定义Ignore , Allow Reject 3种Policy
>Hook and check Permission
7.3AppOps对开发者的影响
开发者已经申请权限时,但被LBE等安全卫士等的权限限制.
会导致权限一样获取不到.为了代码健壮性,需加多一些try catch.防止异常
7.4设备绑定
应用与设备绑定的需求前景
如,计费应用.
>同时基于SIM卡和Device的绑定(如BREW下载,单机内的下载卡可用.基于SIM卡计费,运营商间排斥)
>仅基于Device的绑定(如Google Store下载,当时下载的Device可用)
>实现: 加密 per device per SIM卡
Device Key: ESN/MEID/IMEI or random generate
SIM ID : IMSI
7.5跨设备使用
基于Account ID的云端管理
Device1 --buy it using xx@x.x account -->AppStore<----Down load freely--(Register as xx@x.x) --Device2
8.应用内计费和App2SDCard
8.1 应用内计费
什么是应用内计费
In App purchase or In app Billing(IAP,IAB)
直接在应用内进行Paymen以unLock某些功能,或者买某些道具等
应用内计费的需求
可支付途径(信用卡,手机卡等)
安全性:
面向用户
可知
可控
面向应用
可信(避免免费使用收费内容)
解决方案
>计费Server接口保密且Transiction加密(SSL)
>仅允许配套的安全本地组件与计费Server通信,且安全本地组件负责
与用户的"显式"交互,同时提供API给Client
>Clent仅允许调用本地计费安全组件来委派Transiction
>Response的signature + Nounce (防止重放攻击)
8.2 SD卡安装应用的安全策略
绑定设备
>绑定perDevice使得防Export:应用以及应用数据(SD卡允许Export)
>以加密实现之:例子,应用安装至SD卡(.Android_Secure in SDCard)
ASEC的不可访问性
由于.Android_Secure的加密特性,所以需要禁止应用直接Access该Folder(允许Access SDCard上的其他任何内容)
9.Android中的多用户安全
4.2开始可以支持
9.1需求场景
已有的例子/ Windows/Linux多用户
Android中的差别
UID/GID跟着User走
UID/GID和User的区分和绑定
应用的可控共享
共享,不存在多份Code
可控,控制谁可见.
数据的多用户独立
工作目录
External Storage(外部存储器)
9.2UserManagerService
作用:
管理User的属性信息: 设置/获取用户的UserId,Name,Icon,RestrictProfile等
管理User:创建,删除等
UserId(UserHandle)是Process的属性,不100%等同于当前设置切换的用户
一切与多用户相关的运行时行为(比如Mount的SDCard等)与进程的UserID所属有关,
而与当前设置中的当前用户没有必然联系
典型的例子:
通过adb shell的方式,永远只能访问User0的SDCard:/data/media/0,不管切换哪个用户
通过文件管理器应用访问的SDCard则与当前用户相关.
原因: adb shell只存在User0,不管在哪个当前设置用户下.
9.3对开发者的影响
永远使用相对路径(基于工作目录)以及基于Environment.getXXXX来获取你感兴趣的路径(Environment内部
会处理多用户).否则会出现路径错误而访问被拒绝的问题.
|
|
10.Android Superuser机制讲解
10.1 ROOT的作用
Customization(定制,用户化)
任何需要特权的操作
10.2 ROOT的第一步:寻找漏洞并安装特权文件
Hack会寻找漏洞,如UID设置设备(ADB)
手机Root后,最重要的是,给手机安装了su程序和superuser apk. su一般被安装在/system/xbin或者/system/bin
10.3 SU的sUID的特性
Android的App授权获取Root权限,其实不是App自身的权限提升了,而是通过具有Root权限的Sh流来执行shell命令.
|
|
这里可以看到,su是Owner和Group分别为Root,Root.Other用户具有Execute权限,另外,su设置了suid和sgid,这个非常重要,
使得Su进程可以提升自身的EUID.
10.4 SU的核心代码分析
在JB MR2(4.3)之前,Apk内部可以通过Java的Runtime执行一个
具有Root-setUid的可执行文件而提升Effective UID来完成一些特权操作,典型的Root包中的su就是这个原理.
JB MR2中,修补了改漏洞.
10.5 MR2后的方案:SU Deamon Service
怎么办? Native Service依然可以利用Root-setUID的su提升权限
11.SEAndroid
11.1 DAC和MAC
DAC
自主访问控制
主体(Process)的Capability觉得了它能访问和操作什么?
Root进程可以访问和操作一切!
传统(legacy)Linux的安全模式,基于UID/GID/Capability
MAC
强制访问控制
系统的Policy觉得了主体能操作访问哪些客体
即便是ROOT进程,系统Policy配置了你能做什么,你只能做什么,在MAC模式下,ROOT进程和普通进程是无区别对待的.
11.2 基于Label的MAC
每个主体/客体在运行时都绑定一个标签(Label)
该标签又称为Security Context
Security Context的构成
User : Role : Type : SecurityLevel
比如: u:r:zygote:s0
Type Enhancement
Security Context中的Type主要是用于Policy的设定,即Policy
一般的Rule是:
Allow Type Type : Operation
Allow appdomain zygote_tmpfs:file read;
所以,Type被实际用于"授权"的Decision,所以称之为Type Enhancement
ls命令的SELinux版本: ls -l -Z
Ps命令的SELinux版本: ps -Z
11.3 推荐读物
Your visual how-to guide for SELinux policy enforcement
Demo下载
Android中的组件的安全机制之组件的权限分配(Demo)
Activity Service ContentProvide BroadcastReceiver四大组件不同App数据通信:
Demo