该部分旨在建立了一个客观、准确评估应用安全性的模型,主要用于分析Android
APP扫描后的数据,根据风险的数量、分布和威胁程度,计算应用的安全分值。该模型认为,应用风险是造成应用安全问题的最主要的原因,将风险分为高危、中危、低危、警告、提醒和安全六个等级,每个等级赋予一定的分值,计算所有存在风险的分值之和,利用给定的指数函数模型,计算出该应用的安全分值,完成安全性评估。
1 风险等级的划分与数学表达
我们将风险分为六个等级,每个等级对应的分值见下表:
风险等级 | 分值 | 符号 | 编程所用的代号 |
---|---|---|---|
高危 | 8 | $R_{3}$ | 3 |
中危 | 4 | $R_{2}$ | 2 |
低危 | 2 | $R_{1}$ | 1 |
提醒 | 1 | $R_{0}$ | 0 |
安全 | 0 | $R_{-1}$ | -1 |
展示 | 0 | $R_{-2}$ | -2 |
表1.风险等级分值表
提醒一般为罗列需要注意的事项,低危、中危和高危说明存在由低至高的风险威胁,安全说明该风险项的威胁不存在,展示仅罗列给用户看的有意义的信息。
显然,分值分布符合2的指数幂的关系,即
特别地,令$ R_{-1} = R_{-2} = 0 $
在文档的后面,我会讲述为什么要将等级的分值进行这样的设定,此处暂且不解释。
该模型将所有的检测项目分为12类(表2),其中前3类是应用的基本信息共12项,不计入风险的评估环节,从第4类到第12类总共有70项,每项的风险等级在评估前可能有多个取值,但是在评估后都是唯一的,例如第4检查项,根据应用风险的暴露程度,可能是高危,也可能是提醒,但是在评估后,可以确认为是高危和提醒的其中一个,这是唯一的。
12类风险扫描项涵盖了大部分安卓应用存在的风险点,更详细的信息可参见文档的第三章,里边有关于每一个检测项的详细说明。
- 第1类 文件信息
- 第2类 权限信息检测
- 第3类 四大组件
- 第4类 Menifest文件检测
- 第5类 组件安全检测
- 第6类 Webview组件安全检测
- 第7类 Sqlite安全检测
- 第8类 网络通信安全检测
- 第9类 弱加密风险检测
- 第10类 数据安全检测
- 第11类 敏感函数调用检测
- 第12类 系统漏洞检测
定义$P_{i}$为评估前第i个检测项的风险等级的取值集合
项目序号 | 唯一标识 | 风险描述 | 风险等级 | 检测方式 | 风险集合Pi |
---|---|---|---|---|---|
1 | 01001 | 文件名 | 无 | 静态 |
$\varnothing$ |
2 | 01002 | 文件大小 | 无 | 静态 |
$\varnothing$ |
3 | 01003 | MD5 | 无 | 静态 |
$\varnothing$ |
4 | 01004 | 包名 | 无 | 静态 |
$\varnothing$ |
5 | 01005 | Main Activity | 无 | 静态 |
$\varnothing$ |
6 | 01006 | Min SDK | 无 | 静态 |
$\varnothing$ |
7 | 01007 | Target SDK | 无 | 静态 |
$\varnothing$ |
8 | 02001 | 权限信息检测 | 无 | 静态 |
$\varnothing$ |
9 | 03001 | Activity组件 | 无 | 静态 |
$\varnothing$ |
10 | 03002 | Service组件 | 无 | 静态 |
$\varnothing$ |
11 | 03003 | BroadcastReceiver组件 | 无 | 静态 |
$ \varnothing$ |
12 | 03004 | ContentProvider组件 | 无 | 静态 |
$\varnothing$ |
13 | 04001 | AndroidManifest文件中PermissionGroup检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
14 | 04002 | AndroidManifest文件中系统权限使用检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
15 | 04003 | AndroidManifest文件中ProtectionLevel权限检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
16 | 04004 | AndroidManifest sharedUserId检测 | 提醒 ,高危 |
静态 |
$\{R_{0},R_3\}$ |
17 | 04005 | allowBackup标志检测 | 低危 |
静态 |
$\{R_{1}\}$ |
18 | 04006 | Debuggable配置检测 | 高危 |
静态 |
$\{R_{3}\}$ |
19 | 04007 | 非必要权限检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
20 | 04008 | app最低版本检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
21 | 05001 | Activity组件导出检测 | 中危 |
静态 |
$\{R_{2}\}$ |
22 | 05002 | Service组件导出检测 | 中危 |
静态 |
$\{R_{2}\}$ |
23 | 05003 | Receiver组件导出检测 | 中危 |
静态 |
$\{R_{2}\}$ |
24 | 05004 | Provider组件导出检测 | 高危 |
静态 |
$\{R_{3}\}$ |
25 | 05005 | Provider: grant-uri-permission属性检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
26 | 05006 | Intent-Based攻击检测 | 低危 |
静态 |
$\{R_{1}\}$ |
27 | 05007 | Intent Scheme URL漏洞攻击检测 | 高危 |
静态 |
$\{R_{3}\}$ |
28 | 05008 | 应用本地拒绝服务器漏洞检测 | 低危 |
静态 |
$\{R_{1}\}$ |
29 | 05009 | manifest中定义组件未实现检测 | 中危 |
静态 |
$\{R_{2}\}$ |
30 | 05010 | Debug或Test敏感测试组件泄露检测 | 中危 ,低危 |
静态 |
$\{R_{2},R_1\}$ |
31 | 05011 | Intent不安全反射风险检测 | 低危 |
静态 |
$\{R_{1}\}$ |
32 | 06001 | Webview远程执行漏洞检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
33 | 06002 | WebView潜在XSS攻击检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
34 | 06003 | WebView本地文件访问漏洞检测 | 高危 |
静态 |
$\{R_{3}\}$ |
35 | 06004 | WebView密码明文存储漏洞检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
36 | 06005 | 主机名弱校验检测 | 中危 |
静态 |
$\{R_{2}\}$ |
37 | 06006 | 证书弱校验检测 | 中危 |
静态 |
$\{R_{2}\}$ |
38 | 06007 | 中间人攻击漏洞检测 | 中危 |
静态 |
$\{R_{2}\}$ |
39 | 06008 | WebView不校验证书漏洞检测 | 中危 |
静态 |
$\{R_{2}\}$ |
40 | 06009 | WebView组件系统隐藏接口未移除漏洞 | 低危 |
静态 |
$\{R_{1}\}$ |
41 | 07001 | SQLite数据库加密(SQLCipher)检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
42 | 07002 | SQLite数据库加密拓展(SQLite Encryption Extension,SEE)检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
43 | 07003 | SQLite数据库的对称密钥检测 - 未实现 | 提醒 |
静态 |
$\{R_{0}\}$ |
44 | 07004 | SQLite Database Transaction Deprecated(SQL注入)检测 - 未实现 | 所有 |
动态 |
$\{R_{3},R_{2},R_{1},R_{0}\}$ |
45 | 07005 | Databases任意读写漏洞检测 - 废弃 | 中危 |
静态 |
$\{R_{2}\}$ |
46 | 08001 | SSL不安全组件检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
47 | 08002 | SSL连接检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
48 | 08003 | HttpHost检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
49 | 08004 | HttpURLConnection漏洞检测 - 废弃 | 低危 |
静态 |
$\{R_{1}\}$ |
50 | 08005 | 网络端口开放威胁检测 | 低危 |
混合 |
$\{R_{1}\}$ |
51 | 09001 | 弱加密算法风险检测 | 低危 |
静态 |
$\{R_{1}\}$ |
52 | 09002 | 不安全的密钥长度风险检测 | 低危 |
静态 |
$\{R_{1}\}$ |
53 | 09003 | ECB弱加密模式风险检测 | 低危 |
静态 |
$\{R_{1}\}$ |
54 | 09004 | IVParameterSpec不安全初始化向量风险检测 | 低危 |
混合 |
$\{R_{1}\}$ |
55 | 09005 | RSA中不使用Padding风险检测 | 低危 |
静态 |
$\{R_{1}\}$ |
56 | 09006 | 检测keystore是否使用密码保护 - 未实现 | 高危 |
动态 |
$\{R_{3}\}$ |
57 | 10001 | 敏感信息检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
58 | 10002 | 剪贴板敏感信息泄露风险检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
59 | 10003 | Intent敏感数据泄露风险检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
60 | 10004 | PendingIntent误用风险 | 中危 |
静态 |
$\{ R_{2} \}$ |
61 | 10005 | 密钥硬编码风险检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
62 | 10006 | 数据或程序加载检查 - 未实现 | 提醒 |
动态 |
$\{R_{0}\}$ |
63 | 10007 | BASE64安全检测 | 展示 |
静态 |
$\{R_{-2}\}$ |
64 | 10008 | 文件全局读写漏洞检测 | 中危 |
静态 |
$\{R_{2}\}$ |
65 | 10009 | 日志泄露风险检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
66 | 10010 | 外部加载Dex检测 - 去掉 | 高危 |
静态 |
$\{R_{3}\}$ |
67 | 10011 | 外部存储路径检测 - 未实现 | 提醒 |
动态 |
$\{R_{0}\}$ |
68 | 10012 | 明文数字证书风险 - 未实现 | 提醒 |
静态 |
$\{R_{0}\}$ |
69 | 11001 | 安全相关的函数检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
70 | 11002 | 安全相关的类检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
71 | 11003 | 运行命令检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
72 | 11004 | Native Library加载检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
73 | 11005 | 外部动态加载DEX检测 | 高危 |
混合 |
$\{R_{3}\}$ |
74 | 11006 | root代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
75 | 11007 | 获取IMEI和Device ID敏感信息代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
76 | 11008 | 获取Android ID敏感信息代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
77 | 11009 | 发送SMS敏感代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
78 | 11010 | 文件删除代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
79 | 11011 | signature代码检测 | 提醒 |
静态 |
$\{R_{0}\}$ |
80 | 12001 | fragment注入漏洞检测 | 中危 |
静态 |
$\{R_{2}\}$ |
81 | 12002 | sqlite数据库日志泄露漏洞检测 | 低危 |
静态 |
$\{R_{1}\}$ |
82 | 12003 | 随机数生成漏洞检测 | 高危 |
静态 |
$\{R_{3}\}$ |
表2.风险评估环节表
现在考虑评估完成后的情况,每个检测项都会有唯一标定的风险等级,即从每一项的风险等级集合与安全集合的并集$P_i\cup\{R_{-1}\}$中选取一个合适的值,作为该检测项的评估结果。
定义$r_{i} $为评估后第i个检测项的风险等级,即
特别地, $P_i = \varnothing$则令$r_i = 0$
所以,所有检测项的风险等级的分值总和为S,可以表示为
最后,定义安全系数K
其中Floor是向下取整函数,则K就是我们所要的结果
为什么采用K(s)来表示威胁与安全系数的关系是接下来要说明的,我们来考虑函数K(s)的性质:
其原型是一个以0.985为底的指数衰减函数,我们记为取整前的函数为K(s)*,即
性质一 K(s)是单调递减函数
性质二 K(s)*变化率随S的增大而减小,表现为曲线由抖变缓
性质三 K(s)*的值域为(0,100],当s足够大时,K(s)*无限趋近于0,向下取整后为0
性质四
令s = 1, 则K(s) = 98
令s = 2, 则K(s) = 97
令s = 4, 则K(s) = 94
令s = 8, 则K(s) = 88
令s = 16, 则K(s) = 78
图1 K(s)函数图像
我们可以观察到,K(s)符合现实中风险与安全系数的关系:
性质一
风险分值S越高,安全指数K越低,应用面临的风险越大;风险分值S越低,安全指数K越高,应用越安全。
性质二
K前期变化率大,后期变化率小,说明在应用出现风险时,应用安全系数会快速下跌,此时往往一两个高危漏洞就可以让系统沦陷;可是当风险已经足够多时,系统已不再安全,应用已经有够多的漏洞可以利用时,再增加风险的分值,对安全系数的减小的影响会降低
性质三
风险评估采用常见的百分制。当风险分值为0,安全系数为100;当风险值不断增大时,安全系数能够取到0。安全系数位于闭区间[0,100]。
性质四
性质四的现实意义可以用下表来表示:
安全系数分值 | 风险分值 | 风险组合的集合表示 | 风险组合的文字表述 |
---|---|---|---|
98 | 1 | $\{R_{0}\times2 \}$ | 1个提醒 |
97 | 2 | $\{R_{1}\}$ | 1个低危 |
94 | 4 | $\{R_{2} \}$ | 1个中危 |
88 | 8 | $\{R_{3} \}$ | 1个高危 |
78 | 16 | $\{R_{3} \}$ | 2个高危 |
表3.风险组合与安全系数的关系
根据性质四,我们可以制定应用安全的等级的标准
应用安全等级 | 安全系数分值区间 | 编程所用的代码 |
---|---|---|
安全 | 90~100 | -1 |
合格 | 70~89 | 0 |
警告 | 50~69 | 1 |
危险 | < 50 | 2 |
表4.应用安全的等级标准说明
最后,我需要说明风险等级分值标定的原因,安全和展示等级可以认为对风险的贡献为0。根据经验,我们可以直观地理解,随着风险等级的提升,其危害程度不应该是线性递增,而应该是指数递增,例如高危风险的危害程度应该远远大于低危风险。所以在标定风险的分值时,我采用了2的指数幂的方式进行标定分值,能更好地拟合现实中危害程度随风险等级的变化。
风险等级 | 分值 | 符号 | 指数关系 |
---|---|---|---|
高危 | 8 | $R_{3}$ | $2^3$ |
中危 | 4 | $R_{2}$ | $2^2$ |
低危 | 2 | $R_{1}$ | $2^1$ |
提醒 | 1 | $R_{0}$ | $2^0$ |
安全 | 0 | $R_{-1}$ | 特殊情况 |
展示 | 0 | $R_{-2}$ | 特殊情况 |
表5.风险等级与指数的关系